Skip to content

feat(psychometric): restore Driver p.16 asymDIFFUSIONstd p/p=1 on main - #267

Open
seonghobae wants to merge 1 commit into
mainfrom
agent/psychometric-standardised-asymptotic-diffusion-on-main
Open

feat(psychometric): restore Driver p.16 asymDIFFUSIONstd p/p=1 on main#267
seonghobae wants to merge 1 commit into
mainfrom
agent/psychometric-standardised-asymptotic-diffusion-on-main

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Outcome

Restores the executable Driver, Oud, and Voelkle (2017) p. 16 asymDIFFUSIONstd scalar on current main after 0ce16e8 dropped the pre-consolidation code while research notes already named the map (register items 89–90).

Head is independent of any open PR (none open at open time). Lands on protected main c7cf34b after #266 analysis-run status HTTP, #265 T0VARstd, #262 T0MEANSstd, #250 asymCINTstd, and #244 discreteCINTstd.

JSS PDF re-opened 2026-08-26T17:20Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104. Table 2 (p. 12), footnote 4 (p. 16), Eq. 4 (p. 5), and the p. 16 std suffix were read from that PDF in this cycle.

  • Page 16 prints standardised matrices with the suffix std when appropriate, and names asymDIFFUSION the total within-subject variance as Δt → ∞. The printed example on p. 16 is discreteDRIFTstd, not asymDIFFUSIONstd.
  • Footnote 4: standardisations use only the relevant variance, not the total. The relevant variance for that named process-dynamics correlation is within-subject asymDIFFUSION p = −q / (2 a), not free first-occasion T0VAR.
  • The 2017-era summary.ctsemFit.R forms asymDIFFUSIONstd as solve(sqrt(diag(asymDIFFUSION))) %&% asymDIFFUSION when verbose = TRUE. OpenMx %&% is t(A) %*% B %*% A. The default ridging = FALSE adds 0, not 0.0001; that ridge is a numerical hack and is not this exact map.
  • Scalar map: p / p = 1 after strictly positive asymDIFFUSION. Form strictly positive p first, then 1 / √p, then (1 / √p) p (1 / √p). Unstandardised p is defined for a zero process; standardised asymDIFFUSION is not. Zero q has no positive SD and fails closed. Lasting p requires stable a < 0. A non-event clock fails closed. Distinct positive p recover the same 1.
  • p_0 / p_0 = 1 is T0VARstd and recovers the same number and remains a distinct named quantity. This crate already exports T0VARstd; the refuse names that quantity.
  • q / p = −2 a is DIFFUSIONstd and is not this correlation. Equal numbers when a = −0.5 remain distinct named quantities. This crate does not currently export DIFFUSIONstd; the refuse still names that quantity.
  • v / v = 1 is TIPREDVARstd and recovers the same number and remains a distinct named quantity. This crate does not currently export TIPREDVARstd; the refuse still names that quantity.

Still not a Kalman filter, not a matrix expm, not ESEM estimation, not DSEM, not MGCFA, and not ctsem estimation.

Meredith (1993) remains unread (Unpaywall 2026-08-26T17:20Z: is_oa: false; OpenAlex closed; Springer content/pdf is an HTML stub). Mislevy (1991) remains unread on the same terms (DOI 10.1007/bf02294457; Unpaywall is_oa: false). #84 metric still does not license latent means.

Do not merge without independent non-author APPROVE and exact-head required-check success. Author will not self-approve. Org has only collaborator seonghobae. Do not request Copilot.

Next restore after this slice: TRAITVARstd (register items 81–82).

Verification at this head

  • cargo +1.98.0 test -p psychometric_core --lib — 180 passed
  • cargo +1.98.0 test -p psychometric_core --test multilevel_event_time_recovery_contract --test scientific_claim_boundary_contract standardised_asymptotic_diffusion — 2 + 1 passed
  • cargo +1.98.0 clippy -p psychometric_core --all-targets -- -D warnings
  • cargo +1.98.0 fmt -p psychometric_core -- --check
  • RUSTDOCFLAGS='-D warnings' cargo +1.98.0 doc -p psychometric_core --no-deps

Contract

  • crate: psychometric_core (not a second invariance crate)
  • map: recover_standardised_asymptotic_diffusion
  • ADR: 0005

Open in Devin Review

