Skip to content

feat(psychometric): recover 2017-era active asymptotes=TRUE DIFFUSION rewrite on main - #357

Draft
seonghobae wants to merge 1 commit into
mainfrom
agent/psychometric-asymptotes-true-diffusion-on-main
Draft

feat(psychometric): recover 2017-era active asymptotes=TRUE DIFFUSION rewrite on main#357
seonghobae wants to merge 1 commit into
mainfrom
agent/psychometric-asymptotes-true-diffusion-on-main

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Summary

psychometric_core recovers the 2017-era active asymptotes=TRUE DIFFUSION rewrite as the scalar −2 a · q on current main.

This is an independent companion of still-unmerged PR #349 (CINT <- -DRIFT %*% CINT as −a · κ) and PR #355 (TIPREDEFFECT <- -DRIFT %*% TIPREDEFFECT as −a · B). It branches from origin/main 1bc02f58, does not wait for those drafts, and is not stacked on them. cran/ctsem 2.5.0 summary.ctsemFit.R has three active asymptotes=TRUE rewrites: CINT (L213), DIFFUSION (L230), TIPREDEFFECT (L378–379). DIFFUSION was not on main and not in any open PR.

cran/ctsem 2.5.0 forms DRIFTHATCH <- (DRIFT %x% I) + (I %x% DRIFT) then if(asymptotes==TRUE) DIFFUSION <- matrix(-DRIFTHATCH %*% OpenMx::rvectorize(DIFFUSION), nrow=n.latent, ncol=n.latent) immediately after mxEval(DIFFUSION, mxobj, compute=TRUE) and puts that rewrite in the active outlist. Driver, Oud, and Voelkle (2017, Table 2, p. 12; Eq. 4, p. 5; p. 16; JSS PDF re-opened 2026-08-31T07:40Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104) name DIFFUSION the continuous process-noise covariance. For one latent the Kronecker sum is 2 a, so the scalar map is −2 a · q. Form 2 a first, then negate, then multiply by q. When asymptotes=TRUE the stored DIFFUSION is the asymptotic parameterization Table 2 / p. 16 names asymDIFFUSION p = −q / (2 a); multiplying by -DRIFTHATCH converts that stored value back to original q. −2 a · (−q / (2 a)) = q. The companion active rewrites CINT <- -DRIFT %*% CINT and TIPREDEFFECT <- -DRIFT %*% TIPREDEFFECT use -DRIFT, not -DRIFTHATCH, on different matrices and are not this process-noise map.

A zero diffusion is exactly zero even if a ≥ 0. a ≥ 0 with a nonzero diffusion fails closed. A negative diffusion fails closed. Numeric: a = −0.25, q = 0.4 recovers 0.2, distinct from unstandardised DIFFUSION (0.4), from asymDIFFUSION −q / (2 a) (0.8), from the finite-interval discreteDIFFUSION at Δt = 1 (≈ 0.3148), and from DIFFUSIONstd q / p = −2 a (0.5). Stored p = 0.8 recovers original q 0.4. The rate is not a = −0.5, so −2 a · q ≠ q. Unstandardised q is not this rewrite. asymDIFFUSION is not this rewrite. Finite-interval Q_Δt is not this rewrite. DIFFUSIONstd is not this rewrite. A non-event clock fails closed.

Meredith (1993) remains unread (Unpaywall historically is_oa: false; Springer content/pdf is an HTML stub). Mislevy (1991, Psychometrika, 56, 177–196, DOI 10.1007/bf02294457) remains unread on the same terms. Still not a Kalman filter, not a matrix expm, not ESEM estimation, not DSEM, and not ctsem estimation.

Plan

Fail-closed scalar recover_asymptotes_true_continuous_diffusion(continuous_diffusion, log_rate, clock) as −2 a · q on origin/main, with four refuse helpers (unstandardised q, asymDIFFUSION, discreteDIFFUSION, DIFFUSIONstd), five error variants, register items 110–111, CHANGELOG, ADR 0005, and crate/contract tests. Independent of #349 and #355.

Verification

  • cargo fmt --all
  • cargo clippy -p psychometric_core --all-targets -- -D warnings
  • cargo test -p psychometric_core --lib (193)
  • cargo test -p psychometric_core --test multilevel_event_time_recovery_contract (110)
  • cargo test -p psychometric_core --test scientific_claim_boundary_contract (53)
  • RUSTDOCFLAGS='-D warnings' cargo doc -p psychometric_core --no-deps

Register items 110–111.

Opened by: Grok Build (xAI) on behalf of Seongho Bae.

Do not merge without independent non-author APPROVE + exact-head required-check success. Do not convert from draft. Do not self-approve.

… rewrite

Scalar −2a · q from cran/ctsem 2.5.0 summary.ctsemFit.R
if(asymptotes==TRUE) DIFFUSION <- -DRIFTHATCH %*% rvectorize(DIFFUSION).
Register items 110–111. Independent of #349 and #355.
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant