use std::fmt;
use std::sync::OnceLock;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ClosedInterval {
pub lo: f64,
pub hi: f64,
}
impl ClosedInterval {
#[inline]
pub const fn new(lo: f64, hi: f64) -> Self {
Self { lo, hi }
}
#[inline]
pub const fn point(value: f64) -> Self {
Self {
lo: value,
hi: value,
}
}
#[inline]
pub const fn entire() -> Self {
Self {
lo: f64::NEG_INFINITY,
hi: f64::INFINITY,
}
}
#[inline]
pub fn contains(self, value: f64) -> bool {
self.lo <= value && value <= self.hi
}
#[inline]
pub fn contains_zero(self) -> bool {
self.contains(0.0)
}
#[inline]
fn is_valid(self) -> bool {
!self.lo.is_nan() && !self.hi.is_nan() && self.lo <= self.hi
}
#[inline]
fn hull(self, other: Self) -> Self {
Self {
lo: self.lo.min(other.lo),
hi: self.hi.max(other.hi),
}
}
#[inline]
fn intersection(self, other: Self) -> Option<Self> {
let intersection = Self {
lo: self.lo.max(other.lo),
hi: self.hi.min(other.hi),
};
(intersection.lo <= intersection.hi).then_some(intersection)
}
#[inline]
fn max_abs(self) -> f64 {
self.lo.abs().max(self.hi.abs())
}
#[inline]
fn widen(self, radius: f64) -> Self {
if radius == 0.0 {
return self;
}
if radius == f64::INFINITY {
return Self::entire();
}
Self {
lo: next_down(self.lo - radius),
hi: next_up(self.hi + radius),
}
}
#[inline]
pub fn add(self, other: Self) -> Self {
Self {
lo: sum_down(self.lo, other.lo),
hi: sum_up(self.hi, other.hi),
}
}
#[inline]
pub fn sub(self, other: Self) -> Self {
Self {
lo: sum_down(self.lo, -other.hi),
hi: sum_up(self.hi, -other.lo),
}
}
#[inline]
pub fn neg(self) -> Self {
Self {
lo: -self.hi,
hi: -self.lo,
}
}
pub fn mul(self, other: Self) -> Self {
let pairs = [
(self.lo, other.lo),
(self.lo, other.hi),
(self.hi, other.lo),
(self.hi, other.hi),
];
let mut lo = f64::INFINITY;
let mut hi = f64::NEG_INFINITY;
for (left, right) in pairs {
lo = lo.min(product_down(left, right));
hi = hi.max(product_up(left, right));
}
Self { lo, hi }
}
#[inline]
pub fn scale(self, value: f64) -> Self {
self.mul(Self::point(value))
}
fn square(self) -> Self {
if self.lo >= 0.0 {
Self {
lo: product_down(self.lo, self.lo).max(0.0),
hi: product_up(self.hi, self.hi),
}
} else if self.hi <= 0.0 {
Self {
lo: product_down(self.hi, self.hi).max(0.0),
hi: product_up(self.lo, self.lo),
}
} else {
Self {
lo: 0.0,
hi: product_up(self.lo, self.lo).max(product_up(self.hi, self.hi)),
}
}
}
fn ln_positive(self) -> Self {
assert!(
self.lo > 0.0,
"ln_positive requires a strictly positive interval, got lo={}",
self.lo
);
let lo = certified_ln_positive(self.lo)
.expect("ln_positive lower endpoint is finite and positive");
let hi = certified_ln_positive(self.hi)
.expect("ln_positive upper endpoint is finite and positive");
Self::new(lo.lo, hi.hi)
}
fn div_positive(self, denominator: Self) -> Self {
assert!(
denominator.lo > 0.0,
"div_positive requires a strictly positive denominator interval, got lo={}",
denominator.lo
);
let reciprocal = Self {
lo: quotient_down(1.0, denominator.hi).max(0.0),
hi: quotient_up(1.0, denominator.lo),
};
self.mul(reciprocal)
}
fn div_nonzero(self, denominator: Self) -> Self {
if denominator.lo > 0.0 {
self.div_positive(denominator)
} else {
assert!(
denominator.hi < 0.0,
"div_nonzero requires a denominator interval excluding zero, got {denominator:?}"
);
self.div_positive(denominator.neg()).neg()
}
}
#[inline]
fn nonnegative(self) -> Self {
Self {
lo: self.lo.max(0.0),
hi: self.hi.max(0.0),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ScoreJet {
pub value: f64,
pub derivative: f64,
pub curvature: f64,
pub third: f64,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ScoreSample {
pub x: f64,
pub value: f64,
pub derivative: f64,
pub curvature: f64,
pub third: f64,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ScoreValueEnclosure {
pub value: ClosedInterval,
pub evaluation_error: f64,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DerivativeEnclosure {
pub score: ScoreValueEnclosure,
pub derivative: ClosedInterval,
pub curvature: ClosedInterval,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ResolutionFlatRegion {
pub sample: ScoreSample,
pub bracket: ClosedInterval,
pub score: ClosedInterval,
pub max_score_gap: f64,
pub score_resolution: f64,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct StationaryPoint {
pub sample: ScoreSample,
pub bracket: ClosedInterval,
pub score: ScoreValueEnclosure,
pub curvature: ClosedInterval,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct GlobalScoreCertificate {
pub selected: ClosedInterval,
pub maximum: ClosedInterval,
pub maximum_excess: f64,
pub comparison_resolution: f64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ScoreOptimumLocation {
LowerBoundary,
UpperBoundary,
Stationary(usize),
ResolutionFlat(usize),
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DominatedRegion {
pub bracket: ClosedInterval,
pub score: ScoreValueEnclosure,
pub incumbent_lower: f64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct ScoreSearchResult {
pub optimum: ScoreSample,
pub location: ScoreOptimumLocation,
pub lower_boundary: ScoreSample,
pub upper_boundary: ScoreSample,
pub stationary_points: Vec<StationaryPoint>,
pub resolution_flat_regions: Vec<ResolutionFlatRegion>,
pub dominated_regions: Vec<DominatedRegion>,
pub value_certificate: GlobalScoreCertificate,
}
#[derive(Debug)]
pub enum ScoreSearchError<E> {
InvalidDomain {
lo: f64,
hi: f64,
},
InvalidResolution {
resolution: f64,
},
PointEvaluation {
x: f64,
source: E,
},
EnclosureEvaluation {
lo: f64,
hi: f64,
source: E,
},
NonFiniteSample {
sample: ScoreSample,
},
InvalidEnclosure {
lo: f64,
hi: f64,
enclosure: DerivativeEnclosure,
},
ScoreValueEnclosureMissesEndpoint {
lo: f64,
hi: f64,
endpoint: ScoreSample,
score: ScoreValueEnclosure,
},
DisjointEndpointEnclosure {
lo: f64,
hi: f64,
endpoint: ScoreSample,
endpoint_derivative: ClosedInterval,
enclosure: DerivativeEnclosure,
},
InconsistentRootEnclosure {
lo: f64,
hi: f64,
left_derivative: ClosedInterval,
right_derivative: ClosedInterval,
curvature: ClosedInterval,
left_newton: ClosedInterval,
right_newton: ClosedInterval,
point_newton: ClosedInterval,
},
Unresolved {
lo: f64,
hi: f64,
requested_resolution: f64,
enclosure: DerivativeEnclosure,
},
SubdivisionBudget {
lo: f64,
hi: f64,
cell_lo: f64,
cell_hi: f64,
requested_resolution: f64,
subdivisions: usize,
budget: usize,
depth_bound: u32,
enclosure: DerivativeEnclosure,
},
}
pub fn subdivision_budget(lo: f64, hi: f64, resolution: f64) -> (usize, u32) {
let width = hi - lo;
if !(width.is_finite() && width > 0.0 && resolution.is_finite() && resolution > 0.0) {
return (1, 0);
}
let levels = (width / resolution).log2().ceil();
let depth_bound = if levels.is_finite() && levels >= 1.0 {
levels.min(u32::MAX as f64) as u32
} else {
1
};
let depth = depth_bound as usize;
(8 * depth * depth, depth_bound)
}
impl<E: fmt::Display> fmt::Display for ScoreSearchError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidDomain { lo, hi } => {
write!(f, "score search: invalid domain [{lo}, {hi}]")
}
Self::InvalidResolution { resolution } => {
write!(f, "score search: invalid resolution {resolution}")
}
Self::PointEvaluation { x, source } => {
write!(f, "score search: evaluation failed at {x}: {source}")
}
Self::EnclosureEvaluation { lo, hi, source } => write!(
f,
"score search: score/derivative enclosure failed on [{lo}, {hi}]: {source}"
),
Self::NonFiniteSample { sample } => write!(
f,
"score search: non-finite jet at {} (value {}, derivative {}, curvature {}, third {})",
sample.x, sample.value, sample.derivative, sample.curvature, sample.third
),
Self::InvalidEnclosure { lo, hi, enclosure } => write!(
f,
"score search: invalid score/derivative enclosure on [{lo}, {hi}]: {enclosure:?}"
),
Self::ScoreValueEnclosureMissesEndpoint {
lo,
hi,
endpoint,
score,
} => write!(
f,
"score search: exact score range {:?} plus evaluator error {} on [{lo}, {hi}] misses the rounded endpoint value {} at {}",
score.value, score.evaluation_error, endpoint.value, endpoint.x
),
Self::DisjointEndpointEnclosure {
lo,
hi,
endpoint,
endpoint_derivative,
enclosure,
} => write!(
f,
"score search: derivative enclosures on [{lo}, {hi}] and its endpoint {} are disjoint: endpoint range {endpoint_derivative:?}, cell {enclosure:?}; point estimate {endpoint:?}",
endpoint.x
),
Self::InconsistentRootEnclosure {
lo,
hi,
left_derivative,
right_derivative,
curvature,
left_newton,
right_newton,
point_newton,
} => write!(
f,
"score search: interval-Newton certificates for the unique root on [{lo}, {hi}] \
are inconsistent: left derivative {left_derivative:?}, right derivative \
{right_derivative:?}, curvature {curvature:?}, left image {left_newton:?}, \
right image {right_newton:?}, point image {point_newton:?}"
),
Self::Unresolved {
lo,
hi,
requested_resolution,
enclosure,
} => {
let evaluation_error = enclosure.score.evaluation_error;
let verdict = if evaluation_error >= *requested_resolution {
" -- the REQUEST is unsatisfiable: the certified evaluation error at this cell \
already reaches the requested resolution, so no bracket narrower than about \
twice that error is decidable and no additional subdivision can close it"
} else {
""
};
write!(
f,
"score search: stationary structure unresolved on [{lo}, {hi}] at requested \
resolution {requested_resolution} (certified evaluation error \
{evaluation_error:e}){verdict}: {enclosure:?}"
)
}
Self::SubdivisionBudget {
lo,
hi,
cell_lo,
cell_hi,
requested_resolution,
subdivisions,
budget,
depth_bound,
enclosure,
} => {
let evaluation_error = enclosure.score.evaluation_error;
let verdict = if evaluation_error >= *requested_resolution {
"a LARGER BUDGET CANNOT HELP -- the certified evaluation error already reaches \
the requested resolution, so no subdivision separates stationary structure at \
this tolerance; the resolution asked for is finer than the evaluator delivers"
} else {
"the evaluation error is below the requested resolution, so this cell was still \
separable and a larger budget may resolve it"
};
write!(
f,
"score search: {subdivisions} cell subdivisions on [{lo}, {hi}] at requested \
resolution {requested_resolution} exceed the budget {budget} derived from this \
domain's subdivision depth bound {depth_bound}; the criterion is still \
undecomposable at [{cell_lo}, {cell_hi}], so it neither excludes nor isolates \
stationary structure over a region the search can only enumerate. Certified \
evaluation error at this cell is {evaluation_error:e} against requested \
resolution {requested_resolution:e}: {verdict}"
)
}
}
}
}
impl<E: std::error::Error + 'static> std::error::Error for ScoreSearchError<E> {}
#[derive(Clone, Copy)]
struct SearchSample {
sample: ScoreSample,
point_enclosure: Option<DerivativeEnclosure>,
}
#[derive(Clone, Copy)]
struct SearchNode {
left: SearchSample,
right: SearchSample,
}
#[derive(Clone, Copy)]
struct TerminalScoreCandidate {
score: ScoreValueEnclosure,
comparison_error: f64,
point_x: Option<f64>,
}
impl TerminalScoreCandidate {
#[inline]
fn point(x: f64, score: ScoreValueEnclosure) -> Self {
Self {
score,
comparison_error: score.evaluation_error,
point_x: Some(x),
}
}
#[inline]
fn region(score: ScoreValueEnclosure, comparison_error: f64) -> Self {
Self {
score,
comparison_error,
point_x: None,
}
}
}
fn evaluate_sample<E, F>(x: f64, evaluate: &mut F) -> Result<SearchSample, ScoreSearchError<E>>
where
F: FnMut(f64) -> Result<ScoreJet, E>,
{
let jet = evaluate(x).map_err(|source| ScoreSearchError::PointEvaluation { x, source })?;
let sample = ScoreSample {
x,
value: jet.value,
derivative: jet.derivative,
curvature: jet.curvature,
third: jet.third,
};
if sample.value.is_finite()
&& sample.derivative.is_finite()
&& sample.curvature.is_finite()
&& sample.third.is_finite()
{
Ok(SearchSample {
sample,
point_enclosure: None,
})
} else {
Err(ScoreSearchError::NonFiniteSample { sample })
}
}
fn checked_enclosure<E, F>(
left: ScoreSample,
right: ScoreSample,
enclose: &mut F,
) -> Result<DerivativeEnclosure, ScoreSearchError<E>>
where
F: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
let lo = left.x;
let hi = right.x;
let enclosure = enclose(left, right)
.map_err(|source| ScoreSearchError::EnclosureEvaluation { lo, hi, source })?;
if !(enclosure.derivative.is_valid()
&& enclosure.curvature.is_valid()
&& enclosure.score.value.is_valid()
&& enclosure.score.evaluation_error.is_finite()
&& enclosure.score.evaluation_error >= 0.0)
{
return Err(ScoreSearchError::InvalidEnclosure { lo, hi, enclosure });
}
let score = enclosure.score;
let resolved_score = score.value.widen(score.evaluation_error);
for endpoint in [left, right] {
if !resolved_score.contains(endpoint.value) {
return Err(ScoreSearchError::ScoreValueEnclosureMissesEndpoint {
lo,
hi,
endpoint,
score,
});
}
}
Ok(enclosure)
}
fn certify_point<E, F>(
point: &mut SearchSample,
enclose: &mut F,
) -> Result<DerivativeEnclosure, ScoreSearchError<E>>
where
F: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
let enclosure = match point.point_enclosure {
Some(enclosure) => enclosure,
None => {
let enclosure = checked_enclosure(point.sample, point.sample, enclose)?;
point.point_enclosure = Some(enclosure);
enclosure
}
};
Ok(enclosure)
}
fn certify_endpoint_derivative<E, F>(
point: &mut SearchSample,
cell_lo: f64,
cell_hi: f64,
cell: DerivativeEnclosure,
enclose: &mut F,
) -> Result<ClosedInterval, ScoreSearchError<E>>
where
F: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
let endpoint_derivative = certify_point(point, enclose)?.derivative;
endpoint_derivative.intersection(cell.derivative).ok_or(
ScoreSearchError::DisjointEndpointEnclosure {
lo: cell_lo,
hi: cell_hi,
endpoint: point.sample,
endpoint_derivative,
enclosure: cell,
},
)
}
#[derive(Clone, Copy, PartialEq, Eq)]
enum StrictSign {
Negative,
Positive,
}
#[inline]
fn strict_sign(interval: ClosedInterval) -> Option<StrictSign> {
if interval.hi < 0.0 {
Some(StrictSign::Negative)
} else if interval.lo > 0.0 {
Some(StrictSign::Positive)
} else {
None
}
}
#[inline]
fn is_exact_zero(interval: ClosedInterval) -> bool {
interval.lo == 0.0 && interval.hi == 0.0
}
fn certify_bracket_score<E, Eval, Enclose>(
bracket: ClosedInterval,
representative: SearchSample,
evaluate: &mut Eval,
enclose: &mut Enclose,
) -> Result<ScoreValueEnclosure, ScoreSearchError<E>>
where
Eval: FnMut(f64) -> Result<ScoreJet, E>,
Enclose: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
if bracket.lo == bracket.hi {
let mut representative = representative;
return Ok(certify_point(&mut representative, enclose)?.score);
}
let left = if representative.sample.x == bracket.lo {
representative
} else {
evaluate_sample(bracket.lo, evaluate)?
};
let right = if representative.sample.x == bracket.hi {
representative
} else {
evaluate_sample(bracket.hi, evaluate)?
};
Ok(checked_enclosure(left.sample, right.sample, enclose)?.score)
}
enum UniqueRootRefinement {
Stationary(StationaryPoint),
ResolutionFlat {
region: ResolutionFlatRegion,
maximum: ScoreValueEnclosure,
},
}
fn refine_unique_root<E, Eval, Enclose>(
mut left: SearchSample,
mut right: SearchSample,
resolution: f64,
enclosure: DerivativeEnclosure,
evaluate: &mut Eval,
enclose: &mut Enclose,
) -> Result<UniqueRootRefinement, ScoreSearchError<E>>
where
Eval: FnMut(f64) -> Result<ScoreJet, E>,
Enclose: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
let bracket_lo = left.sample.x;
let bracket_hi = right.sample.x;
let mut left_derivative =
certify_endpoint_derivative(&mut left, bracket_lo, bracket_hi, enclosure, enclose)?;
let mut right_derivative =
certify_endpoint_derivative(&mut right, bracket_lo, bracket_hi, enclosure, enclose)?;
let curvature_sign =
strict_sign(enclosure.curvature).ok_or(ScoreSearchError::InvalidEnclosure {
lo: left.sample.x,
hi: right.sample.x,
enclosure,
})?;
let increasing = curvature_sign == StrictSign::Positive;
let expected_left_sign = if increasing {
StrictSign::Negative
} else {
StrictSign::Positive
};
let expected_right_sign = if increasing {
StrictSign::Positive
} else {
StrictSign::Negative
};
if strict_sign(left_derivative) != Some(expected_left_sign)
|| strict_sign(right_derivative) != Some(expected_right_sign)
{
return Err(ScoreSearchError::InvalidEnclosure {
lo: left.sample.x,
hi: right.sample.x,
enclosure,
});
}
let mut force_midpoint = false;
while right.sample.x - left.sample.x > resolution {
let width = right.sample.x - left.sample.x;
let midpoint = left.sample.x + 0.5 * width;
if !(midpoint > left.sample.x && midpoint < right.sample.x) {
return Err(ScoreSearchError::Unresolved {
lo: left.sample.x,
hi: right.sample.x,
requested_resolution: resolution,
enclosure,
});
}
let base = if left_derivative.max_abs() <= right_derivative.max_abs() {
left.sample
} else {
right.sample
};
let newton = if base.curvature != 0.0 {
base.x - base.derivative / base.curvature
} else {
f64::NAN
};
let guard = 0.25 * width;
let x = if !force_midpoint
&& newton.is_finite()
&& newton >= left.sample.x + guard
&& newton <= right.sample.x - guard
{
newton
} else {
midpoint
};
force_midpoint = false;
if !(x > left.sample.x && x < right.sample.x) {
return Err(ScoreSearchError::Unresolved {
lo: left.sample.x,
hi: right.sample.x,
requested_resolution: resolution,
enclosure,
});
}
let mut sample = evaluate_sample(x, evaluate)?;
let probe_x = sample.sample.x;
let mut point_derivative = certify_endpoint_derivative(
&mut sample,
left.sample.x,
right.sample.x,
enclosure,
enclose,
)?;
let mut root_curvature = enclosure.curvature;
if !is_exact_zero(point_derivative) && strict_sign(point_derivative).is_none() {
let left_cell = checked_enclosure(left.sample, sample.sample, enclose)?;
let right_cell = checked_enclosure(sample.sample, right.sample, enclose)?;
let left_probe_derivative = certify_endpoint_derivative(
&mut sample,
left.sample.x,
probe_x,
left_cell,
enclose,
)?;
let right_probe_derivative = certify_endpoint_derivative(
&mut sample,
probe_x,
right.sample.x,
right_cell,
enclose,
)?;
point_derivative = left_probe_derivative
.intersection(right_probe_derivative)
.ok_or(ScoreSearchError::DisjointEndpointEnclosure {
lo: left.sample.x,
hi: right.sample.x,
endpoint: sample.sample,
endpoint_derivative: left_probe_derivative,
enclosure: right_cell,
})?;
let child_curvature = left_cell.curvature.hull(right_cell.curvature);
root_curvature = enclosure.curvature.intersection(child_curvature).ok_or(
ScoreSearchError::InvalidEnclosure {
lo: left.sample.x,
hi: right.sample.x,
enclosure: right_cell,
},
)?;
}
if is_exact_zero(point_derivative) {
let bracket = ClosedInterval::point(x);
let score = certify_bracket_score(bracket, sample, evaluate, enclose)?;
return Ok(UniqueRootRefinement::Stationary(StationaryPoint {
sample: sample.sample,
bracket,
score,
curvature: root_curvature,
}));
}
if let Some(sign) = strict_sign(point_derivative) {
match (increasing, sign) {
(true, StrictSign::Negative) | (false, StrictSign::Positive) => {
left = sample;
left_derivative = point_derivative;
}
(true, StrictSign::Positive) | (false, StrictSign::Negative) => {
right = sample;
right_derivative = point_derivative;
}
}
continue;
}
let bracket = ClosedInterval::new(left.sample.x, right.sample.x);
let point_newton =
ClosedInterval::point(x).sub(point_derivative.div_nonzero(root_curvature));
let left_newton = ClosedInterval::point(left.sample.x)
.sub(left_derivative.div_nonzero(enclosure.curvature));
let right_newton = ClosedInterval::point(right.sample.x)
.sub(right_derivative.div_nonzero(enclosure.curvature));
let root = bracket
.intersection(point_newton)
.and_then(|root| root.intersection(left_newton))
.and_then(|root| root.intersection(right_newton))
.ok_or(ScoreSearchError::InconsistentRootEnclosure {
lo: left.sample.x,
hi: right.sample.x,
left_derivative,
right_derivative,
curvature: enclosure.curvature,
left_newton,
right_newton,
point_newton,
})?;
if root.hi - root.lo <= resolution {
let score = certify_bracket_score(root, sample, evaluate, enclose)?;
return Ok(UniqueRootRefinement::Stationary(StationaryPoint {
sample: sample.sample,
bracket: root,
score,
curvature: root_curvature,
}));
}
let point_score = certify_point(&mut sample, enclose)?.score;
if let Some((region, maximum)) = score_resolved_concave_maximum(
SearchNode { left, right },
enclosure,
sample.sample,
point_derivative,
root_curvature,
point_score,
) {
return Ok(UniqueRootRefinement::ResolutionFlat { region, maximum });
}
if root.lo > left.sample.x || root.hi < right.sample.x {
let mut new_left = if root.lo == sample.sample.x {
sample
} else {
evaluate_sample(root.lo, evaluate)?
};
let mut new_right = if root.hi == sample.sample.x {
sample
} else {
evaluate_sample(root.hi, evaluate)?
};
let contracted_enclosure =
checked_enclosure(new_left.sample, new_right.sample, enclose)?;
let point_score = certify_point(&mut sample, enclose)?.score;
let displacement = ClosedInterval::new(root.lo - x, root.hi - x);
let taylor_score = point_score
.value
.add(point_derivative.mul(displacement))
.add(root_curvature.mul(displacement.square()).scale(0.5));
let tightened_score = contracted_enclosure
.score
.value
.intersection(taylor_score)
.ok_or(ScoreSearchError::InvalidEnclosure {
lo: root.lo,
hi: root.hi,
enclosure: contracted_enclosure,
})?;
let contracted_enclosure = DerivativeEnclosure {
score: ScoreValueEnclosure {
value: tightened_score,
evaluation_error: contracted_enclosure.score.evaluation_error,
},
..contracted_enclosure
};
if let Some(region) = resolution_flat_region(
SearchNode {
left: new_left,
right: new_right,
},
contracted_enclosure,
) {
return Ok(UniqueRootRefinement::ResolutionFlat {
region,
maximum: contracted_enclosure.score,
});
}
let new_left_derivative = if new_left.sample.x == sample.sample.x {
point_derivative
} else {
certify_endpoint_derivative(
&mut new_left,
root.lo,
root.hi,
contracted_enclosure,
enclose,
)?
};
let new_right_derivative = if new_right.sample.x == sample.sample.x {
point_derivative
} else {
certify_endpoint_derivative(
&mut new_right,
root.lo,
root.hi,
contracted_enclosure,
enclose,
)?
};
let mut preserved_sign_contraction = false;
if root.lo > left.sample.x {
match strict_sign(new_left_derivative) {
Some(sign) if sign == expected_left_sign => {
left = new_left;
left_derivative = new_left_derivative;
preserved_sign_contraction = true;
}
Some(_) => {
return Err(ScoreSearchError::InvalidEnclosure {
lo: root.lo,
hi: root.hi,
enclosure: contracted_enclosure,
});
}
None => {}
}
}
if root.hi < right.sample.x {
match strict_sign(new_right_derivative) {
Some(sign) if sign == expected_right_sign => {
right = new_right;
right_derivative = new_right_derivative;
preserved_sign_contraction = true;
}
Some(_) => {
return Err(ScoreSearchError::InvalidEnclosure {
lo: root.lo,
hi: root.hi,
enclosure: contracted_enclosure,
});
}
None => {}
}
}
if preserved_sign_contraction {
continue;
}
}
if x != midpoint {
force_midpoint = true;
continue;
}
return Err(ScoreSearchError::Unresolved {
lo: left.sample.x,
hi: right.sample.x,
requested_resolution: resolution,
enclosure,
});
}
let midpoint = left.sample.x + 0.5 * (right.sample.x - left.sample.x);
let sample = if midpoint > left.sample.x && midpoint < right.sample.x {
evaluate_sample(midpoint, evaluate)?.sample
} else if left_derivative.max_abs() <= right_derivative.max_abs() {
left.sample
} else {
right.sample
};
let bracket = ClosedInterval::new(left.sample.x, right.sample.x);
let representative = SearchSample {
sample,
point_enclosure: None,
};
let score = certify_bracket_score(bracket, representative, evaluate, enclose)?;
Ok(UniqueRootRefinement::Stationary(StationaryPoint {
sample,
bracket,
score,
curvature: enclosure.curvature,
}))
}
fn isolate_shared_endpoint_root<E, Eval, Enclose>(
endpoint: SearchSample,
domain_lo: f64,
domain_hi: f64,
resolution: f64,
evaluate: &mut Eval,
enclose: &mut Enclose,
) -> Result<Option<StationaryPoint>, ScoreSearchError<E>>
where
Eval: FnMut(f64) -> Result<ScoreJet, E>,
Enclose: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
let radius = 0.5 * resolution;
let left_x = endpoint.sample.x - radius;
let mut right_x = endpoint.sample.x + radius;
if !(left_x >= domain_lo
&& right_x <= domain_hi
&& left_x < endpoint.sample.x
&& right_x > endpoint.sample.x)
{
return Ok(None);
}
while right_x - left_x > resolution {
right_x = next_down(right_x);
}
if !(right_x > endpoint.sample.x && right_x - left_x <= resolution) {
return Ok(None);
}
let mut left = evaluate_sample(left_x, evaluate)?;
let mut right = evaluate_sample(right_x, evaluate)?;
let probe_enclosure = checked_enclosure(left.sample, right.sample, enclose)?;
if probe_enclosure.curvature.contains_zero() {
return Ok(None);
}
let left_derivative =
certify_endpoint_derivative(&mut left, left_x, right_x, probe_enclosure, enclose)?;
let right_derivative =
certify_endpoint_derivative(&mut right, left_x, right_x, probe_enclosure, enclose)?;
if strict_sign(left_derivative)
.zip(strict_sign(right_derivative))
.is_some_and(|(left_sign, right_sign)| left_sign != right_sign)
{
Ok(Some(StationaryPoint {
sample: endpoint.sample,
bracket: ClosedInterval::new(left_x, right_x),
score: probe_enclosure.score,
curvature: probe_enclosure.curvature,
}))
} else {
Ok(None)
}
}
fn resolution_flat_region(
node: SearchNode,
enclosure: DerivativeEnclosure,
) -> Option<ResolutionFlatRegion> {
let score = enclosure.score;
let max_score_gap = if score.value.lo == score.value.hi {
0.0
} else {
next_up(score.value.hi - score.value.lo)
};
let score_resolution = if score.evaluation_error == 0.0 {
0.0
} else {
next_up(2.0 * score.evaluation_error)
};
if !(max_score_gap.is_finite() && score_resolution.is_finite()) {
return None;
}
let sample = if node.right.sample.value > node.left.sample.value {
node.right.sample
} else {
node.left.sample
};
(max_score_gap <= score_resolution).then_some(ResolutionFlatRegion {
sample,
bracket: ClosedInterval::new(node.left.sample.x, node.right.sample.x),
score: score.value,
max_score_gap,
score_resolution,
})
}
fn score_resolved_concave_maximum(
node: SearchNode,
enclosure: DerivativeEnclosure,
sample: ScoreSample,
point_derivative: ClosedInterval,
curvature: ClosedInterval,
point_score: ScoreValueEnclosure,
) -> Option<(ResolutionFlatRegion, ScoreValueEnclosure)> {
if !(curvature.hi < 0.0 && sample.x >= node.left.sample.x && sample.x <= node.right.sample.x) {
return None;
}
let maximum_excess = point_derivative
.square()
.scale(0.5)
.div_positive(curvature.neg())
.hi;
let comparison_resolution = point_score.evaluation_error;
if !(maximum_excess.is_finite()
&& maximum_excess >= 0.0
&& comparison_resolution.is_finite()
&& maximum_excess <= comparison_resolution)
{
return None;
}
let maximum = ClosedInterval::new(
point_score.value.lo,
enclosure
.score
.value
.hi
.min(sum_up(point_score.value.hi, maximum_excess)),
);
if !maximum.is_valid() {
return None;
}
let region = ResolutionFlatRegion {
sample,
bracket: ClosedInterval::new(node.left.sample.x, node.right.sample.x),
score: enclosure.score.value,
max_score_gap: maximum_excess,
score_resolution: comparison_resolution,
};
Some((
region,
ScoreValueEnclosure {
value: maximum,
evaluation_error: point_score
.evaluation_error
.max(enclosure.score.evaluation_error),
},
))
}
fn certified_domain_boundary(
node: &SearchNode,
derivative_sign: StrictSign,
domain_lo: f64,
domain_hi: f64,
) -> Option<(ScoreSample, ScoreOptimumLocation)> {
if node.left.sample.x != domain_lo || node.right.sample.x != domain_hi {
return None;
}
Some(match derivative_sign {
StrictSign::Positive => (node.right.sample, ScoreOptimumLocation::UpperBoundary),
StrictSign::Negative => (node.left.sample, ScoreOptimumLocation::LowerBoundary),
})
}
pub fn maximize_score_1d<E, Eval, Enclose>(
lo: f64,
hi: f64,
resolution: f64,
mut evaluate: Eval,
mut enclose: Enclose,
) -> Result<ScoreSearchResult, ScoreSearchError<E>>
where
Eval: FnMut(f64) -> Result<ScoreJet, E>,
Enclose: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
if !(lo.is_finite() && hi.is_finite() && lo <= hi && (hi - lo).is_finite()) {
return Err(ScoreSearchError::InvalidDomain { lo, hi });
}
if !(resolution.is_finite() && resolution > 0.0) {
return Err(ScoreSearchError::InvalidResolution { resolution });
}
let mut lower_boundary = evaluate_sample(lo, &mut evaluate)?;
if lo == hi {
let score =
checked_enclosure(lower_boundary.sample, lower_boundary.sample, &mut enclose)?.score;
return Ok(ScoreSearchResult {
optimum: lower_boundary.sample,
location: ScoreOptimumLocation::LowerBoundary,
lower_boundary: lower_boundary.sample,
upper_boundary: lower_boundary.sample,
stationary_points: Vec::new(),
resolution_flat_regions: Vec::new(),
dominated_regions: Vec::new(),
value_certificate: GlobalScoreCertificate {
selected: score.value,
maximum: score.value,
maximum_excess: 0.0,
comparison_resolution: 0.0,
},
});
}
let mut upper_boundary = evaluate_sample(hi, &mut evaluate)?;
let lower_boundary_score = certify_point(&mut lower_boundary, &mut enclose)?.score;
let upper_boundary_score = certify_point(&mut upper_boundary, &mut enclose)?.score;
let mut incumbent_lower = lower_boundary_score
.value
.lo
.max(upper_boundary_score.value.lo);
let (mut optimum, mut location) = if upper_boundary.sample.value > lower_boundary.sample.value {
(upper_boundary.sample, ScoreOptimumLocation::UpperBoundary)
} else {
(lower_boundary.sample, ScoreOptimumLocation::LowerBoundary)
};
let (budget, depth_bound) = subdivision_budget(lo, hi, resolution);
let mut subdivisions = 0usize;
let mut stationary_points = Vec::<StationaryPoint>::new();
let mut resolution_flat_regions = Vec::<ResolutionFlatRegion>::new();
let mut dominated_regions = Vec::<DominatedRegion>::new();
let mut terminal_maxima = vec![
TerminalScoreCandidate::point(lower_boundary.sample.x, lower_boundary_score),
TerminalScoreCandidate::point(upper_boundary.sample.x, upper_boundary_score),
];
let mut stack = vec![SearchNode {
left: lower_boundary,
right: upper_boundary,
}];
while let Some(mut node) = stack.pop() {
let mathematical_enclosure =
checked_enclosure(node.left.sample, node.right.sample, &mut enclose)?;
let enclosure = mathematical_enclosure;
if enclosure.score.value.hi < incumbent_lower {
dominated_regions.push(DominatedRegion {
bracket: ClosedInterval::new(node.left.sample.x, node.right.sample.x),
score: enclosure.score,
incumbent_lower,
});
continue;
}
if !enclosure.derivative.contains_zero() {
let derivative_sign = if enclosure.derivative.lo > 0.0 {
StrictSign::Positive
} else {
StrictSign::Negative
};
if let Some((proven_optimum, proven_location)) =
certified_domain_boundary(&node, derivative_sign, lo, hi)
{
optimum = proven_optimum;
location = proven_location;
}
let endpoint = match derivative_sign {
StrictSign::Positive => &mut node.right,
StrictSign::Negative => &mut node.left,
};
let endpoint_score = certify_point(endpoint, &mut enclose)?.score;
incumbent_lower = incumbent_lower.max(endpoint_score.value.lo);
terminal_maxima.push(TerminalScoreCandidate::point(
endpoint.sample.x,
endpoint_score,
));
continue;
}
let monotone = !enclosure.curvature.contains_zero();
if monotone {
let node_lo = node.left.sample.x;
let node_hi = node.right.sample.x;
let left_derivative = certify_endpoint_derivative(
&mut node.left,
node_lo,
node_hi,
enclosure,
&mut enclose,
)?;
let right_derivative = certify_endpoint_derivative(
&mut node.right,
node_lo,
node_hi,
enclosure,
&mut enclose,
)?;
let left_sign = strict_sign(left_derivative);
let right_sign = strict_sign(right_derivative);
let mut root_flat = None;
let stationary = if is_exact_zero(left_derivative) {
let score = certify_point(&mut node.left, &mut enclose)?.score;
Some(StationaryPoint {
sample: node.left.sample,
bracket: ClosedInterval::point(node.left.sample.x),
score,
curvature: enclosure.curvature,
})
} else if is_exact_zero(right_derivative) {
let score = certify_point(&mut node.right, &mut enclose)?.score;
Some(StationaryPoint {
sample: node.right.sample,
bracket: ClosedInterval::point(node.right.sample.x),
score,
curvature: enclosure.curvature,
})
} else if left_sign
.zip(right_sign)
.is_some_and(|(left_sign, right_sign)| left_sign != right_sign)
{
match refine_unique_root(
node.left,
node.right,
resolution,
enclosure,
&mut evaluate,
&mut enclose,
)? {
UniqueRootRefinement::Stationary(stationary) => Some(stationary),
UniqueRootRefinement::ResolutionFlat { region, maximum } => {
root_flat = Some((region, maximum));
None
}
}
} else if left_sign.is_none() {
isolate_shared_endpoint_root(
node.left,
lo,
hi,
resolution,
&mut evaluate,
&mut enclose,
)?
} else if right_sign.is_none() {
isolate_shared_endpoint_root(
node.right,
lo,
hi,
resolution,
&mut evaluate,
&mut enclose,
)?
} else {
None
};
if let Some((flat, maximum)) = root_flat {
let index = resolution_flat_regions.len();
if flat.sample.value > optimum.value {
optimum = flat.sample;
location = ScoreOptimumLocation::ResolutionFlat(index);
}
let mut representative = SearchSample {
sample: flat.sample,
point_enclosure: None,
};
let representative_score = certify_point(&mut representative, &mut enclose)?.score;
incumbent_lower = incumbent_lower.max(representative_score.value.lo);
terminal_maxima.push(TerminalScoreCandidate::region(
maximum,
representative_score
.evaluation_error
.max(maximum.evaluation_error),
));
resolution_flat_regions.push(flat);
continue;
}
if let Some(stationary) = stationary {
let mut representative = SearchSample {
sample: stationary.sample,
point_enclosure: None,
};
let representative_score = certify_point(&mut representative, &mut enclose)?.score;
incumbent_lower = incumbent_lower.max(representative_score.value.lo);
let duplicate = stationary_points
.last()
.is_some_and(|previous| previous.sample.x == stationary.sample.x);
if !duplicate {
let index = stationary_points.len();
if stationary.sample.value > optimum.value {
optimum = stationary.sample;
location = ScoreOptimumLocation::Stationary(index);
}
stationary_points.push(stationary);
}
if enclosure.curvature.hi < 0.0 {
let score = stationary.score;
terminal_maxima.push(if stationary.bracket.lo == stationary.bracket.hi {
TerminalScoreCandidate::point(stationary.sample.x, score)
} else {
TerminalScoreCandidate::region(
score,
representative_score
.evaluation_error
.max(score.evaluation_error),
)
});
} else {
let left_score = certify_point(&mut node.left, &mut enclose)?.score;
let right_score = certify_point(&mut node.right, &mut enclose)?.score;
incumbent_lower = incumbent_lower
.max(left_score.value.lo)
.max(right_score.value.lo);
terminal_maxima.push(TerminalScoreCandidate::point(
node.left.sample.x,
left_score,
));
terminal_maxima.push(TerminalScoreCandidate::point(
node.right.sample.x,
right_score,
));
}
continue;
}
if let Some((left_sign, right_sign)) = left_sign.zip(right_sign)
&& left_sign == right_sign
{
if let Some((proven_optimum, proven_location)) =
certified_domain_boundary(&node, left_sign, lo, hi)
{
optimum = proven_optimum;
location = proven_location;
}
let endpoint = match left_sign {
StrictSign::Positive => &mut node.right,
StrictSign::Negative => &mut node.left,
};
let endpoint_score = certify_point(endpoint, &mut enclose)?.score;
incumbent_lower = incumbent_lower.max(endpoint_score.value.lo);
terminal_maxima.push(TerminalScoreCandidate::point(
endpoint.sample.x,
endpoint_score,
));
continue;
}
}
if let Some(flat) = resolution_flat_region(node, mathematical_enclosure) {
let index = resolution_flat_regions.len();
if flat.sample.value > optimum.value {
optimum = flat.sample;
location = ScoreOptimumLocation::ResolutionFlat(index);
}
let mut representative = SearchSample {
sample: flat.sample,
point_enclosure: None,
};
let representative_score = certify_point(&mut representative, &mut enclose)?.score;
incumbent_lower = incumbent_lower.max(representative_score.value.lo);
terminal_maxima.push(TerminalScoreCandidate::region(
enclosure.score,
representative_score
.evaluation_error
.max(enclosure.score.evaluation_error),
));
resolution_flat_regions.push(flat);
continue;
}
let width = node.right.sample.x - node.left.sample.x;
let midpoint = node.left.sample.x + 0.5 * width;
if width <= resolution || !(midpoint > node.left.sample.x && midpoint < node.right.sample.x)
{
return Err(ScoreSearchError::Unresolved {
lo: node.left.sample.x,
hi: node.right.sample.x,
requested_resolution: resolution,
enclosure,
});
}
subdivisions += 1;
if subdivisions > budget {
return Err(ScoreSearchError::SubdivisionBudget {
lo,
hi,
cell_lo: node.left.sample.x,
cell_hi: node.right.sample.x,
requested_resolution: resolution,
subdivisions,
budget,
depth_bound,
enclosure,
});
}
let middle = evaluate_sample(midpoint, &mut evaluate)?;
stack.push(SearchNode {
left: middle,
right: node.right,
});
stack.push(SearchNode {
left: node.left,
right: middle,
});
}
let mut selected_sample = SearchSample {
sample: optimum,
point_enclosure: None,
};
let selected_score = certify_point(&mut selected_sample, &mut enclose)?.score;
let global_lower = terminal_maxima
.iter()
.map(|candidate| candidate.score.value.lo)
.fold(selected_score.value.lo, f64::max);
let global_upper = terminal_maxima
.iter()
.map(|candidate| candidate.score.value.hi)
.fold(selected_score.value.hi, f64::max);
let candidate_evaluation_error = terminal_maxima
.iter()
.filter(|candidate| candidate.point_x != Some(optimum.x))
.map(|candidate| candidate.comparison_error)
.fold(0.0_f64, f64::max);
let maximum_excess = terminal_maxima
.iter()
.filter(|candidate| candidate.point_x != Some(optimum.x))
.map(|candidate| {
if candidate.score.value.hi <= selected_score.value.lo {
0.0
} else {
next_up(candidate.score.value.hi - selected_score.value.lo)
}
})
.fold(0.0_f64, f64::max);
let comparison_resolution =
add_nonnegative_upward(selected_score.evaluation_error, candidate_evaluation_error);
Ok(ScoreSearchResult {
optimum,
location,
lower_boundary: lower_boundary.sample,
upper_boundary: upper_boundary.sample,
stationary_points,
resolution_flat_regions,
dominated_regions,
value_certificate: GlobalScoreCertificate {
selected: selected_score.value,
maximum: ClosedInterval::new(global_lower, global_upper),
maximum_excess,
comparison_resolution,
},
})
}
pub fn maximize_score_1d_value_ordered<E, Eval, Enclose>(
lo: f64,
hi: f64,
initial_resolution: f64,
mut evaluate: Eval,
mut enclose: Enclose,
) -> Result<ScoreSearchResult, ScoreSearchError<E>>
where
Eval: FnMut(f64) -> Result<ScoreJet, E>,
Enclose: FnMut(ScoreSample, ScoreSample) -> Result<DerivativeEnclosure, E>,
{
let mut resolution = initial_resolution;
let mut search = maximize_score_1d(lo, hi, resolution, &mut evaluate, &mut enclose)?;
loop {
let certificate = search.value_certificate;
if certificate.maximum_excess <= certificate.comparison_resolution {
return Ok(search);
}
let binary_refinement = 0.5 * resolution;
let value_directed_refinement = if certificate.comparison_resolution > 0.0 {
resolution * (certificate.comparison_resolution / certificate.maximum_excess)
} else {
binary_refinement
};
let next_resolution = binary_refinement.min(value_directed_refinement);
if !(next_resolution.is_finite() && next_resolution > 0.0 && next_resolution < resolution) {
return Ok(search);
}
match maximize_score_1d(lo, hi, next_resolution, &mut evaluate, &mut enclose) {
Ok(refined) => {
search = refined;
resolution = next_resolution;
}
Err(
ScoreSearchError::Unresolved { .. } | ScoreSearchError::SubdivisionBudget { .. },
) => return Ok(search),
Err(error) => return Err(error),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AffineRemlError {
EmptyModes,
EmptyResponses,
ShapeMismatch {
gram_modes: usize,
penalty_modes: usize,
projected_rhs_squared: usize,
responses: usize,
},
InvalidMode {
index: usize,
gram: f64,
penalty: f64,
},
InvalidProjectedSquare {
index: usize,
value: f64,
},
InvalidResponseEnergy {
output: usize,
value: f64,
},
ZeroLambdaResidualUnavailable {
output: usize,
},
InvalidResidualDof {
value: f64,
},
InvalidLogdetConstant {
value: f64,
},
RankMismatch {
supplied: usize,
inferred: usize,
},
InvalidLogLambda {
value: f64,
},
InvalidLogLambdaInterval {
lo: f64,
hi: f64,
},
ElementaryEnclosureUnavailable {
function: &'static str,
lo: f64,
hi: f64,
},
NonPositiveMode {
index: usize,
log_lambda: f64,
value: f64,
},
NonPositiveResidual {
output: usize,
log_lambda: f64,
value: f64,
},
NonPositiveResidualInterval {
output: usize,
lo: f64,
hi: f64,
lower_bound: f64,
},
InconsistentResidualEnclosures {
output: usize,
lo: f64,
hi: f64,
direct: ClosedInterval,
complement: ClosedInterval,
},
UnboundedScoreEvaluationError {
lo: f64,
hi: f64,
error: f64,
},
}
impl fmt::Display for AffineRemlError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::EmptyModes => write!(f, "affine REML profile has no modes"),
Self::EmptyResponses => write!(f, "affine REML profile has no responses"),
Self::ShapeMismatch {
gram_modes,
penalty_modes,
projected_rhs_squared,
responses,
} => write!(
f,
"affine REML profile shape mismatch: gram {gram_modes}, penalty {penalty_modes}, projected squares {projected_rhs_squared}, responses {responses}"
),
Self::InvalidMode {
index,
gram,
penalty,
} => write!(
f,
"affine REML mode {index} must have finite nonnegative (g,s), not both zero; got ({gram}, {penalty})"
),
Self::InvalidProjectedSquare { index, value } => write!(
f,
"affine REML projected square {index} must be finite and nonnegative, got {value}"
),
Self::InvalidResponseEnergy { output, value } => write!(
f,
"affine REML response energy {output} must be finite and nonnegative, got {value}"
),
Self::ZeroLambdaResidualUnavailable { output } => write!(
f,
"affine REML could not certify the zero-smoothing residual for response {output}"
),
Self::InvalidResidualDof { value } => {
write!(
f,
"affine REML residual dof must be finite and positive, got {value}"
)
}
Self::InvalidLogdetConstant { value } => write!(
f,
"affine REML log-determinant constant must be finite, got {value}"
),
Self::RankMismatch { supplied, inferred } => write!(
f,
"affine REML determinant rank {supplied} disagrees with {inferred} positive penalty modes"
),
Self::InvalidLogLambda { value } => {
write!(f, "affine REML invalid log lambda {value}")
}
Self::InvalidLogLambdaInterval { lo, hi } => {
write!(f, "affine REML invalid log-lambda interval [{lo}, {hi}]")
}
Self::ElementaryEnclosureUnavailable { function, lo, hi } => write!(
f,
"affine REML has no finite source-derived {function} enclosure on [{lo}, {hi}]"
),
Self::NonPositiveMode {
index,
log_lambda,
value,
} => write!(
f,
"affine REML mode {index} is nonpositive at log lambda {log_lambda}: {value}"
),
Self::NonPositiveResidual {
output,
log_lambda,
value,
} => write!(
f,
"affine REML residual {output} is nonpositive at log lambda {log_lambda}: {value}"
),
Self::NonPositiveResidualInterval {
output,
lo,
hi,
lower_bound,
} => write!(
f,
"affine REML residual {output} is not certified positive on [{lo}, {hi}] (lower bound {lower_bound})"
),
Self::InconsistentResidualEnclosures {
output,
lo,
hi,
direct,
complement,
} => write!(
f,
"affine REML residual {output} has disjoint direct {direct:?} and zero-smoothing-complement {complement:?} enclosures on [{lo}, {hi}]"
),
Self::UnboundedScoreEvaluationError { lo, hi, error } => write!(
f,
"affine REML score evaluator has no finite forward-error bound on [{lo}, {hi}] (bound {error})"
),
}
}
}
impl std::error::Error for AffineRemlError {}
#[derive(Clone, Debug)]
pub struct AffineRemlProfile<'a> {
gram_modes: &'a [f64],
penalty_modes: &'a [f64],
projected_rhs_squared: &'a [f64],
response_energy: &'a [f64],
zero_lambda_residual: Vec<ClosedInterval>,
residual_dof: f64,
logdet_constant: f64,
}
struct CertifiedCompensatedSum {
leading: f64,
correction: ClosedInterval,
}
impl CertifiedCompensatedSum {
fn new(value: f64) -> Self {
Self {
leading: value,
correction: ClosedInterval::point(0.0),
}
}
fn add_exact(&mut self, value: f64) -> bool {
let sum = self.leading + value;
if !sum.is_finite() {
return false;
}
let virtual_value = sum - self.leading;
let virtual_leading = sum - virtual_value;
let value_residual = value - virtual_value;
let leading_residual = self.leading - virtual_leading;
let error = leading_residual + value_residual;
self.leading = sum;
self.correction = self.correction.add(ClosedInterval::point(error));
self.correction.is_valid()
}
fn subtract_interval(&mut self, value: ClosedInterval) -> bool {
self.correction = self.correction.sub(value);
self.correction.is_valid()
}
fn enclosure(self) -> Option<ClosedInterval> {
let enclosure = ClosedInterval::point(self.leading).add(self.correction);
(enclosure.is_valid() && enclosure.lo.is_finite() && enclosure.hi.is_finite())
.then_some(enclosure)
}
}
fn quotient_leading_and_correction(
numerator: f64,
denominator: f64,
) -> Option<(f64, ClosedInterval)> {
if numerator == 0.0 {
return Some((0.0, ClosedInterval::point(0.0)));
}
if !(numerator.is_finite() && numerator > 0.0 && denominator.is_finite() && denominator > 0.0) {
return None;
}
let leading = numerator / denominator;
if !(leading.is_finite() && leading >= 0.0) {
return None;
}
if denominator == 1.0 {
return Some((leading, ClosedInterval::point(0.0)));
}
let fused_residual = (-leading).mul_add(denominator, numerator);
if !fused_residual.is_finite() {
return None;
}
let exact_residual = ClosedInterval::new(next_down(fused_residual), next_up(fused_residual));
let correction = exact_residual.div_positive(ClosedInterval::point(denominator));
(correction.is_valid() && correction.lo.is_finite() && correction.hi.is_finite())
.then_some((leading, correction))
}
fn certified_zero_lambda_residual(
energy: f64,
gram_modes: &[f64],
projected_squares: &[f64],
) -> Option<ClosedInterval> {
let mut residual = CertifiedCompensatedSum::new(energy);
for (&gram, &projected_square) in gram_modes.iter().zip(projected_squares) {
if gram == 0.0 || projected_square == 0.0 {
continue;
}
let (leading, correction) = quotient_leading_and_correction(projected_square, gram)?;
if !(residual.add_exact(-leading) && residual.subtract_interval(correction)) {
return None;
}
}
residual.enclosure()
}
const DETERMINANT_VALUE_OPS_PER_MODE: usize = 8;
const RESIDUAL_VALUE_OPS_PER_MODE: usize = 4;
const RESIDUAL_LOG_OPS_PER_RESPONSE: usize = 3;
const SCORE_COMBINE_OPS: usize = 4;
impl<'a> AffineRemlProfile<'a> {
pub fn new(
gram_modes: &'a [f64],
penalty_modes: &'a [f64],
projected_rhs_squared: &'a [f64],
response_energy: &'a [f64],
residual_dof: f64,
determinant_rank: usize,
logdet_constant: f64,
) -> Result<Self, AffineRemlError> {
let modes = gram_modes.len();
let responses = response_energy.len();
if modes == 0 {
return Err(AffineRemlError::EmptyModes);
}
if responses == 0 {
return Err(AffineRemlError::EmptyResponses);
}
if penalty_modes.len() != modes
|| projected_rhs_squared.len() != modes.saturating_mul(responses)
{
return Err(AffineRemlError::ShapeMismatch {
gram_modes: modes,
penalty_modes: penalty_modes.len(),
projected_rhs_squared: projected_rhs_squared.len(),
responses,
});
}
for (index, (&gram, &penalty)) in gram_modes.iter().zip(penalty_modes).enumerate() {
if !(gram.is_finite()
&& penalty.is_finite()
&& gram >= 0.0
&& penalty >= 0.0
&& (gram > 0.0 || penalty > 0.0))
{
return Err(AffineRemlError::InvalidMode {
index,
gram,
penalty,
});
}
}
for (index, &value) in projected_rhs_squared.iter().enumerate() {
if !(value.is_finite() && value >= 0.0) {
return Err(AffineRemlError::InvalidProjectedSquare { index, value });
}
}
for (output, &value) in response_energy.iter().enumerate() {
if !(value.is_finite() && value >= 0.0) {
return Err(AffineRemlError::InvalidResponseEnergy { output, value });
}
}
if !(residual_dof.is_finite() && residual_dof > 0.0) {
return Err(AffineRemlError::InvalidResidualDof {
value: residual_dof,
});
}
if !logdet_constant.is_finite() {
return Err(AffineRemlError::InvalidLogdetConstant {
value: logdet_constant,
});
}
let inferred_rank = penalty_modes.iter().filter(|&&value| value > 0.0).count();
if determinant_rank != inferred_rank {
return Err(AffineRemlError::RankMismatch {
supplied: determinant_rank,
inferred: inferred_rank,
});
}
let mut zero_lambda_residual = Vec::with_capacity(responses);
for (output, &energy) in response_energy.iter().enumerate() {
let start = output * modes;
let end = start + modes;
zero_lambda_residual.push(
certified_zero_lambda_residual(
energy,
gram_modes,
&projected_rhs_squared[start..end],
)
.ok_or(AffineRemlError::ZeroLambdaResidualUnavailable { output })?,
);
}
Ok(Self {
gram_modes,
penalty_modes,
projected_rhs_squared,
response_energy,
zero_lambda_residual,
residual_dof,
logdet_constant,
})
}
#[inline]
pub fn num_modes(&self) -> usize {
self.gram_modes.len()
}
#[inline]
pub fn num_responses(&self) -> usize {
self.response_energy.len()
}
pub fn evaluate(&self, log_lambda: f64) -> Result<ScoreJet, AffineRemlError> {
if !log_lambda.is_finite() {
return Err(AffineRemlError::InvalidLogLambda { value: log_lambda });
}
let lambda = certified_exp_representative(log_lambda)
.ok_or(AffineRemlError::InvalidLogLambda { value: log_lambda })?;
if !(lambda.is_finite() && lambda > 0.0) {
return Err(AffineRemlError::InvalidLogLambda { value: log_lambda });
}
let mut normalized_logdet = self.logdet_constant;
let mut determinant_derivative = 0.0;
let mut determinant_curvature = 0.0;
let exp_neg_log_lambda = if log_lambda >= 0.0 {
certified_exp_representative(-log_lambda)
} else {
None
};
for (index, (&gram, &penalty)) in self.gram_modes.iter().zip(self.penalty_modes).enumerate()
{
if gram == 0.0 {
normalized_logdet +=
certified_ln_value(penalty).ok_or(AffineRemlError::NonPositiveMode {
index,
log_lambda,
value: penalty,
})?;
continue;
}
let h = lambda.mul_add(penalty, gram);
if !(h.is_finite() && h > 0.0) {
return Err(AffineRemlError::NonPositiveMode {
index,
log_lambda,
value: h,
});
}
let u = lambda * penalty / h;
let determinant_complement = if penalty == 0.0 { 0.0 } else { gram / h };
let normalized_mode = if penalty == 0.0 {
certified_ln_value(gram)
} else if log_lambda >= 0.0 {
exp_neg_log_lambda
.and_then(|exp_neg_rho| certified_ln_value(penalty + gram * exp_neg_rho))
} else if gram >= penalty * lambda {
certified_ln_value(gram)
.zip(certified_ln_1p_value(penalty * lambda / gram))
.map(|(log_gram, correction)| log_gram - log_lambda + correction)
} else {
certified_ln_value(penalty)
.zip(certified_ln_1p_value(gram / (penalty * lambda)))
.map(|(log_penalty, correction)| log_penalty + correction)
}
.ok_or(AffineRemlError::NonPositiveMode {
index,
log_lambda,
value: h,
})?;
normalized_logdet += normalized_mode;
determinant_derivative -= determinant_complement;
determinant_curvature += u * determinant_complement;
}
let modes = self.num_modes();
let mut residual_log_sum = 0.0;
let mut residual_derivative_sum = 0.0;
let mut residual_curvature_sum = 0.0;
for (output, &energy) in self.response_energy.iter().enumerate() {
let mut residual = energy;
let mut first = 0.0;
let mut second = 0.0;
for i in 0..modes {
let projected_square = self.projected_rhs_squared[output * modes + i];
if projected_square == 0.0 {
continue;
}
if self.gram_modes[i] == 0.0 {
let fitted = positive_ratio_over_product(
projected_square,
self.penalty_modes[i],
lambda,
)
.ok_or(
AffineRemlError::ElementaryEnclosureUnavailable {
function: "gram-zero residual quotient",
lo: log_lambda,
hi: log_lambda,
},
)?;
residual -= fitted;
first += fitted;
second -= fitted;
continue;
}
let h = lambda.mul_add(self.penalty_modes[i], self.gram_modes[i]);
let u = lambda * self.penalty_modes[i] / h;
residual -= projected_square / h;
first += projected_square * u / h;
second += projected_square * u * (1.0 - 2.0 * u) / h;
}
if !(residual.is_finite() && residual > 0.0) {
return Err(AffineRemlError::NonPositiveResidual {
output,
log_lambda,
value: residual,
});
}
let log_derivative = first / residual;
residual_log_sum += certified_ln_value(residual / self.residual_dof).ok_or(
AffineRemlError::NonPositiveResidual {
output,
log_lambda,
value: residual,
},
)?;
residual_derivative_sum += log_derivative;
residual_curvature_sum += second / residual - log_derivative * log_derivative;
}
let outputs = self.num_responses() as f64;
Ok(ScoreJet {
value: -0.5 * (outputs * normalized_logdet + self.residual_dof * residual_log_sum),
derivative: -0.5
* (outputs * determinant_derivative + self.residual_dof * residual_derivative_sum),
curvature: -0.5
* (outputs * determinant_curvature + self.residual_dof * residual_curvature_sum),
third: 0.0,
})
}
pub fn enclose(&self, lo: f64, hi: f64) -> Result<DerivativeEnclosure, AffineRemlError> {
let (direct, direct_third) = self.enclose_direct(lo, hi)?;
if lo == hi {
return Ok(direct);
}
let centre_point = (0.5 * (lo + hi)).clamp(lo, hi);
let (centre, _) = self.enclose_direct(centre_point, centre_point)?;
let offset = ClosedInterval::new(
next_down(lo - centre_point).min(0.0),
next_up(hi - centre_point).max(0.0),
);
let curvature = centred_or(direct.curvature, centre.curvature, direct_third, offset);
let derivative = centred_or(direct.derivative, centre.derivative, curvature, offset);
let value = centred_or(direct.score.value, centre.score.value, derivative, offset);
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: direct.score.evaluation_error,
},
derivative,
curvature,
})
}
fn enclose_direct(
&self,
lo: f64,
hi: f64,
) -> Result<(DerivativeEnclosure, ClosedInterval), AffineRemlError> {
if !(lo.is_finite() && hi.is_finite() && lo <= hi) {
return Err(AffineRemlError::InvalidLogLambdaInterval { lo, hi });
}
let lambda = exp_interval(lo, hi)?;
if !(lambda.lo.is_finite() && lambda.lo > 0.0 && lambda.hi.is_finite()) {
return Err(AffineRemlError::InvalidLogLambdaInterval { lo, hi });
}
let lambda_relative_error =
certified_exp_relative_forward_error(ClosedInterval::new(lo, hi), lambda);
if !lambda_relative_error.is_finite() {
return Err(AffineRemlError::UnboundedScoreEvaluationError {
lo,
hi,
error: lambda_relative_error,
});
}
let mut normalized_logdet = ClosedInterval::point(self.logdet_constant);
let mut normalized_logdet_magnitude = self.logdet_constant.abs();
let mut normalized_logdet_error = 0.0;
let mut determinant_first = ClosedInterval::point(0.0);
let mut determinant_second = ClosedInterval::point(0.0);
let mut determinant_third = ClosedInterval::point(0.0);
for i in 0..self.num_modes() {
let (normalized_mode, normalized_mode_error) =
normalized_log_mode_enclosure(self.gram_modes[i], self.penalty_modes[i], lo, hi)?;
normalized_logdet = normalized_logdet.add(normalized_mode);
normalized_logdet_magnitude = add_nonnegative_upward(
normalized_logdet_magnitude,
add_nonnegative_upward(normalized_mode.max_abs(), normalized_mode_error),
);
normalized_logdet_error =
add_nonnegative_upward(normalized_logdet_error, normalized_mode_error);
let ranges = mode_ranges(self.gram_modes[i], self.penalty_modes[i], 0.0, lambda)?;
determinant_first = determinant_first.sub(ranges.c);
determinant_second = determinant_second.add(ranges.w);
determinant_third = determinant_third.add(ranges.determinant_third);
}
let mut residual_first_sum = ClosedInterval::point(0.0);
let mut residual_second_sum = ClosedInterval::point(0.0);
let mut residual_third_sum = ClosedInterval::point(0.0);
let mut residual_log_sum = ClosedInterval::point(0.0);
let mut residual_log_magnitude = 0.0;
let mut residual_log_error = 0.0;
let modes = self.num_modes();
for (output, &energy) in self.response_energy.iter().enumerate() {
let mut fitted_quadratic = ClosedInterval::point(0.0);
let mut smoothing_increment = ClosedInterval::point(0.0);
let mut singular_fitted = ClosedInterval::point(0.0);
let mut first = ClosedInterval::point(0.0);
let mut second = ClosedInterval::point(0.0);
let mut third = ClosedInterval::point(0.0);
let mut fitted_magnitude = energy;
for i in 0..modes {
let ranges = mode_ranges(
self.gram_modes[i],
self.penalty_modes[i],
self.projected_rhs_squared[output * modes + i],
lambda,
)?;
fitted_quadratic = fitted_quadratic.add(ranges.v);
smoothing_increment = smoothing_increment.add(ranges.smoothing_increment);
singular_fitted = singular_fitted.add(ranges.singular_fitted);
first = first.add(ranges.p);
second = second.add(ranges.q);
third = third.add(ranges.residual_third);
fitted_magnitude = add_nonnegative_upward(fitted_magnitude, ranges.v.max_abs());
}
let direct_residual = ClosedInterval::point(energy).sub(fitted_quadratic);
let complement_residual = self.zero_lambda_residual[output]
.add(smoothing_increment)
.sub(singular_fitted);
let residual = direct_residual.intersection(complement_residual).ok_or(
AffineRemlError::InconsistentResidualEnclosures {
output,
lo,
hi,
direct: direct_residual,
complement: complement_residual,
},
)?;
if !(residual.lo > 0.0 && residual.is_valid()) {
return Err(AffineRemlError::NonPositiveResidualInterval {
output,
lo,
hi,
lower_bound: residual.lo,
});
}
let first_ratio = first.div_positive(residual).nonnegative();
let second_ratio = second.div_positive(residual);
let third_ratio = third.div_positive(residual);
residual_first_sum = residual_first_sum.add(first_ratio);
residual_second_sum = residual_second_sum.add(second_ratio.sub(first_ratio.square()));
residual_third_sum = residual_third_sum.add(
third_ratio
.sub(second_ratio.mul(first_ratio).scale(3.0))
.add(first_ratio.square().mul(first_ratio).scale(2.0)),
);
let fitted_arithmetic_error = wilkinson_roundoff(
fitted_magnitude,
modes.saturating_mul(RESIDUAL_VALUE_OPS_PER_MODE),
);
let fitted_exp_error = next_up(first.max_abs() * lambda_relative_error);
let resolved_fitted_quadratic = fitted_quadratic.widen(add_nonnegative_upward(
fitted_arithmetic_error,
fitted_exp_error,
));
let resolved_residual = ClosedInterval::point(energy).sub(resolved_fitted_quadratic);
if !(resolved_residual.lo > 0.0 && resolved_residual.is_valid()) {
return Err(AffineRemlError::NonPositiveResidualInterval {
output,
lo,
hi,
lower_bound: resolved_residual.lo,
});
}
let residual_over_dof = residual.div_positive(ClosedInterval::point(self.residual_dof));
if !(residual_over_dof.lo > 0.0 && residual_over_dof.hi.is_finite()) {
return Err(AffineRemlError::ElementaryEnclosureUnavailable {
function: "ln",
lo: residual_over_dof.lo,
hi: residual_over_dof.hi,
});
}
let residual_log = residual_over_dof.ln_positive();
residual_log_sum = residual_log_sum.add(residual_log);
let residual_error = enclosure_excess(residual, resolved_residual);
let propagated_residual_error = next_up(residual_error / resolved_residual.lo);
let elementary_error = certified_log_forward_error(
residual.div_positive(ClosedInterval::point(self.residual_dof)),
);
let local_log_error = add_nonnegative_upward(
propagated_residual_error,
add_nonnegative_upward(
elementary_error,
wilkinson_roundoff(
add_nonnegative_upward(1.0, residual_log.max_abs()),
RESIDUAL_LOG_OPS_PER_RESPONSE,
),
),
);
residual_log_error = add_nonnegative_upward(residual_log_error, local_log_error);
residual_log_magnitude = add_nonnegative_upward(
residual_log_magnitude,
add_nonnegative_upward(residual_log.max_abs(), local_log_error),
);
}
let outputs = self.num_responses() as f64;
let first_bracket = determinant_first
.scale(outputs)
.add(residual_first_sum.scale(self.residual_dof));
let second_bracket = determinant_second
.scale(outputs)
.add(residual_second_sum.scale(self.residual_dof));
let third_bracket = determinant_third
.scale(outputs)
.add(residual_third_sum.scale(self.residual_dof));
let derivative = first_bracket.scale(-0.5);
let curvature = second_bracket.scale(-0.5);
let third = third_bracket.scale(-0.5);
let score_value = normalized_logdet
.scale(outputs)
.add(residual_log_sum.scale(self.residual_dof))
.scale(-0.5);
let score_magnitude = add_nonnegative_upward(
next_up(outputs * normalized_logdet_magnitude),
next_up(self.residual_dof * residual_log_magnitude),
);
normalized_logdet_error = add_nonnegative_upward(
normalized_logdet_error,
wilkinson_roundoff(normalized_logdet_magnitude, self.num_modes()),
);
residual_log_error = add_nonnegative_upward(
residual_log_error,
wilkinson_roundoff(residual_log_magnitude, self.num_responses()),
);
let final_arithmetic_error = wilkinson_roundoff(score_magnitude, SCORE_COMBINE_OPS);
let weighted_component_error = add_nonnegative_upward(
next_up(outputs * normalized_logdet_error),
next_up(self.residual_dof * residual_log_error),
);
let value_evaluation_error =
next_up(0.5 * add_nonnegative_upward(weighted_component_error, final_arithmetic_error));
if !(score_value.is_valid() && value_evaluation_error.is_finite()) {
return Err(AffineRemlError::UnboundedScoreEvaluationError {
lo,
hi,
error: value_evaluation_error,
});
}
let score = ScoreValueEnclosure {
value: score_value,
evaluation_error: value_evaluation_error,
};
Ok((
DerivativeEnclosure {
score,
derivative,
curvature,
},
third,
))
}
pub fn maximize_value_ordered(
&self,
lo: f64,
hi: f64,
initial_resolution: f64,
) -> Result<ScoreSearchResult, ScoreSearchError<AffineRemlError>> {
maximize_score_1d_value_ordered(
lo,
hi,
initial_resolution,
|x| self.evaluate(x),
|a, b| self.enclose(a.x, b.x),
)
}
}
#[derive(Clone, Copy)]
struct ModeRanges {
c: ClosedInterval,
w: ClosedInterval,
v: ClosedInterval,
smoothing_increment: ClosedInterval,
singular_fitted: ClosedInterval,
p: ClosedInterval,
q: ClosedInterval,
determinant_third: ClosedInterval,
residual_third: ClosedInterval,
}
fn normalized_log_mode_enclosure(
gram: f64,
penalty: f64,
lo: f64,
hi: f64,
) -> Result<(ClosedInterval, f64), AffineRemlError> {
if penalty == 0.0 {
let range = ClosedInterval::point(gram).ln_positive();
return Ok((
range,
certified_log_forward_error(ClosedInterval::point(gram)),
));
}
if gram == 0.0 {
let range = ClosedInterval::point(penalty).ln_positive();
return Ok((
range,
certified_log_forward_error(ClosedInterval::point(penalty)),
));
}
let at_lo = normalized_log_mode_at(gram, penalty, lo)?;
let at_hi = normalized_log_mode_at(gram, penalty, hi)?;
let range = ClosedInterval::new(at_hi.lo, at_lo.hi);
let negative_rho_abs = if lo < 0.0 { -lo } else { 0.0 };
let arithmetic_scale = add_nonnegative_upward(
add_nonnegative_upward(1.0, range.max_abs()),
next_up(2.0 * negative_rho_abs),
);
let arithmetic_error = wilkinson_roundoff(arithmetic_scale, DETERMINANT_VALUE_OPS_PER_MODE);
let mut exp_input_error = 0.0_f64;
if hi >= 0.0 {
let positive_lo = lo.max(0.0);
let exp_neg_rho = exp_interval(-hi, -positive_lo)?;
let argument_lo = ClosedInterval::point(penalty)
.add(ClosedInterval::point(gram).mul(exp_neg_rho))
.lo;
if argument_lo > 0.0 {
exp_input_error = exp_input_error.max(next_up(
gram * certified_exp_forward_error(
ClosedInterval::new(-hi, -positive_lo),
exp_neg_rho,
) / argument_lo,
));
} else {
exp_input_error = f64::INFINITY;
}
}
if lo < 0.0 {
let negative_hi = hi.min(0.0);
let exp_rho = exp_interval(lo, negative_hi)?;
if exp_rho.lo > 0.0 {
exp_input_error = exp_input_error.max(certified_exp_relative_forward_error(
ClosedInterval::new(lo, negative_hi),
exp_rho,
));
} else {
exp_input_error = f64::INFINITY;
}
}
let log_output_error =
certified_log_error_from_output(at_lo).max(certified_log_error_from_output(at_hi));
let log_gram_error = certified_log_forward_error(ClosedInterval::point(gram));
let log_penalty_error = certified_log_forward_error(ClosedInterval::point(penalty));
let log1p_error = certified_ln1p_forward_error();
let elementary_error = add_nonnegative_upward(
exp_input_error,
add_nonnegative_upward(
log_output_error,
add_nonnegative_upward(
log_gram_error,
add_nonnegative_upward(log_penalty_error, log1p_error),
),
),
);
Ok((
range,
add_nonnegative_upward(arithmetic_error, elementary_error),
))
}
fn normalized_log_mode_at(
gram: f64,
penalty: f64,
rho: f64,
) -> Result<ClosedInterval, AffineRemlError> {
if rho >= 0.0 {
let exp_neg_rho = exp_interval(-rho, -rho)?;
let argument =
ClosedInterval::point(penalty).add(ClosedInterval::point(gram).mul(exp_neg_rho));
if !(argument.lo > 0.0 && argument.hi.is_finite()) {
return Err(AffineRemlError::ElementaryEnclosureUnavailable {
function: "ln",
lo: argument.lo,
hi: argument.hi,
});
}
Ok(argument.ln_positive())
} else {
let exp_rho = exp_interval(rho, rho)?;
let argument = ClosedInterval::point(gram).add(ClosedInterval::point(penalty).mul(exp_rho));
if !(argument.lo > 0.0 && argument.hi.is_finite()) {
return Err(AffineRemlError::ElementaryEnclosureUnavailable {
function: "ln",
lo: argument.lo,
hi: argument.hi,
});
}
Ok(argument.ln_positive().sub(ClosedInterval::point(rho)))
}
}
fn exp_interval(lo: f64, hi: f64) -> Result<ClosedInterval, AffineRemlError> {
let unavailable = || AffineRemlError::ElementaryEnclosureUnavailable {
function: "exp",
lo,
hi,
};
if !(lo.is_finite() && hi.is_finite() && lo <= hi) {
return Err(unavailable());
}
let lower = certified_exp(lo).ok_or_else(unavailable)?;
let upper = certified_exp(hi).ok_or_else(unavailable)?;
let enclosure = ClosedInterval::new(lower.lo.max(0.0), upper.hi).nonnegative();
if !enclosure.is_valid() {
return Err(unavailable());
}
Ok(enclosure)
}
fn finite_nonnegative_quotient(
numerator: ClosedInterval,
denominator: ClosedInterval,
function: &'static str,
) -> Result<ClosedInterval, AffineRemlError> {
if !(numerator.is_valid()
&& numerator.lo >= 0.0
&& denominator.is_valid()
&& denominator.lo > 0.0)
{
return Err(AffineRemlError::ElementaryEnclosureUnavailable {
function,
lo: denominator.lo,
hi: denominator.hi,
});
}
let quotient = ClosedInterval::new(
quotient_down(numerator.lo, denominator.hi).max(0.0),
quotient_up(numerator.hi, denominator.lo),
);
if !(quotient.is_valid() && quotient.hi.is_finite()) {
return Err(AffineRemlError::ElementaryEnclosureUnavailable {
function,
lo: quotient.lo,
hi: quotient.hi,
});
}
Ok(quotient.nonnegative())
}
fn centred_or(
direct: ClosedInterval,
point: ClosedInterval,
slope: ClosedInterval,
offset: ClosedInterval,
) -> ClosedInterval {
if !(slope.is_valid() && slope.lo.is_finite() && slope.hi.is_finite()) {
return direct;
}
let remainder = slope.mul(offset);
if !(remainder.is_valid() && remainder.lo.is_finite() && remainder.hi.is_finite()) {
return direct;
}
let centred = point.add(remainder);
if !centred.is_valid() {
return direct;
}
direct.intersection(centred).unwrap_or(direct)
}
fn mode_ranges(
gram: f64,
penalty: f64,
projected_square: f64,
lambda: ClosedInterval,
) -> Result<ModeRanges, AffineRemlError> {
if penalty == 0.0 {
let v = ClosedInterval::point(projected_square)
.div_positive(ClosedInterval::point(gram))
.nonnegative();
return Ok(ModeRanges {
c: ClosedInterval::point(0.0),
w: ClosedInterval::point(0.0),
v,
smoothing_increment: ClosedInterval::point(0.0),
singular_fitted: ClosedInterval::point(0.0),
p: ClosedInterval::point(0.0),
q: ClosedInterval::point(0.0),
determinant_third: ClosedInterval::point(0.0),
residual_third: ClosedInterval::point(0.0),
});
}
if gram == 0.0 {
let zero = ClosedInterval::point(0.0);
if projected_square == 0.0 {
return Ok(ModeRanges {
c: zero,
w: zero,
v: zero,
smoothing_increment: zero,
singular_fitted: zero,
p: zero,
q: zero,
determinant_third: zero,
residual_third: zero,
});
}
let h = lambda.mul(ClosedInterval::point(penalty)).nonnegative();
let projected = ClosedInterval::point(projected_square);
let v = if h.lo > 0.0 {
finite_nonnegative_quotient(projected, h, "gram-zero residual quotient")?
} else {
let scaled = finite_nonnegative_quotient(
projected,
ClosedInterval::point(penalty),
"gram-zero residual quotient",
)?;
finite_nonnegative_quotient(scaled, lambda, "gram-zero residual quotient")?
};
return Ok(ModeRanges {
c: ClosedInterval::point(0.0),
w: ClosedInterval::point(0.0),
v,
smoothing_increment: zero,
singular_fitted: v,
p: v,
q: v.neg(),
determinant_third: zero,
residual_third: v,
});
}
let t = lambda
.mul(ClosedInterval::point(penalty))
.div_positive(ClosedInterval::point(gram))
.nonnegative();
let scale = ClosedInterval::point(projected_square)
.div_positive(ClosedInterval::point(gram))
.nonnegative();
let kernels = kernel_ranges(t);
Ok(ModeRanges {
c: kernels.v,
w: kernels.w,
v: scale.mul(kernels.v).nonnegative(),
smoothing_increment: scale.mul(kernels.u).nonnegative(),
singular_fitted: ClosedInterval::point(0.0),
p: scale.mul(kernels.w).nonnegative(),
q: scale.mul(kernels.k),
determinant_third: kernels.k,
residual_third: scale.mul(kernels.third),
})
}
#[derive(Clone, Copy)]
struct KernelRanges {
v: ClosedInterval,
u: ClosedInterval,
w: ClosedInterval,
k: ClosedInterval,
third: ClosedInterval,
}
fn kernel_at(t: ClosedInterval) -> KernelRanges {
let one = ClosedInterval::point(1.0);
let denom = one.add(t);
let v = one.div_positive(denom).nonnegative();
let u = t.mul(v).nonnegative();
let w = u.mul(v).nonnegative();
let k = w.mul(one.sub(t)).div_positive(denom);
let third = w
.mul(one.sub(t.scale(4.0)).add(t.square()))
.div_positive(denom.square());
KernelRanges { v, u, w, k, third }
}
fn kernel_ranges(t: ClosedInterval) -> KernelRanges {
let left = kernel_at(ClosedInterval::point(t.lo));
let right = kernel_at(ClosedInterval::point(t.hi));
let mut v = ClosedInterval::new(right.v.lo, left.v.hi).nonnegative();
let u = ClosedInterval::new(left.u.lo, right.u.hi).nonnegative();
let mut w = left.w.hull(right.w).nonnegative();
let mut k = left.k.hull(right.k);
let mut third = left.third.hull(right.third);
if t.contains(1.0) {
let critical = kernel_at(ClosedInterval::point(1.0));
w = w.hull(critical.w).nonnegative();
third = third.hull(critical.third);
}
let sqrt_three =
certified_sqrt_positive(3.0).expect("three is a finite positive square-root argument");
let critical_points = [
ClosedInterval::point(2.0).sub(sqrt_three),
ClosedInterval::point(2.0).add(sqrt_three),
];
for critical in critical_points {
if critical.hi >= t.lo && critical.lo <= t.hi {
k = k.hull(kernel_at(critical).k);
}
}
let sqrt_six =
certified_sqrt_positive(6.0).expect("six is a finite positive square-root argument");
let two_sqrt_six = sqrt_six.scale(2.0);
for critical in [
ClosedInterval::point(5.0).sub(two_sqrt_six),
ClosedInterval::point(5.0).add(two_sqrt_six),
] {
if critical.hi >= t.lo && critical.lo <= t.hi {
third = third.hull(kernel_at(critical).third);
}
}
v.lo = v.lo.max(0.0);
v.hi = v.hi.min(next_up(1.0));
KernelRanges {
v,
u,
w,
k,
third,
}
}
const LOG_SERIES_TERMS: usize = 18;
const EXP_SERIES_TERMS: usize = 18;
const EXP_RANGE_SQUARINGS: usize = 6;
fn certified_sqrt_positive(value: f64) -> Option<ClosedInterval> {
if !(value.is_finite() && value > 0.0) {
return None;
}
let guess = value.sqrt();
if !(guess.is_finite() && guess > 0.0) {
return None;
}
let mut lo = next_down(guess);
for _ in 0..8 {
if ClosedInterval::point(lo).square().hi <= value {
break;
}
lo = next_down(lo);
}
let mut hi = next_up(guess);
for _ in 0..8 {
if ClosedInterval::point(hi).square().lo >= value {
break;
}
hi = next_up(hi);
}
(ClosedInterval::point(lo).square().hi <= value
&& ClosedInterval::point(hi).square().lo >= value)
.then(|| ClosedInterval::new(lo, hi))
}
fn certified_log_from_atanh(z: ClosedInterval) -> ClosedInterval {
let z_abs = z.max_abs();
assert!(z_abs <= 1.0 / 3.0 + f64::EPSILON);
let z2 = z.square();
let mut power = z;
let mut sum = z;
for term in 1..LOG_SERIES_TERMS {
power = power.mul(z2);
sum = sum.add(power.div_positive(ClosedInterval::point((2 * term + 1) as f64)));
}
let next_power = power.mul(z2).max_abs();
let first_denominator = (2 * LOG_SERIES_TERMS + 1) as f64;
let geometric_denominator = next_down(1.0 - next_up(z_abs * z_abs));
let tail = if geometric_denominator > 0.0 {
next_up(next_up(2.0 * next_power) / next_down(first_denominator * geometric_denominator))
} else {
f64::INFINITY
};
sum.scale(2.0).widen(tail)
}
fn certified_ln_two() -> ClosedInterval {
static LN_TWO: OnceLock<ClosedInterval> = OnceLock::new();
*LN_TWO.get_or_init(|| {
let third = ClosedInterval::point(1.0).div_positive(ClosedInterval::point(3.0));
certified_log_from_atanh(third)
})
}
fn positive_binary64_parts(value: f64) -> Option<(f64, i32)> {
if !(value.is_finite() && value > 0.0) {
return None;
}
let bits = value.to_bits();
let exponent_bits = ((bits >> 52) & 0x7ff) as i32;
let fraction = bits & ((1_u64 << 52) - 1);
if exponent_bits == 0 {
let highest = 63_i32 - fraction.leading_zeros() as i32;
let normalized = fraction << (52 - highest);
let mantissa_bits = (1023_u64 << 52) | (normalized - (1_u64 << 52));
Some((f64::from_bits(mantissa_bits), highest - 1074))
} else {
let mantissa_bits = (1023_u64 << 52) | fraction;
Some((f64::from_bits(mantissa_bits), exponent_bits - 1023))
}
}
pub fn certified_ln_positive(value: f64) -> Option<ClosedInterval> {
if !(value.is_finite() && value > 0.0) {
return None;
}
if value == 1.0 {
return Some(ClosedInterval::point(0.0));
}
let (mantissa, exponent) = positive_binary64_parts(value)?;
let m = ClosedInterval::point(mantissa);
let z = m
.sub(ClosedInterval::point(1.0))
.div_positive(m.add(ClosedInterval::point(1.0)));
Some(certified_log_from_atanh(z).add(certified_ln_two().scale(exponent as f64)))
}
pub fn certified_ln_1p(value: f64) -> Option<ClosedInterval> {
if !(value.is_finite() && value > -1.0) {
return None;
}
if value == 0.0 {
return Some(ClosedInterval::point(0.0));
}
if (0.0..=1.0).contains(&value) {
let x = ClosedInterval::point(value);
let z = x.div_positive(ClosedInterval::point(2.0).add(x));
return Some(certified_log_from_atanh(z));
}
if value > 1.0 {
let reciprocal = ClosedInterval::point(1.0)
.div_positive(ClosedInterval::point(value))
.nonnegative();
let z = reciprocal
.div_positive(ClosedInterval::point(2.0).add(reciprocal))
.nonnegative();
return Some(certified_ln_positive(value)?.add(certified_log_from_atanh(z)));
}
let argument = ClosedInterval::point(1.0).add(ClosedInterval::point(value));
if !(argument.lo > 0.0) {
return None;
}
let lo = certified_ln_positive(argument.lo)?;
let hi = certified_ln_positive(argument.hi)?;
Some(ClosedInterval::new(lo.lo, hi.hi))
}
fn exact_power_of_two(exponent: i32) -> Option<f64> {
match exponent {
-1074..=-1023 => {
let bit = (exponent + 1074) as u32;
Some(f64::from_bits(1_u64 << bit))
}
-1022..=1023 => Some(f64::from_bits(((exponent + 1023) as u64) << 52)),
_ => None,
}
}
fn positive_ratio_over_product(
numerator: f64,
first_denominator: f64,
second_denominator: f64,
) -> Option<f64> {
if numerator == 0.0 {
return Some(0.0);
}
let (numerator_mantissa, numerator_exponent) = positive_binary64_parts(numerator)?;
let (first_mantissa, first_exponent) = positive_binary64_parts(first_denominator)?;
let (second_mantissa, second_exponent) = positive_binary64_parts(second_denominator)?;
let mut mantissa = numerator_mantissa / first_mantissa / second_mantissa;
let mut exponent = numerator_exponent - first_exponent - second_exponent;
if !(mantissa.is_finite() && mantissa > 0.0) {
return None;
}
while mantissa < 1.0 {
mantissa *= 2.0;
exponent -= 1;
}
while mantissa >= 2.0 {
mantissa *= 0.5;
exponent += 1;
}
if exponent < -1075 {
return Some(0.0);
}
if exponent > 1023 {
return None;
}
let value = if exponent == -1075 {
(0.5 * mantissa) * exact_power_of_two(-1074)?
} else {
mantissa * exact_power_of_two(exponent)?
};
(value.is_finite() && value >= 0.0).then_some(value)
}
pub fn certified_exp(value: f64) -> Option<ClosedInterval> {
if !value.is_finite() {
return None;
}
if value == 0.0 {
return Some(ClosedInterval::point(1.0));
}
let mut exponent = (value / std::f64::consts::LN_2).round() as i32;
exponent = exponent.clamp(-1074, 1023);
let remainder = ClosedInterval::point(value).sub(certified_ln_two().scale(exponent as f64));
if !(remainder.is_valid() && remainder.max_abs() < 4.0) {
return None;
}
let reduction = (1_u64 << EXP_RANGE_SQUARINGS) as f64;
let reduced = remainder.scale(1.0 / reduction);
if !(reduced.max_abs() < 1.0 / 16.0) {
return None;
}
let mut term = ClosedInterval::point(1.0);
let mut sum = term;
for degree in 1..=EXP_SERIES_TERMS {
term = term
.mul(reduced)
.div_positive(ClosedInterval::point(degree as f64));
sum = sum.add(term);
}
let z = reduced.max_abs();
let first_omitted = next_up(term.max_abs() * z / (EXP_SERIES_TERMS + 1) as f64);
let tail = next_up(first_omitted / next_down(1.0 - z));
let mut result = sum.widen(tail);
for _ in 0..EXP_RANGE_SQUARINGS {
result = result.square();
}
result = result.mul(ClosedInterval::point(exact_power_of_two(exponent)?));
Some(result.nonnegative())
}
#[inline]
fn certified_midpoint(interval: ClosedInterval) -> f64 {
let midpoint = interval.lo + 0.5 * (interval.hi - interval.lo);
midpoint.max(interval.lo).min(interval.hi)
}
#[inline]
pub fn certified_exp_representative(value: f64) -> Option<f64> {
certified_exp(value).map(certified_midpoint)
}
#[inline]
fn certified_ln_value(value: f64) -> Option<f64> {
certified_ln_positive(value).map(certified_midpoint)
}
#[inline]
fn certified_ln_1p_value(value: f64) -> Option<f64> {
certified_ln_1p(value).map(certified_midpoint)
}
fn interval_diameter(interval: ClosedInterval) -> f64 {
if interval.lo == interval.hi {
0.0
} else {
next_up(interval.hi - interval.lo)
}
}
fn log_series_tail_max() -> f64 {
let z = next_up(1.0 / 3.0);
let z2 = next_up(z * z);
let mut power = z;
for _ in 1..LOG_SERIES_TERMS {
power = next_up(power * z2);
}
power = next_up(power * z2);
let denominator = next_down((2 * LOG_SERIES_TERMS + 1) as f64 * next_down(1.0 - z2));
next_up(next_up(2.0 * power) / denominator)
}
fn exp_series_relative_tail_max() -> f64 {
let z = next_up(1.0 / 16.0);
let mut term = 1.0;
for degree in 1..=EXP_SERIES_TERMS {
term = next_up(next_up(term * z) / degree as f64);
}
let first_omitted = next_up(next_up(term * z) / (EXP_SERIES_TERMS + 1) as f64);
let absolute_tail = next_up(first_omitted / next_down(1.0 - z));
let mut factor =
ClosedInterval::point(1.0).add(ClosedInterval::point(next_up(2.0 * absolute_tail)));
for _ in 0..EXP_RANGE_SQUARINGS {
factor = factor.square();
}
next_up(factor.hi - 1.0).max(0.0)
}
fn certified_log_forward_error(input: ClosedInterval) -> f64 {
if !(input.lo > 0.0 && input.hi.is_finite()) {
return f64::INFINITY;
}
let exponent_abs = [input.lo, input.hi]
.into_iter()
.map(|value| {
let bits = value.to_bits();
let exponent_bits = ((bits >> 52) & 0x7ff) as i32;
if exponent_bits == 0 {
let fraction = bits & ((1_u64 << 52) - 1);
let highest = 63_i32 - fraction.leading_zeros() as i32;
(highest - 1074).unsigned_abs() as f64
} else {
(exponent_bits - 1023).unsigned_abs() as f64
}
})
.fold(0.0_f64, f64::max);
let ln_two_uncertainty = next_up(exponent_abs * interval_diameter(certified_ln_two()));
let mantissa_ops = 6 * LOG_SERIES_TERMS + 32;
let mantissa_error =
add_nonnegative_upward(wilkinson_roundoff(1.0, mantissa_ops), log_series_tail_max());
add_nonnegative_upward(ln_two_uncertainty, mantissa_error)
}
fn certified_log_error_from_output(output: ClosedInterval) -> f64 {
if !output.is_valid() {
return f64::INFINITY;
}
let exponent_abs = next_up(output.max_abs() / certified_ln_two().lo.abs()).ceil() + 1.0;
let ln_two_uncertainty = next_up(exponent_abs * interval_diameter(certified_ln_two()));
let mantissa_ops = 6 * LOG_SERIES_TERMS + 32;
add_nonnegative_upward(
ln_two_uncertainty,
add_nonnegative_upward(wilkinson_roundoff(1.0, mantissa_ops), log_series_tail_max()),
)
}
fn certified_ln1p_forward_error() -> f64 {
let operations = 6 * LOG_SERIES_TERMS + 36;
add_nonnegative_upward(wilkinson_roundoff(1.0, operations), log_series_tail_max())
}
fn certified_exp_forward_error(input: ClosedInterval, output: ClosedInterval) -> f64 {
if !(input.is_valid() && output.is_valid() && output.lo >= 0.0) {
return f64::INFINITY;
}
let exponent_abs = next_up(input.max_abs() / certified_ln_two().lo).ceil() + 1.0;
let reduction_error = next_up(exponent_abs * interval_diameter(certified_ln_two()));
if !(reduction_error < 1.0) {
return f64::INFINITY;
}
let propagated_reduction =
next_up(output.max_abs() * reduction_error / next_down(1.0 - reduction_error));
let operations = 6 * EXP_SERIES_TERMS + 4 * EXP_RANGE_SQUARINGS + 40;
let arithmetic = wilkinson_roundoff(output.max_abs(), operations);
let truncation = next_up(output.max_abs() * exp_series_relative_tail_max());
add_nonnegative_upward(
propagated_reduction,
add_nonnegative_upward(arithmetic, truncation),
)
}
fn certified_exp_relative_forward_error(input: ClosedInterval, output: ClosedInterval) -> f64 {
if !(input.is_valid() && output.is_valid() && output.lo > 0.0 && output.hi.is_finite()) {
return f64::INFINITY;
}
let exponent_abs = next_up(input.max_abs() / certified_ln_two().lo).ceil() + 1.0;
let reduction_error = next_up(exponent_abs * interval_diameter(certified_ln_two()));
if !(reduction_error < 1.0) {
return f64::INFINITY;
}
let relative_reduction = next_up(reduction_error / next_down(1.0 - reduction_error));
let operations = 6 * EXP_SERIES_TERMS + 4 * EXP_RANGE_SQUARINGS + 40;
let relative_arithmetic = wilkinson_roundoff(1.0, operations);
let relative_underflow = next_up(wilkinson_roundoff(0.0, operations) / output.lo);
add_nonnegative_upward(
relative_reduction,
add_nonnegative_upward(
relative_arithmetic,
add_nonnegative_upward(exp_series_relative_tail_max(), relative_underflow),
),
)
}
fn add_nonnegative_upward(accumulator: f64, term: f64) -> f64 {
if accumulator == f64::INFINITY || term == f64::INFINITY {
f64::INFINITY
} else if term == 0.0 {
accumulator
} else {
next_up(accumulator + term)
}
}
fn enclosure_excess(mathematical: ClosedInterval, resolved: ClosedInterval) -> f64 {
let lower = if mathematical.lo == resolved.lo {
0.0
} else {
next_up(mathematical.lo - resolved.lo)
};
let upper = if mathematical.hi == resolved.hi {
0.0
} else {
next_up(resolved.hi - mathematical.hi)
};
lower.max(upper).max(0.0)
}
fn wilkinson_roundoff(magnitude: f64, operations: usize) -> f64 {
if operations == 0 {
return 0.0;
}
if !(magnitude.is_finite() && magnitude >= 0.0) {
return f64::INFINITY;
}
let operation_count = next_up(operations as f64);
let underflow = next_up(operation_count * f64::from_bits(1));
if magnitude == 0.0 {
return underflow;
}
let unit_roundoff = 0.5 * f64::EPSILON;
let ku = next_up(operation_count * unit_roundoff);
if !(ku < 1.0) {
return f64::INFINITY;
}
let denominator = next_down(1.0 - ku);
if !(denominator > 0.0) {
return f64::INFINITY;
}
let gamma = next_up(ku / denominator);
add_nonnegative_upward(next_up(gamma * magnitude), underflow)
}
#[inline]
fn sum_down(left: f64, right: f64) -> f64 {
let value = left + right;
if sum_is_exact(left, right, value) {
value
} else {
next_down(value)
}
}
#[inline]
fn sum_up(left: f64, right: f64) -> f64 {
let value = left + right;
if sum_is_exact(left, right, value) {
value
} else {
next_up(value)
}
}
#[inline]
fn sum_is_exact(left: f64, right: f64, value: f64) -> bool {
if left == 0.0 || right == 0.0 {
return true;
}
if !(left.is_finite() && right.is_finite() && value.is_finite()) {
return value == left || value == right;
}
let virtual_right = value - left;
let virtual_left = value - virtual_right;
let right_residual = right - virtual_right;
let left_residual = left - virtual_left;
left_residual + right_residual == 0.0
}
#[inline]
fn product_is_exact(left: f64, right: f64) -> bool {
left == 0.0 || right == 0.0 || left.abs() == 1.0 || right.abs() == 1.0
}
#[inline]
fn product_down(left: f64, right: f64) -> f64 {
let value = left * right;
if product_is_exact(left, right) {
if value.is_nan() { 0.0 } else { value }
} else {
next_down(value)
}
}
#[inline]
fn product_up(left: f64, right: f64) -> f64 {
let value = left * right;
if product_is_exact(left, right) {
if value.is_nan() { 0.0 } else { value }
} else {
next_up(value)
}
}
#[inline]
fn quotient_down(numerator: f64, denominator: f64) -> f64 {
let value = numerator / denominator;
if numerator == 0.0 || denominator.abs() == 1.0 {
value
} else {
next_down(value)
}
}
#[inline]
fn quotient_up(numerator: f64, denominator: f64) -> f64 {
let value = numerator / denominator;
if numerator == 0.0 || denominator.abs() == 1.0 {
value
} else {
next_up(value)
}
}
fn next_down(value: f64) -> f64 {
if value.is_nan() || value == f64::NEG_INFINITY {
return value;
}
if value == 0.0 {
return -f64::from_bits(1);
}
let bits = value.to_bits();
f64::from_bits(if value > 0.0 { bits - 1 } else { bits + 1 })
}
fn next_up(value: f64) -> f64 {
if value.is_nan() || value == f64::INFINITY {
return value;
}
if value == 0.0 {
return f64::from_bits(1);
}
let bits = value.to_bits();
f64::from_bits(if value > 0.0 { bits + 1 } else { bits - 1 })
}
#[cfg(test)]
mod tests {
use super::*;
fn polynomial_hidden_bump_jet(x: f64) -> ScoreJet {
let p = x * (x - 0.5) * (x - 1.0);
let dp = 3.0 * x * x - 3.0 * x + 0.5;
let ddp = 6.0 * x - 3.0;
ScoreJet {
value: x + 1000.0 * p * p,
derivative: 1.0 + 2000.0 * p * dp,
curvature: 2000.0 * (dp * dp + p * ddp),
third: 2000.0 * (3.0 * dp * ddp + p * 6.0),
}
}
fn polynomial_hidden_bump_enclosure(lo: f64, hi: f64) -> DerivativeEnclosure {
let x = ClosedInterval::new(lo, hi);
let p = x
.mul(x.sub(ClosedInterval::point(0.5)))
.mul(x.sub(ClosedInterval::point(1.0)));
let dp = x
.square()
.scale(3.0)
.sub(x.scale(3.0))
.add(ClosedInterval::point(0.5));
let ddp = x.scale(6.0).sub(ClosedInterval::point(3.0));
let value = x.add(p.square().scale(1000.0));
DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: wilkinson_roundoff(value.max_abs(), 7),
},
derivative: ClosedInterval::point(1.0).add(p.mul(dp).scale(2000.0)),
curvature: dp.square().add(p.mul(ddp)).scale(2000.0),
}
}
#[test]
fn hidden_between_endpoint_and_midpoint_samples_is_found() {
let result = maximize_score_1d(
0.0,
1.0,
1.0e-9,
|x| -> Result<_, String> { Ok(polynomial_hidden_bump_jet(x)) },
|lo, hi| -> Result<_, String> { Ok(polynomial_hidden_bump_enclosure(lo.x, hi.x)) },
)
.expect("certified search");
assert_eq!(polynomial_hidden_bump_jet(0.0).derivative, 1.0);
assert_eq!(polynomial_hidden_bump_jet(0.5).derivative, 1.0);
assert_eq!(polynomial_hidden_bump_jet(1.0).derivative, 1.0);
assert!(result.optimum.x > 0.5 && result.optimum.x < 1.0);
assert!(result.optimum.value > 2.9);
assert!(
result
.stationary_points
.iter()
.any(|point| point.bracket.contains(result.optimum.x)),
"the hidden global maximizer must have a retained root certificate"
);
assert!(
result
.dominated_regions
.iter()
.all(|region| region.score.value.hi < region.incumbent_lower),
"every skipped stationary branch must carry a strict exact dominance proof"
);
}
fn quartic_jet(x: f64) -> ScoreJet {
ScoreJet {
value: -(x * x - 1.0).powi(2),
derivative: 4.0 * x - 4.0 * x * x * x,
curvature: 4.0 - 12.0 * x * x,
third: -24.0 * x,
}
}
fn quartic_enclosure(lo: f64, hi: f64) -> DerivativeEnclosure {
let x = ClosedInterval::new(lo, hi);
let shifted_square = x.square().sub(ClosedInterval::point(1.0));
let value = shifted_square.square().neg();
if lo == hi && (lo == -1.0 || lo == 0.0 || lo == 1.0) {
return DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: wilkinson_roundoff(value.max_abs(), 4),
},
derivative: ClosedInterval::point(0.0),
curvature: ClosedInterval::point(quartic_jet(lo).curvature),
};
}
DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: wilkinson_roundoff(value.max_abs(), 4),
},
derivative: x.scale(4.0).sub(x.mul(x).mul(x).scale(4.0)),
curvature: ClosedInterval::point(4.0).sub(x.square().scale(12.0)),
}
}
#[test]
fn globally_relevant_roots_are_isolated_and_dominated_structure_is_audited() {
let result = maximize_score_1d(
-2.0,
2.0,
1.0e-10,
|x| -> Result<_, String> { Ok(quartic_jet(x)) },
|lo, hi| -> Result<_, String> { Ok(quartic_enclosure(lo.x, hi.x)) },
)
.expect("certified search");
assert_eq!(
result.stationary_points.len(),
2,
"both equal global maxima must survive strict dominance"
);
for expected in [-1.0_f64, 1.0] {
let point = result
.stationary_points
.iter()
.find(|point| (point.sample.x - expected).abs() <= 1.0e-9)
.unwrap_or_else(|| panic!("missing global maximum at {expected}"));
assert!(point.bracket.hi - point.bracket.lo <= 1.0e-10);
}
assert!(
result
.dominated_regions
.iter()
.any(|region| region.bracket.contains(0.0)),
"the strictly inferior stationary minimum must remain auditable as dominated"
);
assert!((result.optimum.x.abs() - 1.0).abs() <= 1.0e-9);
}
#[test]
fn exact_dominance_prunes_an_uninformative_saturated_tail() {
let mut evaluations = 0_usize;
let result = maximize_score_1d(
-1.0,
10.0,
1.0e-9,
|x| -> Result<_, String> {
evaluations += 1;
Ok(ScoreJet {
value: 1.0 - x * x,
derivative: -2.0 * x,
curvature: -2.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let x = ClosedInterval::new(left.x, right.x);
let value = ClosedInterval::point(1.0).sub(x.square());
let root_side_cell = right.x <= 1.0;
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: 1.0e-12,
},
derivative: if root_side_cell || left.x == right.x {
x.scale(-2.0)
} else {
ClosedInterval::new(-100.0, 100.0)
},
curvature: if root_side_cell || left.x == right.x {
ClosedInterval::point(-2.0)
} else {
ClosedInterval::new(-100.0, 100.0)
},
})
},
)
.expect("the exact score incumbent must dominate the uninformative tail");
assert_eq!(result.optimum.x, 0.0);
assert!(result.value_certificate.maximum.contains(1.0));
assert!(
!result.dominated_regions.is_empty(),
"the fixture's saturated tail must be terminated by exact dominance"
);
assert!(
result
.dominated_regions
.iter()
.all(|region| region.score.value.hi < region.incumbent_lower),
"every retained dominance decision must expose its strict exact ordering"
);
assert!(
evaluations < 16,
"the low-score tail was enumerated instead of pruned ({evaluations} evaluations)"
);
}
const ROUNDED_ZERO_ABSCISSA: f64 = 1.5;
#[test]
fn a_rounded_zero_at_a_cell_endpoint_does_not_close_the_cell() {
let mut rounded_zeros = 0_usize;
let result = maximize_score_1d(
0.0,
3.0,
1.0e-9,
|x| -> Result<_, String> {
let shifted = x - 2.5;
let derivative = if x == ROUNDED_ZERO_ABSCISSA {
rounded_zeros += 1;
0.0
} else {
-2.0 * shifted
};
Ok(ScoreJet {
value: 1.0 - shifted * shifted,
derivative,
curvature: -2.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let x = ClosedInterval::new(left.x, right.x);
let shifted = x.sub(ClosedInterval::point(2.5));
let value = ClosedInterval::point(1.0).sub(shifted.square());
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: wilkinson_roundoff(value.max_abs(), 3),
},
derivative: shifted.scale(-2.0),
curvature: ClosedInterval::point(-2.0),
})
},
)
.expect("certified search");
assert!(
rounded_zeros > 0,
"fixture premise unmet: the search never evaluated x = {ROUNDED_ZERO_ABSCISSA}"
);
assert!(
(result.optimum.x - 2.5).abs() <= 1.0e-9,
"reported the maximum at x={} (value {}) instead of x=2.5",
result.optimum.x,
result.optimum.value,
);
assert!(
result.value_certificate.maximum.contains(1.0),
"the exact maximum escaped the global score certificate: {:?}",
result.value_certificate,
);
assert!(
result
.stationary_points
.iter()
.all(|point| point.sample.x != ROUNDED_ZERO_ABSCISSA),
"a derivative that rounded to zero was reported as a stationary point",
);
let root = result
.stationary_points
.iter()
.find(|point| point.bracket.contains(2.5))
.expect("the exact quadratic root must be isolated");
assert_eq!(
root.bracket,
ClosedInterval::point(2.5),
"the cancellation-free point enclosure must preserve the exact dyadic root"
);
}
#[test]
fn adjacent_cell_evidence_is_retained_when_point_derivative_is_uninformative() {
let planted = 0.7_f64;
let result = maximize_score_1d(
0.0,
1.0,
1.0e-9,
|x| -> Result<_, String> {
let shifted = x - planted;
Ok(ScoreJet {
value: 1.0 - shifted * shifted,
derivative: -2.0 * shifted,
curvature: -2.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let x = ClosedInterval::new(left.x, right.x);
let shifted = x.sub(ClosedInterval::point(planted));
let value = ClosedInterval::point(1.0).sub(shifted.square());
let interior_point = left.x == right.x && left.x > 0.0 && left.x < 1.0;
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: wilkinson_roundoff(value.max_abs(), 3),
},
derivative: if interior_point {
ClosedInterval::new(-2.0, 2.0)
} else {
shifted.scale(-2.0)
},
curvature: ClosedInterval::point(-2.0),
})
},
)
.expect("adjacent exact cell evidence must isolate the unique root");
assert!(
(result.optimum.x - planted).abs() <= 1.0e-9,
"selected {}, expected {planted}",
result.optimum.x
);
let stationary = result
.stationary_points
.iter()
.find(|point| point.bracket.contains(planted))
.expect("the planted stationary point must be certified");
assert!(stationary.bracket.hi - stationary.bracket.lo <= 1.0e-9);
}
#[test]
fn interval_newton_stationarity_is_not_preempted_by_a_resolved_score_gap() {
let planted = 0.25;
let resolution = 1.0e-9;
let mut unresolved_root_probes = 0;
let result = maximize_score_1d(
-1.0,
1.0,
resolution,
|x| -> Result<_, String> {
let shifted = x - planted;
Ok(ScoreJet {
value: 1.0 - shifted * shifted,
derivative: -2.0 * shifted,
curvature: -2.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let shifted = ClosedInterval::new(left.x, right.x)
.sub(ClosedInterval::point(planted));
let value = ClosedInterval::point(1.0).sub(shifted.square());
let derivative = shifted
.scale(-2.0)
.add(ClosedInterval::new(-1.0e-12, 1.0e-12));
if left.x == planted && right.x == planted {
unresolved_root_probes += 1;
assert!(derivative.contains_zero());
assert!(derivative.lo < derivative.hi);
}
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: 1.0e-12,
},
derivative,
curvature: ClosedInterval::point(-2.0),
})
},
)
.expect("the certified Newton image must retain the stationarity proof");
assert!(unresolved_root_probes > 0, "the ambiguous root must be probed");
let ScoreOptimumLocation::Stationary(index) = result.location else {
panic!(
"a resolved Newton root lost its stationarity proof: {:?}",
result.location
);
};
let point = result.stationary_points[index];
assert!(point.bracket.contains(planted));
assert!(point.bracket.hi - point.bracket.lo <= resolution);
assert!(point.curvature.hi < 0.0);
assert!(result.resolution_flat_regions.is_empty());
}
#[test]
fn signed_endpoint_newton_reaches_the_existing_score_resolution_floor() {
let planted = 0.8_f64;
let ambiguous_probe = 0.5_f64;
let mut ambiguous_probe_calls = 0_usize;
let result = maximize_score_1d(
0.0,
1.0,
1.0e-9,
|x| -> Result<_, String> {
let shifted = x - planted;
Ok(ScoreJet {
value: 1.0 - shifted * shifted,
derivative: -2.0 * shifted,
curvature: -2.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let x = ClosedInterval::new(left.x, right.x);
let shifted = x.sub(ClosedInterval::point(planted));
let value = ClosedInterval::point(1.0).sub(shifted.square());
let derivative = if left.x == right.x {
if left.x == ambiguous_probe {
ambiguous_probe_calls += 1;
ClosedInterval::new(-2.0, 2.0)
} else {
ClosedInterval::point(-2.0 * (left.x - planted))
}
} else {
ClosedInterval::new(-2.0, 2.0)
};
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: 0.021,
},
derivative,
curvature: ClosedInterval::new(-4.0, -1.0),
})
},
)
.expect("signed endpoint Newton images must reach a typed score-resolution proof");
assert!(
ambiguous_probe_calls > 0,
"fixture premise unmet: the cancellation-heavy midpoint was never certified"
);
let ScoreOptimumLocation::ResolutionFlat(index) = result.location else {
panic!(
"the unique root's location is below the declared information floor: {:?}",
result.location
);
};
let flat = result.resolution_flat_regions[index];
assert!(
flat.bracket.contains(planted),
"contracted flat bracket {:?} lost the unique root",
flat.bracket
);
assert!(
flat.max_score_gap <= flat.score_resolution,
"typed flat proof exceeded its existing evaluator floor: {flat:?}"
);
assert!(result.stationary_points.is_empty());
}
#[test]
fn strict_concavity_certifies_the_quintic_scan_optimum_at_score_resolution() {
let left = SearchSample {
sample: ScoreSample {
x: -12.105_374_438_144_967,
value: 134.053_351_995_058_96,
derivative: 1.0e-3,
curvature: -1.0,
third: 0.0,
},
point_enclosure: None,
};
let right = SearchSample {
sample: ScoreSample {
x: -12.104_760_848_454_575,
value: 134.054_279_259_553_65,
derivative: -1.0e-3,
curvature: -1.0,
third: 0.0,
},
point_enclosure: None,
};
let sample = ScoreSample {
x: left.sample.x + 0.5 * (right.sample.x - left.sample.x),
value: 134.053_9,
derivative: 0.0,
curvature: -1.0,
third: 0.0,
};
let evaluation_error = 3.966_754_013_333_685e-4;
let point_score = ScoreValueEnclosure {
value: ClosedInterval::point(sample.value),
evaluation_error,
};
let enclosure = DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::new(134.053_351_995_058_96, 134.054_279_259_553_65),
evaluation_error,
},
derivative: ClosedInterval::new(-1.8562e-3, 1.6607e-3),
curvature: ClosedInterval::new(-2.2666, -0.2358),
};
assert!(
resolution_flat_region(SearchNode { left, right }, enclosure).is_none(),
"fixture premise: the full score diameter exceeds pairwise evaluation error"
);
let (flat, maximum) = score_resolved_concave_maximum(
SearchNode { left, right },
enclosure,
sample,
enclosure.derivative,
enclosure.curvature,
point_score,
)
.expect("strict concavity must close the already score-resolved optimum");
assert!(flat.bracket.contains(sample.x));
assert!(flat.max_score_gap < 7.4e-6);
assert!(flat.max_score_gap <= flat.score_resolution);
assert!(
maximum.value.hi < enclosure.score.value.hi,
"the strong-concavity maximum bound must remove the loose cell-wide score tail"
);
}
#[test]
fn monotone_score_selects_exact_boundary() {
let result = maximize_score_1d(
-4.0,
9.0,
1.0e-9,
|x| -> Result<_, String> {
Ok(ScoreJet {
value: 0.3 * x,
derivative: 0.3,
curvature: 0.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let value = ClosedInterval::new(left.x, right.x).scale(0.3);
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value,
evaluation_error: wilkinson_roundoff(value.max_abs(), 1),
},
derivative: ClosedInterval::point(0.3),
curvature: ClosedInterval::point(0.0),
})
},
)
.expect("certified search");
assert_eq!(result.location, ScoreOptimumLocation::UpperBoundary);
assert_eq!(result.optimum.x, 9.0);
assert!(result.stationary_points.is_empty());
assert_eq!(
result.value_certificate.maximum_excess, 0.0,
"the exact same terminal point is not a competing uncertain value"
);
}
#[test]
fn certified_increase_selects_upper_boundary_when_rounded_values_tie() {
let result = maximize_score_1d(
-1.0,
1.0,
1.0e-9,
|_| -> Result<_, String> {
Ok(ScoreJet {
value: 0.0,
derivative: 1.0,
curvature: 0.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::new(left.x, right.x),
evaluation_error: 1.0,
},
derivative: ClosedInterval::point(1.0),
curvature: ClosedInterval::point(0.0),
})
},
)
.expect("a whole-domain positive derivative orders tied rounded endpoints");
assert_eq!(result.lower_boundary.value, result.upper_boundary.value);
assert_eq!(result.location, ScoreOptimumLocation::UpperBoundary);
assert_eq!(result.optimum.x, 1.0);
assert_eq!(result.value_certificate.maximum_excess, 0.0);
}
#[test]
fn certified_decrease_selects_lower_boundary_when_rounded_values_tie() {
let result = maximize_score_1d(
-1.0,
1.0,
1.0e-9,
|_| -> Result<_, String> {
Ok(ScoreJet {
value: 0.0,
derivative: -1.0,
curvature: 0.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::new(-right.x, -left.x),
evaluation_error: 1.0,
},
derivative: ClosedInterval::point(-1.0),
curvature: ClosedInterval::point(0.0),
})
},
)
.expect("a whole-domain negative derivative orders tied rounded endpoints");
assert_eq!(result.lower_boundary.value, result.upper_boundary.value);
assert_eq!(result.location, ScoreOptimumLocation::LowerBoundary);
assert_eq!(result.optimum.x, -1.0);
assert_eq!(result.value_certificate.maximum_excess, 0.0);
}
#[test]
fn tangential_nonmaximum_structure_is_closed_by_exact_dominance() {
let result = maximize_score_1d(
-1.0,
1.0,
1.0e-8,
|x| -> Result<_, String> {
Ok(ScoreJet {
value: x * x * x,
derivative: 3.0 * x * x,
curvature: 6.0 * x,
third: 6.0,
})
},
|lo, hi| -> Result<_, String> {
let x = ClosedInterval::new(lo.x, hi.x);
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: x.mul(x).mul(x),
evaluation_error: f64::EPSILON,
},
derivative: x.square().scale(3.0),
curvature: x.scale(6.0),
})
},
)
.expect("the inferior inflection is immaterial by exact score ordering");
assert_eq!(result.location, ScoreOptimumLocation::UpperBoundary);
assert!(
!result.dominated_regions.is_empty(),
"the search must record the exact dominance proof instead of silently dropping the cell"
);
for region in result.dominated_regions {
assert!(region.score.value.hi < region.incumbent_lower);
}
}
#[test]
fn unresolved_nonflat_cell_remains_typed() {
let error = maximize_score_1d(
0.0,
1.0e-8,
1.0e-8,
|x| -> Result<_, String> {
Ok(ScoreJet {
value: x,
derivative: 0.0,
curvature: 0.0,
third: 0.0,
})
},
|lo, hi| -> Result<_, String> {
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::new(lo.x, hi.x),
evaluation_error: 0.0,
},
derivative: ClosedInterval::new(-1.0, 1.0),
curvature: ClosedInterval::new(-1.0, 1.0),
})
},
)
.expect_err("a derivative enclosure admitting visible score motion is not flat");
assert!(matches!(error, ScoreSearchError::Unresolved { .. }));
}
#[test]
fn undecomposable_criterion_exhausts_the_budget_instead_of_enumerating_the_domain() {
let lo = 0.0;
let hi = 32.0;
let resolution = f64::EPSILON.sqrt();
let flat_error = 5.0e-4;
let (budget, depth_bound) = subdivision_budget(lo, hi, resolution);
assert_eq!(depth_bound, 31, "log2(32 / sqrt(eps)) rounds up to 31");
assert_eq!(
budget,
8 * 31 * 31,
"budget must track the 8 D^2 coefficient in subdivision_budget"
);
let error = maximize_score_1d(
lo,
hi,
resolution,
|_| -> Result<_, String> {
Ok(ScoreJet {
value: 0.0,
derivative: 0.0,
curvature: 0.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let half_width = 0.5 * (right.x - left.x);
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::new(-half_width, half_width),
evaluation_error: flat_error,
},
derivative: ClosedInterval::new(-1.0, 1.0),
curvature: ClosedInterval::new(-1.0, 1.0),
})
},
)
.expect_err("a decomposition this large must refuse, not enumerate");
let ScoreSearchError::SubdivisionBudget {
subdivisions,
budget: reported_budget,
depth_bound: reported_depth,
cell_lo,
cell_hi,
..
} = error
else {
panic!("expected a subdivision-budget refusal, got {error}");
};
assert_eq!(
subdivisions,
budget + 1,
"the budget stops the split that exceeds it"
);
assert_eq!(reported_budget, budget);
assert_eq!(reported_depth, depth_bound);
assert!(
cell_hi - cell_lo > 2.0 * flat_error,
"the reported cell must be one the search could still have split and \
had not yet certified ({cell_lo}, {cell_hi}); a narrower cell would \
mean the depth floor, not the breadth budget, was binding"
);
}
#[test]
fn a_converging_search_stays_far_under_the_subdivision_budget() {
let lo = 0.0;
let hi = 32.0;
let resolution = f64::EPSILON.sqrt();
let (budget, depth_bound) = subdivision_budget(lo, hi, resolution);
let evaluations = std::cell::Cell::new(0usize);
let result = maximize_score_1d(
lo,
hi,
resolution,
|x| -> Result<_, String> {
evaluations.set(evaluations.get() + 1);
let shifted = x - 7.0;
Ok(ScoreJet {
value: -shifted * shifted,
derivative: -2.0 * shifted,
curvature: -2.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
let x = ClosedInterval::new(left.x, right.x);
let shifted = x.sub(ClosedInterval::point(7.0));
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: shifted.square().scale(-1.0),
evaluation_error: f64::EPSILON * 1024.0,
},
derivative: shifted.scale(-2.0),
curvature: ClosedInterval::point(-2.0),
})
},
)
.expect("a strictly concave criterion is decomposable");
let ScoreOptimumLocation::Stationary(index) = result.location else {
panic!("expected the interior maximum, got {:?}", result.location);
};
let bracket = result.stationary_points[index].bracket;
assert!(
bracket.lo <= 7.0 && bracket.hi >= 7.0,
"certified bracket {bracket:?} must contain the planted maximum"
);
assert!(
evaluations.get() < budget / 8,
"a converging search used {} evaluations against budget {budget} at depth \
bound {depth_bound}; a budget within 8x of a converging search is a \
tuning parameter, not a backstop",
evaluations.get()
);
}
#[test]
fn resolution_flatness_is_exactly_value_diameter_vs_pairwise_error() {
let sample = SearchSample {
sample: ScoreSample {
x: 0.0,
value: 7.0,
derivative: 0.0,
curvature: 0.0,
third: 0.0,
},
point_enclosure: None,
};
let node = SearchNode {
left: sample,
right: SearchSample {
sample: ScoreSample {
x: 1.0,
..sample.sample
},
point_enclosure: None,
},
};
let error = 0.125;
for (upper, expected) in [(1024.25, true), (next_up(1024.25), false)] {
let enclosure = DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::new(1024.0, upper),
evaluation_error: error,
},
derivative: ClosedInterval::new(-1.0, 1.0),
curvature: ClosedInterval::new(-1.0, 1.0),
};
assert_eq!(
resolution_flat_region(node, enclosure).is_some(),
expected,
"flatness must be equivalent to outward diameter <= outward 2*value error"
);
}
}
#[test]
fn resolution_flat_cells_remain_regions_instead_of_fake_points() {
let resolution = 0.25;
let result = maximize_score_1d(
0.0,
1.0,
resolution,
|_| -> Result<_, String> {
Ok(ScoreJet {
value: 3.0,
derivative: 0.0,
curvature: 0.0,
third: 0.0,
})
},
|_, _| -> Result<_, String> {
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::point(3.0),
evaluation_error: 0.0,
},
derivative: ClosedInterval::new(-1.0, 1.0),
curvature: ClosedInterval::new(-1.0, 1.0),
})
},
)
.expect("an exactly constant score is resolution-flat");
assert_eq!(result.resolution_flat_regions.len(), 1);
assert!(
result.resolution_flat_regions[0].bracket.hi
- result.resolution_flat_regions[0].bracket.lo
> resolution,
"value resolution may close a wide cell, so callers must not reinterpret it \
as an abscissa-resolved stationary point"
);
}
#[test]
fn directed_arithmetic_preserves_cancellation_and_subnormal_error() {
assert_eq!(
ClosedInterval::point(1.0).sub(ClosedInterval::point(1.0)),
ClosedInterval::point(0.0),
"an exact structural zero must not acquire artificial uncertainty"
);
let minimum_subnormal = f64::from_bits(1);
let underflowing_product =
ClosedInterval::point(minimum_subnormal).mul(ClosedInterval::point(0.5));
assert!(
underflowing_product.lo <= 0.5 * minimum_subnormal
&& underflowing_product.hi >= 0.5 * minimum_subnormal
&& underflowing_product.lo < 0.0
&& underflowing_product.hi > 0.0,
"a nonzero exact product that rounds to zero needs additive subnormal width"
);
assert!(
wilkinson_roundoff(0.0, 1) >= minimum_subnormal,
"a zero-magnitude relative model must still charge additive underflow"
);
}
#[test]
fn certified_elementary_intervals_cover_normal_and_subnormal_lanes() {
for value in [
f64::from_bits(1),
f64::MIN_POSITIVE,
0.5,
1.0,
2.0,
f64::MAX,
] {
let enclosure = certified_ln_positive(value).expect("certified positive log");
assert!(enclosure.is_valid() && enclosure.lo.is_finite() && enclosure.hi.is_finite());
assert!(
enclosure.contains(value.ln()),
"independent platform log sanity value {} escaped {:?}",
value.ln(),
enclosure
);
}
for value in [-744.0_f64, -708.0, -1.0, 0.0, 1.0, 709.0] {
let enclosure = certified_exp(value).expect("certified exponential");
assert!(enclosure.is_valid() && enclosure.lo >= 0.0);
assert!(
enclosure.contains(value.exp()),
"independent platform exp sanity value {} escaped {:?}",
value.exp(),
enclosure
);
}
for value in [f64::from_bits(1), 1.0e-12, 0.25, 1.0] {
let enclosure = certified_ln_1p(value).expect("certified log1p");
assert!(
enclosure.contains(value.ln_1p()),
"independent platform log1p sanity value {} escaped {:?}",
value.ln_1p(),
enclosure
);
}
}
#[test]
fn exact_range_is_not_compared_to_a_separately_rounded_curvature() {
let denormal = f64::from_bits(1);
let result = maximize_score_1d(
0.0,
1.0,
1.0e-8,
|x| -> Result<_, String> {
Ok(ScoreJet {
value: x,
derivative: 1.0,
curvature: -0.0,
third: 0.0,
})
},
|left, right| -> Result<_, String> {
Ok(DerivativeEnclosure {
score: ScoreValueEnclosure {
value: ClosedInterval::new(left.x, right.x),
evaluation_error: 0.0,
},
derivative: ClosedInterval::point(1.0),
curvature: ClosedInterval::point(-denormal),
})
},
)
.expect("an exact-real enclosure need not contain a separately rounded scalar jet");
assert_eq!(result.location, ScoreOptimumLocation::UpperBoundary);
}
fn affine_fixture() -> AffineRemlProfile<'static> {
const G: &[f64] = &[2.0, 0.5, 0.0, 3.0];
const S: &[f64] = &[1.0, 0.0, 2.0, 0.25];
const Q: &[f64] = &[
0.6, 0.1, 0.02, 0.3, 0.2, 0.4, 0.01, 0.5, ];
const Y2: &[f64] = &[8.0, 10.0];
AffineRemlProfile::new(G, S, Q, Y2, 12.0, 3, 0.7).expect("valid fixture")
}
#[test]
fn affine_reml_jet_matches_test_only_differences() {
let profile = affine_fixture();
for x in [-2.0_f64, -0.4, 0.7, 2.0] {
let h = 1.0e-5;
let center = profile.evaluate(x).unwrap();
let left = profile.evaluate(x - h).unwrap();
let right = profile.evaluate(x + h).unwrap();
let derivative = (right.value - left.value) / (2.0 * h);
let curvature = (right.derivative - left.derivative) / (2.0 * h);
assert!(
(center.derivative - derivative).abs() <= 2.0e-8 * (1.0 + derivative.abs()),
"first derivative mismatch at {x}: analytic {}, difference {derivative}",
center.derivative
);
assert!(
(center.curvature - curvature).abs() <= 2.0e-8 * (1.0 + curvature.abs()),
"curvature mismatch at {x}: analytic {}, difference {curvature}",
center.curvature
);
}
}
#[test]
fn affine_reml_enclosure_contains_value_jets() {
let profile = affine_fixture();
let enclosure = profile.enclose(-2.5, 1.75).expect("enclosure");
let score = enclosure.score;
let resolved_score = score.value.widen(score.evaluation_error);
for x in [-2.5_f64, -1.7, -0.3, 0.0, 0.9, 1.75] {
let jet = profile.evaluate(x).unwrap();
let point = profile.enclose(x, x).expect("point enclosure");
assert!(
resolved_score.contains(jet.value),
"score {} at {x} outside {:?} ± {}",
jet.value,
score.value,
score.evaluation_error
);
assert!(
enclosure
.derivative
.intersection(point.derivative)
.is_some(),
"exact point gradient {:?} at {x} is disjoint from {:?}",
point.derivative,
enclosure.derivative
);
assert!(
enclosure.curvature.intersection(point.curvature).is_some(),
"exact point curvature {:?} at {x} is disjoint from {:?}",
point.curvature,
enclosure.curvature
);
}
}
#[test]
fn affine_reml_zero_smoothing_complement_retains_residual_correlation() {
const MODES: usize = 64;
let grams = [1.0; MODES];
let penalties = [1.0; MODES];
let projected = [1.0; MODES];
let energies = [MODES as f64];
let profile = AffineRemlProfile::new(
&grams,
&penalties,
&projected,
&energies,
MODES as f64,
MODES,
0.0,
)
.expect("valid cancellation fixture");
let rho = -23.025850929940457_f64; let enclosure = profile
.enclose(rho, rho)
.expect("equivalent residual forms must retain their intersection");
assert!(
enclosure.derivative.contains_zero(),
"the analytically constant profile must contain zero derivative: {:?}",
enclosure.derivative
);
assert!(
enclosure.derivative.hi - enclosure.derivative.lo < 1.0e-6,
"the residual complement must remove the independent near-one dependency: {:?}",
enclosure.derivative
);
}
#[test]
fn the_value_enclosure_never_exceeds_the_bound_its_own_derivative_certifies() {
const MODES: usize = 33;
let grams = [1.0; MODES];
let penalties = [1.0; MODES];
let projected = [1.0; MODES];
let energies = [MODES as f64];
let profile = AffineRemlProfile::new(
&grams,
&penalties,
&projected,
&energies,
MODES as f64,
MODES,
0.0,
)
.expect("valid cancellation fixture");
let centre = -12.0_f64;
let mut previous_width = f64::INFINITY;
for exponent in [-1_i32, -2, -3, -4, -5, -6] {
let half = 10.0_f64.powi(exponent);
let (a, b) = (centre - half, centre + half);
let width = b - a;
let cell = profile.enclose(a, b).expect("cell enclosure");
let point = profile.enclose(centre, centre).expect("point enclosure");
assert!(
cell.score.value.lo <= point.score.value.lo
&& point.score.value.hi <= cell.score.value.hi,
"w={width:e}: the midpoint value range {:?} escaped the cell range {:?}",
point.score.value,
cell.score.value
);
assert!(
cell.derivative.lo <= point.derivative.lo
&& point.derivative.hi <= cell.derivative.hi,
"w={width:e}: the midpoint derivative range {:?} escaped the cell range {:?}",
point.derivative,
cell.derivative
);
let value_width = cell.score.value.hi - cell.score.value.lo;
let point_width = point.score.value.hi - point.score.value.lo;
let derivative_bound = cell.derivative.hi.abs().max(cell.derivative.lo.abs());
let mean_value_bound = point_width + derivative_bound * width;
assert!(
value_width <= mean_value_bound * (1.0 + 1.0e-9),
"w={width:e}: the value range is {value_width:e} wide but this cell's own \
derivative enclosure {:?} bounds the score's movement across it by \
{mean_value_bound:e} — the natural extension is back",
cell.derivative
);
println!(
"[GATE] w={width:e} value_width={value_width:e} point_width={point_width:e} \
mvt={mean_value_bound:e} D={derivative_bound:e}"
);
assert!(
value_width <= previous_width / 50.0 || value_width <= 2.0 * point_width,
"w={width:e}: the value range fell only {previous_width:e} -> \
{value_width:e}, and it is not at the point-enclosure floor \
{point_width:e} — that is first-order behaviour"
);
previous_width = value_width;
}
}
#[test]
fn the_centred_enclosure_holds_on_degenerate_adjacent_and_extreme_cells() {
let grams = [1.0, 4.0, 1.0e-9, 2.5e7];
let penalties = [1.0, 1.0, 1.0, 1.0];
let projected = [0.5, 0.25, 1.0e-3, 3.0];
let energies = [8.0];
let profile =
AffineRemlProfile::new(&grams, &penalties, &projected, &energies, 6.0, 4, 0.25)
.expect("valid fixture");
for &x in &[-600.0_f64, -37.5, -1.0, 0.0, 2.75, 600.0] {
let Ok((direct, _)) = profile.enclose_direct(x, x) else {
continue;
};
let centred = profile.enclose(x, x).expect("a point cell must enclose");
assert_eq!(
centred, direct,
"a point cell must return the natural extension untouched at x={x}"
);
let up = next_up(x);
let Ok(cell) = profile.enclose(x, up) else {
continue;
};
let point = profile.enclose(x, x).expect("point cell");
assert!(
cell.score.value.lo <= point.score.value.lo
&& point.score.value.hi <= cell.score.value.hi,
"adjacent-float cell at {x}: point value range {:?} escaped {:?}",
point.score.value,
cell.score.value
);
assert!(
cell.derivative.lo <= point.derivative.lo
&& point.derivative.hi <= cell.derivative.hi,
"adjacent-float cell at {x}: point derivative range {:?} escaped {:?}",
point.derivative,
cell.derivative
);
assert!(
cell.score.value.is_valid() && cell.derivative.is_valid(),
"adjacent-float cell at {x} produced an invalid enclosure: {cell:?}"
);
let (wide, _) = profile.enclose_direct(x, up).expect("direct adjacent cell");
assert!(
cell.score.value.lo >= wide.score.value.lo
&& cell.score.value.hi <= wide.score.value.hi,
"the centred value range {:?} is not inside the natural extension {:?} at {x}",
cell.score.value,
wide.score.value
);
assert!(
cell.derivative.lo >= wide.derivative.lo
&& cell.derivative.hi <= wide.derivative.hi,
"the centred derivative range {:?} is not inside the natural extension {:?} at {x}",
cell.derivative,
wide.derivative
);
}
}
fn cascade_profile_parts() -> (Vec<f64>, Vec<f64>, Vec<f64>, Vec<f64>) {
let grams = vec![
0.021513523027428847, 0.023421509558465926, 0.024477791743994424,
0.03028760364561828, 0.03510108223379587, 0.040671848915996144,
0.042394860646972565, 0.044208976267946384, 0.046980397477518414,
0.051041787441650194, 0.053417305918114666, 0.05575657456312382,
0.056982691606415704, 0.059623191536431024, 0.06072593823762461,
0.061603808142128846, 0.0626306391548814, 0.06415989316153273, 0.06612727525342801,
0.07201682707299777, 0.10499606046436369, 0.12037535776467499, 0.1486138626340859,
0.1762399329554861, 0.19315924476245142, 0.26688703253550705, 0.2848266927054469,
0.33232244706214037, 0.6015439556821448, 1.1406886269841172, 1.3973782387809837,
1.8043547873076875, 2.0890420358314765,
];
let penalties = vec![1.0_f64; 33];
let projected = vec![
0.0008447602450715568, 0.004744115853417025, 0.0013711877079256205,
0.000556576229807026, 0.00032950514304538826, 0.00015869074743770514,
0.004035749350652998, 0.002408288703125203, 0.0002161132863778849,
0.0024599052556113317, 0.00028155268264135145, 9.068039769807838e-7,
0.0004390033211936947, 0.004642257342083, 5.722227645019854e-6,
0.003702111930202603, 0.003943553329808974, 0.0011808139994261783,
1.490921408482301e-5, 0.001728436851442388, 0.00040290378245105683,
0.0006710268119971442, 0.0032383572156905664, 0.00013742753101732549,
6.681227329297447e-5, 0.054339495839186305, 0.018972176651153957,
0.04535732957447296, 0.1129209190002305, 0.05428138627351111, 1.5501891913959478,
0.14151749008562448, 0.11704548115908926,
];
let energies = vec![2.7067510572921663_f64];
(grams, penalties, projected, energies)
}
#[test]
fn the_centred_form_keeps_the_natural_extension_when_the_remainder_is_not_finite() {
let direct = ClosedInterval::new(-10.0, 10.0);
let point = ClosedInterval::new(-1.0, 1.0);
let touching_zero = ClosedInterval::new(-0.5, 0.0);
let straddling_zero = ClosedInterval::new(-0.5, 0.5);
let narrowed = ClosedInterval::new(f64::NAN, 1.0).mul(straddling_zero);
assert!(
narrowed.lo.is_finite() && narrowed.hi.is_finite(),
"premise: a NaN endpoint must reduce to a finite-LOOKING range ({narrowed:?}); if \
`mul` stops dropping it this gate is about nothing"
);
let infinite = ClosedInterval::new(f64::NEG_INFINITY, f64::NEG_INFINITY)
.mul(ClosedInterval::new(-1.0, 0.0));
assert!(
infinite.lo <= 0.0 && infinite.hi.is_infinite(),
"`inf * 0` must stay sound through `product_down`'s exact-zero mapping, got \
{infinite:?}"
);
for slope in [
ClosedInterval::new(f64::NEG_INFINITY, 3.0),
ClosedInterval::new(-3.0, f64::INFINITY),
ClosedInterval::new(f64::NEG_INFINITY, f64::INFINITY),
ClosedInterval::new(f64::NEG_INFINITY, f64::NEG_INFINITY),
ClosedInterval::new(f64::NAN, 1.0),
ClosedInterval::new(1.0, f64::NAN),
] {
for offset in [touching_zero, straddling_zero, ClosedInterval::new(0.0, 0.5)] {
assert_eq!(
centred_or(direct, point, slope, offset),
direct,
"a non-finite slope {slope:?} over offset {offset:?} must leave the natural \
extension in place"
);
}
}
let tightened = centred_or(
direct,
point,
ClosedInterval::new(-2.0, 2.0),
straddling_zero,
);
assert!(
tightened.lo > direct.lo && tightened.hi < direct.hi,
"a finite remainder must still tighten: {tightened:?} against {direct:?}"
);
}
#[test]
fn the_centred_ranges_contain_the_function_at_every_interior_point() {
let (grams, penalties, projected, energies) = cascade_profile_parts();
let profile = AffineRemlProfile::new(
&grams,
&penalties,
&projected,
&energies,
33.0,
33,
9.226276711274537,
)
.expect("valid cascade profile");
let mut curvature_tightened = false;
for centre in [-20.0_f64, -12.5, -6.0, -1.679, 3.0, 11.0, 17.5] {
for exponent in [0_i32, -1, -2, -3, -4] {
let half = 10.0_f64.powi(exponent);
let (a, b) = (centre - half, centre + half);
let cell = profile.enclose(a, b).expect("cell enclosure");
let (natural, _) = profile.enclose_direct(a, b).expect("natural extension");
assert!(
cell.curvature.lo >= natural.curvature.lo
&& cell.curvature.hi <= natural.curvature.hi,
"cell [{a}, {b}]: the centred curvature {:?} is not inside the natural \
extension {:?}",
cell.curvature,
natural.curvature
);
if cell.curvature.hi - cell.curvature.lo
< 0.5 * (natural.curvature.hi - natural.curvature.lo)
{
curvature_tightened = true;
}
for step in 0..=8 {
let x = a + (b - a) * (step as f64 / 8.0);
let point = profile.enclose(x, x).expect("point enclosure");
assert!(
cell.score.value.lo <= point.score.value.lo
&& point.score.value.hi <= cell.score.value.hi,
"cell [{a}, {b}] value range {:?} does not contain the exact value at \
x={x}, {:?}",
cell.score.value,
point.score.value
);
assert!(
cell.derivative.lo <= point.derivative.lo
&& point.derivative.hi <= cell.derivative.hi,
"cell [{a}, {b}] derivative range {:?} does not contain the exact \
derivative at x={x}, {:?}",
cell.derivative,
point.derivative
);
assert!(
cell.curvature.lo <= point.curvature.lo
&& point.curvature.hi <= cell.curvature.hi,
"cell [{a}, {b}] curvature range {:?} does not contain the exact \
curvature at x={x}, {:?} — the third-derivative kernel the curvature \
is centred on is wrong",
cell.curvature,
point.curvature
);
}
}
}
assert!(
curvature_tightened,
"the centred curvature never halved the natural extension's range anywhere in this \
sweep, so the containment checks above would pass for a WRONG third-derivative \
kernel too — this gate has gone vacuous"
);
}
#[test]
fn the_located_optimum_is_enclosure_independent_and_accurate_to_the_contract() {
let grams = [1.0_f64; 3];
let penalties = [1.0_f64; 3];
let projected = [4.0 / 3.0; 3];
let energies = [10.0_f64];
let profile =
AffineRemlProfile::new(&grams, &penalties, &projected, &energies, 15.0, 3, 0.0)
.expect("valid ridge profile");
let lo = certified_ln_positive(f64::MIN_POSITIVE).expect("lo").lo;
let hi = certified_ln_positive(f64::MAX / 2.0).expect("hi").hi;
let resolution = f64::EPSILON.sqrt();
let truth = 0.6_f64;
let natural = maximize_score_1d(
lo,
hi,
resolution,
|x| profile.evaluate(x),
|a, b| profile.enclose_direct(a.x, b.x).map(|(e, _)| e),
)
.expect("the natural extension decomposes this domain");
let centred = maximize_score_1d(lo, hi, resolution, |x| profile.evaluate(x), |a, b| {
profile.enclose(a.x, b.x)
})
.expect("the centred form decomposes this domain");
assert_eq!(
natural.optimum.x, centred.optimum.x,
"the two enclosure forms located different optima ({} against {}); tightening may \
change which cells are visited but must not move the certified root",
natural.optimum.x, centred.optimum.x
);
for (label, search) in [("natural", &natural), ("centred", ¢red)] {
assert!(
matches!(search.location, ScoreOptimumLocation::Stationary(_)),
"{label}: this fixture has an interior stationary optimum, got {:?}",
search.location
);
let offset = (search.optimum.x - truth.ln()).abs();
assert!(
offset <= resolution,
"{label}: the located root is {offset:e} from the closed form in rho, outside \
the requested resolution {resolution:e} — that is a location-contract failure"
);
assert!(
offset > 0.0,
"{label}: an exactly-attained root would mean this gate has stopped measuring \
what it claims"
);
}
}
#[test]
fn zz_measure_centred_enclosure_search_cost() {
let (grams, penalties, projected, energies) = cascade_profile_parts();
let cascade = AffineRemlProfile::new(
&grams,
&penalties,
&projected,
&energies,
33.0,
33,
9.226276711274537,
)
.expect("valid cascade profile");
let full_lo = certified_ln_positive(f64::MIN_POSITIVE).expect("domain lo").lo;
let full_hi = certified_ln_positive(f64::MAX / 2.0).expect("domain hi").hi;
let cases: [(&str, f64, f64); 3] = [
("cascade/40.6-wide", -21.860900258111, 18.75853229939662),
("cascade/narrow-around-the-optimum", -3.0, 0.0),
("cascade/full-representable-domain", full_lo, full_hi),
];
for (label, lo, hi) in cases {
let profile = &cascade;
let resolution = f64::EPSILON.sqrt();
let started = std::time::Instant::now();
let natural = maximize_score_1d(
lo,
hi,
resolution,
|x| profile.evaluate(x),
|a, b| profile.enclose_direct(a.x, b.x).map(|(e, _)| e),
);
let natural_seconds = started.elapsed().as_secs_f64();
let started = std::time::Instant::now();
let centred = maximize_score_1d(
lo,
hi,
resolution,
|x| profile.evaluate(x),
|a, b| profile.enclose(a.x, b.x),
);
let centred_seconds = started.elapsed().as_secs_f64();
println!(
"#COST {label}: natural {:.4}s ({}) centred {:.4}s ({}) speedup {:.2}x",
natural_seconds,
natural.as_ref().map_or("REFUSED", |_| "ok"),
centred_seconds,
centred.as_ref().map_or("REFUSED", |_| "ok"),
natural_seconds / centred_seconds.max(f64::MIN_POSITIVE),
);
assert!(
centred.is_ok() || natural.is_err(),
"{label}: the centred oracle refused ({centred:?}) where the natural extension \
succeeded — an intersection can only tighten, so this is impossible unless the \
centred form is unsound"
);
if natural.is_ok() {
assert!(
centred_seconds <= natural_seconds * 2.5 + 1.0e-3,
"{label}: centring cost {centred_seconds:.4}s against the natural \
extension's {natural_seconds:.4}s — more than the doubled per-cell work \
can explain"
);
}
}
}
#[test]
fn the_natural_extension_cannot_decompose_a_domain_the_centred_form_certifies() {
let (grams, penalties, projected, energies) = cascade_profile_parts();
let profile = AffineRemlProfile::new(
&grams,
&penalties,
&projected,
&energies,
33.0,
33,
9.226276711274537,
)
.expect("valid cascade profile");
let (lo, hi) = (-21.860900258111_f64, 18.75853229939662);
let resolution = f64::EPSILON.sqrt();
let natural = maximize_score_1d(
lo,
hi,
resolution,
|x| profile.evaluate(x),
|a, b| profile.enclose_direct(a.x, b.x).map(|(enclosure, _)| enclosure),
);
let centred = maximize_score_1d(
lo,
hi,
resolution,
|x| profile.evaluate(x),
|a, b| profile.enclose(a.x, b.x),
);
let centred = centred.unwrap_or_else(|error| {
panic!(
"the centred enclosure must decompose this 33-mode cascade domain: {error}"
)
});
assert!(
matches!(
natural,
Err(ScoreSearchError::SubdivisionBudget { .. } | ScoreSearchError::Unresolved { .. })
),
"PREMISE LOST: the natural extension now decomposes this domain \
({natural:?}), so this fixture no longer exercises the defect and the \
comparison below proves nothing — widen the mode spread or the domain \
until it refuses again",
);
assert!(
!matches!(centred.location, ScoreOptimumLocation::ResolutionFlat(_)),
"the centred search must decide a location, got {:?}",
centred.location
);
assert!(
centred.value_certificate.maximum_excess
<= centred.value_certificate.comparison_resolution,
"the centred search's value ordering must close: excess {} against {}",
centred.value_certificate.maximum_excess,
centred.value_certificate.comparison_resolution
);
assert!(
centred.optimum.x >= lo && centred.optimum.x <= hi && centred.optimum.x.is_finite(),
"the selected log lambda must lie in the domain, got {}",
centred.optimum.x
);
}
#[test]
fn affine_reml_zero_smoothing_schur_residual_keeps_division_low_parts() {
let grams = [3.0; 3];
let penalties = [1.0; 3];
let projected = [1.0; 3];
let energies = [1.0];
let profile =
AffineRemlProfile::new(&grams, &penalties, &projected, &energies, 3.0, 3, 0.0)
.expect("valid nonrepresentable-quotient fixture");
let zero_residual = profile.zero_lambda_residual[0];
assert!(
zero_residual.contains_zero(),
"the exact identity 1 - 3*(1/3) = 0 must be retained: {zero_residual:?}"
);
assert!(
zero_residual.hi - zero_residual.lo < 1.0e-28,
"division corrections must live below ordinary binary64 cancellation scale: \
{zero_residual:?}"
);
let rho = -23.025850929940457_f64;
let enclosure = profile
.enclose(rho, rho)
.expect("the small positive smoothing residual must remain resolved");
assert!(
enclosure.derivative.contains_zero(),
"determinant and residual derivatives cancel analytically: {:?}",
enclosure.derivative
);
assert!(
enclosure.derivative.hi - enclosure.derivative.lo < 1.0e-6,
"the exact Schur residual must control the profiled derivative: {:?}",
enclosure.derivative
);
}
#[test]
fn affine_reml_saturated_tail_preserves_complement_signs() {
let profile = AffineRemlProfile::new(&[1.0], &[1.0], &[0.0], &[1.0], 4.0, 1, 0.0)
.expect("valid saturated-tail fixture");
let log_lambda = 700.0;
let jet = profile.evaluate(log_lambda).expect("point jet");
let enclosure = profile
.enclose(log_lambda, log_lambda)
.expect("point enclosure");
assert!(
jet.derivative > 0.0,
"the point derivative must preserve +0.5/(1+exp(rho)), got {}",
jet.derivative
);
assert!(
jet.curvature < 0.0,
"the point curvature must preserve its negative u*c sign, got {}",
jet.curvature
);
assert!(
enclosure.curvature.hi <= 0.0,
"the exact saturated curvature remains nonpositive: {:?}",
enclosure.curvature
);
assert!(
enclosure.derivative.lo >= 0.0,
"the exact saturated derivative remains nonnegative: {:?}",
enclosure.derivative
);
let score = enclosure.score;
assert!(score.evaluation_error.is_finite());
assert!(
score
.value
.widen(score.evaluation_error)
.contains(jet.value),
"the stable score evaluator must lie inside its exact value range plus forward error"
);
}
#[test]
fn affine_reml_extreme_domain_one_direction_encloses_and_maximizes_repeatably() {
let gram_modes = [1.0, 1.0, 1.0];
let penalty_modes = [1.0, 1.0, 1.0];
let projected_rhs_squared = [4.0 / 3.0, 4.0 / 3.0, 4.0 / 3.0];
let response_energy = [10.0];
let profile = AffineRemlProfile::new(
&gram_modes,
&penalty_modes,
&projected_rhs_squared,
&response_energy,
15.0,
3,
0.0,
)
.expect("valid normalized one-direction ridge profile");
let rho_lo = certified_ln_positive(f64::MIN_POSITIVE)
.expect("finite-domain lower log bound")
.lo;
let rho_hi = certified_ln_positive(f64::MAX / 2.0)
.expect("finite-domain upper log bound")
.hi;
let whole_domain = profile
.enclose(rho_lo, rho_hi)
.expect("scale-safe relative exp error keeps the full-domain residual finite");
assert!(
whole_domain.score.value.is_valid()
&& whole_domain.score.value.lo.is_finite()
&& whole_domain.score.value.hi.is_finite()
);
assert!(whole_domain.score.evaluation_error.is_finite());
assert!(whole_domain.derivative.contains_zero());
let resolution = f64::EPSILON.sqrt();
let first = profile
.maximize_value_ordered(rho_lo, rho_hi, resolution)
.expect("finite subdivision must certify the planted stationary optimum");
let repeated = profile
.maximize_value_ordered(rho_lo, rho_hi, resolution)
.expect("the same exact search must be repeatable");
assert_eq!(first, repeated);
let ScoreOptimumLocation::Stationary(index) = first.location else {
panic!(
"the planted one-direction optimum must be stationary, got {:?}",
first.location
);
};
let stationary = first
.stationary_points
.get(index)
.expect("stationary result index");
let expected = certified_ln_positive(0.6).expect("analytic stationary log");
assert!(
stationary.bracket.lo <= expected.lo && stationary.bracket.hi >= expected.hi,
"certified bracket {:?} must contain analytic log(0.6) {:?}",
stationary.bracket,
expected
);
assert!(
first.value_certificate.maximum_excess <= first.value_certificate.comparison_resolution,
"an isolated stationary root is not yet a globally ordered score candidate: \
maximum excess {}, comparison resolution {}, bracket {:?}",
first.value_certificate.maximum_excess,
first.value_certificate.comparison_resolution,
stationary.bracket,
);
}
#[test]
fn affine_reml_gram_zero_subnormal_zero_projection_is_structural() {
let minimum_subnormal = f64::from_bits(1);
let log_lambda = -740.0;
let lambda = exp_interval(log_lambda, log_lambda)
.expect("the fixture needs a certified subnormal lambda");
assert!(lambda.lo > 0.0 && lambda.hi < f64::MIN_POSITIVE);
let raw_h = lambda.mul(ClosedInterval::point(minimum_subnormal));
assert!(
raw_h.lo < 0.0 && raw_h.hi > 0.0,
"the raw outward product must cross rounded zero: {raw_h:?}"
);
let h = raw_h.nonnegative();
assert_eq!(
h.lo, 0.0,
"known nonnegative product must clamp its outward lower bound to zero"
);
let ranges = mode_ranges(0.0, minimum_subnormal, 0.0, lambda)
.expect("the zero projection cancels before any residual division");
assert_eq!(ranges.c, ClosedInterval::point(0.0));
assert_eq!(ranges.w, ClosedInterval::point(0.0));
assert_eq!(ranges.v, ClosedInterval::point(0.0));
assert_eq!(ranges.p, ClosedInterval::point(0.0));
assert_eq!(ranges.q, ClosedInterval::point(0.0));
let gram_modes = [0.0];
let penalty_modes = [minimum_subnormal];
let projected_rhs_squared = [0.0];
let response_energy = [1.0];
let profile = AffineRemlProfile::new(
&gram_modes,
&penalty_modes,
&projected_rhs_squared,
&response_energy,
1.0,
1,
0.0,
)
.expect("valid gram-zero structural fixture");
let jet = profile
.evaluate(log_lambda)
.expect("normalized determinant and zero residual projection stay finite");
let enclosure = profile
.enclose(log_lambda, log_lambda)
.expect("the proof path must not divide by a zero-containing h interval");
assert_eq!(jet.derivative, 0.0);
assert_eq!(jet.curvature, 0.0);
assert!(is_exact_zero(enclosure.derivative));
assert!(is_exact_zero(enclosure.curvature));
assert!(
enclosure
.score
.value
.widen(enclosure.score.evaluation_error)
.contains(jet.value)
);
}
#[test]
fn affine_reml_gram_zero_subnormal_nonzero_projection_stays_finite() {
let minimum_subnormal = f64::from_bits(1);
let log_lambda = -740.0;
let lambda = exp_interval(log_lambda, log_lambda)
.expect("the fixture needs a certified subnormal lambda");
let penalty = 0.01;
let h = lambda.mul(ClosedInterval::point(penalty)).nonnegative();
assert_eq!(
h.lo, 0.0,
"the fixture must enter the structural quotient path"
);
let ranges = mode_ranges(0.0, penalty, minimum_subnormal, lambda)
.expect("the scaled quotient has a finite representable range");
assert_eq!(ranges.c, ClosedInterval::point(0.0));
assert_eq!(ranges.w, ClosedInterval::point(0.0));
assert!(ranges.v.lo > 0.0 && ranges.v.hi.is_finite());
assert_eq!(ranges.p, ranges.v);
assert_eq!(ranges.q, ranges.v.neg());
let gram_modes = [0.0];
let penalty_modes = [penalty];
let projected_rhs_squared = [minimum_subnormal];
let response_energy = [10.0];
let profile = AffineRemlProfile::new(
&gram_modes,
&penalty_modes,
&projected_rhs_squared,
&response_energy,
1.0,
1,
0.0,
)
.expect("valid gram-zero finite-ratio fixture");
let jet = profile
.evaluate(log_lambda)
.expect("the point ratio must avoid the underflowing product");
let enclosure = profile
.enclose(log_lambda, log_lambda)
.expect("the interval ratio must remain finite without a reciprocal overflow");
assert!(
enclosure
.score
.value
.widen(enclosure.score.evaluation_error)
.contains(jet.value)
);
}
#[test]
fn affine_reml_gram_zero_unrepresentable_projection_is_typed() {
let minimum_subnormal = f64::from_bits(1);
let log_lambda = -740.0;
let gram_modes = [0.0];
let penalty_modes = [minimum_subnormal];
let projected_rhs_squared = [1.0];
let response_energy = [10.0];
let profile = AffineRemlProfile::new(
&gram_modes,
&penalty_modes,
&projected_rhs_squared,
&response_energy,
1.0,
1,
0.0,
)
.expect("valid gram-zero refusal fixture");
assert!(matches!(
profile.evaluate(log_lambda),
Err(AffineRemlError::ElementaryEnclosureUnavailable {
function: "gram-zero residual quotient",
..
})
));
assert!(matches!(
profile.enclose(log_lambda, log_lambda),
Err(AffineRemlError::ElementaryEnclosureUnavailable {
function: "gram-zero residual quotient",
..
})
));
}
#[test]
fn affine_reml_rejects_nonpositive_profile_residual() {
let profile = AffineRemlProfile::new(&[1.0], &[1.0], &[2.0], &[1.0], 4.0, 1, 0.0)
.expect("statically valid");
assert!(matches!(
profile.evaluate(-2.0),
Err(AffineRemlError::NonPositiveResidual { .. })
));
}
}