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
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
mod f64impls;
pub mod functions;
mod i64impls;
mod vecimpls;
mod vecvecimpls;

use crate::functions::GreenIt;
use anyhow::Result;

/// Median and quartiles
#[derive(Default)]
pub struct Med {
    pub lquartile: f64,
    pub median: f64,
    pub uquartile: f64,
}
impl std::fmt::Display for Med {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(
            f,
            "(Lower Q: {}, Median: {}, Upper Q: {})",
            GreenIt(self.lquartile),
            GreenIt(self.median),
            GreenIt(self.uquartile)
        )
    }
}

/// Mean and standard deviation (or std ratio for geometric mean).
#[derive(Default)]
pub struct MStats {
    pub mean: f64,
    pub std: f64,
}
impl std::fmt::Display for MStats {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "mean±std: {}±{}", GreenIt(self.mean), GreenIt(self.std))
    }
}

/// Basic one dimensional (1-d) statistical measures.
/// All these methods operate on only one vector (of data). They take no arguments.
pub trait RStats {
    /// Arithmetic mean
    fn amean(self) -> Result<f64>;
    /// Arithmetic mean and standard deviation
    fn ameanstd(self) -> Result<MStats>;
    /// Weighted arithmetic mean
    fn awmean(self) -> Result<f64>;
    /// Weighted arithmetic men and standard deviation
    fn awmeanstd(self) -> Result<MStats>;
    /// Harmonic mean
    fn hmean(self) -> Result<f64>;
    /// Weighted harmonic mean
    fn hwmean(self) -> Result<f64>;
    /// Geometric mean
    fn gmean(self) -> Result<f64>;
    /// Geometric mean and stndard deviation ratio
    fn gmeanstd(self) -> Result<MStats>;
    /// Weighed geometric mean
    fn gwmean(self) -> Result<f64>;
    /// Weighted geometric mean and standard deviation ratio
    fn gwmeanstd(self) -> Result<MStats>;
    /// Median and quartiles
    fn median(self) -> Result<Med>;
    /// Creates vector of ranks for values in self
    fn ranks(self) -> Result<Vec<f64>>;
}

/// Vector algebra on one or two vectors.
pub trait Vectors {
    /// Utility method to retrieve a sub-slice from multidimensional flat slice.
    fn point(&self, d: usize, i: usize) -> &[f64];

    /// Scalar product of two vectors
    fn dotp(self, v: &[f64]) -> f64;
    /// Vector subtraction
    fn vsub(self, v: &[f64]) -> Vec<f64>;
    /// Vector addition
    fn vadd(self, v: &[f64]) -> Vec<f64>;
    /// Vector magnitude
    fn vmag(self) -> f64;
    /// Euclidian distance between two points
    fn vdist(self, v: &[f64]) -> f64;
    /// Scalar multiplication
    fn smult(self, s: f64) -> Vec<f64>;
    /// Unit vector
    fn vunit(self) -> Vec<f64>;

    /// Correlation
    fn correlation(self, v: &[f64]) -> Result<f64>;
    /// Kendall's tau-b (rank order) correlation
    fn kendalcorr(self, v: &[f64]) -> Result<f64>;
    /// Spearman's rho (rank differences) correlation
    fn spearmancorr(self, v: &[f64]) -> Result<f64>;
    /// Autocorrelation
    fn autocorr(self) -> Result<f64>;
    /// Minimum, minimum's index, maximum, maximum's index.
    fn minmax(self) -> (f64, usize, f64, usize);

