From 7a7be8756efd9a318d76a574ececb8533e7ab8fe Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 09:47:22 +0000 Subject: [PATCH 1/7] style(psychometric_core): apply rustfmt to #232 stack union Protected-main rust-quality fails cargo fmt --all --check on the consolidated event_time unit tests and multilevel recovery contract. Formatting only; call-site arity is a follow-up commit. Co-authored-by: Seongho Bae --- crates/psychometric_core/src/event_time.rs | 208 ++++-------------- ...multilevel_event_time_recovery_contract.rs | 154 +++---------- 2 files changed, 71 insertions(+), 291 deletions(-) diff --git a/crates/psychometric_core/src/event_time.rs b/crates/psychometric_core/src/event_time.rs index 09bbd0c1f..13b757e1c 100644 --- a/crates/psychometric_core/src/event_time.rs +++ b/crates/psychometric_core/src/event_time.rs @@ -10536,12 +10536,9 @@ mod tests { recover_discrete_lag_from_log_rate(drift, source_delta, LagClock::EventTime) .expect("forward"); assert!((source_lag - (drift * source_delta).exp()).abs() < 1e-12); - let same = map_discrete_lag_across_event_intervals( - source_lag, - source_delta, - LagClock::EventTime, - ) - .expect("same interval"); + let same = + map_discrete_lag_across_event_intervals(source_lag, source_delta, LagClock::EventTime) + .expect("same interval"); assert!((same - source_lag).abs() < 1e-12); let remapped = map_discrete_lag_across_event_intervals( source_lag, @@ -10805,11 +10802,7 @@ mod tests { // Voelkle 2012, p. 21: Eq. 14 is not Eq. 12. assert!((recovered - constant).abs() > 1e-3); assert_eq!( - recover_discrete_time_varying_predictor_effect( - 0.0, - delta, - LagClock::EventTime - ), + recover_discrete_time_varying_predictor_effect(0.0, delta, LagClock::EventTime), Ok(0.0) ); } @@ -10881,19 +10874,11 @@ mod tests { Err(PsychometricError::UnmatchedTimeVaryingInterval) ); assert_eq!( - recover_discrete_time_varying_predictor_effect( - f64::NAN, - delta, - LagClock::EventTime - ), + recover_discrete_time_varying_predictor_effect(f64::NAN, delta, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_discrete_time_varying_predictor_effect( - 1e308, - 10.0, - LagClock::EventTime - ), + recover_discrete_time_varying_predictor_effect(1e308, 10.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -12275,14 +12260,9 @@ mod tests { ), Ok(loading * evolved) ); - let zero_evolved = recover_discrete_observed_mean( - loading, - 0.0, - manifest_mean, - delta, - LagClock::EventTime, - ) - .expect("zero-mu"); + let zero_evolved = + recover_discrete_observed_mean(loading, 0.0, manifest_mean, delta, LagClock::EventTime) + .expect("zero-mu"); assert!((zero_evolved - manifest_mean).abs() < 1e-15); let integrator = recover_discrete_observed_mean( loading, @@ -12414,12 +12394,9 @@ mod tests { recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); assert!((impulse - intercept_effect).abs() > 1e-3); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - delta, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) + .expect("eq14"); assert!((impulse - equation_fourteen).abs() > 1e-3); } @@ -12431,12 +12408,9 @@ mod tests { let intercept_effect = recover_discrete_continuous_intercept_effect(effect, -0.5, 2.0, LagClock::EventTime) .expect("cint"); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - 2.0, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, 2.0, LagClock::EventTime) + .expect("eq14"); assert_eq!( refuse_time_dependent_impulse_as_continuous_intercept(impulse, effect), Err(PsychometricError::TimeDependentImpulseIsNotContinuousIntercept) @@ -12492,13 +12466,7 @@ mod tests { Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_discrete_latent_mean_with_impulse( - 1e308, - 0.0, - 1e308, - 1.0, - LagClock::EventTime - ), + recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -13582,11 +13550,7 @@ mod tests { Ok(0.0) ); assert_eq!( - recover_asymptotic_time_independent_predictor_effect( - effect, - 0.0, - LagClock::EventTime - ), + recover_asymptotic_time_independent_predictor_effect(effect, 0.0, LagClock::EventTime), Ok(0.0) ); } @@ -14526,22 +14490,11 @@ mod tests { Err(PsychometricError::StationaryVarianceRequiresStableDrift) ); assert_eq!( - recover_stationary_initial_latent_variance( - 0.0, - -0.225, - 1.0, - 0.5, - LagClock::EventTime - ), + recover_stationary_initial_latent_variance(0.0, -0.225, 1.0, 0.5, LagClock::EventTime), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_initial_latent_variance( - 0.0, - 1.0, - 0.0, - LagClock::EventTime - ), + recover_stationary_initial_latent_variance(0.0, 1.0, 0.0, LagClock::EventTime), Ok(0.0) ); assert_eq!( @@ -14555,12 +14508,7 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_stationary_initial_latent_variance( - f64::MAX, - 0.0, - -0.5, - LagClock::EventTime - ), + recover_stationary_initial_latent_variance(f64::MAX, 0.0, -0.5, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -15089,13 +15037,7 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_lagged_latent_covariance( - 0.0, - 1.0, - 0.0, - 1.0, - LagClock::EventTime - ), + recover_stationary_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), Ok(0.0) ); assert_eq!( @@ -15647,13 +15589,7 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_later_latent_variance( - 0.0, - 1.0, - 0.0, - 1.0, - LagClock::EventTime - ), + recover_stationary_later_latent_variance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), Ok(0.0) ); assert_eq!( @@ -15668,13 +15604,7 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_stationary_later_latent_variance( - f64::MAX, - 0.0, - -0.5, - 1.0, - LagClock::EventTime - ), + recover_stationary_later_latent_variance(f64::MAX, 0.0, -0.5, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -16259,13 +16189,7 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_later_latent_variance( - 0.0, - 1.0, - 0.0, - 1.0, - LagClock::EventTime - ), + recover_predetermined_later_latent_variance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), Ok(0.0) ); let growing = recover_predetermined_later_latent_variance( @@ -16864,23 +16788,12 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_lagged_latent_covariance( - 0.0, - 1.0, - 0.0, - 1.0, - LagClock::EventTime - ), + recover_predetermined_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), Ok(0.0) ); - let brownian = recover_predetermined_lagged_latent_covariance( - 0.0, - 2.0, - 0.0, - 1.0, - LagClock::EventTime, - ) - .expect("Brownian a=0"); + let brownian = + recover_predetermined_lagged_latent_covariance(0.0, 2.0, 0.0, 1.0, LagClock::EventTime) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_lagged_latent_covariance( @@ -17552,12 +17465,9 @@ mod tests { recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); let impulse = recover_time_dependent_predictor_impulse(effect, predictor).expect("tdpred"); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - delta, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) + .expect("eq14"); assert!((increment - intercept_effect).abs() > 1e-3); assert!((increment - impulse).abs() > 1e-3); assert!((increment - equation_fourteen).abs() > 1e-3); @@ -17642,12 +17552,9 @@ mod tests { ) .expect("tipred"); let impulse = recover_time_dependent_predictor_impulse(effect, predictor).expect("tdpred"); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - 2.0, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, 2.0, LagClock::EventTime) + .expect("eq14"); assert_eq!( refuse_time_independent_effect_as_continuous_intercept(increment, effect), Err(PsychometricError::TimeIndependentEffectIsNotContinuousIntercept) @@ -18547,12 +18454,9 @@ mod tests { LagClock::EventTime, ) .expect("tipred"); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - delta, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) + .expect("eq14"); assert!((carry - impulse).abs() > 1e-3); assert!((carry - intercept_effect).abs() > 1e-3); assert!((carry - time_independent).abs() > 1e-3); @@ -18985,12 +18889,7 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_initial_time_independent_predictor_carry( - 1.0, - 1e308, - 10.0, - LagClock::EventTime - ), + recover_initial_time_independent_predictor_carry(1.0, 1e308, 10.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -19622,12 +19521,7 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_initial_time_dependent_predictor_carry( - 1.0, - 1e308, - 10.0, - LagClock::EventTime - ), + recover_initial_time_dependent_predictor_carry(1.0, 1e308, 10.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -20156,21 +20050,12 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_initial_latent_variance( - 0.0, - 1.0, - 0.0, - LagClock::EventTime - ), + recover_predetermined_initial_latent_variance(0.0, 1.0, 0.0, LagClock::EventTime), Ok(0.0) ); - let brownian = recover_predetermined_initial_latent_variance( - 0.0, - 2.0, - 0.0, - LagClock::EventTime, - ) - .expect("Brownian a=0"); + let brownian = + recover_predetermined_initial_latent_variance(0.0, 2.0, 0.0, LagClock::EventTime) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_initial_latent_variance( @@ -20183,12 +20068,7 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_predetermined_initial_latent_variance( - f64::MAX, - 0.0, - -0.5, - LagClock::EventTime - ), + recover_predetermined_initial_latent_variance(f64::MAX, 0.0, -0.5, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( diff --git a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs index 681390d78..9f3795fe4 100644 --- a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs +++ b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs @@ -638,19 +638,11 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { #[test] fn time_varying_predictor_equation_fourteen_numeric_inputs_fail_closed() { assert_eq!( - recover_discrete_time_varying_predictor_effect( - f64::NAN, - 1.0, - LagClock::EventTime - ), + recover_discrete_time_varying_predictor_effect(f64::NAN, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_discrete_time_varying_predictor_effect( - 1e308, - 10.0, - LagClock::EventTime - ), + recover_discrete_time_varying_predictor_effect(1e308, 10.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); } @@ -1555,12 +1547,9 @@ fn time_dependent_impulse_recovers_driver_equation_three_fourth_summand() { let intercept_effect = recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - delta, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) + .expect("eq14"); assert!((impulse - intercept_effect).abs() > 1e-3); assert!((impulse - equation_fourteen).abs() > 1e-3); assert_eq!( @@ -1584,24 +1573,11 @@ fn time_dependent_impulse_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_discrete_latent_mean_with_impulse( - 1.0, - -0.5, - 0.3, - 0.4, - 2.0, - LagClock::SystemTime - ), + recover_discrete_latent_mean_with_impulse(1.0, -0.5, 0.3, 0.4, 2.0, LagClock::SystemTime), Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_discrete_latent_mean_with_impulse( - 1e308, - 0.0, - 1e308, - 1.0, - LagClock::EventTime - ), + recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -1876,12 +1852,9 @@ fn time_independent_predictor_recovers_driver_equation_three_second_summand() { recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); let impulse = recover_time_dependent_predictor_impulse(effect, predictor).expect("tdpred"); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - delta, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) + .expect("eq14"); assert!(rmse(&[increment], &[intercept_effect]) > rmse(&[expected], &[increment])); assert!(rmse(&[increment], &[impulse]) > rmse(&[expected], &[increment])); assert!(rmse(&[increment], &[equation_fourteen]) > rmse(&[expected], &[increment])); @@ -2947,12 +2920,9 @@ fn time_dependent_impulse_carry_recovers_driver_equation_one_two_dissipation() { LagClock::EventTime, ) .expect("tipred"); - let equation_fourteen = recover_discrete_time_varying_predictor_effect( - effect, - delta, - LagClock::EventTime, - ) - .expect("eq14"); + let equation_fourteen = + recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) + .expect("eq14"); assert!(rmse(&[carry], &[impulse]) > rmse(&[expected], &[carry])); assert!(rmse(&[carry], &[intercept_effect]) > rmse(&[expected], &[carry])); assert!(rmse(&[carry], &[time_independent]) > rmse(&[expected], &[carry])); @@ -3021,13 +2991,7 @@ fn time_dependent_impulse_carry_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_time_dependent_predictor_impulse_carry( - 0.4, - 3.0, - -0.5, - 2.0, - LagClock::EventTime - ), + recover_time_dependent_predictor_impulse_carry(0.4, 3.0, -0.5, 2.0, LagClock::EventTime), Err(PsychometricError::NonPositiveInterval) ); assert_eq!( @@ -3054,13 +3018,7 @@ fn time_dependent_impulse_carry_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_time_dependent_predictor_impulse_carry( - 1.0, - 1_000.0, - 2.0, - 1.0, - LagClock::EventTime - ), + recover_time_dependent_predictor_impulse_carry(1.0, 1_000.0, 2.0, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); } @@ -4645,11 +4603,7 @@ fn asymptotic_time_independent_variance_refuses_unstable_drift_and_non_event_clo Ok(0.0) ); assert_eq!( - recover_asymptotic_time_independent_predictor_variance( - 1.0, - -1e-308, - LagClock::EventTime - ), + recover_asymptotic_time_independent_predictor_variance(1.0, -1e-308, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -4956,14 +4910,7 @@ fn stationary_initial_observed_mean_refuses_unstable_drift_and_non_event_clocks( Err(PsychometricError::AsymptoticContinuousInterceptRequiresStableDrift) ); assert_eq!( - recover_stationary_initial_observed_mean( - 2.0, - 0.0, - -0.225, - 1.0, - 0.5, - LagClock::EventTime - ), + recover_stationary_initial_observed_mean(2.0, 0.0, -0.225, 1.0, 0.5, LagClock::EventTime), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( @@ -5087,22 +5034,11 @@ fn stationary_initial_latent_variance_refuses_unstable_drift_and_non_event_clock Ok(0.0) ); assert_eq!( - recover_stationary_initial_latent_variance( - f64::NAN, - 0.4, - 0.0, - -0.5, - LagClock::EventTime - ), + recover_stationary_initial_latent_variance(f64::NAN, 0.4, 0.0, -0.5, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_stationary_initial_latent_variance( - f64::MAX, - 0.0, - -0.5, - LagClock::EventTime - ), + recover_stationary_initial_latent_variance(f64::MAX, 0.0, -0.5, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -5455,13 +5391,7 @@ fn stationary_lagged_latent_covariance_refuses_unstable_drift_and_non_event_cloc Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_lagged_latent_covariance( - 0.0, - 1.0, - 0.0, - 1.0, - LagClock::EventTime - ), + recover_stationary_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), Ok(0.0) ); } @@ -5787,14 +5717,7 @@ fn stationary_later_latent_variance_refuses_unstable_drift_and_non_event_clocks( Err(PsychometricError::StationaryVarianceRequiresStableDrift) ); assert_eq!( - recover_stationary_later_latent_variance( - 0.0, - -0.225, - 1.0, - 0.5, - 1.0, - LagClock::EventTime - ), + recover_stationary_later_latent_variance(0.0, -0.225, 1.0, 0.5, 1.0, LagClock::EventTime), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( @@ -6184,13 +6107,7 @@ fn predetermined_later_latent_variance_refuses_non_event_clocks_and_keeps_growin Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_later_latent_variance( - 0.0, - 1.0, - 0.0, - 1.0, - LagClock::EventTime - ), + recover_predetermined_later_latent_variance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), Ok(0.0) ); } @@ -6569,14 +6486,9 @@ fn predetermined_lagged_latent_covariance_refuses_non_event_clocks_and_keeps_gro ) .expect("growing carry"); assert!(growing > 2.0); - let brownian = recover_predetermined_lagged_latent_covariance( - 0.0, - 2.0, - 0.0, - 1.0, - LagClock::EventTime, - ) - .expect("Brownian a=0"); + let brownian = + recover_predetermined_lagged_latent_covariance(0.0, 2.0, 0.0, 1.0, LagClock::EventTime) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_lagged_latent_covariance( @@ -6590,13 +6502,7 @@ fn predetermined_lagged_latent_covariance_refuses_non_event_clocks_and_keeps_gro Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_lagged_latent_covariance( - 0.0, - 1.0, - 0.0, - 1.0, - LagClock::EventTime - ), + recover_predetermined_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), Ok(0.0) ); } @@ -6973,13 +6879,7 @@ fn predetermined_initial_latent_variance_refuses_non_event_clocks_and_keeps_unst .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( - recover_predetermined_initial_latent_variance( - 0.0, - -0.225, - 1.0, - 0.5, - LagClock::EventTime - ), + recover_predetermined_initial_latent_variance(0.0, -0.225, 1.0, 0.5, LagClock::EventTime), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( From 3ae67eed3ee074dabe84c86ee974cd1901027267 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 09:49:54 +0000 Subject: [PATCH 2/7] fix(psychometric_core): align Eq. 14 and interval-remap call sites Voelkle Eq. 14 now takes event, sampling, and constancy intervals. Stale 3-arg calls repeat the existing event interval so sampling = constancy = event, matching scientific_claim_boundary_contract.rs. Same-interval remapping passes source_delta as reference_delta. Zero predictor/variance asymptotic calls insert the licensed 0 log-rate; negative TIPREDVAR keeps the existing v < 0 refusal. Co-authored-by: Seongho Bae --- crates/psychometric_core/src/event_time.rs | 107 ++++++++++++++---- ...multilevel_event_time_recovery_contract.rs | 66 +++++++++-- 2 files changed, 139 insertions(+), 34 deletions(-) diff --git a/crates/psychometric_core/src/event_time.rs b/crates/psychometric_core/src/event_time.rs index 13b757e1c..fd6afab89 100644 --- a/crates/psychometric_core/src/event_time.rs +++ b/crates/psychometric_core/src/event_time.rs @@ -10536,9 +10536,13 @@ mod tests { recover_discrete_lag_from_log_rate(drift, source_delta, LagClock::EventTime) .expect("forward"); assert!((source_lag - (drift * source_delta).exp()).abs() < 1e-12); - let same = - map_discrete_lag_across_event_intervals(source_lag, source_delta, LagClock::EventTime) - .expect("same interval"); + let same = map_discrete_lag_across_event_intervals( + source_lag, + source_delta, + source_delta, + LagClock::EventTime, + ) + .expect("same interval"); assert!((same - source_lag).abs() < 1e-12); let remapped = map_discrete_lag_across_event_intervals( source_lag, @@ -10788,6 +10792,8 @@ mod tests { let recovered = recover_discrete_time_varying_predictor_effect( outcome_on_predictor, delta, + delta, + delta, LagClock::EventTime, ) .expect("eq 14"); @@ -10802,7 +10808,13 @@ mod tests { // Voelkle 2012, p. 21: Eq. 14 is not Eq. 12. assert!((recovered - constant).abs() > 1e-3); assert_eq!( - recover_discrete_time_varying_predictor_effect(0.0, delta, LagClock::EventTime), + recover_discrete_time_varying_predictor_effect( + 0.0, + delta, + delta, + delta, + LagClock::EventTime + ), Ok(0.0) ); } @@ -10815,6 +10827,8 @@ mod tests { recover_discrete_time_varying_predictor_effect( outcome_on_predictor, delta, + delta, + delta, LagClock::SystemTime ), Err(PsychometricError::EventTimeRequired) @@ -10823,6 +10837,8 @@ mod tests { recover_discrete_time_varying_predictor_effect( outcome_on_predictor, 0.0, + 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -10832,6 +10848,7 @@ mod tests { outcome_on_predictor, -1.0, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -10851,6 +10868,7 @@ mod tests { outcome_on_predictor, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -10860,6 +10878,7 @@ mod tests { outcome_on_predictor, 1.0, 2.0, + 2.0, LagClock::EventTime ), Err(PsychometricError::UnmatchedTimeVaryingInterval) @@ -10869,16 +10888,29 @@ mod tests { outcome_on_predictor, 2.0, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::UnmatchedTimeVaryingInterval) ); assert_eq!( - recover_discrete_time_varying_predictor_effect(f64::NAN, delta, LagClock::EventTime), + recover_discrete_time_varying_predictor_effect( + f64::NAN, + delta, + delta, + delta, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_discrete_time_varying_predictor_effect(1e308, 10.0, LagClock::EventTime), + recover_discrete_time_varying_predictor_effect( + 1e308, + 10.0, + 10.0, + 10.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -12394,9 +12426,14 @@ mod tests { recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); assert!((impulse - intercept_effect).abs() > 1e-3); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + delta, + delta, + delta, + LagClock::EventTime, + ) + .expect("eq14"); assert!((impulse - equation_fourteen).abs() > 1e-3); } @@ -12408,9 +12445,14 @@ mod tests { let intercept_effect = recover_discrete_continuous_intercept_effect(effect, -0.5, 2.0, LagClock::EventTime) .expect("cint"); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, 2.0, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + 2.0, + 2.0, + 2.0, + LagClock::EventTime, + ) + .expect("eq14"); assert_eq!( refuse_time_dependent_impulse_as_continuous_intercept(impulse, effect), Err(PsychometricError::TimeDependentImpulseIsNotContinuousIntercept) @@ -13550,7 +13592,12 @@ mod tests { Ok(0.0) ); assert_eq!( - recover_asymptotic_time_independent_predictor_effect(effect, 0.0, LagClock::EventTime), + recover_asymptotic_time_independent_predictor_effect( + effect, + 0.0, + 0.0, + LagClock::EventTime, + ), Ok(0.0) ); } @@ -13699,6 +13746,7 @@ mod tests { recover_asymptotic_time_independent_predictor_variance( effect, 0.0, + 0.0, LagClock::EventTime ), Ok(0.0) @@ -17465,9 +17513,14 @@ mod tests { recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); let impulse = recover_time_dependent_predictor_impulse(effect, predictor).expect("tdpred"); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + delta, + delta, + delta, + LagClock::EventTime, + ) + .expect("eq14"); assert!((increment - intercept_effect).abs() > 1e-3); assert!((increment - impulse).abs() > 1e-3); assert!((increment - equation_fourteen).abs() > 1e-3); @@ -17552,9 +17605,14 @@ mod tests { ) .expect("tipred"); let impulse = recover_time_dependent_predictor_impulse(effect, predictor).expect("tdpred"); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, 2.0, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + 2.0, + 2.0, + 2.0, + LagClock::EventTime, + ) + .expect("eq14"); assert_eq!( refuse_time_independent_effect_as_continuous_intercept(increment, effect), Err(PsychometricError::TimeIndependentEffectIsNotContinuousIntercept) @@ -18454,9 +18512,14 @@ mod tests { LagClock::EventTime, ) .expect("tipred"); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + delta, + delta, + delta, + LagClock::EventTime, + ) + .expect("eq14"); assert!((carry - impulse).abs() > 1e-3); assert!((carry - intercept_effect).abs() > 1e-3); assert!((carry - time_independent).abs() > 1e-3); diff --git a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs index 9f3795fe4..df07496b9 100644 --- a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs +++ b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs @@ -524,6 +524,8 @@ fn time_varying_predictor_discrete_effect_recovers_equation_fourteen() { let recovered = recover_discrete_time_varying_predictor_effect( outcome_on_predictor, delta, + delta, + delta, LagClock::EventTime, ) .expect("eq 14"); @@ -547,6 +549,7 @@ fn time_varying_predictor_discrete_effect_recovers_equation_fourteen() { outcome_on_predictor, 1.0, 2.0, + 2.0, LagClock::EventTime ), Err(PsychometricError::UnmatchedTimeVaryingInterval) @@ -564,6 +567,8 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { recover_discrete_time_varying_predictor_effect( outcome_on_predictor, 1.0, + 1.0, + 1.0, LagClock::SystemTime ), Err(PsychometricError::EventTimeRequired) @@ -573,6 +578,7 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { outcome_on_predictor, f64::NAN, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -582,6 +588,7 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { outcome_on_predictor, 0.0, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -611,6 +618,7 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { outcome_on_predictor, 1.0, f64::NAN, + f64::NAN, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -620,6 +628,7 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { outcome_on_predictor, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -629,6 +638,7 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { outcome_on_predictor, 2.0, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::UnmatchedTimeVaryingInterval) @@ -638,11 +648,23 @@ fn time_varying_predictor_equation_fourteen_intervals_fail_closed() { #[test] fn time_varying_predictor_equation_fourteen_numeric_inputs_fail_closed() { assert_eq!( - recover_discrete_time_varying_predictor_effect(f64::NAN, 1.0, LagClock::EventTime), + recover_discrete_time_varying_predictor_effect( + f64::NAN, + 1.0, + 1.0, + 1.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_discrete_time_varying_predictor_effect(1e308, 10.0, LagClock::EventTime), + recover_discrete_time_varying_predictor_effect( + 1e308, + 10.0, + 10.0, + 10.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); } @@ -1547,9 +1569,14 @@ fn time_dependent_impulse_recovers_driver_equation_three_fourth_summand() { let intercept_effect = recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + delta, + delta, + delta, + LagClock::EventTime, + ) + .expect("eq14"); assert!((impulse - intercept_effect).abs() > 1e-3); assert!((impulse - equation_fourteen).abs() > 1e-3); assert_eq!( @@ -1852,9 +1879,14 @@ fn time_independent_predictor_recovers_driver_equation_three_second_summand() { recover_discrete_continuous_intercept_effect(effect, drift, delta, LagClock::EventTime) .expect("cint"); let impulse = recover_time_dependent_predictor_impulse(effect, predictor).expect("tdpred"); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + delta, + delta, + delta, + LagClock::EventTime, + ) + .expect("eq14"); assert!(rmse(&[increment], &[intercept_effect]) > rmse(&[expected], &[increment])); assert!(rmse(&[increment], &[impulse]) > rmse(&[expected], &[increment])); assert!(rmse(&[increment], &[equation_fourteen]) > rmse(&[expected], &[increment])); @@ -2920,9 +2952,14 @@ fn time_dependent_impulse_carry_recovers_driver_equation_one_two_dissipation() { LagClock::EventTime, ) .expect("tipred"); - let equation_fourteen = - recover_discrete_time_varying_predictor_effect(effect, delta, LagClock::EventTime) - .expect("eq14"); + let equation_fourteen = recover_discrete_time_varying_predictor_effect( + effect, + delta, + delta, + delta, + LagClock::EventTime, + ) + .expect("eq14"); assert!(rmse(&[carry], &[impulse]) > rmse(&[expected], &[carry])); assert!(rmse(&[carry], &[intercept_effect]) > rmse(&[expected], &[carry])); assert!(rmse(&[carry], &[time_independent]) > rmse(&[expected], &[carry])); @@ -4603,7 +4640,12 @@ fn asymptotic_time_independent_variance_refuses_unstable_drift_and_non_event_clo Ok(0.0) ); assert_eq!( - recover_asymptotic_time_independent_predictor_variance(1.0, -1e-308, LagClock::EventTime), + recover_asymptotic_time_independent_predictor_variance( + 1.0, + -1e-308, + -0.5, + LagClock::EventTime, + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( From eb37b795a602a1f49db28e8b02597d58fe8eabb9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 10:03:55 +0000 Subject: [PATCH 3/7] fix(psychometric_core): align discrete mean and predetermined observed call arities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Insert licensed zeros for intercept, manifest-mean, predictor, and measurement extras, and restore missing t-u/Δt from each test so overflow and refusal assertions keep the same Ok/Err variant. Co-authored-by: Seongho Bae --- crates/psychometric_core/src/event_time.rs | 264 +++++++++++++++++- ...multilevel_event_time_recovery_contract.rs | 135 ++++++++- 2 files changed, 376 insertions(+), 23 deletions(-) diff --git a/crates/psychometric_core/src/event_time.rs b/crates/psychometric_core/src/event_time.rs index fd6afab89..3e4824e44 100644 --- a/crates/psychometric_core/src/event_time.rs +++ b/crates/psychometric_core/src/event_time.rs @@ -12293,7 +12293,7 @@ mod tests { Ok(loading * evolved) ); let zero_evolved = - recover_discrete_observed_mean(loading, 0.0, manifest_mean, delta, LagClock::EventTime) + recover_discrete_observed_mean(loading, 0.0, 0.0, 0.0, manifest_mean, delta, LagClock::EventTime) .expect("zero-mu"); assert!((zero_evolved - manifest_mean).abs() < 1e-15); let integrator = recover_discrete_observed_mean( @@ -12503,12 +12503,13 @@ mod tests { 0.3, 0.4, 2.0, + 2.0, LagClock::SystemTime ), Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 1.0, LagClock::EventTime), + recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 0.0, 0.0, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -12769,6 +12770,7 @@ mod tests { coupling, predictor, extra, + extra, delta, LagClock::EventTime, ) @@ -13509,6 +13511,7 @@ mod tests { predictor, extra, 2.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -14195,6 +14198,7 @@ mod tests { recover_stationary_initial_observed_mean( loading, 0.0, + 0.0, 1.0, 0.0, manifest_mean, @@ -14336,6 +14340,7 @@ mod tests { -0.225, 1.0, 0.5, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -14356,6 +14361,7 @@ mod tests { recover_stationary_initial_observed_mean( 2.0, 1e308, + 0.0, 1.0, -1e-308, 0.5, @@ -14420,6 +14426,7 @@ mod tests { .expect("trait-only"); assert!((trait_only - trait_variance).abs() < 1e-15); let added_only = recover_stationary_initial_latent_variance( + 0.0, 0.0, printed_effect, predictor_variance, @@ -14430,6 +14437,8 @@ mod tests { assert!((added_only - added).abs() < 1e-15); assert_eq!( recover_stationary_initial_latent_variance( + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -14439,6 +14448,8 @@ mod tests { ); assert_eq!( recover_stationary_initial_latent_variance( + 0.0, + 0.0, 0.0, predictor_variance, 0.5, @@ -14538,11 +14549,18 @@ mod tests { Err(PsychometricError::StationaryVarianceRequiresStableDrift) ); assert_eq!( - recover_stationary_initial_latent_variance(0.0, -0.225, 1.0, 0.5, LagClock::EventTime), + recover_stationary_initial_latent_variance( + 0.0, + 0.0, + -0.225, + 1.0, + 0.5, + LagClock::EventTime, + ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_initial_latent_variance(0.0, 1.0, 0.0, LagClock::EventTime), + recover_stationary_initial_latent_variance(0.0, 0.0, 0.0, 1.0, 0.0, LagClock::EventTime), Ok(0.0) ); assert_eq!( @@ -14550,13 +14568,21 @@ mod tests { f64::NAN, 0.4, 0.0, + 0.0, -0.5, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_stationary_initial_latent_variance(f64::MAX, 0.0, -0.5, LagClock::EventTime), + recover_stationary_initial_latent_variance( + f64::MAX, + 0.0, + 0.0, + 0.0, + -0.5, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -14651,6 +14677,8 @@ mod tests { recover_stationary_initial_observed_variance( loading, 0.0, + 0.0, + 0.0, 1.0, 0.0, measurement_error, @@ -14785,10 +14813,12 @@ mod tests { recover_stationary_initial_observed_variance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -14797,6 +14827,8 @@ mod tests { recover_stationary_initial_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, 0.5, @@ -14811,6 +14843,7 @@ mod tests { 1.0, 0.4, 0.0, + 0.0, -0.5, 0.5, 0.0, @@ -14823,6 +14856,8 @@ mod tests { 2.0, f64::MAX, 0.0, + 0.0, + 0.0, -0.5, 0.5, 0.0, @@ -14913,6 +14948,7 @@ mod tests { let trait_only = recover_stationary_lagged_latent_covariance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -14921,6 +14957,7 @@ mod tests { .expect("trait-only lagged"); assert!((trait_only - trait_variance).abs() < 1e-15); let added_only = recover_stationary_lagged_latent_covariance( + 0.0, 0.0, printed_effect, predictor_variance, @@ -14932,6 +14969,8 @@ mod tests { assert!((added_only - added).abs() < 1e-15); assert_eq!( recover_stationary_lagged_latent_covariance( + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -15075,6 +15114,7 @@ mod tests { ); assert_eq!( recover_stationary_lagged_latent_covariance( + 0.0, 0.0, -0.225, 1.0, @@ -15085,7 +15125,15 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), + recover_stationary_lagged_latent_covariance( + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 1.0, + LagClock::EventTime + ), Ok(0.0) ); assert_eq!( @@ -15093,6 +15141,7 @@ mod tests { f64::NAN, 0.4, 0.0, + 0.0, -0.5, 1.0, LagClock::EventTime @@ -15103,6 +15152,8 @@ mod tests { recover_stationary_lagged_latent_covariance( f64::MAX, 0.0, + 0.0, + 0.0, -0.5, 1.0, LagClock::EventTime @@ -15197,6 +15248,8 @@ mod tests { recover_stationary_lagged_observed_covariance( loading, 0.0, + 0.0, + 0.0, 1.0, 0.0, event_delta, @@ -15334,6 +15387,7 @@ mod tests { recover_stationary_lagged_observed_covariance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, @@ -15347,6 +15401,8 @@ mod tests { recover_stationary_lagged_observed_covariance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, 1.0, @@ -15361,6 +15417,7 @@ mod tests { 1.0, 0.4, 0.0, + 0.0, -0.5, 1.0, 0.0, @@ -15373,6 +15430,8 @@ mod tests { 2.0, f64::MAX, 0.0, + 0.0, + 0.0, -0.5, 1.0, 0.0, @@ -15473,6 +15532,7 @@ mod tests { let trait_only = recover_stationary_later_latent_variance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -15481,6 +15541,7 @@ mod tests { .expect("trait-only later"); assert!((trait_only - trait_variance).abs() < 1e-15); let added_only = recover_stationary_later_latent_variance( + 0.0, 0.0, printed_effect, predictor_variance, @@ -16061,6 +16122,8 @@ mod tests { let trait_only = recover_predetermined_later_latent_variance( trait_variance, 0.0, + 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -16069,6 +16132,8 @@ mod tests { .expect("trait-only predetermined later"); assert!((trait_only - trait_variance).abs() < 1e-15); let added_only = recover_predetermined_later_latent_variance( + 0.0, + 0.0, 0.0, printed_effect, predictor_variance, @@ -16080,6 +16145,9 @@ mod tests { assert!((added_only - added).abs() < 1e-15); assert_eq!( recover_predetermined_later_latent_variance( + 0.0, + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -16117,6 +16185,7 @@ mod tests { initial_latent_variance, diffusion, 0.0, + 0.0, 0.5, event_delta, LagClock::EventTime, @@ -16227,6 +16296,8 @@ mod tests { ); assert_eq!( recover_predetermined_later_latent_variance( + 0.0, + 0.0, 0.0, -0.225, 1.0, @@ -16237,7 +16308,16 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_later_latent_variance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), + recover_predetermined_later_latent_variance( + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 1.0, + LagClock::EventTime + ), Ok(0.0) ); let growing = recover_predetermined_later_latent_variance( @@ -16245,6 +16325,8 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -16389,10 +16471,14 @@ mod tests { recover_predetermined_later_observed_variance( loading, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, event_delta, 0.0, + 0.0, LagClock::EventTime, ), Ok(0.0) @@ -16529,11 +16615,14 @@ mod tests { recover_predetermined_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, -0.225, 1.0, 0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -16542,8 +16631,11 @@ mod tests { recover_predetermined_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.5, 0.1, @@ -16558,9 +16650,11 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, -0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -16570,9 +16664,13 @@ mod tests { 2.0, f64::MAX, 0.0, + 0.0, + 0.0, + 0.0, -0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -16665,6 +16763,8 @@ mod tests { assert!((recovered - initial_latent_variance).abs() > 1e-3); assert_eq!( recover_predetermined_lagged_latent_covariance( + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -16676,6 +16776,7 @@ mod tests { let trait_only = recover_predetermined_lagged_latent_covariance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -16709,6 +16810,7 @@ mod tests { 0.0, initial_latent_variance, 0.0, + 0.0, 0.5, event_delta, LagClock::EventTime, @@ -16826,6 +16928,7 @@ mod tests { ); assert_eq!( recover_predetermined_lagged_latent_covariance( + 0.0, 0.0, -0.225, 1.0, @@ -16836,18 +16939,35 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), + recover_predetermined_lagged_latent_covariance( + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 1.0, + LagClock::EventTime + ), Ok(0.0) ); let brownian = - recover_predetermined_lagged_latent_covariance(0.0, 2.0, 0.0, 1.0, LagClock::EventTime) - .expect("Brownian a=0"); + recover_predetermined_lagged_latent_covariance( + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 1.0, + LagClock::EventTime, + ) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_lagged_latent_covariance( f64::NAN, 2.0, 0.0, + 0.0, -0.5, 1.0, LagClock::EventTime @@ -16966,8 +17086,10 @@ mod tests { recover_predetermined_lagged_observed_covariance( loading, 0.0, + 0.0, 1.0, 0.0, + 0.0, event_delta, 0.0, LagClock::EventTime, @@ -17098,6 +17220,7 @@ mod tests { recover_predetermined_lagged_observed_covariance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, @@ -17111,8 +17234,10 @@ mod tests { recover_predetermined_lagged_observed_covariance( 2.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.1, LagClock::EventTime @@ -17138,6 +17263,7 @@ mod tests { 1.0, 2.0, 0.0, + 0.0, -0.5, 1.0, 0.0, @@ -17150,6 +17276,8 @@ mod tests { 2.0, f64::MAX, 0.0, + 0.0, + 0.0, -0.5, 1.0, 0.0, @@ -17360,8 +17488,10 @@ mod tests { 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -17371,8 +17501,10 @@ mod tests { 1e308, 1.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -17401,8 +17533,10 @@ mod tests { 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -17410,10 +17544,12 @@ mod tests { ); assert_eq!( recover_discrete_observed_mean_with_impulse( + 1.0, 1.0, 710.0, 0.0, 3.0, + 0.0, 0.5, 1.0, LagClock::EventTime @@ -17427,6 +17563,8 @@ mod tests { 1e308, 1.0, 0.0, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -17703,6 +17841,7 @@ mod tests { 1.0, 1e308, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -17715,6 +17854,7 @@ mod tests { 0.3, 1e308, 2.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -17929,8 +18069,10 @@ mod tests { 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -17939,8 +18081,11 @@ mod tests { let finite_loaded = recover_discrete_observed_mean_with_time_independent_predictor( 1e308, 0.0, + 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -17951,8 +18096,10 @@ mod tests { 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -17993,6 +18140,8 @@ mod tests { 1e308, 1.0, 0.0, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -18356,8 +18505,10 @@ mod tests { 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 2.0, 1.0, LagClock::EventTime, @@ -18368,8 +18519,10 @@ mod tests { 1e308, 1.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 2.0, 1.0, LagClock::EventTime, @@ -18400,8 +18553,10 @@ mod tests { 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 2.0, 1.0, LagClock::EventTime @@ -18410,10 +18565,12 @@ mod tests { ); assert_eq!( recover_discrete_observed_mean_with_impulse_carry( + 1.0, 1.0, 710.0, 0.0, 3.0, + 0.0, 0.5, 1.0, 0.5, @@ -18428,6 +18585,8 @@ mod tests { 1e308, 1.0, 0.0, + 0.0, + 0.0, 2.0, 1.0, LagClock::EventTime @@ -18463,6 +18622,7 @@ mod tests { 3.0, 0.5, 2.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -18659,6 +18819,7 @@ mod tests { 3.0, -0.5, 2.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -18680,6 +18841,7 @@ mod tests { 0.0, 1e308, 1.0, + 0.0, 2.0, 1.0, LagClock::EventTime @@ -18927,6 +19089,8 @@ mod tests { 1e308, 0.0, 1e308, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -18937,6 +19101,7 @@ mod tests { 1.0, f64::INFINITY, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -18952,7 +19117,7 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_initial_time_independent_predictor_carry(1.0, 1e308, 10.0, LagClock::EventTime), + recover_initial_time_independent_predictor_carry(1.0, 1e308, 10.0, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -19214,8 +19379,10 @@ mod tests { 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -19224,8 +19391,11 @@ mod tests { let finite_loaded = recover_discrete_observed_mean_with_initial_time_independent_predictor( 1e308, 0.0, + 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -19236,8 +19406,10 @@ mod tests { 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -19278,6 +19450,8 @@ mod tests { 1e308, 1.0, 0.0, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -19559,6 +19733,8 @@ mod tests { 1e308, 0.0, 1e308, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -19569,6 +19745,7 @@ mod tests { 1.0, f64::INFINITY, 1.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -19584,7 +19761,7 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_initial_time_dependent_predictor_carry(1.0, 1e308, 10.0, LagClock::EventTime), + recover_initial_time_dependent_predictor_carry(1.0, 1e308, 10.0, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -19828,8 +20005,10 @@ mod tests { 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -19840,8 +20019,10 @@ mod tests { 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -19882,6 +20063,8 @@ mod tests { 1e308, 1.0, 0.0, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -20000,6 +20183,7 @@ mod tests { let trait_only = recover_predetermined_initial_latent_variance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, LagClock::EventTime, @@ -20113,11 +20297,11 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_initial_latent_variance(0.0, 1.0, 0.0, LagClock::EventTime), + recover_predetermined_initial_latent_variance(0.0, 0.0, 0.0, 1.0, 0.0, LagClock::EventTime), Ok(0.0) ); let brownian = - recover_predetermined_initial_latent_variance(0.0, 2.0, 0.0, LagClock::EventTime) + recover_predetermined_initial_latent_variance(0.0, 2.0, 0.0, 0.0, 0.0, LagClock::EventTime) .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( @@ -20125,6 +20309,7 @@ mod tests { f64::NAN, 2.0, 0.0, + 0.0, -0.5, LagClock::EventTime ), @@ -20239,8 +20424,12 @@ mod tests { recover_predetermined_initial_observed_variance( loading, 0.0, + 0.0, 1.0, 0.0, + 0.0, + 0.0, + 0.0, LagClock::EventTime, ), Ok(0.0) @@ -20294,10 +20483,12 @@ mod tests { recover_predetermined_initial_observed_variance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -20309,6 +20500,8 @@ mod tests { 0.0, 1.0, 0.0, + 0.0, + 0.0, LagClock::EventTime, ) .expect("Brownian a=0"); @@ -20317,8 +20510,10 @@ mod tests { recover_predetermined_initial_observed_variance( 2.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.5, 0.1, LagClock::EventTime @@ -20331,8 +20526,10 @@ mod tests { f64::NAN, 2.0, 0.0, + 0.0, -0.5, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -20342,8 +20539,11 @@ mod tests { 2.0, f64::MAX, 0.0, + 0.0, + 0.0, -0.5, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -20481,6 +20681,9 @@ mod tests { assert!((near_later - later).abs() < 1e-9); assert_eq!( recover_predetermined_later_lagged_latent_covariance( + 0.0, + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -20493,6 +20696,8 @@ mod tests { let trait_only = recover_predetermined_later_lagged_latent_covariance( trait_variance, 0.0, + 0.0, + 0.0, predictor_variance, 0.0, start_delta, @@ -20635,6 +20840,8 @@ mod tests { ); assert_eq!( recover_predetermined_later_lagged_latent_covariance( + 0.0, + 0.0, 0.0, -0.225, 1.0, @@ -20650,8 +20857,10 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, 0.5, 1.0, + 1.0, LagClock::EventTime, ) .expect("growing a>0"); @@ -20663,6 +20872,7 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, -0.5, 2.0, 1.0, @@ -20791,8 +21001,11 @@ mod tests { recover_predetermined_later_lagged_observed_covariance( loading, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, start_delta, lag_delta, 0.0, @@ -20861,6 +21074,8 @@ mod tests { recover_predetermined_later_lagged_observed_covariance( 2.0, 0.0, + 0.0, + 0.0, -0.225, 1.0, 0.5, @@ -20891,8 +21106,11 @@ mod tests { recover_predetermined_later_lagged_observed_covariance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, 2.0, 1.0, 0.1, @@ -20907,6 +21125,7 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, -0.5, 2.0, 1.0, @@ -21094,6 +21313,9 @@ mod tests { assert!((near_first - later_over_s).abs() < 1e-9); assert_eq!( recover_predetermined_later_start_later_latent_variance( + 0.0, + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -21309,6 +21531,7 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, -0.5, 2.0, 1.0, @@ -21447,11 +21670,15 @@ mod tests { recover_predetermined_later_start_later_observed_variance( loading, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, start_delta, lag_delta, 0.0, + 0.0, LagClock::EventTime, ), Ok(0.0) @@ -21520,12 +21747,15 @@ mod tests { recover_predetermined_later_start_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, -0.225, 1.0, 0.5, 2.0, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -21551,8 +21781,11 @@ mod tests { recover_predetermined_later_start_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, 2.0, 1.0, 0.5, @@ -21568,10 +21801,12 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, -0.5, 2.0, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -24390,6 +24625,7 @@ mod tests { loading, coefficient, 0.0, + -0.5, LagClock::EventTime, ) .expect("zero variance"); diff --git a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs index df07496b9..b402dc9a9 100644 --- a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs +++ b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs @@ -1600,11 +1600,11 @@ fn time_dependent_impulse_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_discrete_latent_mean_with_impulse(1.0, -0.5, 0.3, 0.4, 2.0, LagClock::SystemTime), + recover_discrete_latent_mean_with_impulse(1.0, -0.5, 0.3, 0.4, 2.0, 2.0, LagClock::SystemTime), Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 1.0, LagClock::EventTime), + recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 0.0, 0.0, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -1790,8 +1790,10 @@ fn discrete_observed_mean_with_impulse_refuses_overflow_and_non_event_clocks() { 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -1832,6 +1834,8 @@ fn discrete_observed_mean_with_impulse_refuses_overflow_and_non_event_clocks() { 1e308, 1.0, 0.0, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -1841,8 +1845,10 @@ fn discrete_observed_mean_with_impulse_refuses_overflow_and_non_event_clocks() { 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -1958,6 +1964,8 @@ fn time_independent_predictor_refuses_overflow_and_non_event_clocks() { 1e308, 0.0, 1e308, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -1970,6 +1978,7 @@ fn time_independent_predictor_refuses_overflow_and_non_event_clocks() { 0.3, 1e308, 2.0, + 1.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -2092,6 +2101,8 @@ fn initial_time_independent_predictor_refuses_overflow_and_non_event_clocks() { 1e308, 0.0, 1e308, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -2239,6 +2250,8 @@ fn initial_time_dependent_predictor_refuses_overflow_and_non_event_clocks() { 1e308, 0.0, 1e308, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -2562,8 +2575,10 @@ fn discrete_observed_mean_with_initial_time_independent_predictor_refuses_overfl 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -2601,8 +2616,10 @@ fn discrete_observed_mean_with_initial_time_independent_predictor_refuses_overfl 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -2855,8 +2872,10 @@ fn discrete_observed_mean_with_time_independent_predictor_refuses_overflow_and_n 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -2897,6 +2916,8 @@ fn discrete_observed_mean_with_time_independent_predictor_refuses_overflow_and_n 1e308, 1.0, 0.0, + 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -2906,8 +2927,10 @@ fn discrete_observed_mean_with_time_independent_predictor_refuses_overflow_and_n 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -3028,7 +3051,7 @@ fn time_dependent_impulse_carry_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_time_dependent_predictor_impulse_carry(0.4, 3.0, -0.5, 2.0, LagClock::EventTime), + recover_time_dependent_predictor_impulse_carry(0.4, 3.0, -0.5, 2.0, 0.0, LagClock::EventTime), Err(PsychometricError::NonPositiveInterval) ); assert_eq!( @@ -3037,6 +3060,7 @@ fn time_dependent_impulse_carry_refuses_overflow_and_non_event_clocks() { 0.0, 1e308, 1.0, + 0.0, 2.0, 1.0, LagClock::EventTime @@ -3055,7 +3079,7 @@ fn time_dependent_impulse_carry_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_time_dependent_predictor_impulse_carry(1.0, 1_000.0, 2.0, 1.0, LagClock::EventTime), + recover_time_dependent_predictor_impulse_carry(1.0, 1_000.0, 1e308, 2.0, 1.0, LagClock::EventTime), Err(PsychometricError::InvalidNumericInput) ); } @@ -3235,8 +3259,10 @@ fn discrete_observed_mean_with_impulse_carry_refuses_overflow_and_non_event_cloc 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 2.0, 1.0, LagClock::EventTime @@ -3268,6 +3294,7 @@ fn discrete_observed_mean_with_impulse_carry_refuses_overflow_and_non_event_cloc 3.0, 0.5, 2.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -3279,6 +3306,8 @@ fn discrete_observed_mean_with_impulse_carry_refuses_overflow_and_non_event_cloc 1e308, 1.0, 0.0, + 0.0, + 0.0, 2.0, 1.0, LagClock::EventTime @@ -3289,8 +3318,10 @@ fn discrete_observed_mean_with_impulse_carry_refuses_overflow_and_non_event_cloc 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 2.0, 1.0, LagClock::EventTime, @@ -3647,8 +3678,10 @@ fn discrete_observed_mean_with_initial_time_dependent_predictor_refuses_overflow 1e308, 2.0, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime ), @@ -3686,8 +3719,10 @@ fn discrete_observed_mean_with_initial_time_dependent_predictor_refuses_overflow 1e308, 1e-308, 0.0, + 0.0, 3.0, 0.0, + 0.0, 1.0, LagClock::EventTime, ) @@ -4238,6 +4273,7 @@ fn extra_process_observed_mean_refuses_clock_nonpositive_interval_and_nonnegativ 1e308, 0.0, 1e308, + 0.0, 1.0, extra, 1.0, @@ -4394,6 +4430,7 @@ fn after_extra_process_observed_mean_refuses_non_interior_interval_and_clock() { original, extra, 2.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -4416,6 +4453,7 @@ fn after_extra_process_observed_mean_refuses_non_interior_interval_and_clock() { ); assert_eq!( recover_discrete_observed_mean_with_extra_process_after( + 0.0, 0.0, original, 0.0, @@ -6046,6 +6084,9 @@ fn predetermined_later_latent_variance_recovers_driver_section_four_point_three( assert!(rmse(&[from_stationary_start], &[stationary_later]) < 1e-12); assert_eq!( recover_predetermined_later_latent_variance( + 0.0, + 0.0, + 0.0, 0.0, predictor_variance, log_rate, @@ -6058,6 +6099,8 @@ fn predetermined_later_latent_variance_recovers_driver_section_four_point_three( recover_predetermined_later_latent_variance( trait_variance, 0.0, + 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -6139,6 +6182,8 @@ fn predetermined_later_latent_variance_refuses_non_event_clocks_and_keeps_growin assert!((growing - 2.4).abs() < 1e-12); assert_eq!( recover_predetermined_later_latent_variance( + 0.0, + 0.0, 0.0, -0.225, 1.0, @@ -6149,7 +6194,16 @@ fn predetermined_later_latent_variance_refuses_non_event_clocks_and_keeps_growin Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_later_latent_variance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), + recover_predetermined_later_latent_variance( + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 1.0, + LagClock::EventTime + ), Ok(0.0) ); } @@ -6306,6 +6360,7 @@ fn predetermined_later_observed_variance_refuses_non_event_clocks_and_keeps_grow 0.0, 1.0, 0.0, + 0.0, LagClock::EventTime, ) .expect("Brownian a=0"); @@ -6314,11 +6369,14 @@ fn predetermined_later_observed_variance_refuses_non_event_clocks_and_keeps_grow recover_predetermined_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, -0.225, 1.0, 0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -6327,8 +6385,11 @@ fn predetermined_later_observed_variance_refuses_non_event_clocks_and_keeps_grow recover_predetermined_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.5, 0.1, @@ -6427,6 +6488,8 @@ fn predetermined_lagged_latent_covariance_recovers_driver_section_four_point_thr assert!(rmse(&[from_stationary_start], &[stationary_lagged]) < 1e-12); assert_eq!( recover_predetermined_lagged_latent_covariance( + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -6439,6 +6502,7 @@ fn predetermined_lagged_latent_covariance_recovers_driver_section_four_point_thr recover_predetermined_lagged_latent_covariance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -6522,6 +6586,7 @@ fn predetermined_lagged_latent_covariance_refuses_non_event_clocks_and_keeps_gro 0.0, 2.0, 0.0, + 0.0, 0.5, 1.0, LagClock::EventTime, @@ -6529,11 +6594,20 @@ fn predetermined_lagged_latent_covariance_refuses_non_event_clocks_and_keeps_gro .expect("growing carry"); assert!(growing > 2.0); let brownian = - recover_predetermined_lagged_latent_covariance(0.0, 2.0, 0.0, 1.0, LagClock::EventTime) - .expect("Brownian a=0"); + recover_predetermined_lagged_latent_covariance( + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 1.0, + LagClock::EventTime, + ) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_lagged_latent_covariance( + 0.0, 0.0, -0.225, 1.0, @@ -6544,7 +6618,15 @@ fn predetermined_lagged_latent_covariance_refuses_non_event_clocks_and_keeps_gro Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), + recover_predetermined_lagged_latent_covariance( + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 1.0, + LagClock::EventTime + ), Ok(0.0) ); } @@ -6730,6 +6812,7 @@ fn predetermined_lagged_observed_covariance_refuses_non_event_clocks_and_keeps_g recover_predetermined_lagged_observed_covariance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, @@ -6743,8 +6826,10 @@ fn predetermined_lagged_observed_covariance_refuses_non_event_clocks_and_keeps_g recover_predetermined_lagged_observed_covariance( 2.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 0.1, LagClock::EventTime @@ -6857,6 +6942,8 @@ fn predetermined_initial_latent_variance_recovers_driver_section_four_point_thre assert!(rmse(&[near_later], &[recovered]) < 1e-9); assert_eq!( recover_predetermined_initial_latent_variance( + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -6868,6 +6955,7 @@ fn predetermined_initial_latent_variance_recovers_driver_section_four_point_thre recover_predetermined_initial_latent_variance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, LagClock::EventTime, @@ -6921,7 +7009,14 @@ fn predetermined_initial_latent_variance_refuses_non_event_clocks_and_keeps_unst .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( - recover_predetermined_initial_latent_variance(0.0, -0.225, 1.0, 0.5, LagClock::EventTime), + recover_predetermined_initial_latent_variance( + 0.0, + 0.0, + -0.225, + 1.0, + 0.5, + LagClock::EventTime + ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( @@ -7076,6 +7171,8 @@ fn predetermined_initial_observed_variance_refuses_non_event_clocks_and_keeps_un 0.0, 1.0, 0.0, + 0.0, + 0.0, LagClock::EventTime, ) .expect("Brownian a=0"); @@ -7084,10 +7181,12 @@ fn predetermined_initial_observed_variance_refuses_non_event_clocks_and_keeps_un recover_predetermined_initial_observed_variance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -7096,8 +7195,10 @@ fn predetermined_initial_observed_variance_refuses_non_event_clocks_and_keeps_un recover_predetermined_initial_observed_variance( 2.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.5, 0.1, LagClock::EventTime @@ -7562,8 +7663,10 @@ fn predetermined_later_lagged_observed_covariance_refuses_non_event_clocks_and_k 2.0, 0.4, 0.0, + 0.0, 0.5, 1.0, + 1.0, 0.0, LagClock::EventTime, ) @@ -7573,6 +7676,8 @@ fn predetermined_later_lagged_observed_covariance_refuses_non_event_clocks_and_k recover_predetermined_later_lagged_observed_covariance( 2.0, 0.0, + 0.0, + 0.0, -0.225, 1.0, 0.5, @@ -7587,8 +7692,11 @@ fn predetermined_later_lagged_observed_covariance_refuses_non_event_clocks_and_k recover_predetermined_later_lagged_observed_covariance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, 2.0, 1.0, 0.1, @@ -8122,8 +8230,11 @@ fn predetermined_later_start_later_observed_variance_refuses_non_event_clocks_an 2.0, 0.4, 0.0, + 0.0, 0.5, 1.0, + 1.0, + 0.0, 0.0, LagClock::EventTime, ) @@ -8133,12 +8244,15 @@ fn predetermined_later_start_later_observed_variance_refuses_non_event_clocks_an recover_predetermined_later_start_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, -0.225, 1.0, 0.5, 2.0, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -8147,8 +8261,11 @@ fn predetermined_later_start_later_observed_variance_refuses_non_event_clocks_an recover_predetermined_later_start_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, + 0.0, 2.0, 1.0, 0.5, From faf64b9f5b8eeaa7729d9a4a8c359db04efa4e7b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 10:06:42 +0000 Subject: [PATCH 4/7] fix(psychometric_core): finish event_time discrete-mean arity sites Apply the same licensed-zero and existing-interval inserts to the remaining event_time.rs unit-test calls that the first pass missed because of indentation. Co-authored-by: Seongho Bae --- crates/psychometric_core/src/event_time.rs | 117 +++++++++++--- ...multilevel_event_time_recovery_contract.rs | 153 +++++++++++++++--- 2 files changed, 228 insertions(+), 42 deletions(-) diff --git a/crates/psychometric_core/src/event_time.rs b/crates/psychometric_core/src/event_time.rs index 3e4824e44..fa6c90f13 100644 --- a/crates/psychometric_core/src/event_time.rs +++ b/crates/psychometric_core/src/event_time.rs @@ -12292,9 +12292,16 @@ mod tests { ), Ok(loading * evolved) ); - let zero_evolved = - recover_discrete_observed_mean(loading, 0.0, 0.0, 0.0, manifest_mean, delta, LagClock::EventTime) - .expect("zero-mu"); + let zero_evolved = recover_discrete_observed_mean( + loading, + 0.0, + 0.0, + 0.0, + manifest_mean, + delta, + LagClock::EventTime, + ) + .expect("zero-mu"); assert!((zero_evolved - manifest_mean).abs() < 1e-15); let integrator = recover_discrete_observed_mean( loading, @@ -12509,7 +12516,15 @@ mod tests { Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 0.0, 0.0, 1.0, LagClock::EventTime), + recover_discrete_latent_mean_with_impulse( + 1e308, + 0.0, + 1e308, + 0.0, + 0.0, + 1.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -13418,6 +13433,7 @@ mod tests { original, extra, 2.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::NonPositiveInterval) @@ -14560,7 +14576,14 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_initial_latent_variance(0.0, 0.0, 0.0, 1.0, 0.0, LagClock::EventTime), + recover_stationary_initial_latent_variance( + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + LagClock::EventTime + ), Ok(0.0) ); assert_eq!( @@ -15825,10 +15848,13 @@ mod tests { recover_stationary_later_observed_variance( loading, 0.0, + 0.0, + 0.0, 1.0, 0.0, event_delta, 0.0, + 0.0, LagClock::EventTime, ), Ok(0.0) @@ -15963,6 +15989,7 @@ mod tests { 0.0, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::StationaryVarianceRequiresStableDrift) @@ -15971,11 +15998,13 @@ mod tests { recover_stationary_later_observed_variance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -15984,6 +16013,8 @@ mod tests { recover_stationary_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, 1.0, @@ -15999,9 +16030,11 @@ mod tests { 1.0, 0.4, 0.0, + 0.0, -0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -16011,9 +16044,12 @@ mod tests { 2.0, f64::MAX, 0.0, + 0.0, + 0.0, -0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::InvalidNumericInput) @@ -16338,6 +16374,7 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, -0.5, 1.0, LagClock::EventTime @@ -16358,6 +16395,7 @@ mod tests { recover_predetermined_later_latent_variance( f64::MAX, 0.0, + 0.0, 1.0, f64::MAX, -1.0, @@ -16950,17 +16988,16 @@ mod tests { ), Ok(0.0) ); - let brownian = - recover_predetermined_lagged_latent_covariance( - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 1.0, - LagClock::EventTime, - ) - .expect("Brownian a=0"); + let brownian = recover_predetermined_lagged_latent_covariance( + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 1.0, + LagClock::EventTime, + ) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_lagged_latent_covariance( @@ -19117,7 +19154,13 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_initial_time_independent_predictor_carry(1.0, 1e308, 10.0, 1.0, LagClock::EventTime), + recover_initial_time_independent_predictor_carry( + 1.0, + 1e308, + 10.0, + 1.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -19761,7 +19804,13 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_initial_time_dependent_predictor_carry(1.0, 1e308, 10.0, 1.0, LagClock::EventTime), + recover_initial_time_dependent_predictor_carry( + 1.0, + 1e308, + 10.0, + 1.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -20173,6 +20222,8 @@ mod tests { assert!((near_later - recovered).abs() < 1e-9); assert_eq!( recover_predetermined_initial_latent_variance( + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -20193,6 +20244,8 @@ mod tests { let unstable_trait = recover_predetermined_initial_latent_variance( trait_variance, 0.0, + 0.0, + 0.0, 0.5, LagClock::EventTime, ) @@ -20288,6 +20341,7 @@ mod tests { ); assert_eq!( recover_predetermined_initial_latent_variance( + 0.0, 0.0, -0.225, 1.0, @@ -20297,12 +20351,25 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_predetermined_initial_latent_variance(0.0, 0.0, 0.0, 1.0, 0.0, LagClock::EventTime), + recover_predetermined_initial_latent_variance( + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + LagClock::EventTime + ), Ok(0.0) ); - let brownian = - recover_predetermined_initial_latent_variance(0.0, 2.0, 0.0, 0.0, 0.0, LagClock::EventTime) - .expect("Brownian a=0"); + let brownian = recover_predetermined_initial_latent_variance( + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + LagClock::EventTime, + ) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_initial_latent_variance( @@ -21328,6 +21395,8 @@ mod tests { let trait_only = recover_predetermined_later_start_later_latent_variance( trait_variance, 0.0, + 0.0, + 0.0, predictor_variance, 0.0, start_delta, @@ -21503,6 +21572,8 @@ mod tests { ); assert_eq!( recover_predetermined_later_start_later_latent_variance( + 0.0, + 0.0, 0.0, -0.225, 1.0, @@ -21518,8 +21589,10 @@ mod tests { 2.0, 0.4, 0.0, + 0.0, 0.5, 1.0, + 1.0, LagClock::EventTime, ) .expect("growing a>0"); diff --git a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs index b402dc9a9..ab155d6c2 100644 --- a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs +++ b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs @@ -1600,11 +1600,27 @@ fn time_dependent_impulse_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_discrete_latent_mean_with_impulse(1.0, -0.5, 0.3, 0.4, 2.0, 2.0, LagClock::SystemTime), + recover_discrete_latent_mean_with_impulse( + 1.0, + -0.5, + 0.3, + 0.4, + 2.0, + 2.0, + LagClock::SystemTime + ), Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_discrete_latent_mean_with_impulse(1e308, 0.0, 1e308, 0.0, 0.0, 1.0, LagClock::EventTime), + recover_discrete_latent_mean_with_impulse( + 1e308, + 0.0, + 1e308, + 0.0, + 0.0, + 1.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -3051,7 +3067,14 @@ fn time_dependent_impulse_carry_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::EventTimeRequired) ); assert_eq!( - recover_time_dependent_predictor_impulse_carry(0.4, 3.0, -0.5, 2.0, 0.0, LagClock::EventTime), + recover_time_dependent_predictor_impulse_carry( + 0.4, + 3.0, + -0.5, + 2.0, + 0.0, + LagClock::EventTime + ), Err(PsychometricError::NonPositiveInterval) ); assert_eq!( @@ -3079,7 +3102,14 @@ fn time_dependent_impulse_carry_refuses_overflow_and_non_event_clocks() { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_time_dependent_predictor_impulse_carry(1.0, 1_000.0, 1e308, 2.0, 1.0, LagClock::EventTime), + recover_time_dependent_predictor_impulse_carry( + 1.0, + 1_000.0, + 1e308, + 2.0, + 1.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); } @@ -4990,7 +5020,15 @@ fn stationary_initial_observed_mean_refuses_unstable_drift_and_non_event_clocks( Err(PsychometricError::AsymptoticContinuousInterceptRequiresStableDrift) ); assert_eq!( - recover_stationary_initial_observed_mean(2.0, 0.0, -0.225, 1.0, 0.5, LagClock::EventTime), + recover_stationary_initial_observed_mean( + 2.0, + 0.0, + -0.225, + 1.0, + 0.5, + 0.0, + LagClock::EventTime, + ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( @@ -5045,6 +5083,8 @@ fn stationary_initial_latent_variance_recovers_driver_section_four_point_three() assert!(rmse(&[recovered], &[2.838]) > error); assert_eq!( recover_stationary_initial_latent_variance( + 0.0, + 0.0, 0.0, predictor_variance, log_rate, @@ -5056,6 +5096,7 @@ fn stationary_initial_latent_variance_recovers_driver_section_four_point_three() recover_stationary_initial_latent_variance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, LagClock::EventTime, @@ -5114,11 +5155,25 @@ fn stationary_initial_latent_variance_refuses_unstable_drift_and_non_event_clock Ok(0.0) ); assert_eq!( - recover_stationary_initial_latent_variance(f64::NAN, 0.4, 0.0, -0.5, LagClock::EventTime), + recover_stationary_initial_latent_variance( + f64::NAN, + 0.4, + 0.0, + 0.0, + -0.5, + LagClock::EventTime, + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_stationary_initial_latent_variance(f64::MAX, 0.0, -0.5, LagClock::EventTime), + recover_stationary_initial_latent_variance( + f64::MAX, + 0.0, + 0.0, + 0.0, + -0.5, + LagClock::EventTime, + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( @@ -5281,10 +5336,12 @@ fn stationary_initial_observed_variance_refuses_unstable_drift_and_non_event_clo recover_stationary_initial_observed_variance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -5293,6 +5350,8 @@ fn stationary_initial_observed_variance_refuses_unstable_drift_and_non_event_clo recover_stationary_initial_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, 0.5, @@ -5367,6 +5426,8 @@ fn stationary_lagged_latent_covariance_recovers_driver_section_four_point_three( assert!(rmse(&[recovered], &[trait_plus_state]) > error); assert_eq!( recover_stationary_lagged_latent_covariance( + 0.0, + 0.0, 0.0, predictor_variance, log_rate, @@ -5379,6 +5440,7 @@ fn stationary_lagged_latent_covariance_recovers_driver_section_four_point_three( recover_stationary_lagged_latent_covariance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -5461,6 +5523,7 @@ fn stationary_lagged_latent_covariance_refuses_unstable_drift_and_non_event_cloc ); assert_eq!( recover_stationary_lagged_latent_covariance( + 0.0, 0.0, -0.225, 1.0, @@ -5471,7 +5534,15 @@ fn stationary_lagged_latent_covariance_refuses_unstable_drift_and_non_event_cloc Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_lagged_latent_covariance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), + recover_stationary_lagged_latent_covariance( + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 1.0, + LagClock::EventTime + ), Ok(0.0) ); } @@ -5620,6 +5691,7 @@ fn stationary_lagged_observed_covariance_refuses_unstable_drift_and_non_event_cl recover_stationary_lagged_observed_covariance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, @@ -5633,6 +5705,8 @@ fn stationary_lagged_observed_covariance_refuses_unstable_drift_and_non_event_cl recover_stationary_lagged_observed_covariance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, 1.0, @@ -5722,6 +5796,8 @@ fn stationary_later_latent_variance_recovers_driver_section_four_point_three() { assert!(rmse(&[recovered], &[process_noise]) > error); assert_eq!( recover_stationary_later_latent_variance( + 0.0, + 0.0, 0.0, predictor_variance, log_rate, @@ -5734,6 +5810,7 @@ fn stationary_later_latent_variance_recovers_driver_section_four_point_three() { recover_stationary_later_latent_variance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, event_delta, @@ -5797,7 +5874,15 @@ fn stationary_later_latent_variance_refuses_unstable_drift_and_non_event_clocks( Err(PsychometricError::StationaryVarianceRequiresStableDrift) ); assert_eq!( - recover_stationary_later_latent_variance(0.0, -0.225, 1.0, 0.5, 1.0, LagClock::EventTime), + recover_stationary_later_latent_variance( + 0.0, + 0.0, + -0.225, + 1.0, + 0.5, + 1.0, + LagClock::EventTime, + ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( @@ -5962,6 +6047,7 @@ fn stationary_later_observed_variance_refuses_unstable_drift_and_non_event_clock 0.0, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::StationaryVarianceRequiresStableDrift) @@ -5970,11 +6056,13 @@ fn stationary_later_observed_variance_refuses_unstable_drift_and_non_event_clock recover_stationary_later_observed_variance( 2.0, 0.0, + 0.0, -0.225, 1.0, 0.5, 1.0, 0.0, + 0.0, LagClock::EventTime ), Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) @@ -5983,6 +6071,8 @@ fn stationary_later_observed_variance_refuses_unstable_drift_and_non_event_clock recover_stationary_later_observed_variance( 2.0, 0.0, + 0.0, + 0.0, 1.0, 0.0, 1.0, @@ -6593,17 +6683,16 @@ fn predetermined_lagged_latent_covariance_refuses_non_event_clocks_and_keeps_gro ) .expect("growing carry"); assert!(growing > 2.0); - let brownian = - recover_predetermined_lagged_latent_covariance( - 0.0, - 2.0, - 0.0, - 0.0, - 0.0, - 1.0, - LagClock::EventTime, - ) - .expect("Brownian a=0"); + let brownian = recover_predetermined_lagged_latent_covariance( + 0.0, + 2.0, + 0.0, + 0.0, + 0.0, + 1.0, + LagClock::EventTime, + ) + .expect("Brownian a=0"); assert!((brownian - 2.0).abs() < 1e-12); assert_eq!( recover_predetermined_lagged_latent_covariance( @@ -7339,6 +7428,9 @@ fn predetermined_later_lagged_latent_covariance_recovers_driver_section_four_poi assert!(rmse(&[near_later], &[later]) < 1e-9); assert_eq!( recover_predetermined_later_lagged_latent_covariance( + 0.0, + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -7352,6 +7444,8 @@ fn predetermined_later_lagged_latent_covariance_recovers_driver_section_four_poi recover_predetermined_later_lagged_latent_covariance( trait_variance, 0.0, + 0.0, + 0.0, predictor_variance, 0.0, start_delta, @@ -7442,14 +7536,18 @@ fn predetermined_later_lagged_latent_covariance_refuses_non_event_clocks_and_kee 2.0, 0.4, 0.0, + 0.0, 0.5, 1.0, + 1.0, LagClock::EventTime, ) .expect("growing a>0"); assert!(growing.is_finite() && growing > 2.0); assert_eq!( recover_predetermined_later_lagged_latent_covariance( + 0.0, + 0.0, 0.0, -0.225, 1.0, @@ -7462,6 +7560,9 @@ fn predetermined_later_lagged_latent_covariance_refuses_non_event_clocks_and_kee ); assert_eq!( recover_predetermined_later_lagged_latent_covariance( + 0.0, + 0.0, + 0.0, 0.0, 1.0, 0.0, @@ -7884,6 +7985,9 @@ fn predetermined_later_start_later_latent_variance_recovers_driver_section_four_ assert!(rmse(&[near_first], &[later_over_s]) < 1e-9); assert_eq!( recover_predetermined_later_start_later_latent_variance( + 0.0, + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -7897,6 +8001,8 @@ fn predetermined_later_start_later_latent_variance_recovers_driver_section_four_ recover_predetermined_later_start_later_latent_variance( trait_variance, 0.0, + 0.0, + 0.0, predictor_variance, 0.0, start_delta, @@ -7997,14 +8103,18 @@ fn predetermined_later_start_later_latent_variance_refuses_non_event_clocks_and_ 2.0, 0.4, 0.0, + 0.0, 0.5, 1.0, + 1.0, LagClock::EventTime, ) .expect("growing a>0"); assert!(growing.is_finite() && growing > 2.0); assert_eq!( recover_predetermined_later_start_later_latent_variance( + 0.0, + 0.0, 0.0, -0.225, 1.0, @@ -8017,6 +8127,9 @@ fn predetermined_later_start_later_latent_variance_refuses_non_event_clocks_and_ ); assert_eq!( recover_predetermined_later_start_later_latent_variance( + 0.0, + 0.0, + 0.0, 0.0, 1.0, 0.0, From 1ca11653ae9220229dde760a3ef50b7537118e7d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 10:08:09 +0000 Subject: [PATCH 5/7] fix(psychometric_core): insert licensed zeros for remaining later-latent arity Complete the last recover_stationary_later_latent_variance and trait-only initial-variance call sites so B/v slots are explicit zeros and printed LeisureTime TIPREDEFFECT -0.225 stays in the B slot. Co-authored-by: Seongho Bae --- crates/psychometric_core/src/event_time.rs | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/psychometric_core/src/event_time.rs b/crates/psychometric_core/src/event_time.rs index fa6c90f13..79bc52017 100644 --- a/crates/psychometric_core/src/event_time.rs +++ b/crates/psychometric_core/src/event_time.rs @@ -14435,6 +14435,7 @@ mod tests { let trait_only = recover_stationary_initial_latent_variance( trait_variance, 0.0, + 0.0, predictor_variance, 0.0, LagClock::EventTime, @@ -15576,6 +15577,8 @@ mod tests { assert!((added_only - added).abs() < 1e-15); assert_eq!( recover_stationary_later_latent_variance( + 0.0, + 0.0, 0.0, predictor_variance, 0.0, @@ -15711,6 +15714,7 @@ mod tests { ); assert_eq!( recover_stationary_later_latent_variance( + 0.0, 0.0, -0.225, 1.0, @@ -15721,7 +15725,15 @@ mod tests { Err(PsychometricError::AsymptoticTimeIndependentEffectRequiresStableDrift) ); assert_eq!( - recover_stationary_later_latent_variance(0.0, 1.0, 0.0, 1.0, LagClock::EventTime), + recover_stationary_later_latent_variance( + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 1.0, + LagClock::EventTime + ), Ok(0.0) ); assert_eq!( @@ -15729,6 +15741,7 @@ mod tests { f64::NAN, 0.4, 0.0, + 0.0, -0.5, 1.0, LagClock::EventTime @@ -15736,7 +15749,15 @@ mod tests { Err(PsychometricError::InvalidNumericInput) ); assert_eq!( - recover_stationary_later_latent_variance(f64::MAX, 0.0, -0.5, 1.0, LagClock::EventTime), + recover_stationary_later_latent_variance( + f64::MAX, + 0.0, + 0.0, + 0.0, + -0.5, + 1.0, + LagClock::EventTime + ), Err(PsychometricError::InvalidNumericInput) ); assert_eq!( From 67c3f0d3b0cb9cb7398461c23427a0c2f60a73b3 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 10:15:39 +0000 Subject: [PATCH 6/7] fix(psychometric_core): finish last five predetermined-variance arity sites Remove three short MAX overflow calls that duplicated the sibling (B=1, v=MAX, a=-1) pattern after the #232 signature growth, and pad later-lagged / later-start-later latent overflow calls with licensed zeros so workspace rust-quality can compile. Co-authored-by: Seongho Bae --- crates/psychometric_core/src/event_time.rs | 34 +++++----------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/crates/psychometric_core/src/event_time.rs b/crates/psychometric_core/src/event_time.rs index 79bc52017..cf7c3ff34 100644 --- a/crates/psychometric_core/src/event_time.rs +++ b/crates/psychometric_core/src/event_time.rs @@ -16402,16 +16402,6 @@ mod tests { ), Err(PsychometricError::InvalidNumericInput) ); - assert_eq!( - recover_predetermined_later_latent_variance( - f64::MAX, - 0.0, - -0.5, - 1.0, - LagClock::EventTime - ), - Err(PsychometricError::InvalidNumericInput) - ); assert_eq!( recover_predetermined_later_latent_variance( f64::MAX, @@ -17032,16 +17022,6 @@ mod tests { ), Err(PsychometricError::InvalidNumericInput) ); - assert_eq!( - recover_predetermined_lagged_latent_covariance( - f64::MAX, - 0.0, - -0.5, - 1.0, - LagClock::EventTime - ), - Err(PsychometricError::InvalidNumericInput) - ); assert_eq!( recover_predetermined_lagged_latent_covariance( f64::MAX, @@ -20403,10 +20383,6 @@ mod tests { ), Err(PsychometricError::InvalidNumericInput) ); - assert_eq!( - recover_predetermined_initial_latent_variance(f64::MAX, 0.0, -0.5, LagClock::EventTime), - Err(PsychometricError::InvalidNumericInput) - ); assert_eq!( recover_predetermined_initial_latent_variance( f64::MAX, @@ -20972,7 +20948,10 @@ mod tests { recover_predetermined_later_lagged_latent_covariance( f64::MAX, 0.0, - -0.5, + 0.0, + 1.0, + f64::MAX, + -1.0, 2.0, 1.0, LagClock::EventTime @@ -21637,7 +21616,10 @@ mod tests { recover_predetermined_later_start_later_latent_variance( f64::MAX, 0.0, - -0.5, + 0.0, + 1.0, + f64::MAX, + -1.0, 2.0, 1.0, LagClock::EventTime From 6613ee5a1916f679ffb71cdb3e8f234876625253 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 10:16:56 +0000 Subject: [PATCH 7/7] fix(psychometric_core): drop licensed-zero MAX calls that are not overflow Trait = MAX with q = B = v = 0 is a finite composition after the #232 signature growth. Overflow remains covered by the sibling (B=1, v=MAX, a=-1) assertions in the same fail-closed tests. Co-authored-by: Seongho Bae --- crates/psychometric_core/src/event_time.rs | 35 ------------------- ...multilevel_event_time_recovery_contract.rs | 11 ------ 2 files changed, 46 deletions(-) diff --git a/crates/psychometric_core/src/event_time.rs b/crates/psychometric_core/src/event_time.rs index cf7c3ff34..7c225a4b0 100644 --- a/crates/psychometric_core/src/event_time.rs +++ b/crates/psychometric_core/src/event_time.rs @@ -14598,17 +14598,6 @@ mod tests { ), Err(PsychometricError::InvalidNumericInput) ); - assert_eq!( - recover_stationary_initial_latent_variance( - f64::MAX, - 0.0, - 0.0, - 0.0, - -0.5, - LagClock::EventTime - ), - Err(PsychometricError::InvalidNumericInput) - ); assert_eq!( recover_stationary_initial_latent_variance( f64::MAX, @@ -15172,18 +15161,6 @@ mod tests { ), Err(PsychometricError::InvalidNumericInput) ); - assert_eq!( - recover_stationary_lagged_latent_covariance( - f64::MAX, - 0.0, - 0.0, - 0.0, - -0.5, - 1.0, - LagClock::EventTime - ), - Err(PsychometricError::InvalidNumericInput) - ); assert_eq!( recover_stationary_lagged_latent_covariance( f64::MAX, @@ -15748,18 +15725,6 @@ mod tests { ), Err(PsychometricError::InvalidNumericInput) ); - assert_eq!( - recover_stationary_later_latent_variance( - f64::MAX, - 0.0, - 0.0, - 0.0, - -0.5, - 1.0, - LagClock::EventTime - ), - Err(PsychometricError::InvalidNumericInput) - ); assert_eq!( recover_stationary_later_latent_variance( f64::MAX, diff --git a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs index ab155d6c2..dac50709a 100644 --- a/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs +++ b/crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs @@ -5165,17 +5165,6 @@ fn stationary_initial_latent_variance_refuses_unstable_drift_and_non_event_clock ), Err(PsychometricError::InvalidNumericInput) ); - assert_eq!( - recover_stationary_initial_latent_variance( - f64::MAX, - 0.0, - 0.0, - 0.0, - -0.5, - LagClock::EventTime, - ), - Err(PsychometricError::InvalidNumericInput) - ); assert_eq!( recover_stationary_initial_latent_variance( f64::MAX,