Summary by CodeRabbit

  • 새로운 기능

    • 표준화된 점근적 within-subject variance 복원 기능을 추가했습니다.
    • 비사건 시계, 불안정한 drift, 0 또는 유효하지 않은 diffusion 입력을 안전하게 거부합니다.
    • 유사한 초기 분산·연속 diffusion·예측변수 분산과의 개념 혼동을 방지합니다.
  • 버그 수정

    • 양의 정상상태 분산이 보장되지 않는 경우 명확한 오류를 제공합니다.
  • 문서

    • 관련 수량의 정의, 적용 범위 및 과학적 근거를 문서화했습니다.

Restore recover_standardised_asymptotic_diffusion on current main after
0ce16e8 dropped the pre-consolidation code while research notes already
named the map (register items 89–90). Scalar is p/p=1 after strictly
positive asymDIFFUSION p=−q/(2a). Distinct from T0VARstd, DIFFUSIONstd,
and TIPREDVARstd even when those equal 1.
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 81133b44-c5b8-4eb5-8176-d1c30dc023c6

📥 Commits

Reviewing files that changed from the base of the PR and between c7cf34b and a7c805a.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • crates/psychometric_core/src/error.rs
  • crates/psychometric_core/src/event_time.rs
  • crates/psychometric_core/src/lib.rs
  • crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs
  • crates/psychometric_core/tests/scientific_claim_boundary_contract.rs
  • docs/adr/0005-posterior-esem-dsem.md
  • docs/research/multilevel-event-time-recovery.md

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

asymDIFFUSIONstd 복원 API가 추가되었습니다. 이 API는 p = −q / (2a)로 양의 stationary variance를 계산하고 자기 자신으로 표준화합니다. 비-event clock, 불안정한 drift, 무효 diffusion, 관련 수량의 오인을 오류로 처리합니다.

Changes

표준화 점근 확산

Layer / File(s) Summary
오류 계약 정의
crates/psychometric_core/src/error.rs
표준화 점근 확산의 양의 정상상태 분산 요구와 관련 개념의 오인을 나타내는 오류 변형, 표시 문자열, 안정성 테스트가 추가되었습니다.
복원 API 및 공개 재수출
crates/psychometric_core/src/event_time.rs, crates/psychometric_core/src/lib.rs
recover_standardised_asymptotic_diffusion이 event-time clock, 안정적인 drift, 유효한 diffusion을 검증하고 표준화 결과를 반환합니다. 관련 refuse 함수가 공개 API로 재수출되었습니다.
계약 검증 및 정의 문서화
crates/psychometric_core/tests/*, CHANGELOG.md, docs/adr/0005-posterior-esem-dsem.md, docs/research/multilevel-event-time-recovery.md
복원값의 불변성, fail-closed 조건, T0VARstd, DIFFUSIONstd, TIPREDVARstd와의 구분을 테스트와 문서에 반영했습니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to a7c80

The PR restores a localized psychometric scalar with documented validation and passing checks; no actionable merge-blocking risk remains beyond normal review.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant recover_standardised_asymptotic_diffusion
  participant LagClock
  participant PsychometricError
  Caller->>recover_standardised_asymptotic_diffusion: 입력값과 clock 전달
  recover_standardised_asymptotic_diffusion->>LagClock: event-time clock 검증
  LagClock-->>recover_standardised_asymptotic_diffusion: 검증 결과 반환
  recover_standardised_asymptotic_diffusion->>PsychometricError: 무효 입력 오류 생성
  recover_standardised_asymptotic_diffusion-->>Caller: 1 또는 오류 반환
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 recover_standardised_asymptotic_diffusion 구현과 Driver p.16의 asymDIFFUSIONstd 스칼라 p / p = 1 복원을 정확히 요약합니다. 변경의 주요 목적과 일치하며 간결하고 구체적입니다.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 4 files. (4 skipped: 3…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 4 files. (4 skipped: 3 unsupported, 1 too large.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/psychometric-standardised-asymptotic-diffusion-on-main

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.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment on lines +1821 to +1824
let process_sd = stationary.sqrt();
let inverse_sd = require_finite(1.0 / process_sd)?;
let scaled = require_finite(inverse_sd * stationary)?;
require_finite(scaled * inverse_sd)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Overflow guards in the p/p=1 map are unreachable

In recover_standardised_asymptotic_diffusion the result (1/√p) p (1/√p) always equals 1 for finite positive p, so the three require_finite overflow guards can never fail. The documented InvalidNumericInput overflow path (event_time.rs:1806-1809) is dead. This mirrors the existing recover_standardised_initial_latent_variance, so it is consistent with the crate pattern rather than a regression.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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