Finds Gamma(a, b) hyperprior parameters that exactly match target moments for the number of clusters K_J under a Dirichlet process prior.
Usage
DPprior_a2_newton(
J,
mu_K,
var_K,
a0 = NULL,
b0 = NULL,
tol_F = .TOL_NEWTON,
tol_step = 1e-10,
max_iter = 20L,
damping = TRUE,
use_fallback = TRUE,
M = .QUAD_NODES_DEFAULT,
verbose = FALSE
)Arguments
- J
Integer; sample size (number of observations/sites). Must be >= 2.
- mu_K
Numeric; target prior mean \(E[K_J]\). Must satisfy \(1 < \mu_K < J\).
- var_K
Numeric; target prior variance \(\mathrm{Var}(K_J)\). Must be positive.
- a0
Numeric or NULL; initial shape parameter. If NULL, computed via
DPprior_a1.- b0
Numeric or NULL; initial rate parameter. If NULL, computed via
DPprior_a1.- tol_F
Numeric; stopping tolerance for the residual norm ||F|| = sqrt((M1 - mu_K)^2 + (V - var_K)^2). Default: 1e-8.
- tol_step
Numeric; stopping tolerance for Newton step size. Default: 1e-10.
- max_iter
Integer; maximum Newton iterations. Default: 20.
- damping
Logical; if TRUE, use backtracking line search for damped Newton updates. Default: TRUE.
- use_fallback
Logical; if TRUE, use Nelder-Mead fallback when Newton fails to converge. Default: TRUE.
- M
Integer; number of quadrature nodes for moment computation. Default: 80.
- verbose
Logical; if TRUE, print iteration progress. Default: FALSE.
Value
A DPprior_fit object (S3 class) with components:
aNumeric; optimal shape parameter
bNumeric; optimal rate parameter
JInteger; sample size
targetList with
mu_K,var_K, andtype = "moments"methodCharacter; "A2-MN" or "A2-MN+NM" if fallback was used
statusCharacter; convergence status ("success", "stagnated", "max_iter")
convergedLogical; whether algorithm converged to target tolerance
iterationsInteger; number of iterations
terminationCharacter; reason for termination ("residual", "step", "max_iter", "nelder_mead")
fitList with achieved
mu_K,var_K, andresidualdiagnosticsList with diagnostic information
traceData frame with iteration history
Details
The A2-MN algorithm uses Newton's method in log-scale to ensure positivity of the Gamma parameters. The Jacobian is computed exactly using score function identities (RN-04 Corollary 1), avoiding finite difference approximations.
Algorithm Steps:
Initialize: \((a_0, b_0)\) from A1 closed-form or user-provided
Log-parameterize: \(\eta = (\log a, \log b)\)
For each iteration:
Compute moments \((M_1, V)\) and Jacobian \(J_F\)
Compute residual \(F = (M_1 - \mu_K, V - \sigma^2_K)\)
Transform Jacobian to log-scale: \(J_{\log} = J_F \cdot \text{diag}(a, b)\)
Newton step: \(\Delta = -J_{\log}^{-1} F\)
Backtracking line search (if damping enabled)
Update: \(\eta \leftarrow \eta + \lambda \Delta\)
Return \((a, b) = \exp(\eta)\)
Convergence Behavior:
For typical targets, converges in 3-8 iterations
For targets requiring very small \(a\) (quasi-improper priors), convergence may be slower; the Nelder-Mead fallback handles these cases
Machine-precision accuracy (residual < 1e-10) is typically achieved
Termination Conditions:
residual: ||F|| < tol_F (success)step: ||delta|| < tol_step (stagnation - may not have converged)max_iter: maximum iterations reachednelder_mead: Nelder-Mead fallback succeeded
Error Handling:
If Jacobian becomes singular, falls back to gradient descent
If Newton fails after
max_iter, uses Nelder-Mead if enabledWarns for quasi-improper priors (\(a < 0.1\))
References
Lee, J. (2025). RN-04: A2 Small-J Correction Note. Research Notes for DPprior Package Development.
See also
DPprior_a1 for closed-form initialization,
moments_with_jacobian for Jacobian computation,
exact_K_moments for moment verification
Examples
# Basic usage
fit <- DPprior_a2_newton(J = 50, mu_K = 5, var_K = 8)
print(fit)
#> DPprior Prior Elicitation Result
#> =============================================
#>
#> Gamma Hyperprior: α ~ Gamma(a = 2.0361, b = 1.6051)
#> E[α] = 1.269, SD[α] = 0.889
#>
#> Target (J = 50):
#> E[K_J] = 5.00
#> Var(K_J) = 8.00
#>
#> Achieved:
#> E[K_J] = 5.000000, Var(K_J) = 8.000000
#> Residual = 7.60e-09
#>
#> Method: A2-MN (6 iterations)
# Verify exact moment matching
achieved <- exact_K_moments(50, fit$a, fit$b)
cat(sprintf("Target E[K]=5, Achieved E[K]=%.10f\n", achieved$mean))
#> Target E[K]=5, Achieved E[K]=4.9999999992
cat(sprintf("Target Var=8, Achieved Var=%.10f\n", achieved$var))
#> Target Var=8, Achieved Var=8.0000000076
# Compare A1 vs A2 accuracy
a1 <- DPprior_a1(J = 50, mu_K = 5, var_K = 8)
a1_mom <- exact_K_moments(50, a1$a, a1$b)
a2_mom <- exact_K_moments(50, fit$a, fit$b)
cat(sprintf("A1 mean error: %.6f\n", abs(a1_mom$mean - 5)))
#> A1 mean error: 0.538649
cat(sprintf("A2 mean error: %.2e\n", abs(a2_mom$mean - 5)))
#> A2 mean error: 8.31e-10
# View iteration trace (includes step size and Jacobian determinant)
head(fit$trace)
#> iter a b M1 V residual step det_Jlog
#> 1 1 4.000000 3.9120230 4.461351 4.783136 3.261649e+00 1 -5.300969
#> 2 2 1.178650 0.9119694 4.909046 10.854537 2.855986e+00 1 -21.553612
#> 3 3 1.844384 1.4552538 4.974913 8.399473 4.002603e-01 1 -15.313512
#> 4 4 2.029223 1.5996801 4.999187 8.013243 1.326844e-02 1 -14.298307
#> 5 5 2.036082 1.6050455 4.999999 8.000021 2.078492e-05 1 -14.263052
#> 6 6 2.036093 1.6050541 5.000000 8.000000 7.600370e-09 NA -14.262997