Compare commits
2 Commits
6c75c3704d
...
90361ba15b
Author | SHA1 | Date | |
---|---|---|---|
90361ba15b | |||
ce4b537a73 |
@ -1,7 +1,12 @@
|
|||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
use crate::push::state::{Gene, PushState};
|
use crate::push::state::{Gene, PushState};
|
||||||
|
|
||||||
|
fn min_max_bounds(ndx: i128, length: usize) -> usize {
|
||||||
|
max(0, min(ndx.unsigned_abs() as usize, length - 1))
|
||||||
|
}
|
||||||
|
|
||||||
/// Acts as a NoOp, does nothing with the vals list.
|
/// Acts as a NoOp, does nothing with the vals list.
|
||||||
fn _noop<T>(_: Vec<T>) -> Option<T> {
|
fn _noop<T>(_: Vec<T>) -> Option<T> {
|
||||||
None
|
None
|
||||||
@ -66,6 +71,228 @@ pub fn code_from_exec(state: &mut PushState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Duplicates an item
|
||||||
|
pub fn _dup<T: Clone>(vals: Vec<T>) -> Option<Vec<T>> {
|
||||||
|
Some(vec![vals[0].clone(), vals[0].clone()])
|
||||||
|
}
|
||||||
|
make_instruction_mult!(int, int, _dup, i128, 1);
|
||||||
|
make_instruction_mult!(float, float, _dup, Decimal, 1);
|
||||||
|
make_instruction_mult!(string, string, _dup, Vec<char>, 1);
|
||||||
|
make_instruction_mult!(boolean, boolean, _dup, bool, 1);
|
||||||
|
make_instruction_mult!(char, char, _dup, char, 1);
|
||||||
|
make_instruction_mult!(vector_int, vector_int, _dup, Vec<i128>, 1);
|
||||||
|
make_instruction_mult!(vector_float, vector_float, _dup, Vec<Decimal>, 1);
|
||||||
|
make_instruction_mult!(vector_string, vector_string, _dup, Vec<Vec<char>>, 1);
|
||||||
|
make_instruction_mult!(vector_boolean, vector_boolean, _dup, Vec<bool>, 1);
|
||||||
|
make_instruction_mult!(vector_char, vector_char, _dup, Vec<char>, 1);
|
||||||
|
make_instruction_mult!(code, code, _dup, Gene, 1);
|
||||||
|
make_instruction_mult!(exec, exec, _dup, Gene, 1);
|
||||||
|
|
||||||
|
pub fn _dup_times<T: Clone>(vals: Vec<T>, auxs: Vec<i128>) -> Option<Vec<T>> {
|
||||||
|
Some(vec![vals[0].clone(); auxs[0] as usize])
|
||||||
|
}
|
||||||
|
make_instruction_mult_aux!(int, int, _dup_times, i128, 1, int, 1, i128);
|
||||||
|
make_instruction_mult_aux!(float, float, _dup_times, Decimal, 1, int, 1, i128);
|
||||||
|
make_instruction_mult_aux!(string, string, _dup_times, Vec<char>, 1, int, 1, i128);
|
||||||
|
make_instruction_mult_aux!(boolean, boolean, _dup_times, bool, 1, int, 1, i128);
|
||||||
|
make_instruction_mult_aux!(char, char, _dup_times, char, 1, int, 1, i128);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_int,
|
||||||
|
vector_int,
|
||||||
|
_dup_times,
|
||||||
|
Vec<i128>,
|
||||||
|
1,
|
||||||
|
int,
|
||||||
|
1,
|
||||||
|
i128
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_float,
|
||||||
|
vector_float,
|
||||||
|
_dup_times,
|
||||||
|
Vec<Decimal>,
|
||||||
|
1,
|
||||||
|
int,
|
||||||
|
1,
|
||||||
|
i128
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_string,
|
||||||
|
vector_string,
|
||||||
|
_dup_times,
|
||||||
|
Vec<Vec<char>>,
|
||||||
|
1,
|
||||||
|
int,
|
||||||
|
1,
|
||||||
|
i128
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_boolean,
|
||||||
|
vector_boolean,
|
||||||
|
_dup_times,
|
||||||
|
Vec<bool>,
|
||||||
|
1,
|
||||||
|
int,
|
||||||
|
1,
|
||||||
|
i128
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(
|
||||||
|
vector_char,
|
||||||
|
vector_char,
|
||||||
|
_dup_times,
|
||||||
|
Vec<char>,
|
||||||
|
1,
|
||||||
|
int,
|
||||||
|
1,
|
||||||
|
i128
|
||||||
|
);
|
||||||
|
make_instruction_mult_aux!(code, code, _dup_times, Gene, 1, int, 1, i128);
|
||||||
|
make_instruction_mult_aux!(exec, exec, _dup_times, Gene, 1, int, 1, i128);
|
||||||
|
|
||||||
|
/// Swaps two values
|
||||||
|
pub fn _swap<T: Clone>(vals: Vec<T>) -> Option<Vec<T>> {
|
||||||
|
Some(vec![vals[0].clone(), vals[1].clone()])
|
||||||
|
}
|
||||||
|
make_instruction_mult!(int, int, _swap, i128, 2);
|
||||||
|
make_instruction_mult!(float, float, _swap, Decimal, 2);
|
||||||
|
make_instruction_mult!(string, string, _swap, Vec<char>, 2);
|
||||||
|
make_instruction_mult!(boolean, boolean, _swap, bool, 2);
|
||||||
|
make_instruction_mult!(char, char, _swap, char, 2);
|
||||||
|
make_instruction_mult!(vector_int, vector_int, _swap, Vec<i128>, 2);
|
||||||
|
make_instruction_mult!(vector_float, vector_float, _swap, Vec<Decimal>, 2);
|
||||||
|
make_instruction_mult!(vector_string, vector_string, _swap, Vec<Vec<char>>, 2);
|
||||||
|
make_instruction_mult!(vector_boolean, vector_boolean, _swap, Vec<bool>, 2);
|
||||||
|
make_instruction_mult!(vector_char, vector_char, _swap, Vec<char>, 2);
|
||||||
|
make_instruction_mult!(code, code, _swap, Gene, 2);
|
||||||
|
make_instruction_mult!(exec, exec, _swap, Gene, 2);
|
||||||
|
|
||||||
|
/// Rotates three values
|
||||||
|
pub fn _rotate<T: Clone>(vals: Vec<T>) -> Option<Vec<T>> {
|
||||||
|
Some(vec![vals[2].clone(), vals[0].clone(), vals[1].clone()])
|
||||||
|
}
|
||||||
|
make_instruction_mult!(int, int, _rotate, i128, 3);
|
||||||
|
make_instruction_mult!(float, float, _rotate, Decimal, 3);
|
||||||
|
make_instruction_mult!(string, string, _rotate, Vec<char>, 3);
|
||||||
|
make_instruction_mult!(boolean, boolean, _rotate, bool, 3);
|
||||||
|
make_instruction_mult!(char, char, _rotate, char, 3);
|
||||||
|
make_instruction_mult!(vector_int, vector_int, _rotate, Vec<i128>, 3);
|
||||||
|
make_instruction_mult!(vector_float, vector_float, _rotate, Vec<Decimal>, 3);
|
||||||
|
make_instruction_mult!(vector_string, vector_string, _rotate, Vec<Vec<char>>, 3);
|
||||||
|
make_instruction_mult!(vector_boolean, vector_boolean, _rotate, Vec<bool>, 3);
|
||||||
|
make_instruction_mult!(vector_char, vector_char, _rotate, Vec<char>, 3);
|
||||||
|
make_instruction_mult!(code, code, _rotate, Gene, 3);
|
||||||
|
make_instruction_mult!(exec, exec, _rotate, Gene, 3);
|
||||||
|
|
||||||
|
/// Checks if two values are equal
|
||||||
|
pub fn _equal<T: Clone + Eq>(vals: Vec<T>) -> Option<bool> {
|
||||||
|
Some(vals[1] == vals[0])
|
||||||
|
}
|
||||||
|
make_instruction!(int, boolean, _equal, i128, 2);
|
||||||
|
make_instruction!(float, boolean, _equal, Decimal, 2);
|
||||||
|
make_instruction_clone!(string, boolean, _equal, Vec<char>, 2);
|
||||||
|
make_instruction!(boolean, boolean, _equal, bool, 2);
|
||||||
|
make_instruction!(char, boolean, _equal, char, 2);
|
||||||
|
make_instruction_clone!(vector_int, boolean, _equal, Vec<i128>, 2);
|
||||||
|
make_instruction_clone!(vector_float, boolean, _equal, Vec<Decimal>, 2);
|
||||||
|
make_instruction_clone!(vector_string, boolean, _equal, Vec<Vec<char>>, 2);
|
||||||
|
make_instruction_clone!(vector_boolean, boolean, _equal, Vec<bool>, 2);
|
||||||
|
make_instruction_clone!(vector_char, boolean, _equal, Vec<char>, 2);
|
||||||
|
make_instruction_clone!(code, boolean, _equal, Gene, 2);
|
||||||
|
make_instruction_clone!(exec, boolean, _equal, Gene, 2);
|
||||||
|
|
||||||
|
/// Checks if two values are not equal
|
||||||
|
pub fn _not_equal<T: Clone + Eq>(vals: Vec<T>) -> Option<bool> {
|
||||||
|
Some(vals[1] != vals[0])
|
||||||
|
}
|
||||||
|
make_instruction!(int, boolean, _not_equal, i128, 2);
|
||||||
|
make_instruction!(float, boolean, _not_equal, Decimal, 2);
|
||||||
|
make_instruction_clone!(string, boolean, _not_equal, Vec<char>, 2);
|
||||||
|
make_instruction!(boolean, boolean, _not_equal, bool, 2);
|
||||||
|
make_instruction!(char, boolean, _not_equal, char, 2);
|
||||||
|
make_instruction_clone!(vector_int, boolean, _not_equal, Vec<i128>, 2);
|
||||||
|
make_instruction_clone!(vector_float, boolean, _not_equal, Vec<Decimal>, 2);
|
||||||
|
make_instruction_clone!(vector_string, boolean, _not_equal, Vec<Vec<char>>, 2);
|
||||||
|
make_instruction_clone!(vector_boolean, boolean, _not_equal, Vec<bool>, 2);
|
||||||
|
make_instruction_clone!(vector_char, boolean, _not_equal, Vec<char>, 2);
|
||||||
|
make_instruction_clone!(code, boolean, _not_equal, Gene, 2);
|
||||||
|
make_instruction_clone!(exec, boolean, _not_equal, Gene, 2);
|
||||||
|
|
||||||
|
macro_rules! flush_state {
|
||||||
|
($in_stack:ident) => {
|
||||||
|
paste::item! {
|
||||||
|
pub fn [< $in_stack _flush >] (state: &mut PushState) {
|
||||||
|
state.$in_stack.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
flush_state!(int);
|
||||||
|
flush_state!(float);
|
||||||
|
flush_state!(string);
|
||||||
|
flush_state!(boolean);
|
||||||
|
flush_state!(char);
|
||||||
|
flush_state!(vector_int);
|
||||||
|
flush_state!(vector_float);
|
||||||
|
flush_state!(vector_string);
|
||||||
|
flush_state!(vector_boolean);
|
||||||
|
flush_state!(vector_char);
|
||||||
|
flush_state!(code);
|
||||||
|
flush_state!(exec);
|
||||||
|
|
||||||
|
macro_rules! stack_depth {
|
||||||
|
($in_stack:ident) => {
|
||||||
|
paste::item! {
|
||||||
|
pub fn [< $in_stack _depth >] (state: &mut PushState) {
|
||||||
|
state.int.push(state.$in_stack.len() as i128)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
stack_depth!(int);
|
||||||
|
stack_depth!(float);
|
||||||
|
stack_depth!(string);
|
||||||
|
stack_depth!(boolean);
|
||||||
|
stack_depth!(char);
|
||||||
|
stack_depth!(vector_int);
|
||||||
|
stack_depth!(vector_float);
|
||||||
|
stack_depth!(vector_string);
|
||||||
|
stack_depth!(vector_boolean);
|
||||||
|
stack_depth!(vector_char);
|
||||||
|
stack_depth!(code);
|
||||||
|
stack_depth!(exec);
|
||||||
|
|
||||||
|
macro_rules! yank {
|
||||||
|
($in_stack:ident, $in_type:expr) => {
|
||||||
|
paste::item! {
|
||||||
|
pub fn [< $in_stack _yank >] (state: &mut PushState) {
|
||||||
|
if state.int.is_empty() || state.$in_stack.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let in_stack_len = state.$in_stack.len();
|
||||||
|
if $in_type == "i128" && in_stack_len < 2 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// no -1 at the end, handled in the min_max_bounds function
|
||||||
|
let idx = min_max_bounds(state.int.pop().unwrap(), in_stack_len);
|
||||||
|
let item = state.$in_stack.remove(in_stack_len - idx);
|
||||||
|
state.$in_stack.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
yank!(int, "i128");
|
||||||
|
yank!(float, "");
|
||||||
|
yank!(string, "");
|
||||||
|
yank!(boolean, "");
|
||||||
|
yank!(char, "");
|
||||||
|
yank!(vector_int, "");
|
||||||
|
yank!(vector_float, "");
|
||||||
|
yank!(vector_string, "");
|
||||||
|
yank!(vector_boolean, "");
|
||||||
|
yank!(vector_char, "");
|
||||||
|
yank!(code, "");
|
||||||
|
yank!(exec, "");
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -116,4 +343,86 @@ mod tests {
|
|||||||
code_from_exec(&mut test_state);
|
code_from_exec(&mut test_state);
|
||||||
assert_eq!(vec![Gene::GeneInt(5)], test_state.code);
|
assert_eq!(vec![Gene::GeneInt(5)], test_state.code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dup_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2];
|
||||||
|
int_dup(&mut test_state);
|
||||||
|
assert_eq!(vec![1, 2, 2], test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dup_times_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![3, 2];
|
||||||
|
int_dup_times(&mut test_state);
|
||||||
|
assert_eq!(vec![3, 3], test_state.int);
|
||||||
|
|
||||||
|
test_state.char = vec!['a', 'b'];
|
||||||
|
test_state.int = vec![3];
|
||||||
|
char_dup_times(&mut test_state);
|
||||||
|
assert_eq!(vec!['a', 'b', 'b', 'b'], test_state.char);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn swap_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2];
|
||||||
|
int_swap(&mut test_state);
|
||||||
|
assert_eq!(vec![2, 1], test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rotate_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2, 3];
|
||||||
|
int_rotate(&mut test_state);
|
||||||
|
assert_eq!(vec![1, 3, 2], test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn equal_not_equal_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2, 3];
|
||||||
|
int_equal(&mut test_state);
|
||||||
|
assert_eq!(vec![false], test_state.boolean);
|
||||||
|
test_state.boolean.clear();
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2, 2];
|
||||||
|
int_equal(&mut test_state);
|
||||||
|
assert_eq!(vec![true], test_state.boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn flush_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2, 3];
|
||||||
|
int_flush(&mut test_state);
|
||||||
|
assert_eq!(Vec::<i128>::new(), test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn stack_depth_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2, 3];
|
||||||
|
int_depth(&mut test_state);
|
||||||
|
assert_eq!(vec![1, 2, 3, 3], test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn yank_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.int = vec![1, 2, 3, 4, 5, 6, 7, 8, 2];
|
||||||
|
int_yank(&mut test_state);
|
||||||
|
assert_eq!(vec![1, 2, 3, 4, 5, 7, 8, 6], test_state.int);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,8 +224,13 @@ pub mod macros {
|
|||||||
aux_inputs.push(state.$aux_stack[aux_stack_len - n].clone());
|
aux_inputs.push(state.$aux_stack[aux_stack_len - n].clone());
|
||||||
}
|
}
|
||||||
for n in 1..=$fn_arity {
|
for n in 1..=$fn_arity {
|
||||||
|
if std::any::type_name::<$fn_type>() == std::any::type_name::<$aux_type>() {
|
||||||
|
inputs.push(state.$in_stack[in_stack_len - $aux_arity - n].clone());
|
||||||
|
} else {
|
||||||
inputs.push(state.$in_stack[in_stack_len - n].clone());
|
inputs.push(state.$in_stack[in_stack_len - n].clone());
|
||||||
}
|
}
|
||||||
|
//inputs.push(state.$in_stack[in_stack_len - n].clone());
|
||||||
|
}
|
||||||
if let Some(result) = $fn_name(inputs, aux_inputs) {
|
if let Some(result) = $fn_name(inputs, aux_inputs) {
|
||||||
for _ in 0..$aux_arity {
|
for _ in 0..$aux_arity {
|
||||||
state.$aux_stack.pop();
|
state.$aux_stack.pop();
|
||||||
@ -487,6 +492,13 @@ pub fn vector_int_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
vector_int_sort_reverse,
|
vector_int_sort_reverse,
|
||||||
vector_int_insert,
|
vector_int_insert,
|
||||||
vector_int_insert_vector,
|
vector_int_insert_vector,
|
||||||
|
vector_int_mean,
|
||||||
|
vector_int_maximum,
|
||||||
|
vector_int_minimum,
|
||||||
|
vector_int_sum,
|
||||||
|
vector_int_mode,
|
||||||
|
vector_int_two_norm,
|
||||||
|
vector_int_cumulative_sum,
|
||||||
// common.rs
|
// common.rs
|
||||||
vector_int_pop,
|
vector_int_pop,
|
||||||
]
|
]
|
||||||
@ -533,6 +545,13 @@ pub fn vector_float_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
vector_float_sort_reverse,
|
vector_float_sort_reverse,
|
||||||
vector_float_insert,
|
vector_float_insert,
|
||||||
vector_float_insert_vector,
|
vector_float_insert_vector,
|
||||||
|
vector_float_mean,
|
||||||
|
vector_float_maximum,
|
||||||
|
vector_float_minimum,
|
||||||
|
vector_float_sum,
|
||||||
|
vector_float_mode,
|
||||||
|
vector_float_two_norm,
|
||||||
|
vector_float_cumulative_sum,
|
||||||
// common.rs
|
// common.rs
|
||||||
vector_float_pop,
|
vector_float_pop,
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
use rust_decimal::prelude::*;
|
use rust_decimal::prelude::*;
|
||||||
use std::ops::{Add, Div};
|
use std::ops::{Add, Div, Mul};
|
||||||
|
|
||||||
/// This trait houses various methods for making instructions
|
/// This trait houses various methods for making instructions
|
||||||
/// more generic instead of declaring a separate function for each
|
/// more generic instead of declaring a separate function for each
|
||||||
@ -8,7 +8,9 @@ use std::ops::{Add, Div};
|
|||||||
///
|
///
|
||||||
/// Trig functions named safe rather than checked to not overlap
|
/// Trig functions named safe rather than checked to not overlap
|
||||||
/// with Decimal library's checked function names.
|
/// with Decimal library's checked function names.
|
||||||
pub trait NumericTrait: Sized + Add<Output = Self> + Div<Output = Self> + Ord {
|
pub trait NumericTrait:
|
||||||
|
Sized + Add<Output = Self> + Mul<Output = Self> + Div<Output = Self> + Ord
|
||||||
|
{
|
||||||
fn checked_div(self, v: Self) -> Option<Self>;
|
fn checked_div(self, v: Self) -> Option<Self>;
|
||||||
fn checked_mod(self, v: Self) -> Option<Self>;
|
fn checked_mod(self, v: Self) -> Option<Self>;
|
||||||
fn increment(self) -> Self;
|
fn increment(self) -> Self;
|
||||||
@ -74,7 +76,7 @@ impl NumericTrait for Decimal {
|
|||||||
dec!(0.0)
|
dec!(0.0)
|
||||||
}
|
}
|
||||||
fn from_usize(num: usize) -> Self {
|
fn from_usize(num: usize) -> Self {
|
||||||
Decimal::new(num as i64, 0)
|
rust_decimal::prelude::FromPrimitive::from_usize(num).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::instructions::utils::NumericTrait;
|
use crate::instructions::utils::NumericTrait;
|
||||||
use crate::push::state::{Gene, PushState};
|
use crate::push::state::{Gene, PushState};
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
/// Generates an index between 0 and length. Takes abs(num) and then mods it by length.
|
/// Generates an index between 0 and length. Takes abs(num) and then mods it by length.
|
||||||
@ -1573,6 +1573,9 @@ make_instruction_aux!(string, string, _insert_vector, Vec<char>, 2, int, 1, i128
|
|||||||
|
|
||||||
/// Takes the mean of a vector
|
/// Takes the mean of a vector
|
||||||
pub fn _mean<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<T> {
|
pub fn _mean<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<T> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(T::zero());
|
||||||
|
}
|
||||||
let mut fin_num = T::zero();
|
let mut fin_num = T::zero();
|
||||||
for num in vals[0].clone().into_iter() {
|
for num in vals[0].clone().into_iter() {
|
||||||
fin_num = fin_num + num;
|
fin_num = fin_num + num;
|
||||||
@ -1582,6 +1585,115 @@ pub fn _mean<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<T> {
|
|||||||
make_instruction_clone!(vector_int, int, _mean, Vec<i128>, 1);
|
make_instruction_clone!(vector_int, int, _mean, Vec<i128>, 1);
|
||||||
make_instruction_clone!(vector_float, float, _mean, Vec<Decimal>, 1);
|
make_instruction_clone!(vector_float, float, _mean, Vec<Decimal>, 1);
|
||||||
|
|
||||||
|
/// Takes the max of a vector
|
||||||
|
pub fn _maximum<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<T> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(T::zero());
|
||||||
|
}
|
||||||
|
Some(vals[0].iter().max()?.clone())
|
||||||
|
}
|
||||||
|
make_instruction_clone!(vector_int, int, _maximum, Vec<i128>, 1);
|
||||||
|
make_instruction_clone!(vector_float, float, _maximum, Vec<Decimal>, 1);
|
||||||
|
|
||||||
|
/// Takes the min of a vector
|
||||||
|
pub fn _minimum<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<T> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(T::zero());
|
||||||
|
}
|
||||||
|
Some(vals[0].iter().min()?.clone())
|
||||||
|
}
|
||||||
|
make_instruction_clone!(vector_int, int, _minimum, Vec<i128>, 1);
|
||||||
|
make_instruction_clone!(vector_float, float, _minimum, Vec<Decimal>, 1);
|
||||||
|
|
||||||
|
/// Takes the sum of a vector
|
||||||
|
pub fn _sum<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<T> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(T::zero());
|
||||||
|
}
|
||||||
|
let mut fin_num = T::zero();
|
||||||
|
for num in vals[0].clone().into_iter() {
|
||||||
|
fin_num = fin_num + num;
|
||||||
|
}
|
||||||
|
Some(fin_num)
|
||||||
|
}
|
||||||
|
make_instruction_clone!(vector_int, int, _sum, Vec<i128>, 1);
|
||||||
|
make_instruction_clone!(vector_float, float, _sum, Vec<Decimal>, 1);
|
||||||
|
|
||||||
|
/// Takes the mode of a vector
|
||||||
|
pub fn _mode<T: NumericTrait + Clone + Hash + Copy>(vals: Vec<Vec<T>>) -> Option<T> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(T::zero());
|
||||||
|
}
|
||||||
|
let mut counts = HashMap::new();
|
||||||
|
vals[0]
|
||||||
|
.iter()
|
||||||
|
.max_by_key(|&x| {
|
||||||
|
let count = counts.entry(x).or_insert(0);
|
||||||
|
*count += 1;
|
||||||
|
*count
|
||||||
|
})
|
||||||
|
.copied()
|
||||||
|
}
|
||||||
|
make_instruction_clone!(vector_int, int, _mode, Vec<i128>, 1);
|
||||||
|
make_instruction_clone!(vector_float, float, _mode, Vec<Decimal>, 1);
|
||||||
|
|
||||||
|
/// Adds the squares of all values in a vector and then takes the square root
|
||||||
|
pub fn _two_norm<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<T> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(T::zero());
|
||||||
|
}
|
||||||
|
let mut fin_num = T::zero();
|
||||||
|
for num in vals[0].clone().into_iter() {
|
||||||
|
fin_num = fin_num + (num.clone() * num);
|
||||||
|
}
|
||||||
|
fin_num.safe_sqrt()
|
||||||
|
}
|
||||||
|
make_instruction_clone!(vector_int, int, _two_norm, Vec<i128>, 1);
|
||||||
|
make_instruction_clone!(vector_float, float, _two_norm, Vec<Decimal>, 1);
|
||||||
|
|
||||||
|
/// Takes the cumulative sum of a vector
|
||||||
|
pub fn _cumulative_sum<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<Vec<T>> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(vec![]);
|
||||||
|
}
|
||||||
|
let mut fin_num = T::zero();
|
||||||
|
let mut ret_vec = vec![];
|
||||||
|
for num in vals[0].clone().into_iter() {
|
||||||
|
fin_num = fin_num + num;
|
||||||
|
ret_vec.push(fin_num.clone());
|
||||||
|
}
|
||||||
|
Some(ret_vec)
|
||||||
|
}
|
||||||
|
make_instruction_clone!(vector_int, vector_int, _cumulative_sum, Vec<i128>, 1);
|
||||||
|
make_instruction_clone!(vector_float, vector_float, _cumulative_sum, Vec<Decimal>, 1);
|
||||||
|
|
||||||
|
/* /// Takes the cumulative mean of a vector
|
||||||
|
pub fn _cumulative_mean<T: NumericTrait + Clone>(vals: Vec<Vec<T>>) -> Option<Vec<T>> {
|
||||||
|
if vals[0].is_empty() {
|
||||||
|
return Some(vec![]);
|
||||||
|
}
|
||||||
|
// This is not an efficient implementation
|
||||||
|
let mut ret_vec = vec![];
|
||||||
|
let mut cum_vec = vec![];
|
||||||
|
for (idx, val) in vals[0].iter().enumerate() {
|
||||||
|
cum_vec.push(val.clone());
|
||||||
|
let mut temp_sum = T::zero();
|
||||||
|
for num in &cum_vec {
|
||||||
|
temp_sum = temp_sum + num.clone();
|
||||||
|
}
|
||||||
|
temp_sum
|
||||||
|
}
|
||||||
|
Some(ret_vec)
|
||||||
|
}
|
||||||
|
make_instruction_clone!(vector_int, vector_int, _cumulative_mean, Vec<i128>, 1);
|
||||||
|
make_instruction_clone!(
|
||||||
|
vector_float,
|
||||||
|
vector_float,
|
||||||
|
_cumulative_mean,
|
||||||
|
Vec<Decimal>,
|
||||||
|
1
|
||||||
|
);*/
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -2330,4 +2442,64 @@ mod tests {
|
|||||||
vector_float_mean(&mut test_state);
|
vector_float_mean(&mut test_state);
|
||||||
assert_eq!(vec![dec!(5.0)], test_state.float);
|
assert_eq!(vec![dec!(5.0)], test_state.float);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn minimum_maximum_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
vector_int_maximum(&mut test_state);
|
||||||
|
assert_eq!(vec![5], test_state.int);
|
||||||
|
test_state.int.clear();
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
vector_int_minimum(&mut test_state);
|
||||||
|
assert_eq!(vec![0], test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sum_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
vector_int_sum(&mut test_state);
|
||||||
|
assert_eq!(vec![17], test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mode_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
vector_int_mode(&mut test_state);
|
||||||
|
assert_eq!(vec![2], test_state.int);
|
||||||
|
test_state.int.clear();
|
||||||
|
|
||||||
|
// returns the last mode to be calculated
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2, 4, 3]];
|
||||||
|
vector_int_mode(&mut test_state);
|
||||||
|
assert_eq!(vec![3], test_state.int);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sqrt_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![5, 5, 5, 5]];
|
||||||
|
vector_int_two_norm(&mut test_state);
|
||||||
|
assert_eq!(vec![10], test_state.int);
|
||||||
|
|
||||||
|
test_state.vector_float = vec![vec![dec!(5.0), dec!(5.0), dec!(5.0), dec!(5.0)]];
|
||||||
|
vector_float_two_norm(&mut test_state);
|
||||||
|
assert_eq!(vec!(dec!(10.0)), test_state.float);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cumulative_sum_test() {
|
||||||
|
let mut test_state = EMPTY_STATE;
|
||||||
|
|
||||||
|
test_state.vector_int = vec![vec![0, 1, 2, 3, 4, 5, 2]];
|
||||||
|
vector_int_cumulative_sum(&mut test_state);
|
||||||
|
assert_eq!(vec![vec![0, 1, 3, 6, 10, 15, 17]], test_state.vector_int);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user