adding first draft for xseries

This commit is contained in:
Palash Tyagi 2025-04-11 23:55:15 +01:00
parent 328fb24509
commit cf2779c5a1

163
src/core/xseries.rs Normal file
View File

@ -0,0 +1,163 @@
use std::ops::{Add, Div, Mul, Sub};
//
// 1) Define a float series: FSeries
//
#[derive(Debug, Clone)]
pub struct FSeries {
data: Vec<f64>,
}
impl FSeries {
/// Create a new FSeries from a vector of f64 values.
pub fn new(data: Vec<f64>) -> Self {
Self { data }
}
pub fn len(&self) -> usize {
self.data.len()
}
/// Elementwise helper applying an operation between two FSeries.
pub fn apply<F>(&self, other: &Self, op: F) -> Self
where
F: Fn(f64, f64) -> f64,
{
assert!(
self.len() == other.len(),
"FSeries must have the same length to apply operations."
);
let data = self
.data
.iter()
.zip(other.data.iter())
.map(|(&a, &b)| op(a, b))
.collect();
FSeries { data }
}
/// Access to the underlying data
pub fn data(&self) -> &[f64] {
&self.data
}
}
// Macros for float series arithmetic (elementwise)
macro_rules! impl_fseries_bin_op {
($trait:ident, $method:ident, $op:tt) => {
impl $trait for FSeries {
type Output = Self;
fn $method(self, rhs: Self) -> Self::Output {
self.apply(&rhs, |a, b| a $op b)
}
}
};
}
impl_fseries_bin_op!(Add, add, +);
impl_fseries_bin_op!(Sub, sub, -);
impl_fseries_bin_op!(Mul, mul, *);
impl_fseries_bin_op!(Div, div, /);
macro_rules! impl_fseries_scalar_op {
($trait:ident, $method:ident, $op:tt) => {
impl $trait<f64> for FSeries {
type Output = Self;
fn $method(mut self, scalar: f64) -> Self::Output {
for x in self.data.iter_mut() {
*x = *x $op scalar;
}
self
}
}
};
}
impl_fseries_scalar_op!(Add, add, +);
impl_fseries_scalar_op!(Sub, sub, -);
impl_fseries_scalar_op!(Mul, mul, *);
impl_fseries_scalar_op!(Div, div, /);
//
// 2) Define an integer series: ISeries
//
#[derive(Debug, Clone)]
pub struct ISeries {
data: Vec<i64>,
}
impl ISeries {
/// Create an ISeries from a vector of i64 values.
pub fn new(data: Vec<i64>) -> Self {
Self { data }
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn data(&self) -> &[i64] {
&self.data
}
/// Elementwise helper for integer series.
pub fn apply<F>(&self, other: &Self, op: F) -> Self
where
F: Fn(i64, i64) -> i64,
{
assert!(
self.len() == other.len(),
"ISeries must have the same length to apply operations."
);
let data = self
.data
.iter()
.zip(other.data.iter())
.map(|(&a, &b)| op(a, b))
.collect();
ISeries { data }
}
}
// Macros for integer series arithmetic (elementwise)
macro_rules! impl_iseries_bin_op {
($trait:ident, $method:ident, $op:tt) => {
impl $trait for ISeries {
type Output = Self;
fn $method(self, rhs: Self) -> Self::Output {
self.apply(&rhs, |a, b| a $op b)
}
}
};
}
impl_iseries_bin_op!(Add, add, +);
impl_iseries_bin_op!(Sub, sub, -);
impl_iseries_bin_op!(Mul, mul, *);
impl_iseries_bin_op!(Div, div, /); // integer division (floor trunc)
// Optional scalar operations (for i64)
macro_rules! impl_iseries_scalar_op {
($trait:ident, $method:ident, $op:tt) => {
impl $trait<i64> for ISeries {
type Output = Self;
fn $method(mut self, scalar: i64) -> Self::Output {
for x in self.data.iter_mut() {
*x = *x $op scalar;
}
self
}
}
};
}
impl_iseries_scalar_op!(Add, add, +);
impl_iseries_scalar_op!(Sub, sub, -);
impl_iseries_scalar_op!(Mul, mul, *);
impl_iseries_scalar_op!(Div, div, /); // floor/trunc division by scalar