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)]
13#[non_exhaustive]
14pub struct DecompositionResult {
15 pub alignment: AlignmentResult,
17 pub d_amplitude: f64,
19 pub d_phase: f64,
21}
22
23#[must_use = "expensive computation whose result should not be discarded"]
51pub fn align_to_target(
52 data: &FdMatrix,
53 target: &[f64],
54 argvals: &[f64],
55 lambda: f64,
56) -> AlignmentSetResult {
57 let (n, m) = data.shape();
58
59 let results: Vec<AlignmentResult> = iter_maybe_parallel!(0..n)
60 .map(|i| {
61 let fi = data.row(i);
62 elastic_align_pair(target, &fi, argvals, lambda)
63 })
64 .collect();
65
66 let mut gammas = FdMatrix::zeros(n, m);
67 let mut aligned_data = FdMatrix::zeros(n, m);
68 let mut distances = Vec::with_capacity(n);
69
70 for (i, r) in results.into_iter().enumerate() {
71 for j in 0..m {
72 gammas[(i, j)] = r.gamma[j];
73 aligned_data[(i, j)] = r.f_aligned[j];
74 }
75 distances.push(r.distance);
76 }
77
78 AlignmentSetResult {
79 gammas,
80 aligned_data,
81 distances,
82 }
83}
84
85pub fn elastic_decomposition(
95 f1: &[f64],
96 f2: &[f64],
97 argvals: &[f64],
98 lambda: f64,
99) -> DecompositionResult {
100 let alignment = elastic_align_pair(f1, f2, argvals, lambda);
101 let d_amplitude = alignment.distance;
102 let d_phase = crate::warping::phase_distance(&alignment.gamma, argvals);
103 DecompositionResult {
104 alignment,
105 d_amplitude,
106 d_phase,
107 }
108}
109
110pub(super) fn apply_stored_warps(data: &FdMatrix, gammas: &FdMatrix, argvals: &[f64]) -> FdMatrix {
112 let (n, m) = data.shape();
113 let mut aligned = FdMatrix::zeros(n, m);
114 for i in 0..n {
115 let fi = data.row(i);
116 let gamma: Vec<f64> = (0..m).map(|j| gammas[(i, j)]).collect();
117 let f_aligned = reparameterize_curve(&fi, argvals, &gamma);
118 for j in 0..m {
119 aligned[(i, j)] = f_aligned[j];
120 }
121 }
122 aligned
123}