use crate::traits::{
math::Vector,
fp::FPVector,
};
use crate::structure::matrix::{Matrix, Shape};
use crate::util::non_macro::zeros_shape;
pub trait VecOps: Vector {
type Scalar;
fn add_v(&self, v: &Self) -> Self;
fn sub_v(&self, v: &Self) -> Self;
fn mul_v(&self, v: &Self) -> Self;
fn div_v(&self, v: &Self) -> Self;
fn add_s(&self, s: Self::Scalar) -> Self;
fn sub_s(&self, s: Self::Scalar) -> Self;
fn mul_s(&self, s: Self::Scalar) -> Self;
fn div_s(&self, s: Self::Scalar) -> Self;
}
pub trait Scalable {
type Vec;
fn resize(&self, size: (usize, usize), shape: Shape) -> Matrix;
fn add_col(&self, v: &Self::Vec) -> Matrix;
fn add_row(&self, v: &Self::Vec) -> Matrix;
}
pub trait ScalableMut {
type Vec;
fn resize_mut(&mut self, size: (usize, usize), shape: Shape);
fn add_col_mut(&mut self, v: &Self::Vec);
fn add_row_mut(&mut self, v: &Self::Vec);
}
impl VecOps for Vec<f64> {
type Scalar = f64;
fn add_v(&self, v: &Self) -> Self {
self.add_vec(&v)
}
fn sub_v(&self, v: &Self) -> Self {
self.zip_with(|x, y| x - y, v)
}
fn mul_v(&self, v: &Self) -> Self {
self.zip_with(|x, y| x * y, v)
}
fn div_v(&self, v: &Self) -> Self {
self.zip_with(|x, y| x / y, v)
}
fn add_s(&self, s: Self::Scalar) -> Self {
self.fmap(|x| x + s)
}
fn sub_s(&self, s: Self::Scalar) -> Self {
self.fmap(|x| x - s)
}
fn mul_s(&self, s: Self::Scalar) -> Self {
self.mul_scalar(s)
}
fn div_s(&self, s: Self::Scalar) -> Self {
self.fmap(|x| x / s)
}
}
impl Scalable for Vec<f64> {
type Vec = Self;
fn resize(&self, (r, c): (usize, usize), shape: Shape) -> Matrix {
assert_eq!(self.len(), r * c);
let mut m = zeros_shape(r, c, shape);
m.data = self[..].to_vec();
m
}
fn add_row(&self, v: &Self::Vec) -> Matrix {
assert_eq!(self.len(), v.len());
let mut x = self[..].to_vec();
x.extend_from_slice(&v[..]);
x.resize((2, self.len()), Shape::Row)
}
fn add_col(&self, v: &Self::Vec) -> Matrix {
assert_eq!(self.len(), v.len());
let mut x = self[..].to_vec();
x.extend_from_slice(&v[..]);
x.resize((self.len(), 2), Shape::Col)
}
}
impl Scalable for Matrix {
type Vec = Vec<f64>;
fn resize(&self, (r, c): (usize, usize), shape: Shape) -> Matrix {
assert_eq!(self.row * self.col, r * c);
let mut m = zeros_shape(r, c, shape);
m.data = self.data[..].to_vec();
m
}
fn add_row(&self, v: &Self::Vec) -> Matrix {
assert_eq!(self.col, v.len());
match self.shape {
Shape::Row => {
let mut m = self.clone();
m.data.extend_from_slice(&v[..]);
m.row += 1;
m
}
Shape::Col => {
let mut m = self.change_shape();
m.data.extend_from_slice(&v[..]);
m.row += 1;
m
}
}
}
fn add_col(&self, v: &Self::Vec) -> Matrix {
assert_eq!(self.row, v.len());
match self.shape {
Shape::Col => {
let mut m = self.clone();
m.data.extend_from_slice(&v[..]);
m.col += 1;
m
}
Shape::Row => {
let mut m = self.change_shape();
m.data.extend_from_slice(&v[..]);
m.col += 1;
m
}
}
}
}
impl ScalableMut for Matrix {
type Vec = Vec<f64>;
fn resize_mut(&mut self, (r, c): (usize, usize), shape: Shape) {
assert_eq!(self.row * self.col, r * c);
self.row = r;
self.col = c;
self.shape = shape;
}
fn add_row_mut(&mut self, v: &Self::Vec) {
assert_eq!(self.col, v.len());
match self.shape {
Shape::Row => {
self.data.extend_from_slice(&v[..]);
self.row += 1;
}
Shape::Col => {
self.change_shape_mut();
self.data.extend_from_slice(&v[..]);
self.row += 1;
}
}
}
fn add_col_mut(&mut self, v: &Self::Vec) {
assert_eq!(self.row, v.len());
match self.shape {
Shape::Col => {
self.data.extend_from_slice(&v[..]);
self.col += 1;
}
Shape::Row => {
self.change_shape_mut();
self.data.extend_from_slice(&v[..]);
self.col += 1;
}
}
}
}