1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Correlation coefficients based on order distance.

use ndarray::*;
use num_traits::Float;

use crate::distances::*;
use crate::error::OrDistError;
use crate::traits::OrDistElement;

/// Spearman correlation coefficient between 2 orders.
pub fn spearman_corrcoef<T: OrDistElement, U: Float>(
    v1: &[T],
    v2: &[T],
) -> Result<U, OrDistError<T>> {
    let d_spear = U::from(spearman_dist(v1, v2)?).unwrap();
    let m = U::from(v1.len()).unwrap();
    let one = U::one();
    Ok(one - U::from(6).unwrap() * d_spear / (m * (m * m - one)))
}

/// Kendall correlation coefficient between 2 orders.
pub fn kendall_corrcoef<T: OrDistElement, U: Float>(
    v1: &[T],
    v2: &[T],
) -> Result<U, OrDistError<T>> {
    let d_ken = U::from(kendall_dist(v1, v2)?).unwrap();
    let m = U::from(v1.len()).unwrap();
    let one = U::one();
    Ok(one - U::from(4).unwrap() * d_ken / (m * (m - one)))
}

/// Trait of correlation coefficient
pub trait OrDistCorrCoef<T: OrDistElement, U: Float> {
    /// Spearman's correlation coefficient with `v`.
    fn spearman_corrcoef(&self, v: &Self) -> Result<U, OrDistError<T>>;
    /// Kendall's correlation coefficient with `v`.
    fn kendall_corrcoef(&self, v: &Self) -> Result<U, OrDistError<T>>;
}

impl<T, U> OrDistCorrCoef<T, U> for Vec<T>
where
    T: OrDistElement,
    U: Float,
{
    fn spearman_corrcoef(&self, v: &Self) -> Result<U, OrDistError<T>> {
        spearman_corrcoef(self, v)
    }
    fn kendall_corrcoef(&self, v: &Self) -> Result<U, OrDistError<T>> {
        kendall_corrcoef(self, v)
    }
}

impl<A, S, U> OrDistCorrCoef<A, U> for ArrayBase<S, Ix1>
where
    A: OrDistElement,
    S: Data<Elem = A>,
    U: Float,
{
    fn spearman_corrcoef(&self, v: &Self) -> Result<U, OrDistError<A>> {
        self.to_vec().spearman_corrcoef(&v.to_vec())
    }
    fn kendall_corrcoef(&self, v: &Self) -> Result<U, OrDistError<A>> {
        self.to_vec().kendall_corrcoef(&v.to_vec())
    }
}