Changes prompted by editorial review at the Journal of Statistical Software.
sharpen_density() gains an optimizer
argument. The default, a bounded quasi-Newton search from several
starting points, reaches the same minimum as the genetic algorithm in a
fraction of the time when the number of distinct shifts is small; the
genetic algorithm remains available as "ga", and any
user-supplied search function of (fn, lower, upper) can be
used. The polishing step is now bounded (L-BFGS-B).make_kernel() builds a kernel object from a density
function alone, and check_kernel() reports whether a kernel
has the properties the estimators assume.conventional_density() evaluates the ordinary kernel
estimator with the package’s own code, so that comparisons do not depend
on stats::density(), whose output changed between R 4.3 and
4.4.bw_flattop() failed on data with a large scale, such as
the waiting column of faithful, because its
search grid could be shorter than the stretch it looked for. Fixed, with
a regression test.tilt_density() and
tilt_density_cv() now say that a matrix or data frame is
accepted; sharpen_density() gives a clear message when
handed one.sum(p * (A %*% p)) rather than
t(p) %*% A %*% p, and block products with
crossprod(); the redundant availability check for
quadprog, which is in Imports, is removed.First release.
tilt_density() implements the tilted estimator of
Doosti and Hall (2016), with weights chosen by minimising the L2
distance to a sinc or trapezoidal comparator estimator.m is finite, the
block boundaries can be chosen in three ways through the
breaks argument: "optimal" selects them
jointly with the weights, as Section 4.1 of the 2016 paper specifies;
"equal" uses near-equal blocks, Algorithm A of the 2018
paper; "modal" places them at the troughs of a pilot
estimate, the refinement suggested in Section 2 of the 2018 paper.
Explicit boundaries may also be supplied.tilt_density_cv() implements method (III) of Doosti,
Hall and Mateu (2018), choosing the bandwidth and the weights together
by cross-validation.sharpen_density() implements the data-sharpened
estimator of Doosti and Hall (2016).kernel argument: "gaussian" (the default, and
the one used for every numerical result in both papers), the
Laplace-convolution family "laplace" through
"laplace4" that Section 3.1 of the 2016 paper states its
condition (3.1) for, and "epanechnikov",
"biweight", "triweight" and
"triangular". Custom kernels may be supplied as a list.
tilt_kernels() lists them.bw_canonical_factor() returns the factor and
bw_convert() maps a bandwidth between kernels;
bw_nrd_robust() gained a kernel argument. The
estimators apply the rescaling to their default bandwidth, so changing
the kernel changes the shape of the fit rather than how much it is
smoothed. For the Gaussian the factor is one, so nothing about the
papers’ setting changes. Weight selection stays a convex quadratic
program whatever the kernel, because the Gram matrix has Fourier
transform phi^2 >= 0 and so is positive semidefinite by
construction.tilt_density() and
tilt_density_cv(): pass a matrix. This is Section 3.3 of
the 2016 paper. The product kernel makes every quantity factorise across
dimensions, so the l-variate matrices are elementwise products of the
univariate ones and the optimisation problem is unchanged.
plot() draws a contour for bivariate fits. Data sharpening
remains univariate.constraint
argument of tilt_density() and
tilt_density_cv(): "unimodal",
"increasing" or "decreasing". The estimator is
linear in the weights, so a shape requirement on a grid becomes linear
inequalities and the problem stays a convex quadratic program.
Shape-constrained tilting is due to Hall and Huang (2002); applying it
to the cross-validation criterion follows the extension suggested in the
discussion of the 2018 paper.sinc_density() and trapezoid_density()
provide the infinite-order comparator estimators on their own.bw_comparator_cv(), bw_flattop() and
bw_nrd_robust() select bandwidths."density", so base plotting
works unchanged, and have print(), summary()
and predict() methods.bw_comparator_cv() handles tied observations, which
real data recorded to limited precision routinely contain.