pub struct BestDosePosterior { /* private fields */ }Expand description
The computed Bayesian posterior for a patient
This is the main public entry point for the two-stage BestDose API:
-
Stage 1: Posterior computation (
BestDosePosterior::compute())- NPAGFULL11: Bayesian filtering of prior support points
- NPAGFULL: Local refinement of each filtered point
-
Stage 2: Dose optimization (
BestDosePosterior::optimize())- Dual optimization (posterior vs uniform weights)
- Final predictions with optimal doses
The posterior can be reused across multiple optimize() calls with
different targets, dose ranges, or bias weights.
§Example
use pmcore::bestdose::{BestDosePosterior, Target, DoseRange};
// Stage 1: Compute posterior (expensive, done once)
let posterior = BestDosePosterior::compute(
&population_theta,
&population_weights,
Some(past),
eq,
settings,
)?;
// Stage 2: Optimize doses (can be called multiple times)
let result = posterior.optimize(
target,
None, // No time offset
DoseRange::new(0.0, 1000.0),
0.5, // bias_weight
Target::Concentration,
)?;Implementations§
Source§impl BestDosePosterior
impl BestDosePosterior
Sourcepub fn posterior_weights(&self) -> &Weights
pub fn posterior_weights(&self) -> &Weights
Get the posterior probability weights
Sourcepub fn population_weights(&self) -> &Weights
pub fn population_weights(&self) -> &Weights
Get the filtered population weights used for the bias term
Sourcepub fn n_support_points(&self) -> usize
pub fn n_support_points(&self) -> usize
Get the number of support points in the posterior
Source§impl BestDosePosterior
impl BestDosePosterior
Sourcepub fn compute(
population_theta: &Theta,
population_weights: &Weights,
past_data: Option<Subject>,
eq: ODE,
settings: Settings,
) -> Result<Self>
pub fn compute( population_theta: &Theta, population_weights: &Weights, past_data: Option<Subject>, eq: ODE, settings: Settings, ) -> Result<Self>
Stage 1: Compute the Bayesian posterior density from population prior and patient data
This performs the expensive posterior calculation (NPAGFULL11 filtering + NPAGFULL refinement)
and returns a reusable BestDosePosterior that can be optimized multiple times.
§Algorithm
Prior (N support points)
↓
NPAGFULL11: Bayesian filtering
P(θᵢ|data) ∝ P(data|θᵢ) × P(θᵢ)
↓
Filtered posterior (M points)
↓
NPAGFULL: Local refinement (max_cycles iterations)
↓
Refined posterior (M points with updated weights)§Arguments
population_theta- Population support points from NPAGpopulation_weights- Population probabilitiespast_data- Patient history (None= use prior directly)eq- Pharmacokinetic/pharmacodynamic modelsettings- NPAG settings (includes error models and posterior refinement config)
§Example
let posterior = BestDosePosterior::compute(
&theta, &weights,
Some(past_subject),
eq, settings,
)?;
println!("Posterior has {} support points", posterior.n_support_points());Sourcepub fn optimize(
&self,
target: Subject,
time_offset: Option<f64>,
dose_range: DoseRange,
bias_weight: f64,
target_type: Target,
) -> Result<BestDoseResult>
pub fn optimize( &self, target: Subject, time_offset: Option<f64>, dose_range: DoseRange, bias_weight: f64, target_type: Target, ) -> Result<BestDoseResult>
Stage 2: Optimize doses for target outcomes using the computed posterior
This runs the dual optimization (posterior weights vs uniform weights) and returns the best dosing regimen. Can be called multiple times on the same posterior with different parameters.
§Arguments
target- Future dosing template with target observationstime_offset- Optional gap (in hours) between the last past event and the start of the future target. 0 means the future starts immediately after the last past event. The effective absolute offset ismax_past_time + time_offset.dose_range- Allowable dose constraintsbias_weight- λ in [0,1]: 0=personalized, 1=populationtarget_type- Concentration or AUC targets
§Example
// Try different bias weights
for &bw in &[0.0, 0.25, 0.5, 0.75, 1.0] {
let result = posterior.optimize(
target.clone(),
None,
DoseRange::new(0.0, 300.0),
bw,
Target::Concentration,
)?;
println!("λ={}: dose={:.1}", bw, result.doses()[0]);
}Trait Implementations§
Source§impl Clone for BestDosePosterior
impl Clone for BestDosePosterior
Source§fn clone(&self) -> BestDosePosterior
fn clone(&self) -> BestDosePosterior
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for BestDosePosterior
impl !RefUnwindSafe for BestDosePosterior
impl Send for BestDosePosterior
impl Sync for BestDosePosterior
impl Unpin for BestDosePosterior
impl !UnwindSafe for BestDosePosterior
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> Twhere
Self: Distribution<T>,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pointable for T
impl<T> Pointable for T
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.