Skip to contents

Calibrates Gamma hyperprior parameters \((a, b)\) by minimizing the Kullback-Leibler divergence between a target distribution and the induced marginal PMF of the number of clusters \(K_J\).

Usage

DPprior_a2_kl(
  J,
  target,
  method = c("pmf", "chisq"),
  max_iter = 100L,
  tol = 1e-06,
  M = .QUAD_NODES_DEFAULT,
  verbose = FALSE,
  ...
)

Arguments

J

Integer; sample size (number of observations). Must be >= 2.

target

Either:

  • Numeric vector of length J or J+1: target PMF for k = 1, ..., J, or for k = 0, ..., J with the k = 0 entry zero and dropped (used when method = "pmf").

  • Named list with mu_K and var_K: construct from moments using a discretized scaled chi-square (used when method = "chisq").

method

Character; "pmf" or "chisq". Default: "pmf".

max_iter

Integer; maximum optimization iterations. Default: 100.

tol

Numeric; convergence tolerance for optimization. Default: 1e-6.

M

Integer; number of quadrature nodes. Default: 80.

verbose

Logical; if TRUE, print optimization progress. Default: FALSE.

...

Optional tuning parameters:

  • log_bounds: numeric length-2 vector giving lower/upper bounds on log(a) and log(b) (default c(-15, 15)).

  • M_verify: compliant higher quadrature order (by default max(2*M, M+40) when supported).

  • kl_tol, l1_tol, mean_scaled_tol, and var_scaled_tol: independent adequacy tolerances.

  • pmf_abs_tol, pmf_rel_tol: higher-order PMF verification tolerances.

  • boundary_tol: log-parameter bound proximity tolerance.

  • fallback_max_iter: iteration budget for the predeclared bounded nlminb fallback.

Value

A canonical dpprior.result/1 DPprior_fit object. The authoritative fields are:

parameters

Selected Gamma shape a, rate b, and the log_ab parameterization.

J

Integer; sample size

target$K

Canonical requested, normalized, and used target. A strict PMF remains authoritative. For method = "chisq", the requested moments remain authoritative and the conditioned chi-square PMF is recorded only as A2_KL_objective derivation evidence.

achieved, residuals

Selected-order induced PMF, moments, and distinct KL, L1, mean, and variance residuals.

computation

Closed controls, quadrature orders, trace, typed initializer/optimizer attempts, fresh candidate evaluations, fallback, candidate selection, and termination evidence.

verification

A fixed-parameter verifier snapshot at the required independent order, four distribution-adequacy gates, and a separate PMF order-stability check.

method

Character; "A2-KL".

status

One of converged, boundary, approximate, infeasible, or failed.

usable, verified

Logical adequacy flags.

provenance

Method, backend, approximation, projection, and migration records.

compatibility

A quarantined non-authoritative Phase 8 view. Top-level a, b, fit, diagnostics, attempts, and trace are registered migration aliases.

Details

The A2-KL algorithm finds \((a^*, b^*)\) by solving: $$(a^*, b^*) = \arg\min_{a,b} D_{KL}(p^*(K_J) \| p_{a,b}(K_J))$$

Algorithm:

  1. Validate a normalized custom PMF, or explicitly construct and support-condition a chi-square target PMF

  2. Initialize \((a_0, b_0)\) from A2-MN (exact moment matching)

  3. Optimize KL divergence using L-BFGS-B in log-space with bounds

  4. If the primary optimizer fails, try a recorded bounded nlminb fallback for the same exact objective

  5. Independently reconstruct target and induced PMFs at a compliant higher quadrature order and assess KL, L1, and scaled moment errors

  6. Classify status from verification and adequacy, not optimizer exit

Stability features:

  • Log-parameterization ensures positivity of (a, b)

  • Explicit bounds prevent numerical overflow/underflow

  • Exact zero-support KL semantics without epsilon smoothing

  • Explicit fallback attempts; initialization is never labelled success

  • A2-MN initialization provides good starting point

When to use A2-KL vs A2-MN:

  • A2-MN: Target moments only (exact moment matching)

  • A2-KL: Full target distribution shape (multi-modal, skewed, expert-elicited)

The canonical achieved and residuals fields always contain the selected-M computation. Higher-order PMF values are retained in the independent verification$verifier_snapshot; they determine status but never replace the selected-order result. The default adequacy limits are KL 0.015, L1 0.11, scaled mean 0.01, and scaled variance 0.065. The PMF order stability tolerance is a separate numerical check and is never substituted for any of those four scientific adequacy gates.

References

Lee, J. (2026). Design-Conditional Prior Elicitation for Dirichlet Process Mixtures. arXiv preprint arXiv:2602.06301.

See also

DPprior_a2_newton for exact moment matching, DPprior_a1 for closed-form initialization, kl_divergence_K for KL divergence computation, discretize_chisq for chi-square discretization

Other elicitation: DPprior_a1(), DPprior_a2_newton(), DPprior_dual(), DPprior_dual_hard(), DPprior_dual_soft(), DPprior_fit(), DPprior_target_K()

Examples

# Example 1: Target from moments (method = "chisq")
fit <- DPprior_a2_kl(J = 50, target = list(mu_K = 5, var_K = 8),
                     method = "chisq")
print(fit)
#> DPprior Prior Elicitation Result
#> ============================================= 
#> 
#> Schema: dpprior.result/1
#> Method: A2-KL (mode: a2_kl)
#> Status: converged; usable: yes; verified: yes
#> 
#> Target (J = 50):
#>   E[K_J]   = 5.0000
#>   Var(K_J) = 8.0000
#> 
#> Canonical candidate:
#>   alpha ~ Gamma(a = 2.2363, b = 1.7627)
#>   Achieved E[K_J] = 5.019984; Var(K_J) = 7.640335
#> 
#> Canonical guidance: A2-KL optimizer and independent adequacy verification passed

# Example 2: Custom target PMF (method = "pmf")
target_pmf <- dbinom(1:50, size = 50, prob = 0.1)
target_pmf <- target_pmf / sum(target_pmf)
fit2 <- DPprior_a2_kl(J = 50, target = target_pmf, method = "pmf")

# Example 3: Compare A2-KL vs A2-MN
a2_mn <- DPprior_a2_newton(J = 50, mu_K = 5, var_K = 8)
a2_kl <- DPprior_a2_kl(J = 50, target = list(mu_K = 5, var_K = 8),
                       method = "chisq")
cat(sprintf(
  "A2-MN: a=%.4f, b=%.4f\n",
  a2_mn$parameters$a, a2_mn$parameters$b
))
#> A2-MN: a=2.0361, b=1.6051
cat(sprintf(
  "A2-KL: a=%.4f, b=%.4f, KL=%.4e\n",
  a2_kl$parameters$a, a2_kl$parameters$b,
  a2_kl$residuals$distribution$kl
))
#> A2-KL: a=2.2363, b=1.7627, KL=5.0297e-03