| Crates.io | curve_similarities |
| lib.rs | curve_similarities |
| version | 1.0.0 |
| created_at | 2024-08-24 09:38:57.115392+00 |
| updated_at | 2025-10-25 18:13:45.525377+00 |
| description | Calculation of curve similarities for nd-array |
| homepage | https://github.com/nucccc/curve_similarities |
| repository | https://github.com/nucccc/curve_similarities |
| max_upload_size | |
| id | 1350147 |
| size | 66,046 |
Implementation of calculations for curves similarities as in python package similarity_measures.
The following distances are currently implemented:
The library requires in input a bidimensional array of the ndarray rust library.
Frechet and DTW distances require in input two curves, potentially with different lengths.
frechet and dtw functions are designed to receive in input a couple of types satisfying DistMatCalc trait, meaning that a pairwise distance matrix can be calculated out of them. At the moment the trait is implemented for:
ndarray::Array1<T> with T being a floatndarray::Array2<T> with T being a floatVec<T> with T being a floatVec<Vec<T>> with T being a floatVec<[T; N]> with T being a float and N the array sizeAs a third argument a DistMetric enum is necessary to specify the type of pairwise distance calculation.
Since the underlying calculation is based on the pairwise distance between every point of a curve, it is possible to specify their pairwise distance metric, which can be either:
DistMetric::EuclideanDistMetric::Manhattanndarray::Array1<T> inputWhen providing in input a ndarray::Array1 input, each element of the array is going to be considered as a single sample:
use curve_similarities::{frechet, DistMetric};
use ndarray::array;
fn main() {
// calculating frechet distance
let fr = frechet(
&array![1.0, 1.0, 3.0],
&array![2.0, 4.0],
DistMetric::Euclidean
).unwrap();
println!("Frechet distance between curves is {}", fr);
}
ndarray::Array2<T> inputWhen providing in input a ndarray::Array2<T> every row is expected to have the same length, while the two arrays can have different lengths (since the curves can be of different legths, but their single elements need to be of the same size).
As an example one can have curves constituted by samples of 4 values (let's say that we are measuring some whatever with 4 different sensors). In such case every row of the array shall have 4 different values, while the arrays can have a different number of rows:
use curve_similarities::{dtw, DistMetric};
use ndarray::array;
fn main() {
// calculating dynamic time warping
let dtw_dist = dtw(
&array![[1.0, 2.0, 3.0, 6.0], [1.0, 4.0, 7.0, 9.0], [3.0, 1.0, -1.0, 2.0]],
&array![[2.0, 5.0, -7.0, 4.0], [4.0, 2.0, 4.0, 2.0]],
DistMetric::Euclidean
).unwrap();
println!("Dynamic Time Warping between curves is {}", dtw_dist);
}
in the above example the first curve is composed of 3 points, while the second one is composed of 2 points.
Vec<T> with T being either f32 or f64In such case the vector is treated as in the case of ndarray::Array1<T>, with every element considered as a sample of the curve:
use curve_similarities::{dtw, DistMetric};
fn main() {
let dtw_dist = dtw(
&vec![1.0, 1.0, 3.0],
&vec![2.0, 4.0],
DistMetric::Euclidean
)
}
Vec<Vec<T>> with T being either f32 or f64In such case the vector can be seen as in the case of ndarray::Array2<T>, with every "subvector" considered as a row.
It is necessary that all "subvectors" have the same length, otherwise an error is returned.
use curve_similarities::{dtw, DistMetric};
fn main() {
let dtw_dist = dtw(
&vec![vec![1.0, 2.0], vec![1.0, 4.0], vec![3.0, 1.0]],
&vec![vec![2.0, 5.0], vec![4.0, 2.0]],
DistMetric::Euclidean
).unwrap();
}
Vec<[T; N]> with T being a float and N the array sizeIn such case the vector can be seen as in the case of ndarray::Array2<T>, with every array considered as a row.
It is necessary that arrays have the same length for both vectors.
use curve_similarities::{dtw, DistMetric};
fn main() {
let dtw_dist = dtw(
&vec![[1.0, 2.0], [1.0, 4.0], [3.0, 1.0]],
&vec![[2.0, 5.0], [4.0, 2.0]],
DistMetric::Euclidean
).unwrap();
}
curve_len_measure and area_between_two_curvescurve_len_measure and area_between_two_curves require each one two bidimensional arrays to be provided in input. Each bidimensional array can have the first dimension to be of whatever size, but the second dimension should be of size 2. So every row shall have two elements, the first the value on the x axis and the second being the one on the y axis:
use curve_similarities::curve_len_measure;
use ndarray::array;
fn main() {
let arr1 = array![[0.1, 2.27], [0.3, 2.24]];
let arr2 = array![[0.2, 2.61], [0.3, 2.68], [0.4, 2.14]];
let res = curve_len_measure(&arr1, &arr2).unwrap();
}
in the case above the first curve arr1 is composed of two points, having values on the x-axis 0.1 and 0.3 respectively, and values on the y-axis 2.27 and 2.24 respectively. The second curve arr2 has 0.2, 0.3 and 0.4 on the x-axis, while 2.61, 2.68 and 2.14 are on the y-axis.