~axect/Peroxide

7851fcd37b2f1f2561c0a337cf977b11421fb5cb — axect 11 months ago a4232b4
Ver 0.14.1 Candidates - More BLAS (BLAS Level 1)
5 files changed, 94 insertions(+), 7 deletions(-)

M Cargo.toml
M RELEASES.md
M example_data/lm_test.png
M src/structure/dual.rs
M src/structure/vector.rs
M Cargo.toml => Cargo.toml +1 -1
@@ 1,6 1,6 @@
[package]
name = "peroxide"
version = "0.14.0"
version = "0.14.1"
authors = ["axect <edeftg@gmail.com>"]
description = "Rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with farmiliar syntax"
repository = "https://github.com/Axect/Peroxide"

M RELEASES.md => RELEASES.md +8 -0
@@ 1,3 1,11 @@
# Release 0.14.1 (2019-08-24) (Candidates)

* More BLAS
    * Vector & Vector Addition/Subtraction (`daxpy`)
    * Vector & Scalar multiplication (`dscal`)
    * Vector & Vector dot product (`ddot`)
    * Vector Euclidean norm (`dnrm2`)

# Release 0.14.0 (2019-08-24)

* **[Important]** Finally, BLAS integrated.

M example_data/lm_test.png => example_data/lm_test.png +0 -0

M src/structure/dual.rs => src/structure/dual.rs +4 -0
@@ 609,6 609,10 @@ impl VecOps for Vec<Dual> {
        self.zip_with(|x, y| x * y, other)
    }

    fn s_mul(&self, scala: f64) -> Self {
        self.fmap(|x| x * scala)
    }

    fn div(&self, other: &Self) -> Self {
        self.zip_with(|x, y| x / y, other)
    }

M src/structure/vector.rs => src/structure/vector.rs +81 -6
@@ 262,6 262,11 @@
//!     }
//!     ```

#[cfg(feature = "native")]
extern crate blas;
#[cfg(feature = "native")]
use blas::{daxpy, ddot, dnrm2, dscal};

use operation::extra_ops::Real;
use std::cmp::min;
use std::convert;


@@ 528,6 533,7 @@ pub trait VecOps {
    fn add(&self, other: &Self) -> Self;
    fn sub(&self, other: &Self) -> Self;
    fn mul(&self, other: &Self) -> Self;
    fn s_mul(&self, scala: f64) -> Self;
    fn div(&self, other: &Self) -> Self;
    fn dot(&self, other: &Self) -> Self::Scalar;
    fn norm(&self) -> Self::Scalar;


@@ 540,12 546,38 @@ impl VecOps for Vector {

    /// Addition
    fn add(&self, other: &Self) -> Self {
        self.zip_with(|x, y| x + y, other)
        match () {
            #[cfg(feature = "native")]
            () => {
                let n_i32 = self.len() as i32;
                let mut y = other.clone();
                unsafe {
                    daxpy(n_i32, 1f64, self, 1, &mut y, 1);
                }
                y
            }
            _ => {
                self.zip_with(|x, y| x + y, other)
            }
        }
    }

    /// Subtraction
    fn sub(&self, other: &Self) -> Self {
        self.zip_with(|x, y| x - y, other)
        match () {
            #[cfg(feature = "native")]
            () => {
                let n_i32 = self.len() as i32;
                let mut y = self.clone();
                unsafe {
                    daxpy(n_i32, -1f64, other, 1, &mut y, 1);
                }
                y
            }
            _ => {
                self.zip_with(|x, y| x - y, other)
            }
        }
    }

    /// Multiplication


@@ 553,6 585,23 @@ impl VecOps for Vector {
        self.zip_with(|x, y| x * y, other)
    }

    fn s_mul(&self, scala: f64) -> Self {
        match () {
            #[cfg(feature = "native")]
            () => {
                let mut x = self.clone();
                let n_i32 = self.len() as i32;
                unsafe {
                    dscal(n_i32, scala, &mut x, 1);
                }
                x
            }
            _ => {
                self.fmap(|x| scala * x)
            }
        }
    }

    /// Division
    fn div(&self, other: &Self) -> Self {
        self.zip_with(|x, y| x / y, other)


@@ 560,17 609,43 @@ impl VecOps for Vector {

    /// Dot product
    fn dot(&self, other: &Self) -> f64 {
        zip_with(|x, y| x * y, &self, other).reduce(0, |x, y| x + y)
        match () {
            #[cfg(feature = "native")]
            () => {
                let n_i32 = self.len() as i32;
                let res: f64;
                unsafe {
                    res = ddot(n_i32, self, 1, other, 1);
                }
                res
            }
            _ => {
                zip_with(|x, y| x * y, &self, other).reduce(0, |x, y| x + y)
            }
        }
    }

    /// Norm
    fn norm(&self) -> f64 {
        self.dot(&self).sqrt()
        match () {
            #[cfg(feature = "native")]
            () => {
                let n_i32 = self.len() as i32;
                let res: f64;
                unsafe {
                    res = dnrm2(n_i32, self, 1);
                }
                res
            }
            _ => {
                self.dot(&self).sqrt()
            }
        }
    }

    /// Normalize
    fn normalize(&self) -> Self {
        let n = self.norm();
        self.fmap(|x| x / n)
        let alpha = self.norm();
        self.s_mul(1f64 / alpha)
    }
}