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
///#Description ///Rank and Fetch adds generic vector ranking and fetching features. It adds vector.rank() and vector.fetch(&my_vec__usize_picks) functionality. ///rank() counts the number of items in a generic vector and returns the a vector of counts for each item greater than itself. Useful for nonparametric statistics with order rather than distances. ///fetch() is intended for user specified subsampling of generic data, and tolerates index errors, but could be used for building old school 8bit character based levels. /// /// This is the early days in rust for me, and my first published crate. I like what it does and it seems to work well enough. Please leave feedback if /// /// #License /// Creative Commons Zero. Use at your own risk, I'm basically a sweaty gorilla that can press computer keys and this is my first published crate. /// Oh, bonus: fn sockball is used to pair an index value to a generic value. Useful, but maybe only if you want to couple tuples for reversing a vector sort. pub fn sockball<T>(a: usize, b: T) -> (T, usize) { //couples any type T with a usize index value return (b, a); //returns a unnamed tupple type, INDEX last } /// vector.rank() borrows a generic vector and returns a usize vector list of the count of greater items for each item. A rank system described by Wassily Hoeffding in 1947 that's like the olympics, but with a zeroth place instead of gold. /// the intended us for rank() is nonparametric statistics. pub fn rank_count_greater<T: PartialOrd + Clone>(vector: &Vec<T>) -> Vec<usize> { //pass in a vector, pass out a sorted list of positions, not values A,C,B -> 1,3,2 if vector.len() < 2 { if vector.is_empty() { let temp: Vec<usize> = vec![]; return temp; } //empty vector for empty vector return vec![0usize]; //return zero as nothing else is larger than first element. } let index: Vec<usize> = (0..vector.len()).collect(); let mut tups = vec![]; for i in 0..index.len() { tups.push(sockball(index[i], vector[i].clone())); //need to clone borrowed vector to sort //note: sockball takes index and vector and returns [vector and index] } tups.sort_by(|a, b| a.partial_cmp(b).unwrap()); //now tups is sorted and index has become elemental position order from low to high let mut fetchorder: Vec<usize> = vec![]; let mut fetchclone: Vec<usize> = vec![]; let mut ranking: Vec<usize> = vec![0]; //first or largest element must be zero for each in tups { let indey = each.1; let index = each.1; fetchorder.push(index); // pull apart tups into fetch ordering and value vector; fetchclone.push(indey); } let mut rank: usize = 0; //three preinit's before while loop let mut same: usize = 0; let mut last: usize = fetchorder.pop().unwrap(); //Already insured vector contains two elements, so unwrap while !fetchorder.is_empty() { let next: usize = fetchorder.pop().unwrap(); //while loop exits when empty so ok to unwrap & does not run on None() condition if vector[last] > vector[next] { rank = rank + 1 + same; same = 0; ranking.push(rank); // print!(">{} ",last); } else { same = same + 1; //print!("={} ",last); ranking.push(rank); } last = next; } //count of greater than items now exists that may be correlated unsorted order //fetchorder is empty let _iterator = 0usize; let mut fetchorder: Vec<usize> = vec![]; for _i in 0..vector.len() { // simple costs "do twice" brush up on box fetchorder.push(0usize); } for i in fetchclone { fetchorder[i] = ranking.pop().unwrap(); //ranking built in reverse order } //rebuild fetchorder return fetchorder; } /// vector.fetch(&my_borrowed_usize_list) will return a vector of your usized picks. Error tollerant and useful for user guided selective statistics, computation of quatriles and building scrolling levels out of 8 bit character bitmaps (maybe?) /// use one of two ways: genericvector.fetch(&vector_usize_index_picks) or from the function with fetch_guard(&genericvector, &your_usize_picklist) pub fn fetch_guard<T: Clone>(vector: &Vec<T>, picks: &Vec<usize>) -> Vec<T> { ///a error tollerant function that gathers picks items from a vector list let limit = vector.len(); let mut result = vec![]; for each in picks { if *each < limit { result.push(vector[*each].clone()) } else { eprint!("!Warn! fn fetch_guard: No item index {} in vec list of {} items. Returning computable results!\n",*each,limit); } } return result; } /// pub trait FetchGuards<T: Clone> { //A new trait to apply to data fn fetch(&self, index: &Vec<usize>) -> Vec<T>; //index: &Vec<usize> is pretty specific and not very flexible or DRY. } //Dry means Don't Repeat Yourself. Re-write for use with [boxes] or hashes or whatever. impl<T> FetchGuards<T> for Vec<T> //This line is high idea density. <T> may refer to the memory lifetime of the type or the Vector of type <T> where T: Clone, //T needs to have a trait 'Clone' (can be copied) for FetchGuards to work. Not all situations allow memory safely faithfully copies { fn fetch(&self, index: &Vec<usize>) -> Vec<T> { //the method will be implemented thus: myvector.fetch( picklist ) and return a new vector of type <T> fetch_guard(&self, &index) //Note it borrows the original vector. } } pub trait Rankable<T>: Clone + PartialOrd { fn rank(&self) -> Vec<usize>; } impl<T> Rankable<T> for Vec<T> where T: Clone + PartialOrd, { fn rank(&self) -> Vec<usize> { rank_count_greater(self) } } fn main() { /// RRANK is a crate that does "counts of greater values" in the style of Wassily Hoeffding for generic vectors. /// Code by Dustan Doud of Cancellogic.com /// #Examples /// /// let let mut avec = vec![167, 205, 98, 9, 205]; /// let mut avec = vec![167, 205, 98, 9, 205]; ///{ /// println!("vector: {:?} and ranks:{:?}", &avec, avec.rank() ); /// } /// avec.push(5); /// let mut bvec:Vec<f64> = vec![]; /// for each in avec {bvec.push(each as f64)}; /// println!("a vector of floating points:\n {:?} and ranks {:?}",&bvec,bvec.rank() ); /// let svec = vec!["r","a","n","k","ed"]; /// println!("a vector of floating points:\n {:?} and ranks {:?}",&svec,svec.rank() ); /// println!("A Wassily Hoeffding style ranking crate for generic vectors that counts number of greater values for each item in a vector and returns a vector of usize with counts. \n Coded by Dustan Doud cancellogic.com \n example vec![11,5,2].rank() = {:?}",vec![11,5,2].rank()); /// let avec = vec!["s","o","r","t"]; /// let picklist = vec![2,1,3,1,2,0]; /// let restructured = avec.fetch(&picklist); /// let empty:Vec<f64> = vec![0.0]; /// println!["test of vector.fetch() functionality: {:?}",empty.fetch(&picklist)]; let _are_we_done_yet=true; }