pub struct SpatialLogKappaCoords {
pub values: Array1<f64>,
pub dims_per_term: Vec<usize>,
}Fields§
§values: Array1<f64>Flattened ψ values. For isotropic terms, one entry per term. For anisotropic terms, d entries per term (one ψ_a per axis).
dims_per_term: Vec<usize>Dimensionality of each term: 1 for isotropic, d for anisotropic.
Implementations§
Source§impl SpatialLogKappaCoords
impl SpatialLogKappaCoords
Sourcepub fn new_with_dims(values: Array1<f64>, dims_per_term: Vec<usize>) -> Self
pub fn new_with_dims(values: Array1<f64>, dims_per_term: Vec<usize>) -> Self
Construct from an explicit dims layout plus values.
Sourcepub fn from_length_scales(
spec: &TermCollectionSpec,
term_indices: &[usize],
options: &SpatialLengthScaleOptimizationOptions,
) -> Self
pub fn from_length_scales( spec: &TermCollectionSpec, term_indices: &[usize], options: &SpatialLengthScaleOptimizationOptions, ) -> Self
Isotropic initialization (backward-compatible path).
Sourcepub fn from_length_scales_aniso(
spec: &TermCollectionSpec,
term_indices: &[usize],
options: &SpatialLengthScaleOptimizationOptions,
) -> Self
pub fn from_length_scales_aniso( spec: &TermCollectionSpec, term_indices: &[usize], options: &SpatialLengthScaleOptimizationOptions, ) -> Self
Anisotropic-aware initialization.
Initialization strategy (per math team recommendation): standardize the knot cloud axiswise, then run the existing isotropic κ initializer in the standardized space. This reuses the trusted isotropic initializer and gives initial η_a = −ln(σ_a) + mean(ln(σ_a)), which satisfies Ση_a = 0 by construction.
For each term, checks whether it has aniso_log_scales set on its basis spec.
- If isotropic (no aniso_log_scales, or 1-D): 1 entry = −ln(length_scale).
- If anisotropic with a scalar length scale: d entries, one ψ_a per axis.
Initialized as ψ_a = −ln(length_scale) + η_a where η_a are the existing
aniso_log_scales (which sum to zero). Multi-dimensional terms without
explicit anisotropy stay scalar here so the seed dimensionality matches
spatial_dims_per_term. - If pure Duchon anisotropic: d - 1 free entries store the leading η_a values directly; the final axis is reconstructed to keep Ση_a = 0.
Sourcepub fn lower_bounds_from_data(
data: ArrayView2<'_, f64>,
spec: &TermCollectionSpec,
term_indices: &[usize],
options: &SpatialLengthScaleOptimizationOptions,
) -> Self
pub fn lower_bounds_from_data( data: ArrayView2<'_, f64>, spec: &TermCollectionSpec, term_indices: &[usize], options: &SpatialLengthScaleOptimizationOptions, ) -> Self
Isotropic lower bounds derived from per-term data geometry.
Each entry gets the ψ_lo bound returned by spatial_term_psi_bounds
for the corresponding term, intersected with the options window.
Sourcepub fn upper_bounds_from_data(
data: ArrayView2<'_, f64>,
spec: &TermCollectionSpec,
term_indices: &[usize],
options: &SpatialLengthScaleOptimizationOptions,
) -> Self
pub fn upper_bounds_from_data( data: ArrayView2<'_, f64>, spec: &TermCollectionSpec, term_indices: &[usize], options: &SpatialLengthScaleOptimizationOptions, ) -> Self
Isotropic upper bounds derived from per-term data geometry.
Sourcepub fn lower_bounds_aniso_from_data(
data: ArrayView2<'_, f64>,
spec: &TermCollectionSpec,
term_indices: &[usize],
dims_per_term: &[usize],
options: &SpatialLengthScaleOptimizationOptions,
) -> Self
pub fn lower_bounds_aniso_from_data( data: ArrayView2<'_, f64>, spec: &TermCollectionSpec, term_indices: &[usize], dims_per_term: &[usize], options: &SpatialLengthScaleOptimizationOptions, ) -> Self
Anisotropic-aware lower bounds derived from per-term data geometry.
For hybrid anisotropic terms the scalar ψ_lo bound applies to the
mean ψ̄, not directly to every raw axis coordinate ψ_a = ψ̄ + η_a.
Shift each axis by the current centered η_a so projecting/clamping
the seed moves only the global scale direction and does not silently
shrink anisotropy that is already consistent with the current
length_scale.
Pure Duchon anisotropy is structurally different: its stored
coordinates are (d-1) free η_a values representing log axis-scale
ratios, NOT log-κ. For those terms the κ-range geometry bound is
over-restrictive (η_a = ±5 is normal, but that corresponds to 7+
orders of magnitude in κ-space and would be rejected by the data
window). Fall back to the options window [-ln(max_ls), -ln(min_ls)]
for those coordinates — that’s the same bound the pre-data-geometry
code used, which is calibrated to allow legitimate anisotropy.
Sourcepub fn upper_bounds_aniso_from_data(
data: ArrayView2<'_, f64>,
spec: &TermCollectionSpec,
term_indices: &[usize],
dims_per_term: &[usize],
options: &SpatialLengthScaleOptimizationOptions,
) -> Self
pub fn upper_bounds_aniso_from_data( data: ArrayView2<'_, f64>, spec: &TermCollectionSpec, term_indices: &[usize], dims_per_term: &[usize], options: &SpatialLengthScaleOptimizationOptions, ) -> Self
Anisotropic-aware upper bounds derived from per-term data geometry.
See lower_bounds_aniso_from_data for the hybrid-aniso offsetting and
pure-Duchon dispatch rationale.
Sourcepub fn reseed_from_data(
self,
data: ArrayView2<'_, f64>,
spec: &TermCollectionSpec,
term_indices: &[usize],
options: &SpatialLengthScaleOptimizationOptions,
) -> Self
pub fn reseed_from_data( self, data: ArrayView2<'_, f64>, spec: &TermCollectionSpec, term_indices: &[usize], options: &SpatialLengthScaleOptimizationOptions, ) -> Self
Rewrite any ψ entries whose originating term lacks an explicit
length_scale so they sit at the midpoint of the per-term data-derived
ψ window. Used so the outer optimizer starts inside the physically
meaningful region instead of at an arbitrary options.max_length_scale
derived seed. For terms with an explicit length_scale, the user’s
choice is respected. Anisotropy offsets η_a (those stored by
from_length_scales_aniso) are preserved: we re-center around the new
ψ̄, keeping Ση_a = 0.
Sourcepub fn clamp_to_bounds(
self,
lower: &SpatialLogKappaCoords,
upper: &SpatialLogKappaCoords,
) -> Self
pub fn clamp_to_bounds( self, lower: &SpatialLogKappaCoords, upper: &SpatialLogKappaCoords, ) -> Self
Project ψ values into [lower, upper] element-wise. Used after
from_length_scales* + reseed_from_data when a user-supplied
spec.length_scale falls outside the data-derived ψ window set by
{lower,upper}_bounds*_from_data. BFGS requires theta0 ∈ [lower,
upper]; projecting is the unique closest feasible seed. The user’s
length_scale was always a hint for the outer optimizer (the optimizer
is authoritative for κ), not a hard constraint — so clipping preserves
their intent as far as the geometry allows. Emits log::info! when
any coordinate moves, so the outside-window case is diagnostically
visible (not silent).
Sourcepub fn from_theta_tail_with_dims(
theta: &Array1<f64>,
start: usize,
dims_per_term: Vec<usize>,
) -> Self
pub fn from_theta_tail_with_dims( theta: &Array1<f64>, start: usize, dims_per_term: Vec<usize>, ) -> Self
Reconstruct from theta tail with known dimensionality layout.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Total number of ψ values in the flat array (= sum of dims_per_term).
Sourcepub fn dims_per_term(&self) -> &[usize]
pub fn dims_per_term(&self) -> &[usize]
Dimensionality layout: how many ψ values each term contributes.
Sourcepub fn term_slice(&self, term_idx: usize) -> &[f64]
pub fn term_slice(&self, term_idx: usize) -> &[f64]
Get the slice of ψ values for logical term i.
pub fn as_array(&self) -> &Array1<f64>
Sourcepub fn set_scalar_slot(&mut self, slot: usize, value: f64) -> bool
pub fn set_scalar_slot(&mut self, slot: usize, value: f64) -> bool
#1464: overwrite the single ψ value of a scalar (1-D) logical term by its
position slot in this coords vector (the same ordering as the
term_indices slice the constructors were built from). Used to inject the
fixed-κ sign-basin seed into a constant-curvature term’s raw-κ slot before
the joint solve. No-op (returns false) when the slot is not scalar.
Sourcepub fn split_at(&self, mid: usize) -> (Self, Self)
pub fn split_at(&self, mid: usize) -> (Self, Self)
Split at a logical-term boundary. mid is the number of terms in the
first half (not a flat-array index).
Sourcepub fn apply_tospec(
&self,
spec: &TermCollectionSpec,
term_indices: &[usize],
) -> Result<TermCollectionSpec, EstimationError>
pub fn apply_tospec( &self, spec: &TermCollectionSpec, term_indices: &[usize], ) -> Result<TermCollectionSpec, EstimationError>
Apply optimized ψ values back to the spec.
For isotropic terms (dims=1): sets scalar length_scale = exp(−ψ). For anisotropic terms (dims=d): hybrid/isotropic families set length_scale = exp(−ψ̄) with centered η_a = ψ_a − ψ̄, while pure Duchon writes only centered η_a and leaves length_scale = None.
Trait Implementations§
Source§impl Clone for SpatialLogKappaCoords
impl Clone for SpatialLogKappaCoords
Source§fn clone(&self) -> SpatialLogKappaCoords
fn clone(&self) -> SpatialLogKappaCoords
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for SpatialLogKappaCoords
impl RefUnwindSafe for SpatialLogKappaCoords
impl Send for SpatialLogKappaCoords
impl Sync for SpatialLogKappaCoords
impl Unpin for SpatialLogKappaCoords
impl UnsafeUnpin for SpatialLogKappaCoords
impl UnwindSafe for SpatialLogKappaCoords
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.