diff --git a/src/numerical/ode.rs b/src/numerical/ode.rs index 88ea1d5d..2856c79e 100644 --- a/src/numerical/ode.rs +++ b/src/numerical/ode.rs @@ -767,15 +767,15 @@ impl ODE for ImplicitODE { &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))), ), ), ) diff --git a/src/structure/ad.rs b/src/structure/ad.rs index 700b1bda..cfe8f1d7 100644 --- a/src/structure/ad.rs +++ b/src/structure/ad.rs @@ -1258,6 +1258,8 @@ impl FPVector for Vec { } impl Vector for Vec { + type Scalar = AD; + fn add_vec<'a, 'b>(&'a self, rhs: &'b Self) -> Self { self.add_v(rhs) } @@ -1266,8 +1268,8 @@ impl Vector for Vec { self.sub_v(rhs) } - fn mul_scalar>(&self, rhs: T) -> Self { - self.mul_s(AD::from(rhs.into())) + fn mul_scalar(&self, rhs: Self::Scalar) -> Self { + self.mul_s(rhs) } } diff --git a/src/structure/dataframe.rs b/src/structure/dataframe.rs index 3f24419d..faa44399 100644 --- a/src/structure/dataframe.rs +++ b/src/structure/dataframe.rs @@ -821,6 +821,11 @@ where Series: TypedVector { Series::new(v.into_iter().zip(w.into_iter()).map(|(x, y)| x - y).collect::>()) } +fn mul_scalar + Clone + Copy>(v: Vec, s: T) -> Series +where Series: TypedVector { + Series::new(v.into_iter().map(|x| x * s).collect::>()) +} + // ============================================================================= // Implementations of DType variables // ============================================================================= @@ -963,6 +968,8 @@ impl Series { } impl Vector for Series { + type Scalar = Scalar; + /// Add series /// /// # Example @@ -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, @@ -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, @@ -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>(&self, rhs: T) -> Self { - let a = self.to_type(F64); - let v: Vec = 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 + ) } } diff --git a/src/structure/matrix.rs b/src/structure/matrix.rs index 1c526d2b..15d3f107 100644 --- a/src/structure/matrix.rs +++ b/src/structure/matrix.rs @@ -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, }; @@ -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); @@ -1450,13 +1452,13 @@ impl Vector for Matrix { } } - fn mul_scalar>(&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 { @@ -1465,7 +1467,7 @@ impl Vector for Matrix { matrix(y, self.row, self.col, self.shape) } _ => { - let scalar = other.into(); + let scalar = other; self.fmap(|x| x * scalar) } } @@ -1473,7 +1475,6 @@ impl Vector for Matrix { } impl Normed for Matrix { - type Scalar = f64; fn norm(&self, kind: Norm) -> f64 { match kind { Norm::F => { diff --git a/src/structure/vector.rs b/src/structure/vector.rs index 5019767a..c3233ec2 100644 --- a/src/structure/vector.rs +++ b/src/structure/vector.rs @@ -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::{ @@ -591,6 +591,8 @@ impl Algorithm for Vec { } impl Vector for Vec { + type Scalar = f64; + fn add_vec(&self, rhs: &Self) -> Self { self.zip_with(|x, y| x + y, rhs) } @@ -599,14 +601,13 @@ impl Vector for Vec { self.zip_with(|x, y| x - y, rhs) } - fn mul_scalar>(&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 { - type Scalar = f64; fn norm(&self, kind: Norm) -> f64 { match kind { Norm::L1 => self.iter().map(|x| x.abs()).sum(), diff --git a/src/traits/math.rs b/src/traits/math.rs index 9288d3a8..4e672d5f 100644 --- a/src/traits/math.rs +++ b/src/traits/math.rs @@ -1,5 +1,4 @@ use crate::structure::matrix::Matrix; -use std::convert::Into; /// Mathematical Vector /// @@ -7,9 +6,10 @@ use std::convert::Into; /// 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>(&self, rhs: T) -> Self; + fn mul_scalar(&self, rhs: Self::Scalar) -> Self; } /// Kinds of Vector & Matrix norm @@ -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 @@ -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 } @@ -77,13 +78,12 @@ impl Vector for f64 { self - rhs } - fn mul_scalar>(&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() }