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
pub mod indices;
pub mod merge;
use std::fmt::Write;
//use std::fmt::Pointer;

pub const GR:&str = "\x1B[01;92m";
pub const UNGR:&str = "\x1B[0m";

/// macro `here!()` gives `&str` with the current `file:line path::function` for error messages.
#[macro_export]
macro_rules! here {
    () => {{
        fn f() {}
        fn type_name_of<T>(_: T) -> &'static str {
            std::any::type_name::<T>()
        }
        let name = type_name_of(f); 
        format!("\n{}:{} {}", file!(), line!(), &name[..name.len()-3])
    }}
}

/// Minimum value, its index, Maximum value, its index
#[derive(Default)]
pub struct MinMax<T> {
    pub min: T,
    pub minindex: usize,
    pub max: T,
    pub maxindex: usize
}
impl <T>std::fmt::Display for MinMax<T> where T:Copy+std::fmt::Display {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f,"min: {}, minindex {}, max: {}, maxindex: {}", 
        self.min.gr(),self.minindex.gr(),self.max.gr(),self.maxindex.gr() )
    }
}

/// Helper function to copy and cast entire &[T] to Vec<f64>.
/// Like the standard .to_vec() method but also casts to f64 end type
pub fn tof64<T>(s: &[T]) -> Vec<f64> where T: Copy, f64: From<T> {
    s.iter().map(| &x | f64::from(x)).collect()
}

/// Method `to_str()` to serialize generic items, slices, and slices of slices.
/// Method `gr()` to serialize and make the resulting string come out in bold green when printed
pub trait Printing<T> {

    /// Method `gr()` to serialize and make the resulting string 
    /// bold green when printed.
    /// This is the default implementation applicable to all types that
    /// trait `Printing` is implemented for
    fn gr(self) -> String where Self:Sized {
        format!("{GR}{}{UNGR}",self.to_str())
    }

    /// Method to serialize generic items, slices, and slices of Vecs.  
    fn to_str(self) -> String; 
}

impl<T> Printing<T> for T  where T:std::fmt::Display {
    fn to_str(self) -> String { self.to_string() } 
}

impl<T> Printing<T> for &[T] where T:std::fmt::Display {
    fn to_str(self) -> String {
        self.iter().fold(
            String::from("["),
            |mut s,item| { write!(s," {}",item).ok(); s } )
        +" ]"    
    } 
}

impl<T> Printing<T> for &[&[T]] where T:std::fmt::Display {
    fn to_str(self) -> String {
        self.iter().fold(
            String::from("["),
            |mut s,&item| { writeln!(s," {}",item.to_str()).ok(); s } )
        +"]"    
    }
}

impl<T> Printing<T> for &[Vec<T>] where T:std::fmt::Display {
    fn to_str(self) -> String {
        self.iter().fold(
            String::from("[\n"),
            |mut s,item| { writeln!(s," {}",item.to_str()).ok(); s } )
        +"]"    
    }
}

/// This just prints the items one by one instead of serializing
pub fn printvv<T>(s: &[Vec<T>]) where T:Copy+std::fmt::Display { 
    println!("{GR}[");
    for v in s { println!(" {}",v.to_str()) }; 
    println!("]{UNGR}");
}

/// Methods to manipulate indices of `Vec<usize>` type.
pub trait Indices { 
    /// Reverse an index slice by simple reverse iteration.
    fn revindex(self) -> Vec<usize>; 
    /// Invert an index.
    fn invindex(self) -> Vec<usize>;
    /// complement of the index - turns ranks from/to ascending/descending
    fn complindex(self) -> Vec<usize>;
    /// Collect values from `v` in the order of indices in self.
    fn unindex<T: Copy>(self, v:&[T], ascending:bool) -> Vec<T>;
    /// Collects values from v, as f64s, in the order given by self index.    
    fn unindexf64<T: Copy>(self, v:&[T], ascending: bool) -> Vec<f64> where f64:From<T>;
    /// Pearson's correlation coefficient of two slices, typically the ranks.  
    fn ucorrelation(self, v: &[usize]) -> f64; 
    /// Potentially useful clone-recast of &[usize] to Vec<f64> 
    fn indx_to_f64 (self) -> Vec<f64>;
}