Skip to content

Commit

Permalink
CHGE: Modify Vector traits (#35)
Browse files Browse the repository at this point in the history
* Now, Vector can handle generic Scalar types
  • Loading branch information
Axect committed Jan 16, 2021
1 parent 6e366f5 commit fcbad8c
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 29 deletions.
8 changes: 4 additions & 4 deletions src/numerical/ode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,15 +767,15 @@ impl<E: Environment> ODE<E> for ImplicitODE<E> {
&f(
t1,
yn.add_vec(
&k1.mul_scalar(GL4_TAB[0][1] * h)
.add_vec(&k2.mul_scalar(GL4_TAB[0][2] * h)),
&k1.mul_scalar(AD::from(GL4_TAB[0][1] * h))
.add_vec(&k2.mul_scalar(AD::from(GL4_TAB[0][2] * h))),
),
),
&f(
t2,
yn.add_vec(
&k1.mul_scalar(GL4_TAB[1][1] * h)
.add_vec(&k2.mul_scalar(GL4_TAB[1][2] * h)),
&k1.mul_scalar(AD::from(GL4_TAB[1][1] * h))
.add_vec(&k2.mul_scalar(AD::from(GL4_TAB[1][2] * h))),
),
),
)
Expand Down
6 changes: 4 additions & 2 deletions src/structure/ad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,8 @@ impl FPVector for Vec<AD> {
}

impl Vector for Vec<AD> {
type Scalar = AD;

fn add_vec<'a, 'b>(&'a self, rhs: &'b Self) -> Self {
self.add_v(rhs)
}
Expand All @@ -1266,8 +1268,8 @@ impl Vector for Vec<AD> {
self.sub_v(rhs)
}

fn mul_scalar<T: Into<f64>>(&self, rhs: T) -> Self {
self.mul_s(AD::from(rhs.into()))
fn mul_scalar(&self, rhs: Self::Scalar) -> Self {
self.mul_s(rhs)
}
}

Expand Down
28 changes: 20 additions & 8 deletions src/structure/dataframe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,11 @@ where Series: TypedVector<T> {
Series::new(v.into_iter().zip(w.into_iter()).map(|(x, y)| x - y).collect::<Vec<T>>())
}

fn mul_scalar<T: std::ops::Mul<T, Output=T> + Clone + Copy>(v: Vec<T>, s: T) -> Series
where Series: TypedVector<T> {
Series::new(v.into_iter().map(|x| x * s).collect::<Vec<T>>())
}

// =============================================================================
// Implementations of DType variables
// =============================================================================
Expand Down Expand Up @@ -963,6 +968,8 @@ impl Series {
}

impl Vector for Series {
type Scalar = Scalar;

/// Add series
///
/// # Example
Expand All @@ -979,7 +986,7 @@ impl Vector for Series {
/// }
/// ```
fn add_vec<'a, 'b>(&'a self, rhs: &'b Self) -> Self {
assert_eq!(self.dtype, rhs.dtype, "DType are not same (add_vec)");
assert_eq!(self.dtype, rhs.dtype, "DTypes are not same (add_vec)");
dtype_match!(
N;
self.dtype,
Expand All @@ -1005,7 +1012,7 @@ impl Vector for Series {
/// }
/// ```
fn sub_vec<'a, 'b>(&'a self, rhs: &'b Self) -> Self {
assert_eq!(self.dtype, rhs.dtype, "DType are not same (add_vec)");
assert_eq!(self.dtype, rhs.dtype, "DTypes are not same (add_vec)");
dtype_match!(
N;
self.dtype,
Expand All @@ -1025,16 +1032,21 @@ impl Vector for Series {
///
/// fn main() {
/// let a = Series::new(vec![1,2,3]);
/// let b = 2;
/// let b = Scalar::new(2);
/// let c = a.mul_scalar(b);
/// assert_eq!(c, Series::new(vec![2,4,6]));
/// }
/// ```
fn mul_scalar<T: Into<f64>>(&self, rhs: T) -> Self {
let a = self.to_type(F64);
let v: Vec<f64> = a.to_vec();
let b = Series::new(v.mul_scalar(rhs));
b.to_type(self.dtype)
fn mul_scalar(&self, rhs: Self::Scalar) -> Self {
assert_eq!(self.dtype, rhs.dtype, "DTypes are not same (mul_scalar)");

dtype_match!(
N;
self.dtype,
self.to_vec(),
|x| mul_scalar(x, rhs.unwrap());
Vec
)
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/structure/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,8 @@ use std::f64::NAN;
pub use self::Shape::{Col, Row};
use crate::numerical::eigen::{eigen, EigenMethod};
use crate::traits::{
fp::{FPMatrix, FPVector},
general::Algorithm,
fp::{FPMatrix, FPVector},
math::{InnerProduct, LinearOp, MatrixProduct, Norm, Normed, Vector},
mutable::MutMatrix,
};
Expand Down Expand Up @@ -1389,6 +1389,8 @@ impl Matrix {
// Mathematics for Matrix
// =============================================================================
impl Vector for Matrix {
type Scalar = f64;

fn add_vec(&self, other: &Self) -> Self {
assert_eq!(self.row, other.row);
assert_eq!(self.col, other.col);
Expand Down Expand Up @@ -1450,13 +1452,13 @@ impl Vector for Matrix {
}
}

fn mul_scalar<T: Into<f64>>(&self, other: T) -> Self {
fn mul_scalar(&self, other: Self::Scalar) -> Self {
match () {
#[cfg(feature = "O3")]
() => {
let x = &self.data;
let mut y = vec![0f64; x.len()];
let a_f64 = other.into();
let a_f64 = other;
let n_i32 = x.len() as i32;

unsafe {
Expand All @@ -1465,15 +1467,14 @@ impl Vector for Matrix {
matrix(y, self.row, self.col, self.shape)
}
_ => {
let scalar = other.into();
let scalar = other;
self.fmap(|x| x * scalar)
}
}
}
}

impl Normed for Matrix {
type Scalar = f64;
fn norm(&self, kind: Norm) -> f64 {
match kind {
Norm::F => {
Expand Down
9 changes: 5 additions & 4 deletions src/structure/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@
#[cfg(feature = "O3")]
extern crate blas;
#[cfg(feature = "O3")]
use blas::{dasum, daxpy, ddot, dnrm2, idamax};
use blas::{daxpy, ddot, dnrm2, idamax};

use crate::structure::matrix::{matrix, Matrix, Row};
use crate::traits::{
Expand Down Expand Up @@ -591,6 +591,8 @@ impl Algorithm for Vec<f64> {
}

impl Vector for Vec<f64> {
type Scalar = f64;

fn add_vec(&self, rhs: &Self) -> Self {
self.zip_with(|x, y| x + y, rhs)
}
Expand All @@ -599,14 +601,13 @@ impl Vector for Vec<f64> {
self.zip_with(|x, y| x - y, rhs)
}

fn mul_scalar<T: Into<f64>>(&self, rhs: T) -> Self {
let alpha: f64 = rhs.into();
fn mul_scalar(&self, rhs: Self::Scalar) -> Self {
let alpha: f64 = rhs;
self.fmap(|x| x * alpha)
}
}

impl Normed for Vec<f64> {
type Scalar = f64;
fn norm(&self, kind: Norm) -> f64 {
match kind {
Norm::L1 => self.iter().map(|x| x.abs()).sum(),
Expand Down
12 changes: 6 additions & 6 deletions src/traits/math.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use crate::structure::matrix::Matrix;
use std::convert::Into;

/// Mathematical Vector
///
/// # Description
/// Vector has two operations : addition, scalar multiplication.
/// And a space of the vector should closed for that operations.
pub trait Vector {
type Scalar;
fn add_vec<'a, 'b>(&'a self, rhs: &'b Self) -> Self;
fn sub_vec<'a, 'b>(&'a self, rhs: &'b Self) -> Self;
fn mul_scalar<T: Into<f64>>(&self, rhs: T) -> Self;
fn mul_scalar(&self, rhs: Self::Scalar) -> Self;
}

/// Kinds of Vector & Matrix norm
Expand All @@ -35,7 +35,6 @@ pub enum Norm {

/// Normed Vector
pub trait Normed: Vector {
type Scalar;
fn norm(&self, kind: Norm) -> Self::Scalar;
fn normalize(&self, kind: Norm) -> Self
where
Expand Down Expand Up @@ -69,6 +68,8 @@ pub trait MatrixProduct {
// =============================================================================

impl Vector for f64 {
type Scalar = Self;

fn add_vec<'a, 'b>(&'a self, rhs: &'b Self) -> Self {
self + rhs
}
Expand All @@ -77,13 +78,12 @@ impl Vector for f64 {
self - rhs
}

fn mul_scalar<T: Into<f64>>(&self, rhs: T) -> Self {
self * rhs.into()
fn mul_scalar(&self, rhs: Self::Scalar) -> Self {
self * rhs
}
}

impl Normed for f64 {
type Scalar = f64;
fn norm(&self, _kind: Norm) -> Self::Scalar {
self.abs()
}
Expand Down

0 comments on commit fcbad8c

Please sign in to comment.