2025-04-27 01:41:38 +01:00

156 lines
4.7 KiB
Rust

use crate::frame::Frame;
use crate::matrix::{Axis, BoolMatrix, BoolOps, FloatMatrix, SeriesOps};
// Macro to delegate method calls to self.matrix()
macro_rules! delegate_to_matrix {
($($method_name:ident -> $return_type:ty),* $(,)?) => {
$(
fn $method_name(&self) -> $return_type {
self.matrix().$method_name()
}
)*
};
}
impl SeriesOps for Frame<f64> {
#[allow(unused_mut)]
fn apply_axis<U, F>(&self, axis: Axis, mut f: F) -> Vec<U>
where
F: FnMut(&[f64]) -> U,
{
self.matrix().apply_axis(axis, f)
}
delegate_to_matrix!(
sum_vertical -> Vec<f64>,
sum_horizontal -> Vec<f64>,
prod_horizontal -> Vec<f64>,
prod_vertical -> Vec<f64>,
cumsum_horizontal -> FloatMatrix,
cumsum_vertical -> FloatMatrix,
count_nan_vertical -> Vec<usize>,
count_nan_horizontal -> Vec<usize>,
is_nan -> BoolMatrix
);
}
impl BoolOps for Frame<bool> {
fn apply_axis<U, F>(&self, axis: Axis, f: F) -> Vec<U>
where
F: FnMut(&[bool]) -> U,
{
self.matrix().apply_axis(axis, f)
}
delegate_to_matrix!(
any_vertical -> Vec<bool>,
any_horizontal -> Vec<bool>,
all_vertical -> Vec<bool>,
all_horizontal -> Vec<bool>,
count_vertical -> Vec<usize>,
count_horizontal -> Vec<usize>,
any -> bool,
all -> bool,
count -> usize
);
}
// use crate::frame::Frame;
// use crate::matrix::{Axis, SeriesOps, FloatMatrix, BoolMatrix};
// impl SeriesOps for Frame<f64> {
// fn apply_axis<U, F>(&self, axis: Axis, mut f: F) -> Vec<U>
// where
// F: FnMut(&[f64]) -> U,
// {
// self.matrix().apply_axis(axis, f)
// }
// fn sum_vertical(&self) -> Vec<f64> {
// self.matrix().sum_vertical()
// }
// fn sum_horizontal(&self) -> Vec<f64> {
// self.matrix().sum_horizontal()
// }
// fn prod_horizontal(&self) -> Vec<f64> {
// self.matrix().prod_horizontal()
// }
// fn prod_vertical(&self) -> Vec<f64> {
// self.matrix().prod_vertical()
// }
// fn cumsum_horizontal(&self) -> FloatMatrix {
// self.matrix().cumsum_horizontal()
// }
// fn cumsum_vertical(&self) -> FloatMatrix {
// self.matrix().cumsum_vertical()
// }
// fn count_nan_vertical(&self) -> Vec<usize> {
// self.matrix().count_nan_vertical()
// }
// fn count_nan_horizontal(&self) -> Vec<usize> {
// self.matrix().count_nan_horizontal()
// }
// fn is_nan(&self) -> BoolMatrix {
// self.matrix().is_nan()
// }
// }
#[cfg(test)]
mod tests {
use super::*;
use crate::matrix::Matrix;
#[test]
fn test_series_ops() {
let col_names = vec!["A".to_string(), "B".to_string()];
let frame = Frame::new(
Matrix::from_cols(vec![vec![1.0, 2.0], vec![3.0, 4.0]]),
col_names,
None,
);
assert_eq!(frame.sum_vertical(), frame.matrix().sum_vertical());
assert_eq!(frame.sum_horizontal(), frame.matrix().sum_horizontal());
assert_eq!(frame.prod_horizontal(), frame.matrix().prod_horizontal());
assert_eq!(frame.prod_vertical(), frame.matrix().prod_vertical());
assert_eq!(
frame.cumsum_horizontal(),
frame.matrix().cumsum_horizontal()
);
assert_eq!(frame.cumsum_vertical(), frame.matrix().cumsum_vertical());
assert_eq!(
frame.count_nan_vertical(),
frame.matrix().count_nan_vertical()
);
assert_eq!(
frame.count_nan_horizontal(),
frame.matrix().count_nan_horizontal()
);
assert_eq!(frame.is_nan(), frame.matrix().is_nan());
assert_eq!(frame.apply_axis(Axis::Row, |x| x[0] + x[1]), vec![4.0, 6.0]);
}
#[test]
fn test_bool_ops() {
let col_names = vec!["A".to_string(), "B".to_string()];
let frame = Frame::new(
Matrix::from_cols(vec![vec![true, false], vec![false, true]]),
col_names,
None,
);
assert_eq!(frame.any_vertical(), vec![true, true]);
assert_eq!(frame.any_horizontal(), vec![true, true]);
assert_eq!(frame.all_horizontal(), vec![false, false]);
assert_eq!(frame.all_vertical(), vec![false, false]);
assert_eq!(frame.count_vertical(), vec![1, 1]);
assert_eq!(frame.count_horizontal(), vec![1, 1]);
assert_eq!(frame.any(), true);
assert_eq!(frame.all(), false);
assert_eq!(frame.count(), 2);
assert_eq!(
frame.apply_axis(Axis::Row, |x| x[0] && x[1]),
vec![false, false]
);
}
}