fdars_core/alignment/
set.rs1use super::pairwise::elastic_align_pair;
4use super::srsf::reparameterize_curve;
5use super::{AlignmentResult, AlignmentSetResult};
6use crate::iter_maybe_parallel;
7use crate::matrix::FdMatrix;
8#[cfg(feature = "parallel")]
9use rayon::iter::ParallelIterator;
10
11#[derive(Debug, Clone, PartialEq)]
13pub struct DecompositionResult {
14 pub alignment: AlignmentResult,
16 pub d_amplitude: f64,
18 pub d_phase: f64,
20}
21
22#[must_use = "expensive computation whose result should not be discarded"]
33pub fn align_to_target(
34 data: &FdMatrix,
35 target: &[f64],
36 argvals: &[f64],
37 lambda: f64,
38) -> AlignmentSetResult {
39 let (n, m) = data.shape();
40
41 let results: Vec<AlignmentResult> = iter_maybe_parallel!(0..n)
42 .map(|i| {
43 let fi = data.row(i);
44 elastic_align_pair(target, &fi, argvals, lambda)
45 })
46 .collect();
47
48 let mut gammas = FdMatrix::zeros(n, m);
49 let mut aligned_data = FdMatrix::zeros(n, m);
50 let mut distances = Vec::with_capacity(n);
51
52 for (i, r) in results.into_iter().enumerate() {
53 for j in 0..m {
54 gammas[(i, j)] = r.gamma[j];
55 aligned_data[(i, j)] = r.f_aligned[j];
56 }
57 distances.push(r.distance);
58 }
59
60 AlignmentSetResult {
61 gammas,
62 aligned_data,
63 distances,
64 }
65}
66
67pub fn elastic_decomposition(
77 f1: &[f64],
78 f2: &[f64],
79 argvals: &[f64],
80 lambda: f64,
81) -> DecompositionResult {
82 let alignment = elastic_align_pair(f1, f2, argvals, lambda);
83 let d_amplitude = alignment.distance;
84 let d_phase = crate::warping::phase_distance(&alignment.gamma, argvals);
85 DecompositionResult {
86 alignment,
87 d_amplitude,
88 d_phase,
89 }
90}
91
92pub(super) fn apply_stored_warps(data: &FdMatrix, gammas: &FdMatrix, argvals: &[f64]) -> FdMatrix {
94 let (n, m) = data.shape();
95 let mut aligned = FdMatrix::zeros(n, m);
96 for i in 0..n {
97 let fi = data.row(i);
98 let gamma: Vec<f64> = (0..m).map(|j| gammas[(i, j)]).collect();
99 let f_aligned = reparameterize_curve(&fi, argvals, &gamma);
100 for j in 0..m {
101 aligned[(i, j)] = f_aligned[j];
102 }
103 }
104 aligned
105}