max_q (now an initial endpoint). Add optional
max_count; exceeding the work limit signals an error instead of capping a
count. Quantiles at probability one use the distribution support endpoint.Fixed a starting-value inconsistency in ctp.fit() that could cause
optim() to silently converge to a degenerate local optimum for
moderately overdispersed data. a_start and gama_start are derived
independently from the sample mean/variance, with nothing guaranteeing
gama_start > 2*a_start + 2. When that margin was non-positive,
eta_start was clamped to log(1e-6), pinning the optimizer's start
right on the variance-existence singularity (gama = 2a + 2), where
the log-density has pathological gradients. ctp.fit() now falls back
to a safe starting margin (with a warning()) instead of clamping to
the boundary, and additionally tries a small grid of alternative
starting points, keeping whichever converges to the best
log-likelihood.
Applied the same safe-margin fallback to the starting-value grid in
zictp.fit(), which shared the same underlying clamp pattern in each
of its multi-start candidates.
ctp.fit() and zictp.fit() now flag fits whose estimated gama is
very close to the variance-existence boundary (gama - 2*a - 2 near
zero) with a warning(), a near_boundary element in the returned
object, and a note in print()/summary() output -- instead of
silently reporting Convergence: YES on an unreliable fit.
Fixed a severe performance bug in dctp(): its normalization-tail loop
grew a vector one element at a time via c(), which is O(n^2) in R.
Near the gama = 2*a + 2 boundary the tail decays very slowly and can
need close to the full 10000-term cap, making individual dctp() calls
take seconds rather than milliseconds -- and this compounds badly
across an optimizer's many function evaluations during ctp.fit()/
zictp.fit(), especially for the exact overdispersed, near-boundary
data most likely to trigger the starting-value bug above. The tail
buffer is now preallocated; a dctp() call near the boundary that
previously took ~0.15s now takes ~0.002s, with identical numerical
output.
Fixed an incorrect mode formula in mode_ctp() and mode_zictp().
The previous implementation used a naive "round to nearest integer"
rule that could return the wrong mode (e.g., returning 1 when the
true mode was 0). Both functions now use the correct threshold-based
rule.
Fixed incorrect variance and skewness formulas in var_ctp() and
skew_ctp(). The previous implementation used an incorrect
algebraic combination of terms. var_zictp() and skew_zictp()
required no changes and inherit the fix automatically, since they
are built directly on var_ctp() and skew_ctp().
Added an explicit validity check (gama > 0) to ctp.fit() and
zictp.fit(). This closes a narrow edge case in the internal
parameter reparameterization where sufficiently extreme starting
conditions could otherwise allow an invalid (non-positive) gama
during optimization. Typical fits to well-behaved data are
unaffected.
tests/testthat/test-moments.R now contains a full suite of
regression tests for mean_ctp(), var_ctp(), skew_ctp(),
mode_ctp(), and their zero-modified counterparts, including a
Monte Carlo cross-check of the skewness formula against simulated
data from rzictp().If you used var_ctp(), skew_ctp(), var_zictp(), skew_zictp(),
mode_ctp(), or mode_zictp() in version 0.1.1 or earlier, results
from those functions will differ under 0.1.2 -- the new results are
correct. We recommend re-running any analysis that relied on their
numeric output.
mean_ctp(), var_ctp(),
skew_ctp(), mode_ctp(), mean_zictp(), var_zictp(),
skew_zictp(), mode_zictp(). These were previously computed only
internally within summary.ctpfit() and summary.zictpfit().