rush/tests/simplification_test.rs
Rowan Torbitzky-Lane c7ec6e110b
All checks were successful
/ Test-Suite (push) Successful in 32s
simplification test forgor 💀
2025-04-30 02:40:50 -05:00

96 lines
3.1 KiB
Rust

use polars::prelude::*;
use rush::gp::simplification::auto_simplify_plushy;
use rush::gp::utils::polars_to_gene;
use rush::instructions::numeric::*;
use rush::push::interpreter::interpret_program;
use rush::push::state::Gene;
use rush::push::utils::most_genes;
use rush::{gp::args::PushArgs, push::state::EMPTY_STATE};
use rust_decimal::prelude::FromPrimitive;
use rust_decimal::{Decimal, dec};
/// This is a prototype for an error function. I'm hoping to have some of this
/// refined later.
fn test_error_function(
push_args: &PushArgs,
data: &DataFrame,
push_program: Vec<Gene>,
) -> Vec<Decimal> {
let mut error_vec: Vec<Decimal> = vec![];
let y = data
.column("y")
.unwrap()
.i32()
.unwrap()
.into_iter()
.map(|opt| opt.map(|v| v as i128))
.collect::<Option<Vec<_>>>()
.unwrap(); // How to convert a series to a vector everybody
let x = data.drop("y").unwrap();
// println!("x: {x:#?}");
// println!("y: {y:#?}");
for n in 0..x.height() {
let mut state = EMPTY_STATE;
let mut inputs: Vec<Gene> = Vec::with_capacity(x.width());
let row = x.get_row(n).unwrap();
for datum in row.0.iter() {
inputs.push(polars_to_gene(datum))
}
state.exec.extend(push_program.clone().into_iter()); // load the program
state.input.extend(inputs.clone().into_iter()); // Make inputs available to the state
interpret_program(&mut state, push_args.step_limit, push_args.max_stack_size);
if let Some(top_int) = state.int.pop() {
error_vec.push(Decimal::from_i128((y[n] - top_int).abs()).unwrap());
} else {
error_vec.push(dec!(999999.0)) // super large error if no stack item.
}
}
// println!("{:?}", error_vec);
error_vec
}
#[test]
fn simplification_function_test() {
let train_df: DataFrame = df!(
"x0" => [4, 5, 6],
"x1" => [7, 8, 9],
"y" => [11, 13, 15],
)
.unwrap();
println!("{}", train_df);
// println!("{:#?}", train_df["x0"]);
// push program declaration
let push_program: Vec<Gene> = vec![
Gene::StateFunc(int_inc), // Should get simplified out
Gene::StateFunc(float_tan), // along with all these float instructions
Gene::StateFunc(float_sub),
Gene::StateFunc(int_add), // stays
Gene::StateFunc(float_tan),
Gene::StateFunc(float_sub),
Gene::StateFunc(float_rem),
Gene::StateFunc(float_inc),
Gene::Place(0), // stays
Gene::Place(1), // stays
];
let mut args = PushArgs::new();
args.training_data = Some(train_df.clone());
args.instructions = Some(most_genes());
args.simplification_steps = 100;
args.error_function = Some(test_error_function);
// test_error_function(&args, &train_df, push_program);
// test the auto simplification here
let simplified_genome = auto_simplify_plushy(push_program, args.error_function.unwrap(), args);
assert_eq!(
vec![Gene::StateFunc(int_add), Gene::Place(0), Gene::Place(1)],
simplified_genome
)
}