1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! Precision-aware numeric control helpers.
use molrs::types::F;
/// Default quadratic-penalty scale (`scale2`) applied when no caller override
/// is supplied — the packer seeds [`PackContext`](crate::PackContext) with it,
/// and post-pack validation scores penalties on the same scale.
pub(crate) const DEFAULT_SCALE2: F = 0.01;
#[derive(Clone, Copy)]
pub(crate) struct NumericControls {
pub(crate) steabs: F,
pub(crate) sterel: F,
pub(crate) epsabs: F,
pub(crate) epsrel: F,
}
#[inline]
pub(crate) fn numeric_controls() -> NumericControls {
// Packmol calibrates these constants for double precision, which is the
// active precision here (`F = molrs::types::F = f64`). The `.max(eps)`
// floors are a defensive lower bound on each finite-difference / "same
// point" threshold; under f64 they are no-ops (every literal already sits
// well above `f64::EPSILON`), but they keep the thresholds meaningful if
// `F` is ever narrowed.
let eps = F::EPSILON;
NumericControls {
steabs: (1.0e-10 as F).max(eps),
sterel: (1.0e-7 as F).max(eps.sqrt()),
epsabs: (1.0e-20 as F).max(eps * eps),
epsrel: (1.0e-10 as F).max(eps),
}
}
#[inline]
pub(crate) fn objective_small_floor() -> F {
(1.0e-10 as F).max(F::EPSILON)
}
#[inline]
pub(crate) fn residual_small_floor() -> F {
(1.0e-10 as F).max(F::EPSILON)
}
#[inline]
pub(crate) fn near_zero_norm_floor() -> F {
F::EPSILON.sqrt()
}
#[inline]
pub(crate) fn positive_norm_floor() -> F {
F::MIN_POSITIVE
}