turnbull: Fix issue with likelihood ratio-based confidence intervals

Previous logic resulted in EM-ICM algorithm terminating too early when constrained, resulting in imprecise confidence intervals
This commit is contained in:
RunasSudo 2023-12-24 22:16:40 +11:00
parent 434b432cf7
commit 606c1636e0
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A

View File

@ -490,7 +490,6 @@ fn do_icm_step(data: &TurnbullData, p: &Vec<f64>, s: &Vec<f64>, ll_tolerance: f6
let likelihood_obs_new = get_likelihood_obs(data, &s_new); let likelihood_obs_new = get_likelihood_obs(data, &s_new);
ll_model_new = likelihood_obs_new.iter().map(|l| l.ln()).sum(); ll_model_new = likelihood_obs_new.iter().map(|l| l.ln()).sum();
if ll_model_new > ll_model {
// Constrain if required // Constrain if required
if let Some(c) = constraint { if let Some(c) = constraint {
let cur_survival_prob = s_new[c.time_index]; let cur_survival_prob = s_new[c.time_index];
@ -502,6 +501,7 @@ fn do_icm_step(data: &TurnbullData, p: &Vec<f64>, s: &Vec<f64>, ll_tolerance: f6
ll_model_new = likelihood_obs_new.iter().map(|l| l.ln()).sum(); ll_model_new = likelihood_obs_new.iter().map(|l| l.ln()).sum();
} }
if ll_model_new > ll_model {
return (p_new, s_new, ll_model_new); return (p_new, s_new, ll_model_new);
} }
@ -513,7 +513,10 @@ fn do_icm_step(data: &TurnbullData, p: &Vec<f64>, s: &Vec<f64>, ll_tolerance: f6
step_size_exponent += 1; step_size_exponent += 1;
if step_size_exponent > 10 { // FIXME: Nasty hack!
// Limit of 10 should be good enough, but sometimes ICM step does not work well when constrained so the limit is increased
// It would be greatly preferable to simply handle this case more gracefully when constrained
if step_size_exponent > 100 {
panic!("ICM fails to increase log-likelihood"); panic!("ICM fails to increase log-likelihood");
} }
} }