Skip to main content

aeon_tk/element/
mod.rs

1use crate::{geometry::IndexSpace, prelude::HyperBox};
2use faer::linalg::svd::SvdError;
3use std::array;
4
5mod approx;
6mod basis;
7mod helpers;
8mod operations;
9mod support;
10
11pub use approx::*;
12pub use basis::*;
13pub use helpers::*;
14pub use operations::*;
15pub use support::*;
16
17/// Performs uniform interpolation on a [-1, 1]ᴺ hypercube.
18#[derive(Default, Clone)]
19pub struct UniformInterpolate<const N: usize> {
20    approx: ApproxOperator,
21    num_points: usize,
22}
23
24impl<const N: usize> UniformInterpolate<N> {
25    pub fn build(
26        &mut self,
27        support: usize,
28        order: usize,
29        bounds: HyperBox<N>,
30        point: [f64; N],
31    ) -> Result<(), SvdError> {
32        let local = bounds.global_to_local(point);
33        let cube: [f64; N] = array::from_fn(|axis| local[axis] * 2.0 - 1.0);
34
35        self.approx.build(
36            &Uniform::new([support]),
37            &Monomials::new([order]),
38            &ProductValue::new(cube),
39        )?;
40        self.num_points = support;
41        Ok(())
42    }
43
44    pub fn apply(&self, values: &[f64]) -> f64 {
45        let weights: [_; N] = array::from_fn(|axis| self.approx.weights(axis));
46
47        let mut result = 0.0;
48
49        let space = IndexSpace::new([self.num_points; N]);
50        for vertex in space.iter() {
51            let index = space.linear_from_cartesian(vertex);
52
53            let weight: f64 = array::from_fn::<_, N, _>(|axis| weights[axis][vertex[axis]])
54                .iter()
55                .product();
56
57            result += weight * values[index];
58        }
59
60        result
61    }
62}