@@ -206,62 +206,25 @@ do_psis_i <- function(log_ratios_i, tail_len_i, ...) {
206206 S <- length(log_ratios_i )
207207 # shift log ratios for safer exponentation
208208 lw_i <- log_ratios_i - max(log_ratios_i )
209- khat <- Inf
210209
211- if (enough_tail_samples(tail_len_i )) {
212- ord <- sort.int(lw_i , index.return = TRUE )
213- tail_ids <- seq(S - tail_len_i + 1 , S )
214- lw_tail <- ord $ x [tail_ids ]
215- if (abs(max(lw_tail ) - min(lw_tail )) < .Machine $ double.eps / 100 ) {
216- warning(
217- " Can't fit generalized Pareto distribution " ,
218- " because all tail values are the same." ,
219- call. = FALSE
220- )
221- } else {
222- cutoff <- ord $ x [min(tail_ids ) - 1 ] # largest value smaller than tail values
223- smoothed <- psis_smooth_tail(lw_tail , cutoff )
224- khat <- smoothed $ k
225- lw_i [ord $ ix [tail_ids ]] <- smoothed $ tail
226- }
227- }
210+ smoothed <- posterior :: pareto_smooth_tail(
211+ x = lw_i ,
212+ ndraws_tail = tail_len_i ,
213+ tail = " right" ,
214+ are_log_weights = TRUE
215+ )
216+
217+ lw_i <- smoothed $ x
218+ khat <- smoothed $ k
228219
229220 # truncate at max of raw wts (i.e., 0 since max has been subtracted)
230221 lw_i [lw_i > 0 ] <- 0
231222 # shift log weights back so that the smallest log weights remain unchanged
232223 lw_i <- lw_i + max(log_ratios_i )
233224
234- list (log_weights = lw_i , pareto_k = khat )
235- }
236-
237- # ' PSIS tail smoothing for a single vector
238- # '
239- # ' @noRd
240- # ' @param x Vector of tail elements already sorted in ascending order.
241- # ' @return A named list containing:
242- # ' * `tail`: vector same size as `x` containing the logs of the
243- # ' order statistics of the generalized pareto distribution.
244- # ' * `k`: scalar shape parameter estimate.
245- # '
246- psis_smooth_tail <- function (x , cutoff ) {
247- len <- length(x )
248- exp_cutoff <- exp(cutoff )
249-
250- # save time not sorting since x already sorted
251- fit <- gpdfit(exp(x ) - exp_cutoff , sort_x = FALSE )
252- k <- fit $ k
253- sigma <- fit $ sigma
254- if (is.finite(k )) {
255- p <- (seq_len(len ) - 0.5 ) / len
256- qq <- qgpd(p , k , sigma ) + exp_cutoff
257- tail <- log(qq )
258- } else {
259- tail <- x
260- }
261- list (tail = tail , k = k )
225+ list (log_weights = lw_i , pareto_k = if (is.na(khat )) Inf else khat )
262226}
263227
264-
265228# ' Calculate tail lengths to use for fitting the GPD
266229# '
267230# ' The number of weights (i.e., tail length) used to fit the generalized Pareto
0 commit comments