use std::iter::FromIterator;
use std::cmp::Ordering;
pub fn sort_perm< T: Ord >( vec: & Vec< T > ) -> Vec< usize > {
let mut indices = (0..vec.len()).collect::<Vec<_>>();
indices.sort_by_key(|&i| & vec[i]);
indices
}
pub fn sort_perm_by_key< T, K: Ord, F: FnMut(&T)-> K >( vec: & Vec< T >, mut get_key: F ) -> Vec< usize > {
let mut indices = (0..vec.len()).collect::<Vec<_>>();
indices.sort_by_key(|&i| get_key(& vec[i]) );
indices
}
pub fn sort_perm_by< T, F: FnMut(&T,&T)-> Ordering >( vec: & Vec< T >, mut compare: F ) -> Vec< usize > {
let mut indices = (0..vec.len()).collect::<Vec<_>>();
indices.sort_by(|&i,&j| compare( &vec[i], &vec[j] ) );
indices
}
pub fn inverse_perm( vec: & Vec< usize > ) -> Vec< usize > {
let mut inv_perm = Vec::from_iter( std::iter::repeat(0).take( vec.len()) );
inv_perm.shrink_to_fit();
for (ind_count, ind) in vec.iter().enumerate() {
inv_perm[ *ind ] = ind_count;
}
inv_perm
}
pub trait SuperIndex < T >
{
fn sindex( &self, index: usize, super_value: T ) -> T;
}
impl < T > SuperIndex < T > for Vec< T >
where T: Clone
{
fn sindex( &self, index: usize, super_value: T ) -> T { if self.len() > index { self[ index ].clone() } else { super_value } }
}
pub fn compose_f_after_g< T: Clone > ( f: &Vec< T >, g: &Vec< usize > ) -> Vec< T > {
Vec::from_iter( g.iter().map(|x| f[ *x ].clone() ) )
}
pub trait EndIndex< T >
{
fn end_index ( &self ) -> Option< usize > ;
}
impl < T > EndIndex< T > for Vec< T >
{
fn end_index( &self ) -> Option< usize > {
match self.is_empty() {
true => None,
false => Some(self.len() - 1)
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct SuperVec< T > {
pub vec: Vec< T >,
pub val: T
}
impl < T > SuperVec < T >
where T : Clone + PartialEq
{
pub fn val( &self, index: usize ) -> T {
println!("PREFER USING SINDEX TRAIT ON VECTORS (DEFINED ABOVE) TO CREATING THIS STRUCT");
if index < self.vec.len() { self.vec[ index ].clone() }
else { self.val.clone() }
}
}
#[cfg(test)]
mod tests {
use itertools::Itertools;
use crate::utilities::binary_search::find_sorted_binary_tuple;
use super::*;
#[test]
fn test_sort_perm()
{
let v = vec![1, 2, 3, 4, 2, 1, 2, 2, 1, 4, 3];
let new_to_old = sort_perm( & v );
let old_to_new = inverse_perm( & new_to_old );
let mut v_sorted = v.clone();
v_sorted.sort();
let ascend = Vec::from_iter( 0..v.len() );
println!("{:?}", compose_f_after_g(&v, &new_to_old));
println!("{:?}", compose_f_after_g(&old_to_new, &new_to_old));
println!("{:?}", compose_f_after_g(&new_to_old, &old_to_new));
assert_eq!( &compose_f_after_g(&v, &new_to_old),
&v_sorted );
assert_eq!( &compose_f_after_g(&old_to_new, &new_to_old),
&ascend );
assert_eq!( &compose_f_after_g(&new_to_old, &old_to_new),
&ascend );
}
#[test]
fn test_find_sorted_binary() {
for veclen in 0 .. 8usize {
for set in (0..veclen).powerset() {
let sparsevec = set.iter().map(|x| (*x, 1.0) ).collect_vec();
for n in 0..veclen {
let in_set = set.contains(&n);
let in_vec = find_sorted_binary_tuple(&sparsevec, n).is_some();
assert!(!(in_set ^ in_vec));
}
}
}
}
}