    /*
       /// Sums of distances from each point to all other points
       fn distances(self, d:usize) -> Result<Vec <f64>>;
       /// Sum of distances from one point given by indx
       fn distsuminset(self, d:usize, indx:usize) -> f64;
       /// Sum of distances from arbitrary point (v) to all the points in self
       fn distsum(self, d:usize, v:&[f64] ) -> f64;
       /// Medoid and Outlier (by distance) of a set of points
       fn medoid(self, d:usize) -> (f64,usize,f64,usize);

       /// Eccentricity vectors from each point
       fn eccentricities(self, d:usize) -> Result<Vec<Vec<f64>>>;
       /// Ecentricity scalar measure of an internal point given by indx
       fn eccentrinset(self, d:usize, indx:usize) -> f64;
       /// Eccentricity scalar measure and vector of any point
       fn veccentr(self, d:usize, thisp:&[f64]) -> Result<(f64,Vec<f64>)>;
       /// Eccentricity scalar measure only, of any point
       fn ecc(self, d:usize, v:&[f64]) -> f64;
       /// Median and quartiles of eccentricities (new robust measure of spread of a multivariate sample)
       fn moe(self, d:usize) -> Med;
       /// Medoid and Outlier as defined by eccentricities.
       fn emedoid(self, d:usize) -> (f64,usize,f64,usize);

       /// Geometric median of the set
       fn nmedian(self, d:usize, eps:f64) -> Result<Vec<f64>>;
       /// Trend between two sets
       fn trend(self, d:usize, eps:f64, v:&[f64]) -> Vec<f64>;
       /// Transform to zero median form. or subtract any other vector `m`
       fn setsub(self, d:usize, m:&[f64]) -> Vec<f64>;
    */
}

/// Mutable primitive vector operations.  
/// Some of the Vec trait methods reimplemented to mutate in-place (for efficiency).
pub trait MutVectors {
    /// mutable multiplication by a scalar
    fn mutsmult(self, s: f64);
    /// mutable vector subtraction
    fn mutvsub(self, v: &[f64]);
    /// mutable vector addition
    fn mutvadd(self, v: &[f64]);
    /// mutably makes into a unit vector
    fn mutvunit(self); 
}

/// Methods applicable to sets of vectors
pub trait VecVec {
    /// Centroid = euclidian mean of a set of points
    fn acentroid(self) -> Vec<f64>;
    /// Sums of distances from each point to all other points
    fn distances(self) -> Vec<f64>;
    /// Sum of distances from one point given by indx
    fn distsuminset(self, indx: usize) -> f64;
    /// Sum of distances from arbitrary point (v) to all the points in self   
    fn distsum(self, v: &[f64]) -> f64;
    /// Medoid and Outlier (by distance) of a set of points
    fn medoid(self) -> (f64, usize, f64, usize);

    /// Eccentricity vectors from each point
    fn eccentricities(self) -> Vec<Vec<f64>>;
    /// Ecentricity scalar measure of an internal point given by indx
    fn eccentrinset(self, indx: usize) -> f64;
    /// Eccentricity scalar measure and vector of any point     
    fn veccentr(self, thisp: &[f64]) -> (f64, Vec<f64>);
    /// Eccentricity scalar measure only, of any point
    fn ecc(self, v: &[f64]) -> f64;
    /// magnitudes of a set of vectors
    fn mags(self) -> Vec<f64>;
    /// scaled magnitudes (typically of eccentricities measures)
    fn scalarecc(self) -> Vec<f64>;
    /// Median and quartiles of eccentricities (new robust measure of spread of a multivariate sample)
    fn moe(self) -> Med;
    /// Medoid and Outlier as defined by eccentricities.
    fn emedoid(self) -> (f64, usize, f64, usize);

    /// Geometric median of a set
    fn nmedian(self, eps: f64) -> Vec<f64>;
    /// Betterpoint gives new approximation to nmedian
    fn betterpoint(self, v: &[f64]) -> (f64, Vec<f64>);
    /// Trend between two sets
    fn trend(self, eps: f64, v: Vec<Vec<f64>>) -> Vec<f64>;
    /// Transform to zero median form. or subtract any other vector `m`
    fn translate(self, m: &[f64]) -> Vec<Vec<f64>>;
}