| Title: | Nonparametric Quantile Density Estimation and Structural Analysis of First-Price Auctions |
|---|---|
| Description: | Nonparametric estimators of the quantile density function (the derivative of the quantile function): kernel, boundary-corrected kernel, Poisson-weight and Bernstein-polynomial smoothers, indirect estimators (Jones (1992) <https://www.ism.ac.jp/editsec/aism/pdf/044_4_0721.pdf>; Soni, Dewan and Jain (2012) <doi:10.1016/j.csda.2012.04.014>; Chaubey, Dewan and Li (2024) <doi:10.1080/03610926.2023.2222922>), and linear, hard-thresholded and block-thresholded wavelet estimators (Chesneau, Dewan and Doosti (2016) <doi:10.1016/j.csda.2015.08.006>; Shirazi and Doosti (2022) <doi:10.1080/03610918.2019.1656250>), with smoothing parameters chosen by biased, robust likelihood (Wu (2019) <doi:10.1080/07350015.2018.1424633>) or least-squares cross-validation. The estimators are applied to the structural analysis of first-price sealed-bid auctions: recovery of private values for independent or affiliated values and risk-neutral or risk-averse bidders (Doosti, Dewan and Talebian (2025) <doi:10.1016/j.econlet.2025.112670>; Doosti (2026) <doi:10.1016/j.econlet.2026.112837>), estimation of the private-value density with kernel benchmarks (Hickman and Hubbard (2015) <doi:10.1002/jae.2385>; Marmer and Shneyerov (2012) <doi:10.1016/j.jeconom.2011.09.020>; Zincenko (2024) <doi:10.1016/j.jeconom.2024.105734>) and confidence bands (Ma, Marmer and Shneyerov (2019) <doi:10.1016/j.jeconom.2019.02.006>), and estimation of the seller's expected revenue and optimal reserve price, with tools for simulating equilibrium bids and comparing estimators. |
| Authors: | Hassan Doosti [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-0290-8122>, affiliation: School of Mathematical and Physical Sciences, Macquarie University), Yogendra P. Chaubey [ctb, cph] (original R code of the quantile density estimators and cross-validation criteria, revised and vectorised in R/estimators.R and R/bandwidth.R), Isha Dewan [ctb, cph] (original R code of the quantile density estimators and cross-validation criteria, revised and vectorised in R/estimators.R and R/bandwidth.R), Jun Li [ctb, cph] (original R code of the quantile density estimators and cross-validation criteria, revised and vectorised in R/estimators.R and R/bandwidth.R), Brent R. Hickman [ctb, cph] (original MATLAB implementation of the boundary-corrected kernel density estimator, translated to R in kde_hh()), Timothy P. Hubbard [ctb, cph] (original MATLAB implementation of the boundary-corrected kernel density estimator, translated to R in kde_hh()), Brani Vidakovic [ctb, cph] (original MATLAB routines Phijk, dwtr, Idwtr and loc_lin, translated to R in scaling_function(), phi_jk(), dwt_periodic(), idwt_periodic() and loclin_smooth()), Vadim Marmer [ctb, cph] (original MATLAB implementation of the quantile-based estimator, translated to R in density_marmer_shneyerov(); reference implementation used to validate fpa_density_ci()), Jun Ma [ctb] (reference implementation of inference for the GPV estimator, used to validate fpa_density_ci()), Artyom Shneyerov [ctb, cph] (original MATLAB implementation of the quantile-based estimator, translated to R in density_marmer_shneyerov()), Federico Zincenko [ctb, cph] (original implementation of the kernel estimator of private values with boundary extrapolation, adapted in fpa_values(method = 'zincenko')) |
| Maintainer: | Hassan Doosti <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.2.0 |
| Built: | 2026-10-22 19:31:34 UTC |
| Source: | https://github.com/doostih/qdfauction |
Three data-driven criteria for the smoothing parameter of a quantile density
estimator, written as functions of so that they can be passed
to stats::optimize(). Each is evaluated on the grid with
spacings , , so that
approximates .
bcv_criterion() is the biased (least-squares) cross-validation used by
Chaubey, Dewan and Li (2024) and Doosti, Dewan and Talebian (2025):
i.e. the classical written in
terms of . (Equation (11) of Doosti, Dewan and
Talebian (2025) prints in the first term; the simulation
code, reproduced here, uses .)
rlcv_criterion() is the robust likelihood cross-validation of Wu (2019),
, with
linearised below the threshold . It is written so that
it is minimised.
wbcv_criterion() is the weighted criterion of Doosti (2026b), which
targets (the quantity entering the first-price auction
inversion) rather than :
Not recommended; kept only for backward compatibility. The criterion
is not scale-invariant: its two terms have different units (the first scales
like the cube of the data units, the second like their inverse), so the
selected bandwidth depends on the units of the data; on data of order one
or larger the first term dominates and the criterion tends to select the
smoothest fit in m_range. The criterion is being revised (Doosti 2026b,
revised version); wbcv_criterion() and bandwidth = "wbcv" issue a
warning and are kept only so that existing code runs. Use BCV, RLCV or a
numeric bandwidth instead.
bcv_criterion(m, x, fun, loo = TRUE, u_scheme = c("i/n", "i/(n+1)")) rlcv_criterion(m, x, fun, loo = TRUE, u_scheme = c("i/n", "i/(n+1)")) wbcv_criterion(m, x, fun, loo = TRUE, u_scheme = c("i/(n+1)", "i/n"))bcv_criterion(m, x, fun, loo = TRUE, u_scheme = c("i/n", "i/(n+1)")) rlcv_criterion(m, x, fun, loo = TRUE, u_scheme = c("i/n", "i/(n+1)")) wbcv_criterion(m, x, fun, loo = TRUE, u_scheme = c("i/(n+1)", "i/n"))
m |
inverse bandwidth, |
x |
numeric sample (sorted internally). |
fun |
an estimator with signature |
loo |
logical; if |
u_scheme |
grid on which the criterion is evaluated: |
a single numeric value; smaller is better.
Wu, X. (2019). Robust likelihood cross validation for kernel density estimation. Journal of Business & Economic Statistics, 37, 761–770.
x <- rgamma(60, 5, 1) bcv_criterion(20, x, qdf_kernel) rlcv_criterion(20, x, qdf_kernel) optimize(bcv_criterion, c(10, 50), x = x, fun = qdf_bernstein)$minimumx <- rgamma(60, 5, 1) bcv_criterion(20, x, qdf_kernel) rlcv_criterion(20, x, qdf_kernel) optimize(bcv_criterion, c(10, 50), x = x, fun = qdf_bernstein)$minimum
Transforms bids to pooled Hazen scores ,
forms all within-auction pairs, and maximises the bivariate copula
log-likelihood over . Only pairs within the same auction are
used (pairs straddling auctions are independent and would bias
toward independence).
copula_fit(bids, family = c("clayton", "gumbel", "frank"), bounds = NULL)copula_fit(bids, family = c("clayton", "gumbel", "frank"), bounds = NULL)
bids |
numeric matrix, one row per auction and one column per bidder. |
family |
|
bounds |
optional search interval for |
a list with theta, tau (implied Kendall's tau), family,
loglik and n_pairs.
set.seed(1) U <- rcopula_archimedean(100, 3, "clayton", theta = 2) copula_fit(U, "clayton")set.seed(1) U <- rcopula_archimedean(100, 3, "clayton", theta = 2) copula_fit(U, "clayton")
For an exchangeable -dimensional Archimedean copula :
copula_psi() is the copula multiplier of Doosti (2026a),
, which enters the inverse bid
function . Under independence
and the GPV formula is recovered.
copula_delta() is the diagonal , the
distribution function of the maximum of the uniform scores.
copula_delta_prime() is its derivative.
copula_psi(u, family = "independence", theta = NULL, n) copula_delta(u, family = "independence", theta = NULL, n) copula_delta_prime(u, family = "independence", theta = NULL, n)copula_psi(u, family = "independence", theta = NULL, n) copula_delta(u, family = "independence", theta = NULL, n) copula_delta_prime(u, family = "independence", theta = NULL, n)
u |
numeric vector in |
family |
|
theta |
copula parameter (ignored for independence). |
n |
number of bidders. |
numeric vector.
Doosti, H. (2026a). A copula-quantile density approach to affiliated private value auctions. Economics Letters, 261, 112837. doi:10.1016/j.econlet.2026.112837
u <- c(0.2, 0.5, 0.8) copula_psi(u, "clayton", theta = 2, n = 3) copula_psi(u, "independence", n = 3) # u / (n - 1) copula_delta(u, "gumbel", theta = 1.5, n = 3)u <- c(0.2, 0.5, 0.8) copula_psi(u, "clayton", theta = 2, n = 3) copula_psi(u, "independence", n = 3) # u / (n - 1) copula_delta(u, "gumbel", theta = 1.5, n = 3)
Estimates the copula multiplier of the inverse bid function
without a parametric copula. In the rank scale,
with a bidder's rank and the highest rank among its rivals in
the same auction,
the ratio of the conditional distribution and density of the highest rival
bid at the bidder's own bid, expressed in ranks (the quantity identified by
Li, Perrigne and Vuong 2002). Both are estimated with beta kernels on
(Chen 1999; Chen and Fan 2006):
Under independence . This is the flexible copula
multiplier of the copula–quantile density estimator (Doosti 2026a); it is
used by fpa_values(family = "nonparametric") and by
copula_spec_test().
copula_psi_np(bids, u, b = NULL)copula_psi_np(bids, u, b = NULL)
bids |
an |
u |
points in |
b |
beta-kernel bandwidth; default |
numeric vector .
Chen, S. X. (1999). Beta kernel estimators for density functions. Computational Statistics & Data Analysis, 31, 131–145.
Chen, X. and Fan, Y. (2006). Estimation of copula-based semiparametric time series models. Journal of Econometrics, 130, 307–335.
Doosti, H. (2026a). A copula-quantile density approach to affiliated private value auctions. Economics Letters, 261, 112837. doi:10.1016/j.econlet.2026.112837
set.seed(1) U <- rcopula_archimedean(300, 3, "clayton", theta = 2) u <- c(0.2, 0.5, 0.8) rbind(nonparametric = copula_psi_np(U, u), clayton = copula_psi(u, "clayton", 2, 3), independence = copula_psi(u, "independence", n = 3))set.seed(1) U <- rcopula_archimedean(300, 3, "clayton", theta = 2) u <- c(0.2, 0.5, 0.8) rbind(nonparametric = copula_psi_np(U, u), clayton = copula_psi(u, "clayton", 2, 3), independence = copula_psi(u, "independence", n = 3))
Tests whether an exchangeable Archimedean copula family is compatible with
the bids, using
over a grid of
interior quantiles (Doosti 2026a), where is
copula_psi_np() and is the pseudo-maximum-likelihood
estimate of copula_fit(). Critical values come from a parametric bootstrap
under the null: rank matrices are simulated from the fitted copula, the
parameter is re-estimated and the statistic recomputed. Because both
multipliers depend on the bids only through their ranks, the test does not
involve the marginal distribution.
copula_spec_test( bids, family = c("clayton", "gumbel", "frank", "independence"), B = 199, grid = seq(0.1, 0.9, by = 0.02), b = NULL )copula_spec_test( bids, family = c("clayton", "gumbel", "frank", "independence"), B = 199, grid = seq(0.1, 0.9, by = 0.02), b = NULL )
bids |
an |
family |
|
B |
number of bootstrap replications. |
grid |
interior quantiles over which the supremum is taken. |
b |
beta-kernel bandwidth, see |
an object of class "htest" with the statistic, the bootstrap
p-value and the fitted parameter.
Call set.seed() beforehand to make the bootstrap reproducible.
set.seed(1) U <- rcopula_archimedean(150, 3, "gumbel", theta = 2) copula_spec_test(U, "gumbel", B = 99) copula_spec_test(U, "independence", B = 99)set.seed(1) U <- rcopula_archimedean(150, 3, "gumbel", theta = 2) copula_spec_test(U, "gumbel", B = 99) copula_spec_test(U, "independence", B = 99)
Convert between Kendall's tau and the copula parameter
copula_tau_to_theta(tau, family = c("clayton", "gumbel", "frank")) copula_theta_to_tau(theta, family = c("clayton", "gumbel", "frank"))copula_tau_to_theta(tau, family = c("clayton", "gumbel", "frank")) copula_theta_to_tau(theta, family = c("clayton", "gumbel", "frank"))
tau, theta
|
scalar values. |
family |
|
numeric scalar.
copula_tau_to_theta(0.5, "clayton") # 2 copula_theta_to_tau(2, "gumbel") # 0.5copula_tau_to_theta(0.5, "clayton") # 2 copula_theta_to_tau(2, "gumbel") # 0.5
Estimates the private-value density in a symmetric IPV first-price auction
directly from bids: the bid quantile function and density are estimated
with a triweight kernel, the preliminary value quantile
is monotonised around
, inverted to give , and the density is
evaluated at . Bandwidths follow the authors'
normal-reference rules ( for ,
for ). This function is an R
translation of the authors' MATLAB implementation, which is available from
the first author's website (see inst/COPYRIGHTS for the exact location).
density_marmer_shneyerov(x, bids, n, tau0 = 0.5, cap = 1000)density_marmer_shneyerov(x, bids, n, tau0 = 0.5, cap = 1000)
x |
evaluation points on the value scale. |
bids |
pooled bids. |
n |
number of bidders per auction. |
tau0 |
reference quantile for the monotonisation. |
cap |
upper cap on the estimate (numerical safeguard). |
numeric vector of density estimates at x.
Marmer, V. and Shneyerov, A. (2012). Quantile-based nonparametric inference for first-price auctions. Journal of Econometrics, 167(2), 345–357. doi:10.1016/j.jeconom.2011.09.020
Forward (dwt_periodic()) and inverse (idwt_periodic()) periodised
orthonormal DWT with L levels, as in Vidakovic (1999). length(x) must be
divisible by 2^L. Coefficients are returned as
c(smooth, detail_coarsest, ..., detail_finest). Translated from the
MATLAB routines dwtr and Idwtr of B. Vidakovic.
dwt_periodic(x, L, filter = "coif1") idwt_periodic(w, L, filter = "coif1")dwt_periodic(x, L, filter = "coif1") idwt_periodic(w, L, filter = "coif1")
x |
numeric vector. |
L |
number of levels. |
filter |
see |
w |
wavelet coefficients from |
numeric vector of the same length as x.
x <- rnorm(32) all.equal(idwt_periodic(dwt_periodic(x, 3, "coif1"), 3, "coif1"), x)x <- rnorm(32) all.equal(idwt_periodic(dwt_periodic(x, 3, "coif1"), 3, "coif1"), x)
Computes the symmetric equilibrium bid function in quantile space,
with the markup solving
, (Milgrom and Weber 1982;
Doosti 2026a). Under independence and this is the
Guerre–Perrigne–Vuong bid function
. A reserve price at
quantile p0 sets . For CRRA bidders with utility
the first-order condition is
(Guerre, Perrigne and Vuong 2009), so the
markup solves the same ODE with replaced by ;
under independence this gives Zincenko's (2024) risk-averse bid function
,
, .
fpa_bid_function( Q, q = NULL, n, family = "independence", theta = NULL, p0 = 0, eta = 0, U = fpa_ugrid() )fpa_bid_function( Q, q = NULL, n, family = "independence", theta = NULL, p0 = 0, eta = 0, U = fpa_ugrid() )
Q |
quantile function of private values (a function of |
q |
quantile density of private values (a function of |
n |
number of bidders. |
family |
|
theta |
copula parameter (ignored for independence). |
p0 |
screening quantile of the reserve price (default 0, no reserve). |
eta |
CRRA risk-aversion parameter in |
U |
quantile grid; see |
a list with U, bid (), value (),
markup and a function beta(v) interpolating the bid at value v.
bf <- fpa_bid_function(Q = function(u) qgamma(u, 2, 10), q = function(u) 1 / dgamma(qgamma(u, 2, 10), 2, 10), n = 5) bf$beta(c(0.1, 0.2, 0.5)) # compare with the direct integral form for IPV v <- 0.2; v - integrate(function(t) pgamma(t, 2, 10)^4, 0, v)$value / pgamma(v, 2, 10)^4bf <- fpa_bid_function(Q = function(u) qgamma(u, 2, 10), q = function(u) 1 / dgamma(qgamma(u, 2, 10), 2, 10), n = 5) bf$beta(c(0.1, 0.2, 0.5)) # compare with the direct integral form for IPV v <- 0.2; v - integrate(function(t) pgamma(t, 2, 10)^4, 0, v)$value / pgamma(v, 2, 10)^4
Decides whether any binding reserve price is optimal. The point rule classifies the sample as a corner (no binding reserve optimal) when
with the estimated affiliated virtual value of
fpa_virtual_value(). The window starts at p_lo = 0.10 rather than at
the boundary: with equal to the lower end of the support,
as for every copula, so the region
near zero carries no information about the corner, while the quantile
density of the pseudo-values is least accurately estimated there.
The decision is the point rule on the full sample (decision = "point",
the default and the rule used in Doosti 2026c): a corner is reported when
. The null tested is "no reserve above the p_lo quantile
beats no reserve". In applications the copula family should be chosen with
copula_spec_test().
With B > 0, auctions are resampled with replacement, with the bandwidths
of both stages selected once on the full sample and held fixed in every
replication, and the frequency with which the point rule reports a corner is
returned. Two alternative uses of the bootstrap are available but are not
the default: decision = "bootstrap" reports a corner when that frequency
is at least level; and corner_not_rejected records whether the upper
bootstrap percentile of is non-negative (a
conservative rule, since , a minimum of a noisy curve, is biased
downward).
fpa_corner_test( bids, v_s = 0, family, method = "poisson", bandwidth = "rlcv", qdf_method = "poisson", p_lo = 0.1, p_hi = 0.98, B = 0, decision = c("point", "bootstrap"), level = 0.5, alpha = 0.1, ... ) ## S3 method for class 'fpa_corner_test' print(x, ...)fpa_corner_test( bids, v_s = 0, family, method = "poisson", bandwidth = "rlcv", qdf_method = "poisson", p_lo = 0.1, p_hi = 0.98, B = 0, decision = c("point", "bootstrap"), level = 0.5, alpha = 0.1, ... ) ## S3 method for class 'fpa_corner_test' print(x, ...)
bids |
an |
v_s |
seller's valuation. |
family |
copula family used to recover the values (see |
method, bandwidth
|
first-stage quantile density estimator and
bandwidth rule for |
qdf_method |
quantile density estimator for the pseudo-values. |
p_lo, p_hi
|
window of quantiles over which the minimum is taken. |
B |
number of bootstrap replications (0: point rule only). |
decision |
|
level |
bootstrap corner frequency above which a corner is reported
when |
alpha |
level for the upper bootstrap percentile of the statistic. |
... |
further arguments to |
x |
an |
An object of class "fpa_corner_test": a list with the
statistic , the decision corner, the estimated virtual value
omega on the grid U, v_s, p_range, the bandwidths used in
the two stages and the decision rule; with B > 0 also
boot_stat, boot_corner_freq, boot_upper and corner_not_rejected.
The print() method is called for its side effect of printing the
decision and returns x invisibly.
Call set.seed() beforehand to make the bootstrap reproducible.
Doosti, H. (2026c). Optimal reserve prices in affiliated private value auctions: a copula–quantile density approach. SSRN preprint. doi:10.2139/ssrn.7273869
set.seed(1) Q <- function(u) (1 - 8 * u / 9)^(-1/2) sim <- fpa_simulate(60, 3, Q, family = "clayton", theta = copula_tau_to_theta(0.5, "clayton")) fpa_corner_test(sim$bids, v_s = 1, family = "clayton")set.seed(1) Q <- function(u) (1 - 8 * u / 9)^(-1/2) sim <- fpa_simulate(60, 3, Q, family = "clayton", theta = copula_tau_to_theta(0.5, "clayton")) fpa_corner_test(sim$bids, v_s = 1, family = "clayton")
Two-step estimation of the density of independent private values.
The first step recovers pseudo-values from the bids (by
default with the Hickman–Hubbard boundary-corrected GPV inversion, or
with any fpa_values() fit); the second step estimates the density of
the pseudo-values by
"wavelet_ll": linear wavelet estimator followed by local-linear
smoothing (the best performer in Doosti, Dewan and Sbai 2026);
"wavelet_linear", "wavelet_hard", "wavelet_block": linear,
hard-thresholded and block-thresholded wavelet estimators;
"wavelet_theory": the hard-thresholding estimator of Theorem 2 of
Doosti, Dewan and Sbai (2026) on a periodised basis, with coefficients
, coarsest level
, finest level and
level-dependent thresholds ,
; by default is set so that
the threshold at the finest level is the universal threshold
(: median absolute finest-level
coefficient / 0.6745); pass kappa to override;
"kde_hh": the boundary-corrected kernel estimator of Hickman and
Hubbard (2015), i.e. GPV with boundary correction at both stages;
"kde": Gaussian kernel with Sheather–Jones bandwidth;
"empirical_quantile": finite-difference density from the empirical
quantile function of the pseudo-values;
"marmer_shneyerov": the quantile-based estimator of Marmer and
Shneyerov (2012), computed directly from the bids (no first stage).
Because the wavelet basis lives on , bids and pseudo-values are
mapped to the unit interval by a monotone map (scale): with "auto" the
identity when the bids lie in (pseudo-values outside are
projected onto for the wavelet coefficients), otherwise
("log", which handles the heavy right tail of the GPV ratio) or a linear
map ("minmax"). Densities are reported on the original scale through the
Jacobian.
fpa_density( bids, n = NULL, method = c("wavelet_ll", "wavelet_linear", "wavelet_hard", "wavelet_block", "wavelet_theory", "kde_hh", "kde", "empirical_quantile", "marmer_shneyerov"), first_stage = "gpv_hh", x = NULL, j0 = 5L, h = 0.15, scale = c("auto", "log", "minmax", "none"), filter = "db3", dwt_filter = "coif1", levels = 3L, kernel = "triweight", side = c("lower", "both"), ... )fpa_density( bids, n = NULL, method = c("wavelet_ll", "wavelet_linear", "wavelet_hard", "wavelet_block", "wavelet_theory", "kde_hh", "kde", "empirical_quantile", "marmer_shneyerov"), first_stage = "gpv_hh", x = NULL, j0 = 5L, h = 0.15, scale = c("auto", "log", "minmax", "none"), filter = "db3", dwt_filter = "coif1", levels = 3L, kernel = "triweight", side = c("lower", "both"), ... )
bids |
pooled bids (vector) or an |
n |
bidders per auction (from |
method |
second-stage estimator; see Description. |
first_stage |
|
x |
evaluation grid on the value scale. Defaults to 200 points spanning the pseudo-values (excluding the extreme 0.5 percent at each end). |
j0 |
resolution level, or |
h |
local-linear bandwidth for |
scale |
|
filter, dwt_filter, levels
|
wavelet settings; see |
kernel, side
|
kernel and correction side for |
... |
for |
An object of class "fpa_density": a list with x, f (density
on the value scale), values (pseudo-values), values_u (on the unit
scale), map, method, j0, h, first_stage, n, and fun, a
function returning the density at arbitrary values.
Doosti, H., Dewan, I. and Sbai, E. (2026). Adaptive wavelet estimation of private-value densities in first-price auctions. SSRN preprint. doi:10.2139/ssrn.7618223
Hickman, B. R. and Hubbard, T. P. (2015). Journal of Applied Econometrics, 30, 739–762.
Marmer, V. and Shneyerov, A. (2012). Journal of Econometrics, 167, 345–357.
set.seed(1) sim <- fpa_simulate(40, 5, Q = function(u) qbeta(u, 2, 2)) fd <- fpa_density(sim$bids, method = "wavelet_ll", j0 = 5, h = 0.1) plot(fd, true = function(v) dbeta(v, 2, 2)) # timber auctions, three bidders, log scale data(timber) fd3 <- fpa_density(timber$n3, method = "wavelet_ll", j0 = 4, h = 0.15) plot(fd3)set.seed(1) sim <- fpa_simulate(40, 5, Q = function(u) qbeta(u, 2, 2)) fd <- fpa_density(sim$bids, method = "wavelet_ll", j0 = 5, h = 0.1) plot(fd, true = function(v) dbeta(v, 2, 2)) # timber auctions, three bidders, log scale data(timber) fd3 <- fpa_density(timber$n3, method = "wavelet_ll", j0 = 4, h = 0.15) plot(fd3)
Pointwise percentile intervals and a uniform confidence band for the
private-value density estimated by any fpa_density() method, for example
the quantile-based estimator of Marmer and Shneyerov (2012) or the wavelet
estimators. The whole two-step procedure (first stage, unit map, second
stage) is repeated on B bootstrap samples. The uniform band is
, with the
bootstrap standard deviation and the quantile of
. For the GPV estimator,
fpa_density_ci() gives the analytic studentisation of Ma, Marmer and
Shneyerov (2019).
The percentile bootstrap reproduces the variability of the estimator but not its smoothing bias, so at the usual bandwidths the intervals can under-cover in moderate samples (in a small check with the Marmer–Shneyerov estimator, 240 bids and nominal level 0.95, pointwise coverage was about 0.86). Undersmoothing, i.e. a smaller bandwidth than is optimal for estimation, is the usual remedy.
fpa_density_boot( bids, n = NULL, method = "marmer_shneyerov", x = NULL, B = 199, level = 0.95, resample = c("bids", "auctions"), ... ) ## S3 method for class 'fpa_density_boot' plot(x, true = NULL, ...)fpa_density_boot( bids, n = NULL, method = "marmer_shneyerov", x = NULL, B = 199, level = 0.95, resample = c("bids", "auctions"), ... ) ## S3 method for class 'fpa_density_boot' plot(x, true = NULL, ...)
bids |
pooled bids (vector) or an |
n |
bidders per auction (from |
method |
second-stage estimator; see Description. |
x |
evaluation grid on the value scale. Defaults to 200 points spanning the pseudo-values (excluding the extreme 0.5 percent at each end). |
B |
number of bootstrap replications. |
level |
confidence level. |
resample |
|
... |
further arguments to |
true |
optional true density function (simulated data). |
an object of class "fpa_density_boot" with x, f, se,
lower, upper (pointwise), band_lower, band_upper, crit, level,
method, B and the matrix boot of bootstrap estimates.
Call set.seed() beforehand to make the bootstrap reproducible.
set.seed(1) sim <- fpa_simulate(60, 4, Q = function(u) qbeta(u, 2, 2)) bb <- fpa_density_boot(sim$bids, method = "marmer_shneyerov", x = seq(0.15, 0.85, by = 0.05), B = 49) bb plot(bb, true = function(v) dbeta(v, 2, 2))set.seed(1) sim <- fpa_simulate(60, 4, Q = function(u) qbeta(u, 2, 2)) bb <- fpa_density_boot(sim$bids, method = "marmer_shneyerov", x = seq(0.15, 0.85, by = 0.05), B = 49) bb plot(bb, true = function(v) dbeta(v, 2, 2))
Inference for the two-step estimator of Guerre, Perrigne and Vuong (2000)
following Ma, Marmer and Shneyerov (2019). The first stage uses the
empirical distribution function of the bids and a fourth-order triweight
kernel density estimate with bandwidth ;
bids within of the sample extremes are trimmed. The second stage
is a triweight kernel density estimate of the pseudo-values with bandwidth
, where and
are the standard deviation and number of the trimmed pseudo-values
(Section 8 of the paper). The trimmed pseudo-values are those of bids at
least from the sample extremes. As scale estimate we use
Silverman's robust rather than
the standard deviation alone; the two coincide in the paper's designs, but
the robust version protects the bandwidths against the few very large
pseudo-values that arise where the estimated bid density is small.
Standard errors use the estimator (4.2) of the asymptotic variance, which
accounts for the estimation error of the first stage. Pointwise intervals
are percentile bootstrap intervals (Theorem 4.2; the default) or normal
intervals . The analytic
standard error contains only the leading, first-stage term of the variance;
in moderate samples, and where is small, the second-stage kernel
variance is not negligible and normal intervals can under-cover, whereas the
percentile intervals and the uniform band, whose critical value is
bootstrapped, are not affected. The uniform band over grid is
, where is the
quantile of
over bootstrap samples of the pooled bids (Theorem 5.2 and Corollary 5.1 of
the paper).
The theory requires grid to lie in the interior of the support of the
valuations. By default it spans the 5th to 95th percentiles of the
pseudo-values of the bids between the 10th and 90th bid percentiles, which
keeps it away from the long right tail of pseudo-values that the first
stage produces where the bid density is small; with real data, choose the
range with care, since the band is only valid where the density of values is
bounded away from zero. Observations whose estimated bid density is not positive
(possible with a fourth-order kernel near the boundary) are dropped.
fpa_density_ci( bids, n = NULL, grid = NULL, level = 0.95, B = 499, pointwise = c("percentile", "normal"), h_g = NULL, h_f = NULL, trim_estimator = FALSE, constants = c(3.72, 3.15), sd_v = c("trimmed", "all"), se = c("augmented", "asymptotic") )fpa_density_ci( bids, n = NULL, grid = NULL, level = 0.95, B = 499, pointwise = c("percentile", "normal"), h_g = NULL, h_f = NULL, trim_estimator = FALSE, constants = c(3.72, 3.15), sd_v = c("trimmed", "all"), se = c("augmented", "asymptotic") )
bids |
pooled bids (vector) or an |
n |
number of bidders per auction (from |
grid |
evaluation points; default 201 points between the 5th and 95th percentiles of the pseudo-values of the bids between the 10th and 90th bid percentiles (see Details). |
level |
confidence level. |
B |
number of bootstrap replications. |
pointwise |
|
h_g, h_f
|
optional bandwidths overriding the rules above. |
trim_estimator |
logical. The trimming of bids within |
constants |
rule-of-thumb constants for |
sd_v |
standard deviation used in |
se |
|
An object of class "fpa_density_ci": a list with v (grid),
f (estimate), se, lower, upper (pointwise interval), band_lower,
band_upper (uniform band), crit (), level, h_g, h_f,
values (trimmed pseudo-values) and B.
Fold assignment (or bootstrap resampling) uses R's random number generator;
call set.seed() beforehand to make results exactly reproducible.
Ma, J., Marmer, V. and Shneyerov, A. (2019). Inference for first-price auctions with Guerre, Perrigne, and Vuong's estimator. Journal of Econometrics, 211, 507–538. doi:10.1016/j.jeconom.2019.02.006
Guerre, E., Perrigne, I. and Vuong, Q. (2000). Optimal nonparametric estimation of first-price auctions. Econometrica, 68, 525–574.
set.seed(1) sim <- fpa_simulate(100, 5, Q = function(u) u) # uniform values ci <- fpa_density_ci(sim$bids, grid = seq(0.2, 0.8, by = 0.01), B = 99) ci plot(ci, true = function(v) dunif(v))set.seed(1) sim <- fpa_simulate(100, 5, Q = function(u) u) # uniform values ci <- fpa_density_ci(sim$bids, grid = seq(0.2, 0.8, by = 0.01), B = 99) ci plot(ci, true = function(v) dunif(v))
Outer folds-fold cross-validation of several second-stage estimators
against a common target (the held-out pseudo-values from the first stage
fitted on the training fold), as in Table 3 of Doosti, Dewan and Sbai
(2026). Wavelet tuning parameters are fixed at j0, h.
fpa_density_cv( bids, n = NULL, methods = c("wavelet_ll", "kde_hh", "marmer_shneyerov"), folds = 5L, j0 = 5L, h = 0.15, first_stage = "gpv_hh", scale = "auto", kernel = "triweight", side = "lower", ... )fpa_density_cv( bids, n = NULL, methods = c("wavelet_ll", "kde_hh", "marmer_shneyerov"), folds = 5L, j0 = 5L, h = 0.15, first_stage = "gpv_hh", scale = "auto", kernel = "triweight", side = "lower", ... )
bids |
pooled bids (vector) or an |
n |
bidders per auction (from |
methods |
character vector of second-stage methods. |
folds |
number of outer folds. |
j0 |
resolution level, or |
h |
local-linear bandwidth for |
first_stage |
|
scale |
|
kernel, side
|
kernel and correction side for |
... |
for |
a named numeric vector of summed held-out log-likelihoods.
Performance criteria used in the papers behind this package.
fpa_evaluate_values() scores recovered private values (Doosti, Dewan and
Talebian 2025): mise, the mean integrated squared error between a
Gaussian kernel density (Sheather–Jones bandwidth) of the values and the
true density; loglik, ; ks, the
Kolmogorov–Smirnov distance between the empirical distribution of the
values and ; and msep, the mean squared error against the true
values when they are supplied (Doosti 2026a), with msep_trim excluding a
share trim at each end of the true-value distribution.
fpa_evaluate_density() scores an fpa_density() object on its grid:
mise over the whole grid and over the upper tail share of the support,
and the expected log-likelihood (Doosti, Dewan and
Sbai 2026).
fpa_evaluate_values(values, pdf, cdf = NULL, true = NULL, trim = 0.05) fpa_evaluate_density(density, pdf, tail = 0.1)fpa_evaluate_values(values, pdf, cdf = NULL, true = NULL, trim = 0.05) fpa_evaluate_density(density, pdf, tail = 0.1)
values |
numeric vector of recovered values, or an |
pdf, cdf
|
true density and distribution functions. |
true |
optional true values, aligned with |
trim |
trimming share for |
density |
an |
tail |
share of the upper support for the tail MISE. |
a named numeric vector.
set.seed(1) sim <- fpa_simulate(20, 5, Q = function(u) qgamma(u, 10, 2)) fv <- fpa_values(sim$bids, method = "bernstein", bandwidth = "bcv", monotone = "spline") fpa_evaluate_values(fv, pdf = function(x) dgamma(x, 10, 2), cdf = function(x) pgamma(x, 10, 2), true = sim$values)set.seed(1) sim <- fpa_simulate(20, 5, Q = function(u) qgamma(u, 10, 2)) fv <- fpa_values(sim$bids, method = "bernstein", bandwidth = "bcv", monotone = "spline") fpa_evaluate_values(fv, pdf = function(x) dgamma(x, 10, 2), cdf = function(x) pgamma(x, 10, 2), true = sim$values)
Repeats: simulate auctions with fpa_simulate(), apply each estimator in
estimators to the bids, and score it with score. Designed to
regenerate the simulation tables of the papers behind this package.
fpa_montecarlo( R, L, n, Q, q = NULL, family = "independence", theta = NULL, estimators, score, seed = NULL, verbose = FALSE, p0 = 0, eta = 0 )fpa_montecarlo( R, L, n, Q, q = NULL, family = "independence", theta = NULL, estimators, score, seed = NULL, verbose = FALSE, p0 = 0, eta = 0 )
R |
number of replications. |
L, n
|
auctions and bidders per replication. |
Q, q, family, theta
|
private-value model, as in |
estimators |
a named list of functions |
score |
a function |
seed |
optional seed. |
verbose |
print progress every 10 replications. |
p0, eta
|
screening quantile of the reserve price and CRRA parameter,
passed to |
a data frame with columns rep, estimator and one column per
criterion; summary() on the result (via aggregate) gives the table.
set.seed(1) pdf <- function(x) dgamma(x, 10, 2); cdf <- function(x) pgamma(x, 10, 2) mc <- fpa_montecarlo(R = 5, L = 20, n = 5, Q = function(u) qgamma(u, 10, 2), estimators = list( B_B = function(b, v) fpa_values(b, method = "bernstein", bandwidth = "bcv"), GPV = function(b, v) fpa_values(b, method = "gpv")), score = function(fit, b, v) fpa_evaluate_values(fit, pdf, cdf, v)) aggregate(cbind(mise, loglik, ks, msep) ~ estimator, mc, mean)set.seed(1) pdf <- function(x) dgamma(x, 10, 2); cdf <- function(x) pgamma(x, 10, 2) mc <- fpa_montecarlo(R = 5, L = 20, n = 5, Q = function(u) qgamma(u, 10, 2), estimators = list( B_B = function(b, v) fpa_values(b, method = "bernstein", bandwidth = "bcv"), GPV = function(b, v) fpa_values(b, method = "gpv")), score = function(fit, b, v) fpa_evaluate_values(fit, pdf, cdf, v)) aggregate(cbind(mise, loglik, ks, msep) ~ estimator, mc, mean)
Maximises the plug-in revenue fpa_revenue() over a grid of reserve prices.
fpa_optimal_reserve(values, eta = NULL, v_s = 0, grid = NULL)fpa_optimal_reserve(values, eta = NULL, v_s = 0, grid = NULL)
values |
an |
eta |
CRRA parameter; taken from |
v_s |
seller's valuation of the object (revenue when unsold). |
grid |
candidate reserve prices; defaults to 200 points between the 2nd and 98th percentiles of the values. |
a list with r_star, revenue and the evaluated grid and R.
Estimates the seller's expected revenue in a symmetric
first-price auction with reserve price , from recovered private
values (Zincenko 2024, eq. 6; Doosti 2026b, eq. 11). With auctions
of bidders, pooled pseudo-values ,
their empirical distribution , and the winner's value
in auction ,
with , for CRRA
bidders with parameter (: risk neutral), and
the seller's own valuation.
fpa_revenue(values, r, eta = NULL, v_s = 0)fpa_revenue(values, r, eta = NULL, v_s = 0)
values |
an |
r |
reserve prices at which to evaluate the revenue. |
eta |
CRRA parameter; taken from |
v_s |
seller's valuation of the object (revenue when unsold). |
numeric vector .
Zincenko, F. (2024). Estimation and inference of seller's expected revenue in first-price auctions. Journal of Econometrics, 241(1), 105734. doi:10.1016/j.jeconom.2024.105734
Doosti, H. (2026b). Estimating seller's expected revenue in first-price sealed-bid auctions via quantile density functions. SSRN preprint. doi:10.2139/ssrn.7071380
set.seed(1) sim <- fpa_simulate(100, 3, Q = function(u) 10 * u) # values U[0, 10] fv <- fpa_values(sim$bids, method = "bernstein", bandwidth = "bcv") r <- 3:8 cbind(r, estimate = fpa_revenue(fv, r, v_s = 2), truth = fpa_revenue_model(function(u) 10 * u, n = 3, r = r, v_s = 2))set.seed(1) sim <- fpa_simulate(100, 3, Q = function(u) 10 * u) # values U[0, 10] fv <- fpa_values(sim$bids, method = "bernstein", bandwidth = "bcv") r <- 3:8 cbind(r, estimate = fpa_revenue(fv, r, v_s = 2), truth = fpa_revenue_model(function(u) 10 * u, n = 3, r = r, v_s = 2))
Recomputes the pseudo-values and the plug-in revenue on B bootstrap
samples of whole auctions (by default; see resample) (Zincenko 2024,
Section 4.3; Doosti 2026b) and
returns the bootstrap standard error
,
symmetric percentile- pointwise confidence intervals (critical value:
the quantile of ), and a uniform confidence
band over r based on the bootstrap distribution of
, .
(The original simulation code used the quantile of
for the pointwise intervals; the symmetric version guarantees
that the band contains the intervals.)
fpa_revenue_boot( bids, r, B = 200, eta = 0, v_s = 0, resample = c("auctions", "bids"), alpha = c(0.1, 0.05, 0.01), trim = Inf, ... )fpa_revenue_boot( bids, r, B = 200, eta = 0, v_s = 0, resample = c("auctions", "bids"), alpha = c(0.1, 0.05, 0.01), trim = Inf, ... )
bids |
|
r |
reserve prices. |
B |
number of bootstrap replications. |
eta, v_s
|
as in |
resample |
|
alpha |
significance levels for the intervals and band. |
trim |
discard bootstrap deviations larger than this constant
( |
... |
arguments to |
an object of class "fpa_revenue_boot": a list with r,
estimate, se, ci (array r by c(lower, upper) by alpha),
band (same layout), the bootstrap critical values, the B by
length(r) matrix of bootstrap estimates and, when the bandwidth was
selected from the data, bandwidth: a list with the selected h and m,
the selector, and at_boundary/boundary (see select_bandwidth()).
Fold assignment (or bootstrap resampling) uses R's random number generator;
call set.seed() beforehand to make results exactly reproducible.
set.seed(1) sim <- fpa_simulate(60, 3, Q = function(u) 10 * u) rb <- fpa_revenue_boot(sim$bids, r = c(3, 5, 7), B = 50, v_s = 2, method = "bernstein", bandwidth = "sqrt") rbset.seed(1) sim <- fpa_simulate(60, 3, Q = function(u) 10 * u) rb <- fpa_revenue_boot(sim$bids, r = c(3, 5, 7), B = 50, v_s = 2, method = "bernstein", bandwidth = "sqrt") rb
Computes the seller's expected revenue for a private-value model with marginal
quantile function Q, copula multiplier and diagonal
(copula_psi(), copula_delta()), where
is the equilibrium bid with reserve price
(fpa_bid_function()). Under independence and risk
neutrality this is the revenue used as the truth in Zincenko (2024).
fpa_optimal_reserve_model() finds the interior maximiser of
from the first-order condition
.
fpa_revenue_model( Q, n, r = NULL, p = NULL, q = NULL, family = "independence", theta = NULL, v_s = 0, eta = 0, U = fpa_ugrid() ) fpa_optimal_reserve_model( Q, n, q = NULL, family = "independence", theta = NULL, v_s = 0, eta = 0, p_lo = 1e-04, p_hi = 0.98, U = fpa_ugrid() )fpa_revenue_model( Q, n, r = NULL, p = NULL, q = NULL, family = "independence", theta = NULL, v_s = 0, eta = 0, U = fpa_ugrid() ) fpa_optimal_reserve_model( Q, n, q = NULL, family = "independence", theta = NULL, v_s = 0, eta = 0, p_lo = 1e-04, p_hi = 0.98, U = fpa_ugrid() )
Q |
quantile function of private values (a function of |
n |
number of bidders. |
r |
reserve prices (on the value scale); alternatively give |
p |
reserve quantiles. |
q |
quantile density of private values (a function of |
family |
|
theta |
copula parameter (ignored for independence). |
v_s |
seller's valuation. |
eta |
CRRA risk-aversion parameter of the bidders. |
U |
quantile grid; see |
p_lo, p_hi
|
search interval for the optimal reserve quantile. |
fpa_revenue_model(): numeric vector of expected revenues.
fpa_optimal_reserve_model(): a list with p_star, r_star,
revenue and interior.
Q <- function(u) (1 - 8 * u / 9)^(-1/2) # truncated Pareto on [1, 3] fpa_revenue_model(Q, n = 3, p = c(0.1, 0.3, 0.5), v_s = 1) fpa_optimal_reserve_model(Q, n = 3, v_s = 1) fpa_optimal_reserve_model(Q, n = 3, v_s = 1, family = "clayton", theta = 2)Q <- function(u) (1 - 8 * u / 9)^(-1/2) # truncated Pareto on [1, 3] fpa_revenue_model(Q, n = 3, p = c(0.1, 0.3, 0.5), v_s = 1) fpa_optimal_reserve_model(Q, n = 3, v_s = 1) fpa_optimal_reserve_model(Q, n = 3, v_s = 1, family = "clayton", theta = 2)
Estimates the seller's expected revenue at reserve quantile
(reserve price ) and the optimal reserve from the
revenue functional of Doosti (2026c, Proposition 1),
where is the diagonal section of the copula of the private
values ( under independence) and is
the equilibrium bid in quantile space with reserve . Writing
, , the
proposition's is
equivalently
because without a reserve the equilibrium bid quantile function is the
observed bid quantile function . The estimator uses this second
form: the empirical bid quantile function carries the upper tail, and the
quantile density of the pseudo-values is needed only below
the reserve quantile, where it is estimated reliably. The optimal reserve
maximises over the quantile grid; at an interior optimum it
satisfies the generalised Myerson condition
, which reduces to
under independence.
This is Stage 3 of the copula–quantile density estimator; Stages 1–2 are
fpa_values() with the same family.
fpa_revenue_qd( values, r = NULL, p = NULL, v_s = 0, qdf_method = "poisson", bandwidth = "rlcv", ... ) fpa_optimal_reserve_qd( values, v_s = 0, qdf_method = "poisson", bandwidth = "rlcv", p_max = 0.98, ... )fpa_revenue_qd( values, r = NULL, p = NULL, v_s = 0, qdf_method = "poisson", bandwidth = "rlcv", ... ) fpa_optimal_reserve_qd( values, v_s = 0, qdf_method = "poisson", bandwidth = "rlcv", p_max = 0.98, ... )
values |
an |
r |
reserve prices at which to evaluate |
p |
reserve quantiles. |
v_s |
seller's valuation. |
qdf_method, bandwidth
|
quantile density estimator for the
pseudo-values, passed to |
... |
further arguments to |
p_max |
largest reserve quantile searched by |
fpa_revenue_qd(): numeric vector .
fpa_optimal_reserve_qd(): a list with r_star, p_star, revenue,
interior (FALSE when is maximised at the smallest reserve,
i.e. no binding reserve is optimal) and the evaluated curve p, R.
Doosti, H. (2026c). Optimal reserve prices in affiliated private value auctions: a copula–quantile density approach. SSRN preprint. doi:10.2139/ssrn.7273869
set.seed(1) Q <- function(u) (1 - 8 * u / 9)^(-1/2) # truncated Pareto on [1, 3] th <- copula_tau_to_theta(0.25, "clayton") sim <- fpa_simulate(50, 3, Q, family = "clayton", theta = th) fv <- fpa_values(sim$bids, method = "poisson", bandwidth = "rlcv", family = "clayton") fpa_optimal_reserve_qd(fv, v_s = 1)[c("r_star", "p_star", "interior")] fpa_optimal_reserve_model(Q, 3, family = "clayton", theta = th, v_s = 1)$r_starset.seed(1) Q <- function(u) (1 - 8 * u / 9)^(-1/2) # truncated Pareto on [1, 3] th <- copula_tau_to_theta(0.25, "clayton") sim <- fpa_simulate(50, 3, Q, family = "clayton", theta = th) fv <- fpa_values(sim$bids, method = "poisson", bandwidth = "rlcv", family = "clayton") fpa_optimal_reserve_qd(fv, v_s = 1)[c("r_star", "p_star", "interior")] fpa_optimal_reserve_model(Q, 3, family = "clayton", theta = th, v_s = 1)$r_star
Draws private values with a given marginal quantile function and an
exchangeable Archimedean copula (independent private values by default),
and computes exact equilibrium bids with fpa_bid_function().
fpa_simulate( L, n, Q, q = NULL, family = "independence", theta = NULL, p0 = 0, eta = 0, bid_function = NULL )fpa_simulate( L, n, Q, q = NULL, family = "independence", theta = NULL, p0 = 0, eta = 0, bid_function = NULL )
L |
number of auctions. |
n |
number of bidders per auction. |
Q |
quantile function of private values (a function of |
q |
quantile density of private values (a function of |
family |
|
theta |
copula parameter (ignored for independence). |
p0 |
screening quantile of the reserve price (default 0, no reserve). |
eta |
CRRA risk-aversion parameter in |
bid_function |
optional precomputed output of |
a list with matrices values and bids (L by n) and the bid
function used.
set.seed(1) sim <- fpa_simulate(20, 5, Q = function(u) qlnorm(u, 0, 0.5)) str(sim$bids)set.seed(1) sim <- fpa_simulate(20, 5, Q = function(u) qlnorm(u, 0, 0.5)) str(sim$bids)
Nonparametric inversion of the equilibrium bid function of a symmetric first-price sealed-bid auction through the quantile density of bids:
where is a quantile density estimate (qdf()), is
the copula multiplier (equal to under independent private
values, so that and the formula is that of
Guerre, Perrigne and Vuong 2000), and accounts for risk
aversion (Guerre, Perrigne and Vuong 2009): the identity for risk-neutral
bidders and for CRRA utility .
method = "zincenko" gives the kernel estimator of Zincenko (2024): a
triweight kernel for and with normal-reference
bandwidths, and linear extrapolation of the inverse bid function within
of the boundaries instead of trimming; the implementation
is adapted from code provided by F. Zincenko.
method = "gpv" gives the conventional benchmark
with a Gaussian kernel and
Sheather–Jones bandwidth for ; "gpv_bc" renormalises a
triweight kernel by its mass inside the bid support (a simple boundary
correction; the Hickman–Hubbard correction is provided by
fpa_density()).
fpa_values( bids, n = NULL, method = "indirect_poisson", bandwidth = "bcv", eta = 0, family = "independence", theta = NULL, u_scheme = c("i/(n+1)", "i/n"), monotone = c("none", "spline", "isotonic"), trim = 0.1, replace = c("all", "boundary"), df = 6, psi_bw = NULL, ... )fpa_values( bids, n = NULL, method = "indirect_poisson", bandwidth = "bcv", eta = 0, family = "independence", theta = NULL, u_scheme = c("i/(n+1)", "i/n"), monotone = c("none", "spline", "isotonic"), trim = 0.1, replace = c("all", "boundary"), df = 6, psi_bw = NULL, ... )
bids |
numeric vector of pooled bids, or an |
n |
number of bidders per auction (taken from |
method |
quantile-density estimator passed to |
bandwidth |
passed to |
eta |
CRRA risk-aversion parameter in |
family |
copula family of the private values: |
theta |
copula parameter; |
u_scheme |
scores |
monotone |
|
trim |
tail share excluded from the spline fit (default 0.1, i.e. the central 80 percent is used). |
replace |
for |
df |
degrees of freedom of the natural spline (default 6). |
psi_bw |
beta-kernel bandwidth for |
... |
further arguments to |
An object of class "fpa_values": a list with
sorted pooled bids and their scores
the quantile density, the copula multiplier and
the estimated markup at each bid
pseudo-values before and after the
monotonicity step (identical when monotone = "none")
when bids is a matrix, values rearranged to the
original L by n layout
the fitted qdf() object (or NULL for the kernel benchmarks)
the copula specification / fit
The equilibrium bid function is increasing, so should be
increasing in . Departures occur mostly near the boundaries.
monotone = "spline" follows Doosti, Dewan and Talebian (2025): a natural
cubic spline of on is fitted to the central
share of the bids and its fitted values replace
either everywhere (replace = "all", the published
implementation) or only in the trimmed tails (replace = "boundary").
monotone = "isotonic" applies the pool-adjacent-violators rearrangement
(stats::isoreg()). "none" returns the raw pseudo-values.
Guerre, E., Perrigne, I. and Vuong, Q. (2000). Optimal nonparametric estimation of first-price auctions. Econometrica, 68, 525–574.
Guerre, E., Perrigne, I. and Vuong, Q. (2009). Nonparametric identification of risk aversion in first-price auctions under exclusion restrictions. Econometrica, 77, 1193–1227.
Doosti, H., Dewan, I. and Talebian, M. (2025). Economics Letters, 257, 112670.
Doosti, H. (2026a). Economics Letters, 261, 112837.
set.seed(1) sim <- fpa_simulate(20, 5, Q = function(u) qgamma(u, 2, 10)) fit <- fpa_values(sim$bids, method = "bernstein", bandwidth = "bcv") fit plot(fit, true = sim$values) # risk-averse bidders with CRRA eta = 0.25 fit_ra <- fpa_values(sim$bids, method = "bernstein", bandwidth = 0.05, eta = 0.25) # affiliated values, Clayton copula estimated from the data sim2 <- fpa_simulate(50, 3, Q = function(u) 1 + 2 * u^2, family = "clayton", theta = 2) fit2 <- fpa_values(sim2$bids, method = "indirect_poisson", family = "clayton") fit2$copula$thetaset.seed(1) sim <- fpa_simulate(20, 5, Q = function(u) qgamma(u, 2, 10)) fit <- fpa_values(sim$bids, method = "bernstein", bandwidth = "bcv") fit plot(fit, true = sim$values) # risk-averse bidders with CRRA eta = 0.25 fit_ra <- fpa_values(sim$bids, method = "bernstein", bandwidth = 0.05, eta = 0.25) # affiliated values, Clayton copula estimated from the data sim2 <- fpa_simulate(50, 3, Q = function(u) 1 + 2 * u^2, family = "clayton", theta = 2) fit2 <- fpa_values(sim2$bids, method = "indirect_poisson", family = "clayton") fit2$copula$theta
The virtual value of affiliated private values in quantile space,
with ,
and the diagonal section of the copula (Doosti 2026c). The
derivative of expected revenue is ,
so no binding reserve is optimal (a corner) when
for all ; under independence is the Myerson virtual
value .
fpa_virtual_value_model() evaluates for a known model;
fpa_virtual_value() estimates it from an fpa_values() object, with the
quantile function and quantile density of the pseudo-values estimated as in
fpa_revenue_qd().
fpa_virtual_value_model( Q, q, n, family = "independence", theta = NULL, U = fpa_ugrid() ) fpa_virtual_value(values, qdf_method = "poisson", bandwidth = "rlcv", ...)fpa_virtual_value_model( Q, q, n, family = "independence", theta = NULL, U = fpa_ugrid() ) fpa_virtual_value(values, qdf_method = "poisson", bandwidth = "rlcv", ...)
Q, q
|
quantile function and quantile density of the private values. |
n |
number of bidders. |
family, theta
|
copula family and parameter, as in |
U |
quantile grid (default |
values |
an |
qdf_method, bandwidth
|
quantile density estimator for the
pseudo-values, passed to |
... |
further arguments to |
A list with the grid U, the virtual value omega and the factor
H; fpa_virtual_value() also returns the estimated Q and q on U
and the bandwidth h used for the pseudo-values.
Doosti, H. (2026c). Optimal reserve prices in affiliated private value auctions: a copula–quantile density approach. SSRN preprint. doi:10.2139/ssrn.7273869
Q <- function(u) (1 - 8 * u / 9)^(-1/2) # truncated Pareto on [1, 3] q <- function(u) (4 / 9) * (1 - 8 * u / 9)^(-3/2) vv <- fpa_virtual_value_model(Q, q, n = 3, family = "clayton", theta = 2) range(vv$omega)Q <- function(u) (1 - 8 * u / 9)^(-1/2) # truncated Pareto on [1, 3] q <- function(u) (4 / 9) * (1 - 8 * u / 9)^(-3/2) vv <- fpa_virtual_value_model(Q, q, n = 3, family = "clayton", theta = 2) range(vv$omega)
Kernel density estimator with the transformation-based boundary correction
of Karunamuni and Zhang (2008) at the lower endpoint of the support, as
implemented by Hickman and Hubbard (2015) for first-price auctions (their
kspdf_bc; this function is an R translation of that code, whose
authors ask that Hickman and Hubbard (2015) be cited). The bandwidth is Silverman's rule scaled by Haerdle's (1991)
canonical-kernel constant. The estimate is set to zero outside the range
of the data. With side = "both" the same correction is applied at the
upper endpoint through the reflected sample.
kde_hh( x, data, kernel = "triweight", side = c("lower", "both"), hardle = TRUE, h = NULL )kde_hh( x, data, kernel = "triweight", side = c("lower", "both"), hardle = TRUE, h = NULL )
x |
evaluation points. |
data |
observed sample (bids or pseudo-values). |
kernel |
|
side |
|
hardle |
logical; use Haerdle's canonical bandwidth constant. |
h |
optional bandwidth override. |
a numeric vector with attribute "h" (the bandwidth used).
Hickman, B. R. and Hubbard, T. P. (2015). Replacing sample trimming with boundary correction in nonparametric estimation of first-price auctions. Journal of Applied Econometrics, 30, 739–762. doi:10.1002/jae.2385
Karunamuni, R. J. and Zhang, S. (2008). Some improvements on a boundary corrected kernel density estimator. Statistics & Probability Letters, 78, 499–507.
x <- rbeta(200, 2, 1) g <- seq(0.01, 0.99, by = 0.01) plot(g, kde_hh(g, x), type = "l"); lines(g, dbeta(g, 2, 1), lty = 2)x <- rbeta(200, 2, 1) g <- seq(0.01, 0.99, by = 0.01) plot(g, kde_hh(g, x), type = "l"); lines(g, dbeta(g, 2, 1), lty = 2)
Post-smoothing of a wavelet estimate on a grid (Ramirez and Vidakovic 2010;
Fan 1992): for each x solves the weighted least-squares line through
(grid, y) with weights and returns its value at x.
Translated from the MATLAB routine loc_lin of B. Vidakovic.
loclin_smooth(x, grid, y, h)loclin_smooth(x, grid, y, h)
x |
evaluation points. |
grid, y
|
tabulated function. |
h |
bandwidth. |
numeric vector.
make_kernel() turns a kernel density function into the object used by
qdf_kernel(), qdf_kernel_corrected(), qdf_jones(), qdf_soni() and
qdf() (argument kernel). The distribution function needed by the
boundary-corrected and Soni estimators is computed numerically.
check_kernel() reports the properties that matter for these estimators:
total mass, symmetry, support, order (the first non-vanishing moment),
and whether the kernel takes negative values; it warns when a
property required by the theory fails.
make_kernel(k, name = "custom", support = 1, n_grid = 20001L) check_kernel(kernel, verbose = TRUE)make_kernel(k, name = "custom", support = 1, n_grid = 20001L) check_kernel(kernel, verbose = TRUE)
k |
a vectorised function, the kernel density. |
name |
a label. |
support |
half-width of an interval |
n_grid |
number of grid points for the numerical integration. |
kernel |
a kernel name, a function, or an object from |
verbose |
print the report. |
make_kernel(): an object of class "qdf_kernel" (a list with the
density d, the distribution function p, name and the check
results). check_kernel(): a list of properties, printed invisibly.
# the biweight (quartic) kernel biweight <- make_kernel(function(u) 15 / 16 * (1 - u^2)^2 * (abs(u) <= 1), "biweight") biweight x <- rgamma(100, 5) qdf_kernel(c(0.25, 0.5, 0.75), x, h = 0.05, kernel = biweight) check_kernel("epanechnikov")# the biweight (quartic) kernel biweight <- make_kernel(function(u) 15 / 16 * (1 - u^2)^2 * (abs(u) <= 1), "biweight") biweight x <- rgamma(100, 5) qdf_kernel(c(0.25, 0.5, 0.75), x, h = 0.05, kernel = biweight) check_kernel("epanechnikov")
Evaluate scaling functions
phi_jk(z, j, k, filter = "db3", levels = 10L)phi_jk(z, j, k, filter = "db3", levels = 10L)
z |
numeric vector of arguments. |
j |
resolution level. |
k |
integer vector of shifts. For a single |
filter |
see |
levels |
dyadic resolution of the table (default 10, i.e. 1024 points per unit interval). |
numeric vector or matrix of values.
z <- seq(0, 1, by = 0.01) plot(z, phi_jk(z, 3, 2), type = "l")z <- seq(0, 1, by = 0.01) plot(z, phi_jk(z, 3, 2), type = "l")
Plot an estimated private-value density
## S3 method for class 'fpa_density' plot(x, true = NULL, rug = TRUE, ...)## S3 method for class 'fpa_density' plot(x, true = NULL, rug = TRUE, ...)
x |
an |
true |
optional true density function for simulated data. |
rug |
logical; add a rug of the pseudo-values. |
... |
passed to |
No return value, called for its side effect of drawing the
estimated density (with an optional rug of pseudo-values and the true
density). The object x is returned invisibly.
Plot a GPV density estimate with confidence bands
## S3 method for class 'fpa_density_ci' plot(x, true = NULL, ...)## S3 method for class 'fpa_density_ci' plot(x, true = NULL, ...)
x |
an |
true |
optional true density function for simulated data. |
... |
passed to |
No return value, called for its side effect of drawing the
density estimate with its pointwise confidence interval and uniform
confidence band. The object x is returned invisibly.
Plot a revenue curve with bootstrap bands
## S3 method for class 'fpa_revenue_boot' plot(x, alpha = 0.05, ...)## S3 method for class 'fpa_revenue_boot' plot(x, alpha = 0.05, ...)
x |
an |
alpha |
which level to draw. |
... |
passed to |
No return value, called for its side effect of drawing the
estimated expected-revenue curve with its pointwise confidence interval
(dashed) and uniform confidence band (shaded). The object x is
returned invisibly.
Plot recovered private values against bids
## S3 method for class 'fpa_values' plot(x, true = NULL, ...)## S3 method for class 'fpa_values' plot(x, true = NULL, ...)
x |
an |
true |
optional true values (vector or matrix in the layout of |
... |
passed to |
No return value, called for its side effect of plotting the
recovered pseudo-values against the bids (with the monotone fit and the
true values when available). The object x is returned invisibly.
Plot a quantile density estimate
## S3 method for class 'qdf' plot(x, true = NULL, ...)## S3 method for class 'qdf' plot(x, true = NULL, ...)
x |
a |
true |
optional function of |
... |
further arguments passed to |
No return value, called for its side effect of drawing the
estimated quantile density (and the true one, if supplied). The object
x is returned invisibly.
Predict from a fitted quantile density estimate
## S3 method for class 'qdf' predict(object, u = NULL, ...)## S3 method for class 'qdf' predict(object, u = NULL, ...)
object |
a |
u |
evaluation points in |
... |
unused. |
numeric vector of .
psi_jk() evaluates the mother wavelet
, with obtained from
the scaling function by the two-scale relation
,
. phi_per() and psi_per() evaluate the
periodised functions and
, which for form an
orthonormal basis of (Daubechies 1992, Section 9.3); they
are used by the nonlinear estimators qdf_wavelet_nl() and
fpa_density(method = "wavelet_theory").
psi_jk(z, j, k, filter = "db3") phi_per(z, j, k, filter = "db3") psi_per(z, j, k, filter = "db3")psi_jk(z, j, k, filter = "db3") phi_per(z, j, k, filter = "db3") psi_per(z, j, k, filter = "db3")
z |
numeric vector in the unit interval. |
j |
resolution level. |
k |
shift(s); for more than one, a matrix |
filter |
scaling filter; see |
numeric vector or matrix.
z <- seq(0, 1, length.out = 2001) P <- psi_per(z, 4, 0:15, "db3") round(crossprod(P)[1:3, 1:3] / 2000, 3) # approximately the identityz <- seq(0, 1, length.out = 2001) P <- psi_per(z, 4, 0:15, "db3") round(crossprod(P)[1:3, 1:3] / 2000, 3) # approximately the identity
Estimates the quantile density function
(Parzen 1979; also called the sparsity function, Tukey 1965) from an i.i.d.
sample, with the smoothing parameter chosen by cross-validation. Ten
estimators are available; see qdf_kernel(), qdf_poisson(),
qdf_jones() and qdf_wavelet() for their definitions and the simulation evidence in Doosti,
Dewan and Talebian (2025), where the indirect Poisson estimator with BCV
bandwidth performed best for first-price auction inversion.
qdf( x, method = c("indirect_poisson", "kernel", "kernel_corrected", "poisson", "bernstein", "jones", "soni", "wavelet", "wavelet_hard", "wavelet_block"), bandwidth = c("bcv", "rlcv", "wbcv", "sqrt", "cv"), m_range = NULL, u = NULL, H = NULL, kernel = "gaussian", j0 = NULL, loo = NULL, grid = NULL, u_scheme = NULL, optimizer = NULL, rescale = TRUE, ... )qdf( x, method = c("indirect_poisson", "kernel", "kernel_corrected", "poisson", "bernstein", "jones", "soni", "wavelet", "wavelet_hard", "wavelet_block"), bandwidth = c("bcv", "rlcv", "wbcv", "sqrt", "cv"), m_range = NULL, u = NULL, H = NULL, kernel = "gaussian", j0 = NULL, loo = NULL, grid = NULL, u_scheme = NULL, optimizer = NULL, rescale = TRUE, ... )
x |
numeric sample. The series estimators ( |
method |
one of |
bandwidth |
either a selector name ( |
m_range |
search range for |
u |
evaluation grid in |
H |
second bandwidth for |
kernel |
kernel for the kernel-type estimators ( |
j0 |
resolution level for the wavelet methods (default 5 when a
numeric |
loo, grid, u_scheme, optimizer
|
passed to |
rescale |
logical (default |
... |
currently unused. |
An object of class "qdf": a list with components
the sorted sample
the evaluation grid and the estimated quantile density on it
the empirical quantile function on u (for convenience)
the estimator and its smoothing parameters
the output of select_bandwidth(), or NULL when a
numeric bandwidth was supplied
with methods predict.qdf(), print() and plot.qdf().
Doosti, H., Dewan, I. and Talebian, M. (2025). Nonparametric estimation of private value distributions in first-price auctions: Evaluating quantile density function approaches. Economics Letters, 257, 112670. doi:10.1016/j.econlet.2025.112670
Parzen, E. (1979). Nonparametric statistical data modeling. Journal of the American Statistical Association, 74, 105–121.
set.seed(1) x <- rgamma(80, 5, 1) fit <- qdf(x, method = "bernstein", bandwidth = "bcv") fit predict(fit, u = c(0.1, 0.5, 0.9)) # compare with the truth 1 / dgamma(qgamma(u, 5), 5) plot(fit, true = function(u) 1 / dgamma(qgamma(u, 5, 1), 5, 1))set.seed(1) x <- rgamma(80, 5, 1) fit <- qdf(x, method = "bernstein", bandwidth = "bcv") fit predict(fit, u = c(0.1, 0.5, 0.9)) # compare with the truth 1 / dgamma(qgamma(u, 5), 5) plot(fit, true = function(u) 1 / dgamma(qgamma(u, 5, 1), 5, 1))
Estimators that exploit by first estimating the
density .
qdf_jones() (Jones 1992; estimator 5) is
with a Gaussian kernel density
estimator .
qdf_soni() (Soni, Dewan and Jain 2012; estimator 6) double-smooths
Jones' estimator on the probability scale. With form = "integrated"
(the form printed in Doosti, Dewan and Talebian 2025),
where is the kernel's distribution function; with
form = "riemann" (the original implementation of Soni, Dewan and Jain)
Here is the density bandwidth on the data scale and the
smoothing bandwidth on the probability scale. For right-censored data
supply status; the empirical scores are then replaced by the
Kaplan–Meier estimate , as in Soni et al.
qdf_indirect_poisson() (Chaubey, Dewan and Li 2024; estimator 7)
smooths the empirical distribution function with Poisson weights,
inverts the result numerically to obtain a smooth quantile estimator, and
takes the reciprocal of the implied density at that quantile. It requires
positive data.
qdf_jones(u, x, h, kernel = "gaussian") qdf_soni( u, x, h, H, kernel = "gaussian", form = c("integrated", "riemann"), status = NULL ) qdf_indirect_poisson( u, x, h, tol = .Machine$double.eps^0.25, invert = c("auto", "newton", "uniroot") )qdf_jones(u, x, h, kernel = "gaussian") qdf_soni( u, x, h, H, kernel = "gaussian", form = c("integrated", "riemann"), status = NULL ) qdf_indirect_poisson( u, x, h, tol = .Machine$double.eps^0.25, invert = c("auto", "newton", "uniroot") )
u |
numeric vector of evaluation points in |
x |
numeric sample (sorted internally). |
h |
for |
kernel |
|
H |
for |
form |
for |
status |
for |
tol |
root-finding tolerance passed to |
invert |
how the smoothed distribution function is inverted:
|
numeric vector of quantile density estimates at u.
Soni, P., Dewan, I. and Jain, K. (2012). Nonparametric estimation of quantile density function. Computational Statistics & Data Analysis, 56, 3876–3886.
x <- rgamma(100, 5, 1) u <- c(0.25, 0.5, 0.75) qdf_jones(u, x, h = 0.5) qdf_soni(u, x, h = 0.5, H = 0.05) qdf_indirect_poisson(u, x, h = 0.05)x <- rgamma(100, 5, 1) u <- c(0.25, 0.5, 0.75) qdf_jones(u, x, h = 0.5) qdf_soni(u, x, h = 0.5, H = 0.05) qdf_indirect_poisson(u, x, h = 0.05)
Kernel-type estimators that smooth the empirical quantile function directly.
qdf_kernel() is the Jones (1992) estimator
with a Gaussian kernel .
qdf_kernel_corrected() is the boundary-corrected version (estimator 2 of
Doosti, Dewan and Talebian 2025), which renormalises the kernel weights by
the mass falling inside and adds a correction proportional to
the kernel quantile estimator.
qdf_kernel(u, x, h, kernel = "gaussian") qdf_kernel_corrected(u, x, h, kernel = "gaussian")qdf_kernel(u, x, h, kernel = "gaussian") qdf_kernel_corrected(u, x, h, kernel = "gaussian")
u |
numeric vector of evaluation points in |
x |
numeric sample (sorted internally). |
h |
bandwidth on the probability scale ( |
kernel |
|
numeric vector of quantile density estimates at u.
Jones, M. C. (1992). Estimating densities, quantiles, quantile densities and density quantiles. Annals of the Institute of Statistical Mathematics, 44, 721–727.
Chaubey, Y. P., Dewan, I. and Li, J. (2024). On some non parametric estimators of the quantile density function for a stationary associated process. Communications in Statistics – Theory and Methods, 53, 5553–5573.
qdf() for automatic bandwidth selection.
x <- rgamma(100, 5, 1) u <- seq(0.05, 0.95, by = 0.05) qdf_kernel(u, x, h = 0.05) qdf_kernel_corrected(u, x, h = 0.05)x <- rgamma(100, 5, 1) u <- seq(0.05, 0.95, by = 0.05) qdf_kernel(u, x, h = 0.05) qdf_kernel_corrected(u, x, h = 0.05)
Estimators that smooth the empirical quantile function with
probability weights on a lattice , .
qdf_poisson() uses Poisson weights (Chaubey, Dewan and Li 2021; estimator
3 of Doosti, Dewan and Talebian 2025):
where are truncated Poisson weights.
qdf_bernstein() uses Bernstein polynomials (estimator 4):
Both require non-negative data because is taken to be 0;
qdf_bernstein() can instead use
(zero_at_origin = FALSE), which is preferable when the data do not start
near zero (for example bids in dollars).
qdf_bernstein_loo() returns the exact leave-one-out Bernstein estimates
, , used by the cross-validation
criteria: removing shifts every higher order statistic down
by one position, so the leave-one-out lattice values are obtained by an
index shift in operations, without refitting.
qdf_poisson(u, x, h) qdf_bernstein(u, x, h, zero_at_origin = TRUE) qdf_bernstein_loo(u, x, h, zero_at_origin = TRUE)qdf_poisson(u, x, h) qdf_bernstein(u, x, h, zero_at_origin = TRUE) qdf_bernstein_loo(u, x, h, zero_at_origin = TRUE)
u |
numeric vector of evaluation points in |
x |
numeric sample (sorted internally). |
h |
bandwidth on the probability scale ( |
zero_at_origin |
logical; |
numeric vector of quantile density estimates at u; for
qdf_bernstein_loo(), the vector
, where u has the
length of x and is paired with the sorted sample.
Chaubey, Y. P., Dewan, I. and Li, J. (2021). On some smooth estimators of the quantile function for a stationary associated process. Sankhya B, 83 (Suppl 1), 114–139. doi:10.1007/s13571-020-00242-x
x <- rgamma(100, 5, 1) qdf_poisson(c(0.25, 0.5, 0.75), x, h = 0.05) qdf_bernstein(c(0.25, 0.5, 0.75), x, h = 0.05) # exact leave-one-out estimates at u_i = i/n agree with refitting xs <- sort(x); u <- seq_along(xs) / length(xs) loo <- qdf_bernstein_loo(u, xs, h = 0.05) all.equal(loo[10], qdf_bernstein(u[10], xs[-10], h = 0.05))x <- rgamma(100, 5, 1) qdf_poisson(c(0.25, 0.5, 0.75), x, h = 0.05) qdf_bernstein(c(0.25, 0.5, 0.75), x, h = 0.05) # exact leave-one-out estimates at u_i = i/n agree with refitting xs <- sort(x); u <- seq_along(xs) / length(xs) loo <- qdf_bernstein_loo(u, xs, h = 0.05) all.equal(loo[10], qdf_bernstein(u[10], xs[-10], h = 0.05))
Projection estimators of on a wavelet basis of
(Chesneau, Dewan and Doosti 2016; Shirazi and Doosti 2022). The scaling
coefficients are estimated by the warped-basis formula
which is exact for the empirical distribution function
(integration = "exact"); "simpson" reproduces the composite Simpson
rule of the original MATLAB implementation.
Three estimators are available through threshold:
"none": the linear estimator ;
"hard": term-by-term hard thresholding of a levels-level periodic DWT
of the coefficient vector;
"block": Cai's BlockJS block thresholding (Shirazi and Doosti 2022).
With smooth = TRUE the estimate is post-smoothed by the local-linear
smoother of Ramirez and Vidakovic (2010) with bandwidth h; this
"smoothed" version was the best performer in both papers' simulations.
qdf_wavelet( u, x, j0 = 5L, h = 0.15, threshold = c("none", "hard", "block"), smooth = TRUE, filter = "db3", dwt_filter = "coif1", levels = 3L, integration = c("exact", "simpson"), ... )qdf_wavelet( u, x, j0 = 5L, h = 0.15, threshold = c("none", "hard", "block"), smooth = TRUE, filter = "db3", dwt_filter = "coif1", levels = 3L, integration = c("exact", "simpson"), ... )
u |
numeric vector of evaluation points in |
x |
numeric sample (sorted internally). |
j0 |
coarsest resolution level; the estimate uses |
h |
bandwidth of the local-linear post-smoother on the probability
scale (default 0.15); ignored when |
threshold |
|
smooth |
logical; apply local-linear smoothing. |
filter |
scaling filter for the basis; see |
dwt_filter |
filter for the secondary DWT used in thresholding
(default |
levels |
number of DWT levels for thresholding (default 3). |
integration |
|
... |
passed to |
numeric vector of quantile density estimates at u.
Chesneau, C., Dewan, I. and Doosti, H. (2016). Nonparametric estimation of a quantile density function by wavelet methods. Computational Statistics & Data Analysis, 94, 161–174.
Shirazi, E. and Doosti, H. (2022). Nonparametric estimation of a quantile
density function under risk via block thresholding method.
Communications in Statistics – Simulation and Computation, 51, 539–553.
Ramirez, P. and Vidakovic, B. (2010). Wavelet density estimation for stratified size-biased sample. Journal of Statistical Planning and Inference, 140, 419–432.
set.seed(1) x <- rbeta(500, 0.5, 0.5) u <- seq(0.02, 0.98, by = 0.02) q_true <- 1 / dbeta(qbeta(u, 0.5, 0.5), 0.5, 0.5) q_lin <- qdf_wavelet(u, x, j0 = 5, smooth = FALSE) q_blk <- qdf_wavelet(u, x, j0 = 5, threshold = "block", smooth = TRUE) plot(u, q_true, type = "l"); lines(u, q_lin, col = 2); lines(u, q_blk, col = 4)set.seed(1) x <- rbeta(500, 0.5, 0.5) u <- seq(0.02, 0.98, by = 0.02) q_true <- 1 / dbeta(qbeta(u, 0.5, 0.5), 0.5, 0.5) q_lin <- qdf_wavelet(u, x, j0 = 5, smooth = FALSE) q_blk <- qdf_wavelet(u, x, j0 = 5, threshold = "block", smooth = TRUE) plot(u, q_true, type = "l"); lines(u, q_lin, col = 2); lines(u, q_blk, col = 4)
Hard-thresholding and block-thresholding estimators of the quantile density built on the wavelet coefficients of the quantile density itself,
computed exactly for the empirical distribution function, on a periodised
orthonormal basis of :
rule = "hard_general": hard thresholding with
, and
(Chesneau, Dewan and Doosti 2016,
Theorem 3.2, no smoothness condition beyond the Besov ball);
rule = "hard_lipschitz": hard thresholding with
and
(Theorem 3.4, under a Lipschitz-1/2 condition on );
rule = "block": block thresholding (Shirazi and Doosti 2022, eq. 6):
at each level the coefficients are grouped in blocks of length
and a block is kept when
, with
.
The constants of the theorems are not available in practice. By default
, so that
(the universal threshold), and , so that a block
is kept when its mean exceeds
(the BlockJS level of Cai 1999), where is the median absolute
coefficient at the finest level divided by 0.6745. With smooth = TRUE the
estimate is post-smoothed by local linear regression (Ramirez and Vidakovic
2010), the "smoothed" versions of both papers.
The periodised basis replaces the boundary-corrected basis of Cohen et al.
(1993) assumed by the theory; periodisation identifies the endpoints of
, so near and these estimators should be
read with care. Local-linear post-smoothing (smooth = TRUE) helps when
is small at both ends of , but when is large at
an endpoint it spreads the error caused by periodisation into the interior,
and the unsmoothed estimators are then more accurate. In simulations the
cross-validated estimators of qdf() were more accurate than all of these
rules; the estimators here are mainly intended for studying the theory.
qdf_wavelet_nl( u, x, rule = c("hard_lipschitz", "hard_general", "block"), tau = 3L, j1 = NULL, const = NULL, p = 2, smooth = FALSE, h = 0.15, filter = "db3" )qdf_wavelet_nl( u, x, rule = c("hard_lipschitz", "hard_general", "block"), tau = 3L, j1 = NULL, const = NULL, p = 2, smooth = FALSE, h = 0.15, filter = "db3" )
u |
numeric vector of evaluation points in |
x |
numeric sample (sorted internally). |
rule |
|
tau |
coarsest level (default 3; must satisfy |
j1 |
finest level; default from the rule as above. |
const |
|
p |
risk exponent: enters |
smooth |
logical; local linear post-smoothing. |
h |
bandwidth of the post-smoother. |
filter |
scaling filter; see |
numeric vector of estimates at u, with attribute "kept", the
number of detail coefficients retained at each level.
Chesneau, C., Dewan, I. and Doosti, H. (2016). Computational Statistics & Data Analysis, 94, 161–174.
Shirazi, E. and Doosti, H. (2022). Communications in Statistics – Simulation and Computation, 51, 539–553.
set.seed(1) x <- rbeta(500, 0.5, 0.5) u <- seq(0.05, 0.95, by = 0.05) q_true <- 1 / dbeta(qbeta(u, 0.5, 0.5), 0.5, 0.5) cbind(q_true, lipschitz = qdf_wavelet_nl(u, x, "hard_lipschitz", smooth = TRUE), block = qdf_wavelet_nl(u, x, "block", smooth = TRUE))set.seed(1) x <- rbeta(500, 0.5, 0.5) u <- seq(0.05, 0.95, by = 0.05) q_true <- 1 / dbeta(qbeta(u, 0.5, 0.5), 0.5, 0.5) cbind(q_true, lipschitz = qdf_wavelet_nl(u, x, "hard_lipschitz", smooth = TRUE), block = qdf_wavelet_nl(u, x, "block", smooth = TRUE))
Marshall–Olkin frailty samplers in base R.
rcopula_archimedean(L, n, family = "independence", theta = NULL)rcopula_archimedean(L, n, family = "independence", theta = NULL)
L |
number of auctions (rows). |
n |
number of bidders (columns). |
family |
|
theta |
copula parameter (ignored for independence). |
an L by n matrix with uniform margins.
U <- rcopula_archimedean(500, 2, "frank", theta = 5) cor(U, method = "kendall")[1, 2] # about 0.46U <- rcopula_archimedean(500, 2, "frank", theta = 5) cor(U, method = "kendall")[1, 2] # about 0.46
Minimises one of the criteria in bcv_criterion() over in
m_range with stats::optimize(), optionally after a coarse grid search.
select_bandwidth( x, fun, selector = c("bcv", "rlcv", "wbcv"), m_range = c(10, 50), loo = NULL, grid = NULL, u_scheme = NULL, optimizer = NULL )select_bandwidth( x, fun, selector = c("bcv", "rlcv", "wbcv"), m_range = c(10, 50), loo = NULL, grid = NULL, u_scheme = NULL, optimizer = NULL )
x |
numeric sample (sorted internally). |
fun |
an estimator with signature |
selector |
|
m_range |
numeric length-2 range for |
loo |
logical; if |
grid |
search method: |
u_scheme |
grid on which the criterion is evaluated: |
optimizer |
optional function |
a list with h, m, selector, criterion (the minimised value)
and m_range; at_boundary (logical) and boundary ("lower",
"upper" or NA), which record a minimiser at an end of m_range; with
grid = "exhaustive" also the evaluated grid grid_m and criterion values
grid_cv.
If the minimiser lies at either end of m_range, whatever the search
method, the criterion did not select a bandwidth in that range. A warning is
issued and at_boundary = TRUE is returned; widen m_range or give the
bandwidth directly.
x <- rgamma(60, 5, 1) select_bandwidth(x, qdf_poisson, "bcv", m_range = c(10, 50))x <- rgamma(60, 5, 1) select_bandwidth(x, qdf_poisson, "bcv", m_range = c(10, 50))
Chooses j0 (and h for "wavelet_ll") by folds-fold cross-validation
on the bids: the first stage and the unit map are fitted on the training
bids and applied to the held-out bids, and the second-stage density
is scored on the held-out pseudo-values by one of two
criteria:
"lscv" (default): least-squares cross-validation (Rudemo 1982; Bowman
1984), ,
an unbiased estimate of the integrated squared error up to a constant, so
that the selected pair targets MISE;
"loglik": the held-out log-likelihood ,
which targets Kullback–Leibler divergence. Because the held-out points are
pseudo-values carrying first-stage error, this criterion tends to favour
the smallest bandwidth on the grid; it is kept for comparison.
Both criteria are evaluated on the interior of the
unit interval (trim): pseudo-values that fall outside are
projected onto the boundary (Algorithm 1 of the paper), which creates a
spurious point mass there that a small bandwidth reproduces; excluding a
boundary strip from the score removes this artefact, in the spirit of the
boundary trimming of Guerre, Perrigne and Vuong (2000). For "lscv" the
trimmed criterion is ,
an unbiased estimate of the ISE over the interior up to a constant.
The returned score is oriented so that larger is better in both cases
(-LSCV for "lscv").
select_fpa_density( bids, n, method = "wavelet_ll", first_stage = "gpv_hh", j0_grid = 3:6, h_grid = c(0.03, 0.05, 0.08, 0.12, 0.2, 0.3, 0.5), folds = 5L, criterion = c("lscv", "loglik"), scale = "auto", filter = "db3", dwt_filter = "coif1", levels = 3L, kernel = "triweight", side = "lower", n_int = 2001L, trim = 0.05 )select_fpa_density( bids, n, method = "wavelet_ll", first_stage = "gpv_hh", j0_grid = 3:6, h_grid = c(0.03, 0.05, 0.08, 0.12, 0.2, 0.3, 0.5), folds = 5L, criterion = c("lscv", "loglik"), scale = "auto", filter = "db3", dwt_filter = "coif1", levels = 3L, kernel = "triweight", side = "lower", n_int = 2001L, trim = 0.05 )
bids |
pooled bids (vector) or an |
n |
bidders per auction (from |
method |
second-stage estimator; see Description. |
first_stage |
|
j0_grid, h_grid
|
candidate values. |
folds |
number of folds. |
criterion |
|
scale |
|
filter, dwt_filter, levels
|
wavelet settings; see |
kernel, side
|
kernel and correction side for |
n_int |
number of points for the numerical integral of |
trim |
boundary strip excluded from the score on the unit scale (default 0.05; 0 scores the whole interval). |
a list with j0, h, criterion and the matrix of summed scores
ll (rows j0_grid, columns h_grid; larger is better).
Fold assignment (or bootstrap resampling) uses R's random number generator;
call set.seed() beforehand to make results exactly reproducible.
Rudemo, M. (1982). Empirical choice of histograms and kernel density estimators. Scandinavian Journal of Statistics, 9, 65–78.
Bowman, A. W. (1984). An alternative method of cross-validation for the smoothing of density estimates. Biometrika, 71, 353–360.
Chooses the resolution level and the post-smoothing bandwidth of
qdf_wavelet() by folds-fold cross-validation. The implied density of the
data is . With
criterion = "lscv" (default) the pair minimises the least-squares
criterion over held-out
observations, using ;
this targets integrated squared error (Rudemo 1982; Bowman 1984). With
criterion = "loglik" it maximises the held-out log-likelihood. Pairs
with below the lattice spacing are not
considered, since the local-linear smoother is then ill-conditioned.
select_wavelet( x, j0_grid = 3:6, h_grid = c(0.03, 0.05, 0.08, 0.12, 0.2, 0.3), folds = 5L, criterion = c("lscv", "loglik"), ... )select_wavelet( x, j0_grid = 3:6, h_grid = c(0.03, 0.05, 0.08, 0.12, 0.2, 0.3), folds = 5L, criterion = c("lscv", "loglik"), ... )
x |
numeric sample. |
j0_grid, h_grid
|
candidate values. |
folds |
number of folds. |
criterion |
|
... |
passed to |
a list with j0, h, and the matrix of criterion values
(ll, rows j0_grid, columns h_grid).
Fold assignment (or bootstrap resampling) uses R's random number generator;
call set.seed() beforehand to make results exactly reproducible.
set.seed(2) x <- rbeta(300, 0.5, 0.5) select_wavelet(x, j0_grid = 4:6, h_grid = c(0.05, 0.15), folds = 3)set.seed(2) x <- rbeta(300, 0.5, 0.5) select_wavelet(x, j0_grid = 4:6, h_grid = c(0.05, 0.15), folds = 3)
Applies a thresholding rule to the detail coefficients of a periodic DWT.
"hard": term-by-term hard thresholding, ,
with (Chesneau, Dewan and
Doosti 2016; in their implementation).
"block": the BlockJS rule of Cai (1999) used by Shirazi and Doosti
(2022): at each level the coefficients are grouped in blocks of length
; a block is kept if
with (rule = "truncate"), or shrunk by
(rule = "james-stein").
is the MAD of the finest-level coefficients.
threshold_coefficients( w, L, n, type = c("hard", "block"), const = NULL, block_length = NULL, rule = c("truncate", "james-stein") )threshold_coefficients( w, L, n, type = c("hard", "block"), const = NULL, block_length = NULL, rule = c("truncate", "james-stein") )
w |
coefficient vector from |
L |
number of DWT levels used to produce |
n |
sample size (enters the threshold). |
type |
|
const |
threshold constant: |
block_length |
block length for |
rule |
for |
thresholded coefficient vector.
Cai, T. T. (1999). Adaptive wavelet estimation: a block thresholding and oracle inequality approach. Annals of Statistics, 27, 898–924.
Homogenised per-unit bids (dollars per unit of timber) in the sealed-bid subsample of the U.S. Forest Service timber auction data assembled by Lu and Perrigne (2008) and deposited in the Journal of Applied Econometrics Data Archive, split by the number of bidders. The bids are not the raw bids: observed lot heterogeneity has been removed as described in Details. The announced reserve price is treated as non-binding in the literature using these data.
timbertimber
A list with two numeric matrices, one row per auction and one column per bidder, in the order in which the archive files record them:
107 auctions with 2 bidders (columns bid1, bid2)
108 auctions with 3 bidders (columns bid1, bid2, bid3)
Each auction in the archive reports the per-unit bid of every bidder together with two lot characteristics: the appraised per-unit value and the timber volume. Observed heterogeneity in these characteristics is removed before the structural analysis, as is standard for these data (Lu and Perrigne 2008; Haile, Hong and Shum 2003), so that the methods of this package can be applied to bids drawn from a common distribution within each stratum.
Within each stratum ( and separately), the log bid is
regressed by ordinary least squares on
, which is
constant within an auction, and every bid is rescaled to the average lot,
The intercept cancels in the difference, so only the slope coefficients
matter. The regressions fit the log bids with for
(slopes 0.642 and 0.043) and for
(slopes 0.553 and 0.070). The stored values are rounded to six
decimal places.
The script that rebuilds the object from the archive files is
data-raw/timber.R of the package sources; the archive files themselves
are not redistributed here.
Journal of Applied Econometrics Data Archive, replication files of Lu, J. and Perrigne, I. (2008). Estimating risk aversion from ascending and sealed-bid auctions: the case of timber auction data. Journal of Applied Econometrics, 23, 871–896. doi:10.1002/jae.1032; data archive entry doi:10.15456/jae.2022319.0720356598. Please cite that paper when using the data.
Haile, P. A., Hong, H. and Shum, M. (2003). Nonparametric tests for common values at first-price sealed-bid auctions. Cowles Foundation Discussion Paper 1445.
data(timber) fit <- fpa_values(timber$n3, method = "bernstein", bandwidth = "bcv") summary(fit$values - fit$bids) # implied markupsdata(timber) fit <- fpa_values(timber$n3, method = "bernstein", bandwidth = "bcv") summary(fit$values - fit$bids) # implied markups
Returns the scaling (low-pass) filter of a compactly supported orthonormal
wavelet. Available: "haar", "db2", "db3", "db4" (Daubechies with 2–4
vanishing moments), "sym4" (Symmlet 8-tap), "coif1", "coif2"
(Coiflets). A numeric vector is returned unchanged after checking that it
sums to .
wavelet_filter(filter = "db3")wavelet_filter(filter = "db3")
filter |
character name or numeric filter. |
numeric filter coefficients.
wavelet_filter("db3")wavelet_filter("db3")