1use crate::err::Error;
2use crate::fnc::util::math::ToFloat;
3use crate::idx::VersionedStore;
4use crate::sql::index::{Distance, VectorType};
5use crate::sql::{Number, Value};
6use ahash::AHasher;
7use ahash::HashSet;
8use linfa_linalg::norm::Norm;
9use ndarray::{Array1, LinalgScalar, Zip};
10use ndarray_stats::DeviationExt;
11use num_traits::Zero;
12use revision::revisioned;
13use rust_decimal::prelude::FromPrimitive;
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15use std::cmp::PartialEq;
16use std::hash::{Hash, Hasher};
17use std::ops::{Add, Deref, Div, Sub};
18use std::sync::Arc;
19
20#[derive(Debug, Clone, PartialEq)]
22#[non_exhaustive]
23pub enum Vector {
24 F64(Array1<f64>),
25 F32(Array1<f32>),
26 I64(Array1<i64>),
27 I32(Array1<i32>),
28 I16(Array1<i16>),
29}
30
31#[revisioned(revision = 1)]
32#[derive(Debug, PartialEq, Serialize, Deserialize)]
33#[non_exhaustive]
34pub enum SerializedVector {
35 F64(Vec<f64>),
36 F32(Vec<f32>),
37 I64(Vec<i64>),
38 I32(Vec<i32>),
39 I16(Vec<i16>),
40}
41
42impl VersionedStore for SerializedVector {}
43
44impl From<&Vector> for SerializedVector {
45 fn from(value: &Vector) -> Self {
46 match value {
47 Vector::F64(v) => Self::F64(v.to_vec()),
48 Vector::F32(v) => Self::F32(v.to_vec()),
49 Vector::I64(v) => Self::I64(v.to_vec()),
50 Vector::I32(v) => Self::I32(v.to_vec()),
51 Vector::I16(v) => Self::I16(v.to_vec()),
52 }
53 }
54}
55
56impl From<SerializedVector> for Vector {
57 fn from(value: SerializedVector) -> Self {
58 match value {
59 SerializedVector::F64(v) => Self::F64(Array1::from_vec(v)),
60 SerializedVector::F32(v) => Self::F32(Array1::from_vec(v)),
61 SerializedVector::I64(v) => Self::I64(Array1::from_vec(v)),
62 SerializedVector::I32(v) => Self::I32(Array1::from_vec(v)),
63 SerializedVector::I16(v) => Self::I16(Array1::from_vec(v)),
64 }
65 }
66}
67
68impl Vector {
69 #[inline]
70 fn chebyshev<T>(a: &Array1<T>, b: &Array1<T>) -> f64
71 where
72 T: ToFloat,
73 {
74 a.iter()
75 .zip(b.iter())
76 .map(|(a, b)| (a.to_float() - b.to_float()).abs())
77 .fold(0.0_f64, f64::max)
78 }
79
80 fn chebyshev_distance(&self, other: &Self) -> f64 {
81 match (self, other) {
82 (Self::F64(a), Self::F64(b)) => a.linf_dist(b).unwrap_or(f64::INFINITY),
83 (Self::F32(a), Self::F32(b)) => {
84 a.linf_dist(b).map(|r| r as f64).unwrap_or(f64::INFINITY)
85 }
86 (Self::I64(a), Self::I64(b)) => {
87 a.linf_dist(b).map(|r| r as f64).unwrap_or(f64::INFINITY)
88 }
89 (Self::I32(a), Self::I32(b)) => {
90 a.linf_dist(b).map(|r| r as f64).unwrap_or(f64::INFINITY)
91 }
92 (Self::I16(a), Self::I16(b)) => Self::chebyshev(a, b),
93 _ => f64::NAN,
94 }
95 }
96
97 #[inline]
98 fn cosine_distance_f64(a: &Array1<f64>, b: &Array1<f64>) -> f64 {
99 let dot_product = a.dot(b);
100 let norm_a = a.norm_l2();
101 let norm_b = b.norm_l2();
102 1.0 - dot_product / (norm_a * norm_b)
103 }
104
105 #[inline]
106 fn cosine_distance_f32(a: &Array1<f32>, b: &Array1<f32>) -> f64 {
107 let dot_product = a.dot(b) as f64;
108 let norm_a = a.norm_l2() as f64;
109 let norm_b = b.norm_l2() as f64;
110 1.0 - dot_product / (norm_a * norm_b)
111 }
112
113 #[inline]
114 fn cosine_dist<T>(a: &Array1<T>, b: &Array1<T>) -> f64
115 where
116 T: ToFloat + LinalgScalar,
117 {
118 let dot_product = a.dot(b).to_float();
119 let norm_a = a.mapv(|x| x.to_float() * x.to_float()).sum().sqrt();
120 let norm_b = b.mapv(|x| x.to_float() * x.to_float()).sum().sqrt();
121 1.0 - dot_product / (norm_a * norm_b)
122 }
123
124 fn cosine_distance(&self, other: &Self) -> f64 {
125 match (self, other) {
126 (Self::F64(a), Self::F64(b)) => Self::cosine_distance_f64(a, b),
127 (Self::F32(a), Self::F32(b)) => Self::cosine_distance_f32(a, b),
128 (Self::I64(a), Self::I64(b)) => Self::cosine_dist(a, b),
129 (Self::I32(a), Self::I32(b)) => Self::cosine_dist(a, b),
130 (Self::I16(a), Self::I16(b)) => Self::cosine_dist(a, b),
131 _ => f64::INFINITY,
132 }
133 }
134
135 #[inline]
136 fn euclidean<T>(a: &Array1<T>, b: &Array1<T>) -> f64
137 where
138 T: ToFloat,
139 {
140 Zip::from(a).and(b).map_collect(|x, y| (x.to_float() - y.to_float()).powi(2)).sum().sqrt()
141 }
142 fn euclidean_distance(&self, other: &Self) -> f64 {
143 match (self, other) {
144 (Self::F64(a), Self::F64(b)) => a.l2_dist(b).unwrap_or(f64::INFINITY),
145 (Self::F32(a), Self::F32(b)) => a.l2_dist(b).unwrap_or(f64::INFINITY),
146 (Self::I64(a), Self::I64(b)) => a.l2_dist(b).unwrap_or(f64::INFINITY),
147 (Self::I32(a), Self::I32(b)) => a.l2_dist(b).unwrap_or(f64::INFINITY),
148 (Self::I16(a), Self::I16(b)) => Self::euclidean(a, b),
149 _ => f64::INFINITY,
150 }
151 }
152
153 #[inline]
154 fn hamming<T>(a: &Array1<T>, b: &Array1<T>) -> f64
155 where
156 T: PartialEq,
157 {
158 Zip::from(a).and(b).fold(0, |acc, a, b| {
159 if a != b {
160 acc + 1
161 } else {
162 acc
163 }
164 }) as f64
165 }
166
167 fn hamming_distance(&self, other: &Self) -> f64 {
168 match (self, other) {
169 (Self::F64(a), Self::F64(b)) => Self::hamming(a, b),
170 (Self::F32(a), Self::F32(b)) => Self::hamming(a, b),
171 (Self::I64(a), Self::I64(b)) => Self::hamming(a, b),
172 (Self::I32(a), Self::I32(b)) => Self::hamming(a, b),
173 (Self::I16(a), Self::I16(b)) => Self::hamming(a, b),
174 _ => f64::INFINITY,
175 }
176 }
177
178 #[inline]
179 fn jaccard_f64(a: &Array1<f64>, b: &Array1<f64>) -> f64 {
180 let mut union: HashSet<u64> = a.iter().map(|f| f.to_bits()).collect();
181 let intersection_size = b.iter().fold(0, |acc, n| {
182 if !union.insert(n.to_bits()) {
183 acc + 1
184 } else {
185 acc
186 }
187 }) as f64;
188 1.0 - intersection_size / union.len() as f64
189 }
190
191 #[inline]
192 fn jaccard_f32(a: &Array1<f32>, b: &Array1<f32>) -> f64 {
193 let mut union: HashSet<u32> = a.iter().map(|f| f.to_bits()).collect();
194 let intersection_size = b.iter().fold(0, |acc, n| {
195 if !union.insert(n.to_bits()) {
196 acc + 1
197 } else {
198 acc
199 }
200 }) as f64;
201 intersection_size / union.len() as f64
202 }
203
204 #[inline]
205 fn jaccard_integers<T>(a: &Array1<T>, b: &Array1<T>) -> f64
206 where
207 T: Eq + Hash + Clone,
208 {
209 let mut union: HashSet<T> = a.iter().cloned().collect();
210 let intersection_size = b.iter().cloned().fold(0, |acc, n| {
211 if !union.insert(n) {
212 acc + 1
213 } else {
214 acc
215 }
216 }) as f64;
217 intersection_size / union.len() as f64
218 }
219
220 pub(super) fn jaccard_similarity(&self, other: &Self) -> f64 {
221 match (self, other) {
222 (Self::F64(a), Self::F64(b)) => Self::jaccard_f64(a, b),
223 (Self::F32(a), Self::F32(b)) => Self::jaccard_f32(a, b),
224 (Self::I64(a), Self::I64(b)) => Self::jaccard_integers(a, b),
225 (Self::I32(a), Self::I32(b)) => Self::jaccard_integers(a, b),
226 (Self::I16(a), Self::I16(b)) => Self::jaccard_integers(a, b),
227 _ => f64::NAN,
228 }
229 }
230
231 #[inline]
232 fn manhattan<T>(a: &Array1<T>, b: &Array1<T>) -> f64
233 where
234 T: Sub<Output = T> + ToFloat + Copy,
235 {
236 a.iter().zip(b.iter()).map(|(&a, &b)| (a - b).to_float().abs()).sum()
237 }
238
239 pub(super) fn manhattan_distance(&self, other: &Self) -> f64 {
240 match (self, other) {
241 (Self::F64(a), Self::F64(b)) => a.l1_dist(b).unwrap_or(f64::INFINITY),
242 (Self::F32(a), Self::F32(b)) => a.l1_dist(b).map(|r| r as f64).unwrap_or(f64::INFINITY),
243 (Self::I64(a), Self::I64(b)) => a.l1_dist(b).map(|r| r as f64).unwrap_or(f64::INFINITY),
244 (Self::I32(a), Self::I32(b)) => a.l1_dist(b).map(|r| r as f64).unwrap_or(f64::INFINITY),
245 (Self::I16(a), Self::I16(b)) => Self::manhattan(a, b),
246 _ => f64::NAN,
247 }
248 }
249
250 #[inline]
251 fn minkowski<T>(a: &Array1<T>, b: &Array1<T>, order: f64) -> f64
252 where
253 T: ToFloat,
254 {
255 let dist: f64 = a
256 .iter()
257 .zip(b.iter())
258 .map(|(a, b)| (a.to_float() - b.to_float()).abs().powf(order))
259 .sum();
260 dist.powf(1.0 / order)
261 }
262
263 pub(super) fn minkowski_distance(&self, other: &Self, order: f64) -> f64 {
264 match (self, other) {
265 (Self::F64(a), Self::F64(b)) => Self::minkowski(a, b, order),
266 (Self::F32(a), Self::F32(b)) => Self::minkowski(a, b, order),
267 (Self::I64(a), Self::I64(b)) => Self::minkowski(a, b, order),
268 (Self::I32(a), Self::I32(b)) => Self::minkowski(a, b, order),
269 (Self::I16(a), Self::I16(b)) => Self::minkowski(a, b, order),
270 _ => f64::NAN,
271 }
272 }
273
274 #[inline]
275 fn pearson<T>(x: &Array1<T>, y: &Array1<T>) -> f64
276 where
277 T: ToFloat + Clone + FromPrimitive + Add<Output = T> + Div<Output = T> + Zero,
278 {
279 let mean_x = x.mean().unwrap().to_float();
280 let mean_y = y.mean().unwrap().to_float();
281
282 let mut sum_xy = 0.0;
283 let mut sum_x2 = 0.0;
284 let mut sum_y2 = 0.0;
285
286 for (xi, yi) in x.iter().zip(y.iter()) {
287 let diff_x = xi.to_float() - mean_x;
288 let diff_y = yi.to_float() - mean_y;
289 sum_xy += diff_x * diff_y;
290 sum_x2 += diff_x.powi(2);
291 sum_y2 += diff_y.powi(2);
292 }
293
294 let numerator = sum_xy;
295 let denominator = (sum_x2 * sum_y2).sqrt();
296
297 if denominator == 0.0 {
298 return 0.0; }
300
301 numerator / denominator
302 }
303
304 fn pearson_similarity(&self, other: &Self) -> f64 {
305 match (self, other) {
306 (Self::F64(a), Self::F64(b)) => Self::pearson(a, b),
307 (Self::F32(a), Self::F32(b)) => Self::pearson(a, b),
308 (Self::I64(a), Self::I64(b)) => Self::pearson(a, b),
309 (Self::I32(a), Self::I32(b)) => Self::pearson(a, b),
310 (Self::I16(a), Self::I16(b)) => Self::pearson(a, b),
311 _ => f64::NAN,
312 }
313 }
314}
315
316#[derive(Debug, Clone)]
322pub struct SharedVector(Arc<Vector>, u64);
323impl From<Vector> for SharedVector {
324 fn from(v: Vector) -> Self {
325 let mut h = AHasher::default();
326 v.hash(&mut h);
327 Self(Arc::new(v), h.finish())
328 }
329}
330
331impl Deref for SharedVector {
332 type Target = Vector;
333
334 fn deref(&self) -> &Self::Target {
335 &self.0
336 }
337}
338
339impl Hash for SharedVector {
340 fn hash<H: Hasher>(&self, state: &mut H) {
341 state.write_u64(self.1);
342 }
343}
344
345impl PartialEq for SharedVector {
346 fn eq(&self, other: &Self) -> bool {
347 self.1 == other.1 && self.0 == other.0
348 }
349}
350impl Eq for SharedVector {}
351
352impl Serialize for SharedVector {
353 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
354 where
355 S: Serializer,
356 {
357 let ser: SerializedVector = self.0.as_ref().into();
359 ser.serialize(serializer)
360 }
361}
362
363impl<'de> Deserialize<'de> for SharedVector {
364 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
365 where
366 D: Deserializer<'de>,
367 {
368 let v: Vector = SerializedVector::deserialize(deserializer)?.into();
370 Ok(v.into())
371 }
372}
373
374impl Hash for Vector {
375 fn hash<H: Hasher>(&self, state: &mut H) {
376 match self {
377 Vector::F64(v) => {
378 let h = v.iter().fold(0, |acc, &x| acc ^ x.to_bits());
379 state.write_u64(h);
380 }
381 Vector::F32(v) => {
382 let h = v.iter().fold(0, |acc, &x| acc ^ x.to_bits());
383 state.write_u32(h);
384 }
385 Vector::I64(v) => {
386 let h = v.iter().fold(0, |acc, &x| acc ^ x);
387 state.write_i64(h);
388 }
389 Vector::I32(v) => {
390 let h = v.iter().fold(0, |acc, &x| acc ^ x);
391 state.write_i32(h);
392 }
393 Vector::I16(v) => {
394 let h = v.iter().fold(0, |acc, &x| acc ^ x);
395 state.write_i16(h);
396 }
397 }
398 }
399}
400
401#[cfg(test)]
402impl SharedVector {
403 pub(crate) fn clone_vector(&self) -> Vector {
404 self.0.as_ref().clone()
405 }
406}
407
408#[cfg(test)]
409impl From<&Vector> for Value {
410 fn from(v: &Vector) -> Self {
411 let vec: Vec<Number> = match v {
412 Vector::F64(a) => a.iter().map(|i| Number::Float(*i)).collect(),
413 Vector::F32(a) => a.iter().map(|i| Number::Float(*i as f64)).collect(),
414 Vector::I64(a) => a.iter().map(|i| Number::Int(*i)).collect(),
415 Vector::I32(a) => a.iter().map(|i| Number::Int(*i as i64)).collect(),
416 Vector::I16(a) => a.iter().map(|i| Number::Int(*i as i64)).collect(),
417 };
418 Value::from(vec)
419 }
420}
421
422impl Vector {
423 pub(super) fn try_from_value(t: VectorType, d: usize, v: &Value) -> Result<Self, Error> {
424 let res = match t {
425 VectorType::F64 => {
426 let mut vec = Vec::with_capacity(d);
427 Self::check_vector_value(v, &mut vec)?;
428 Vector::F64(Array1::from_vec(vec))
429 }
430 VectorType::F32 => {
431 let mut vec = Vec::with_capacity(d);
432 Self::check_vector_value(v, &mut vec)?;
433 Vector::F32(Array1::from_vec(vec))
434 }
435 VectorType::I64 => {
436 let mut vec = Vec::with_capacity(d);
437 Self::check_vector_value(v, &mut vec)?;
438 Vector::I64(Array1::from_vec(vec))
439 }
440 VectorType::I32 => {
441 let mut vec = Vec::with_capacity(d);
442 Self::check_vector_value(v, &mut vec)?;
443 Vector::I32(Array1::from_vec(vec))
444 }
445 VectorType::I16 => {
446 let mut vec = Vec::with_capacity(d);
447 Self::check_vector_value(v, &mut vec)?;
448 Vector::I16(Array1::from_vec(vec))
449 }
450 };
451 Ok(res)
452 }
453
454 fn check_vector_value<T>(value: &Value, vec: &mut Vec<T>) -> Result<(), Error>
455 where
456 T: for<'a> TryFrom<&'a Number, Error = Error>,
457 {
458 match value {
459 Value::Array(a) => {
460 for v in a.0.iter() {
461 Self::check_vector_value(v, vec)?;
462 }
463 Ok(())
464 }
465 Value::Number(n) => {
466 vec.push(n.try_into()?);
467 Ok(())
468 }
469 _ => Err(Error::InvalidVectorValue(value.clone().to_raw_string())),
470 }
471 }
472
473 pub fn try_from_vector(t: VectorType, v: &[Number]) -> Result<Self, Error> {
474 let res = match t {
475 VectorType::F64 => {
476 let mut vec = Vec::with_capacity(v.len());
477 Self::check_vector_number(v, &mut vec)?;
478 Vector::F64(Array1::from_vec(vec))
479 }
480 VectorType::F32 => {
481 let mut vec = Vec::with_capacity(v.len());
482 Self::check_vector_number(v, &mut vec)?;
483 Vector::F32(Array1::from_vec(vec))
484 }
485 VectorType::I64 => {
486 let mut vec = Vec::with_capacity(v.len());
487 Self::check_vector_number(v, &mut vec)?;
488 Vector::I64(Array1::from_vec(vec))
489 }
490 VectorType::I32 => {
491 let mut vec = Vec::with_capacity(v.len());
492 Self::check_vector_number(v, &mut vec)?;
493 Vector::I32(Array1::from_vec(vec))
494 }
495 VectorType::I16 => {
496 let mut vec = Vec::with_capacity(v.len());
497 Self::check_vector_number(v, &mut vec)?;
498 Vector::I16(Array1::from_vec(vec))
499 }
500 };
501 Ok(res)
502 }
503
504 fn check_vector_number<T>(v: &[Number], vec: &mut Vec<T>) -> Result<(), Error>
505 where
506 T: for<'a> TryFrom<&'a Number, Error = Error>,
507 {
508 for n in v {
509 vec.push(n.try_into()?);
510 }
511 Ok(())
512 }
513
514 pub(super) fn len(&self) -> usize {
515 match self {
516 Self::F64(v) => v.len(),
517 Self::F32(v) => v.len(),
518 Self::I64(v) => v.len(),
519 Self::I32(v) => v.len(),
520 Self::I16(v) => v.len(),
521 }
522 }
523
524 pub(super) fn check_expected_dimension(current: usize, expected: usize) -> Result<(), Error> {
525 if current != expected {
526 Err(Error::InvalidVectorDimension {
527 current,
528 expected,
529 })
530 } else {
531 Ok(())
532 }
533 }
534
535 pub(super) fn check_dimension(&self, expected_dim: usize) -> Result<(), Error> {
536 Self::check_expected_dimension(self.len(), expected_dim)
537 }
538}
539
540impl Distance {
541 pub(super) fn calculate(&self, a: &Vector, b: &Vector) -> f64 {
542 match self {
543 Distance::Chebyshev => a.chebyshev_distance(b),
544 Distance::Cosine => a.cosine_distance(b),
545 Distance::Euclidean => a.euclidean_distance(b),
546 Distance::Hamming => a.hamming_distance(b),
547 Distance::Jaccard => a.jaccard_similarity(b),
548 Distance::Manhattan => a.manhattan_distance(b),
549 Distance::Minkowski(order) => a.minkowski_distance(b, order.to_float()),
550 Distance::Pearson => a.pearson_similarity(b),
551 }
552 }
553}
554
555#[cfg(test)]
556mod tests {
557 use crate::idx::trees::knn::tests::{get_seed_rnd, new_random_vec, RandomItemGenerator};
558 use crate::idx::trees::vector::{SharedVector, Vector};
559 use crate::sql::index::{Distance, VectorType};
560
561 fn test_distance(dist: Distance, a1: &[f64], a2: &[f64], res: f64) {
562 let mut v1 = vec![];
564 a1.iter().for_each(|&n| v1.push(n.into()));
565 let mut v2 = vec![];
566 a2.iter().for_each(|&n| v2.push(n.into()));
567
568 assert_eq!(dist.compute(&v1, &v2).unwrap(), res.into());
570
571 let t = VectorType::F64;
573 let v1: SharedVector = Vector::try_from_vector(t, &v1).unwrap().into();
574 let v2: SharedVector = Vector::try_from_vector(t, &v2).unwrap().into();
575 assert_eq!(dist.calculate(&v1, &v2), res);
576 }
577
578 fn test_distance_collection(dist: Distance, size: usize, dim: usize) {
579 let mut rng = get_seed_rnd();
580 for vt in
581 [VectorType::F64, VectorType::F32, VectorType::I64, VectorType::I32, VectorType::I16]
582 {
583 let gen = RandomItemGenerator::new(&dist, dim);
584 let mut num_zero = 0;
585 for i in 0..size {
586 let v1 = new_random_vec(&mut rng, vt, dim, &gen);
587 let v2 = new_random_vec(&mut rng, vt, dim, &gen);
588 let d = dist.calculate(&v1, &v2);
589 assert!(
590 d.is_finite() && !d.is_nan(),
591 "i: {i} - vt: {vt} - v1: {v1:?} - v2: {v2:?}"
592 );
593 assert_ne!(d, f64::NAN, "i: {i} - vt: {vt} - v1: {v1:?} - v2: {v2:?}");
594 assert_ne!(d, f64::INFINITY, "i: {i} - vt: {vt} - v1: {v1:?} - v2: {v2:?}");
595 if d == 0.0 {
596 num_zero += 1;
597 }
598 }
599 let zero_rate = num_zero as f64 / size as f64;
600 assert!(zero_rate < 0.1, "vt: {vt} - zero_rate: {zero_rate}");
601 }
602 }
603
604 #[test]
605 fn test_distance_chebyshev() {
606 test_distance_collection(Distance::Chebyshev, 100, 1536);
607 test_distance(Distance::Chebyshev, &[1.0, 2.0, 3.0], &[2.0, 3.0, 4.0], 1.0);
608 }
609
610 #[test]
611 fn test_distance_cosine() {
612 test_distance_collection(Distance::Cosine, 100, 1536);
613 test_distance(Distance::Cosine, &[1.0, 2.0, 3.0], &[2.0, 3.0, 4.0], 0.007416666029069652);
614 }
615
616 #[test]
617 fn test_distance_euclidean() {
618 test_distance_collection(Distance::Euclidean, 100, 1536);
619 test_distance(Distance::Euclidean, &[1.0, 2.0, 3.0], &[2.0, 3.0, 4.0], 1.7320508075688772);
620 }
621
622 #[test]
623 fn test_distance_hamming() {
624 test_distance_collection(Distance::Hamming, 100, 1536);
625 test_distance(Distance::Hamming, &[1.0, 2.0, 3.0], &[2.0, 3.0, 4.0], 3.0);
626 }
627
628 #[test]
629 fn test_distance_jaccard() {
630 test_distance_collection(Distance::Jaccard, 100, 768);
631 test_distance(Distance::Jaccard, &[1.0, 2.0, 3.0], &[2.0, 3.0, 4.0], 0.5);
632 }
633 #[test]
634 fn test_distance_manhattan() {
635 test_distance_collection(Distance::Manhattan, 100, 1536);
636 test_distance(Distance::Manhattan, &[1.0, 2.0, 3.0], &[2.0, 3.0, 4.0], 3.0);
637 }
638 #[test]
639 fn test_distance_minkowski() {
640 test_distance_collection(Distance::Minkowski(3.into()), 100, 1536);
641 test_distance(
642 Distance::Minkowski(3.into()),
643 &[1.0, 2.0, 3.0],
644 &[2.0, 3.0, 4.0],
645 1.4422495703074083,
646 );
647 }
648
649 #[test]
650 fn test_distance_pearson() {
651 test_distance_collection(Distance::Pearson, 100, 1536);
652 test_distance(Distance::Pearson, &[1.0, 2.0, 3.0], &[2.0, 3.0, 4.0], 1.0);
653 }
654}