This release combines the changes made for the revisions of Doosti (2026b, 2026c) with fixes from the wavelet branch.
copula_psi(),
copula_delta(), copula_delta_prime()) are
evaluated without the catastrophic cancellation in
1 + a^n / D^(n-1) at large theta (Kendall’s
tau above about 0.8); previously psi was exactly 0 near
u = 1 at tau = 0.9.fpa_revenue_qd() and fpa_optimal_reserve_qd()
is accumulated from the top; the previous forward difference lost
precision for Clayton at theta >= 2 (up to 0.05 in
revenue at the 90th reserve percentile for tau = 0.75).fpa_optimal_reserve_model() searches from
p_lo = 1e-4 (was 0.02), so interior optima close to the
lower support are no longer reported as corners.select_bandwidth() and qdf() use exact
leave-one-out by default for every selector, including
"wbcv". The scaling approximation q (n-1)/n,
invalid for estimators built from order statistics, is used only with
loo = FALSE.bcv_criterion(), rlcv_criterion() and
wbcv_criterion() can be called directly with their default
u_scheme (previously an error), and
wbcv_criterion() now uses exact leave-one-out by default
(loo = TRUE), as select_bandwidth() does.qdf() with a wavelet method and no
bandwidth argument now uses cross-validation
(bandwidth = "cv") instead of failing.print() method of fpa_values() no
longer shows theta = NULL for the nonparametric copula
multiplier.timber dataset now states that
the bids are homogenised, not raw: within each stratum the log bids were
regressed on the log appraised per-unit value and the log timber volume
and rescaled to the average lot (R-squared 0.671 for n = 2 and 0.554 for
n = 3). The data are unchanged.data-raw/timber.R now rebuilds the dataset from the
Journal of Applied Econometrics Data Archive files of Lu and Perrigne
(2008) (doi:10.15456/jae.2022319.0720356598), applying that regression,
instead of storing the bids as literal values.fpa_virtual_value() and
fpa_virtual_value_model(): the affiliated virtual value
omega(u) = Q(u) - q(u) H(u).fpa_corner_test() (with a print() method):
a crossing test for whether any binding reserve price is optimal (Doosti
2026c). The decision is the point rule on the full sample, `min over u
in [0.10, 0.98] of omega_hat(u)
; a bootstrap over auctions gives the frequency of that decision. The copulafamily`
is a required argument, because the result depends on it.qdf(bandwidth = "sqrt") (and fpa_values(),
the revenue functions and fpa_revenue_boot() through it):
the deterministic rule m = ceiling(sqrt(N)) for the
Bernstein estimator, used in Doosti (2026b). It lies inside the range
covered by that paper’s asymptotic theory.qdf_bernstein() gains zero_at_origin;
qdf_bernstein_loo() computes exact leave-one-out Bernstein
estimates by an index shift in O(nK) and is used automatically by the
cross-validation criteria.select_bandwidth(grid = "exhaustive") returns the
global minimiser over all integer m in m_range
(not the default).fpa_montecarlo() gains p0 and
eta, passed to the simulator.fpa_revenue_qd(),
fpa_optimal_reserve_qd(), fpa_virtual_value()
and fpa_corner_test(): if the data-driven bandwidth for the
pseudo-values is minimised at an end of m_range, the
quantile density is refitted with the published range
m_range = c(10, 50) and stats::optimize()
(Doosti 2026c), with a warning; if that fit is also at an end, the
function stops and asks for a numeric bandwidth.select_bandwidth() and
qdf() accept only grid = "exhaustive" or a
non-negative integer (a mistyped value used to fall back silently to
optimize()); qdf_bernstein_loo() checks that
u has one increasing value per observation, that the data
are positive and that floor(1/h) >= 2.qdf() lists all ten estimators and gives
the correct pages for Parzen (1979); the default grid of
fpa_density_ci() is described correctly;
qdf_wavelet_nl() explains when post-smoothing helps.inst/benchmarks/scaling.R also times the functions for
affiliated values, the specification test and the density
bootstrap.fpa_revenue_boot() resamples whole auctions by default
(resample = "auctions"; previously "bids").
The revenue estimator uses the highest pseudo-value in each auction, and
resampling pooled bids breaks that structure: in the design of Zincenko
(2024), with the Bernstein estimator and
m = ceiling(sqrt(N)), pooled resampling gave pointwise
coverage of about 0.65-0.80 at nominal 0.90, against 0.85-0.89 with
auction resampling. "bids" is kept for comparison.
fpa_corner_test() already resamples auctions;
fpa_density_boot() keeps "bids", because the
density estimators do not use the auction structure.bandwidth = "wbcv",
select_bandwidth(selector = "wbcv") and
wbcv_criterion() are kept only for backward compatibility,
are not recommended, and now warn. The two terms of the WBCV criterion
have different units, so the selected bandwidth depends on the units of
the data, and on data of order one or larger the criterion tends to
select the smoothest fit in m_range. The criterion is being
revised (Doosti 2026b); it is kept so that existing code runs. Examples,
the README and the vignette now use BCV.select_bandwidth() and qdf() keep
stats::optimize() over m_range as the default
search for every selector, as in the published simulations;
grid = "exhaustive" (every integer m in
m_range, the global minimiser) is available as an option. A
user-supplied optimizer takes precedence over the
exhaustive search."wbcv" in
select_bandwidth() and qdf() (previously the
scaling approximation); see Bug fixes.fpa_revenue_boot() and the bootstrap of
fpa_corner_test() select the bandwidth once, on the full
sample, and hold it fixed in every bootstrap replication, as the theory
assumes (Doosti 2026b, Theorems 6-7); previously the bandwidth was
re-selected in each replicate. Results with a data-driven
bandwidth change; results with a numeric
bandwidth do not. The selected m and whether
it lies at a boundary are returned and printed.select_bandwidth() detects boundary solutions for every
selector and search method: if the minimiser lies at either end of
m_range, it warns and returns
at_boundary = TRUE (and boundary = "lower" or
"upper"), and print() of a qdf()
fit reports it. A boundary minimum means that the criterion did not
select a bandwidth in that range.First CRAN release.
qdf()).fpa_values()), with GPV, boundary-corrected and Zincenko
kernel benchmarks and monotonicity options.fpa_density()), tuned by interior least-squares or
log-likelihood cross-validation
(select_fpa_density()).fpa_density_ci()).fpa_revenue(), fpa_optimal_reserve(),
fpa_revenue_boot()), exact equilibrium bids and simulation
(fpa_bid_function(), fpa_simulate()), Monte
Carlo and evaluation tools (fpa_montecarlo(),
fpa_evaluate_values(),
fpa_evaluate_density()).make_kernel(),
with check_kernel() reporting mass, symmetry, order and
roughness; a user-supplied optimiser for bandwidth selection
(optimizer in select_bandwidth() and
qdf()).inst/benchmarks/scaling.R times the main functions as
the sample grows.timber) and a vignette.fpa_revenue_qd(), fpa_optimal_reserve_qd();
Doosti 2026c).qdf_wavelet_nl()), on a periodised orthonormal basis
(phi_per(), psi_per(),
psi_jk()).fpa_density(method = "wavelet_theory")).copula_psi_np(),
fpa_values(family = "nonparametric")) and a bootstrap
specification test for parametric copulas
(copula_spec_test()) (Doosti 2026a). The semiparametric
estimator of Hubbard, Li and Paarsch (2012) is documented as
fpa_values(method = "gpv", family = ...).fpa_density_boot()).qdf() is now scale-equivariant for every estimator: it
estimates on x / sd(x) and rescales
(rescale = TRUE). This matters for the indirect Poisson,
Jones and Soni estimators, whose smoothing parameter lives on the data
scale; rescale = FALSE reproduces the earlier behaviour.
The default evaluation grid is now i/(n+1).select_wavelet() (and
qdf(..., bandwidth = "cv") for the wavelet estimators) uses
least-squares cross-validation by default
(criterion = "lscv") and skips bandwidths below the lattice
spacing; cross-validation arguments are no longer passed on to the
estimator.