Enum ResidualErrorModel
pub enum ResidualErrorModel {
Constant {
a: f64,
},
Proportional {
b: f64,
},
Combined {
a: f64,
b: f64,
},
Exponential {
sigma: f64,
},
}Expand description
Residual error model for parametric estimation algorithms.
Unlike crate::ErrorModel which uses observations, this uses
the model prediction to compute the standard deviation.
§Usage in SAEM
The error model affects:
- Likelihood computation in E-step: L(y|f) = N(y; f, σ²)
- Residual weighting in M-step: weighted_res² = (y-f)²/σ²
§Examples
use pharmsol::ResidualErrorModel;
// Constant (additive) error: σ = 0.5
let constant = ResidualErrorModel::Constant { a: 0.5 };
assert!((constant.sigma(100.0) - 0.5).abs() < 1e-10);
// Proportional error: σ = 0.1 * |f|
let proportional = ResidualErrorModel::Proportional { b: 0.1 };
assert!((proportional.sigma(100.0) - 10.0).abs() < 1e-10);
// Combined error: σ = sqrt(0.5² + 0.1² * f²)
let combined = ResidualErrorModel::Combined { a: 0.5, b: 0.1 };
// For f=100: σ = sqrt(0.25 + 100) = sqrt(100.25) ≈ 10.01Variants§
Constant
Constant (additive) error model
σ = a
Error is independent of the predicted value. Appropriate when measurement error is constant regardless of concentration.
Proportional
Proportional error model
σ = b * |f|
Error scales linearly with the prediction. Appropriate when measurement error is a constant percentage of the value.
Note: Uses |f| to handle negative predictions gracefully.
Combined
Combined (additive + proportional) error model
σ = sqrt(a² + b² * f²)
This is the standard saemix error model from func_aux.R:
g <- cutoff(sqrt(ab[1]^2 + ab[2]^2 * f^2))The combined model:
- Dominates at low concentrations (a term)
- Scales proportionally at high concentrations (b term)
Exponential
Exponential error model (for log-transformed data)
σ = σ_exp (constant on log scale)
When data is analyzed on the log scale:
log(Y) = log(f) + ε, where ε ~ N(0, σ²)This corresponds to multiplicative error on the original scale.
Implementations§
§impl ResidualErrorModel
impl ResidualErrorModel
pub fn constant(a: f64) -> ResidualErrorModel
pub fn constant(a: f64) -> ResidualErrorModel
pub fn proportional(b: f64) -> ResidualErrorModel
pub fn proportional(b: f64) -> ResidualErrorModel
pub fn combined(a: f64, b: f64) -> ResidualErrorModel
pub fn combined(a: f64, b: f64) -> ResidualErrorModel
Create a combined (additive + proportional) error model
§Arguments
a- Additive componentb- Proportional component
pub fn exponential(sigma: f64) -> ResidualErrorModel
pub fn exponential(sigma: f64) -> ResidualErrorModel
pub fn weighted_squared_residual(
&self,
observation: f64,
prediction: f64,
) -> f64
pub fn weighted_squared_residual( &self, observation: f64, prediction: f64, ) -> f64
Compute the weighted residual for M-step sigma updates
For the M-step in SAEM, we compute the normalized residual:
- For constant/additive: (y - f)² (unweighted)
- For proportional: (y - f)² / f² (weighted by prediction)
- For combined: (y - f)² / (a² + b²*f²) (using current sigma params)
This matches R saemix’s approach in main_mstep.R where for proportional
error: resk <- sum((yobs - fk)**2 / cutoff(fk**2, .Machine$double.eps))
§Arguments
observation- The observed value (y)prediction- The model prediction (f)
§Returns
The weighted squared residual for sigma estimation.
pub fn log_likelihood(&self, observation: f64, prediction: f64) -> f64
pub fn log_likelihood(&self, observation: f64, prediction: f64) -> f64
pub fn with_updated_sigma(self, new_sigma: f64) -> ResidualErrorModel
pub fn with_updated_sigma(self, new_sigma: f64) -> ResidualErrorModel
Update the error model parameters based on M-step sufficient statistics
In SAEM, the residual error is estimated in the M-step. This method updates the appropriate parameter based on the new estimate.
§Arguments
new_sigma- The new sigma estimate from M-step
§Returns
A new error model with updated parameters.
pub fn primary_parameter(&self) -> f64
pub fn primary_parameter(&self) -> f64
Get the primary sigma parameter value
For Constant: returns a For Proportional: returns b For Combined: returns a (additive component) For Exponential: returns sigma
pub fn is_proportional(&self) -> bool
pub fn is_proportional(&self) -> bool
Check if this is a proportional error model
pub fn is_constant(&self) -> bool
pub fn is_constant(&self) -> bool
Check if this is a constant (additive) error model
pub fn is_combined(&self) -> bool
pub fn is_combined(&self) -> bool
Check if this is a combined error model
pub fn is_exponential(&self) -> bool
pub fn is_exponential(&self) -> bool
Check if this is an exponential error model
Trait Implementations§
§impl Clone for ResidualErrorModel
impl Clone for ResidualErrorModel
§fn clone(&self) -> ResidualErrorModel
fn clone(&self) -> ResidualErrorModel
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more§impl Debug for ResidualErrorModel
impl Debug for ResidualErrorModel
§impl Default for ResidualErrorModel
impl Default for ResidualErrorModel
§fn default() -> ResidualErrorModel
fn default() -> ResidualErrorModel
§impl<'de> Deserialize<'de> for ResidualErrorModel
impl<'de> Deserialize<'de> for ResidualErrorModel
§fn deserialize<__D>(
__deserializer: __D,
) -> Result<ResidualErrorModel, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<ResidualErrorModel, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
§impl PartialEq for ResidualErrorModel
impl PartialEq for ResidualErrorModel
§impl Serialize for ResidualErrorModel
impl Serialize for ResidualErrorModel
§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl Copy for ResidualErrorModel
impl StructuralPartialEq for ResidualErrorModel
Auto Trait Implementations§
impl Freeze for ResidualErrorModel
impl RefUnwindSafe for ResidualErrorModel
impl Send for ResidualErrorModel
impl Sync for ResidualErrorModel
impl Unpin for ResidualErrorModel
impl UnwindSafe for ResidualErrorModel
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> Context for T
impl<T> Context for T
fn vector_from_element<V>(&self, len: usize, value: <V as VectorCommon>::T) -> Vwhere
V: Vector<C = Self>,
fn vector_from_vec<V>(&self, vec: Vec<<V as VectorCommon>::T>) -> Vwhere
V: Vector<C = Self>,
fn vector_zeros<V>(&self, len: usize) -> Vwhere
V: Vector<C = Self>,
fn dense_mat_zeros<V>(
&self,
rows: usize,
cols: usize,
) -> <V as DefaultDenseMatrix>::Mwhere
V: Vector<C = Self> + DefaultDenseMatrix,
§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.