~axect/Peroxide

e1ba8c10c8006921a2cf1a171d4dd36dfe536bbf — axect 7 months ago 2e9b274
Ver 0.12.4 - Enhanced functional programming
M Cargo.toml => Cargo.toml +2 -2
@@ 1,8 1,8 @@
[package]
name = "peroxide"
version = "0.12.3"
version = "0.12.4"
authors = ["axect <edeftg@gmail.com>"]
description = "Rust numeric library contains linear algebra, numerical analysis, statistics and machine learning tools with R, MATLAB, Python like macros"
description = "Pure rust comprehensive scientific computation library contains linear algebra, numerical analysis, statistics and machine learning tools with farmiliar syntax"
repository = "https://github.com/Axect/Peroxide"
license = "BSD-3-Clause"
categories = ["science"]

M README.md => README.md +54 -0
@@ 82,6 82,60 @@ peroxide = "0.12"

* [![On docs.rs](https://docs.rs/peroxide/badge.svg)](https://docs.rs/peroxide/)

## Covered Contents

* Linear Algebra
    * Effective Matrix structure
    * Transpose, Determinant, Diagonal
    * LU Decomposition, Inverse matrix, Block partitioning
    * Column, Row operations
* Functional Programming
    * More easy functional programming with `Vec<f64>`
    * For matrix, there are three maps
        * `fmap` : map for all elements
        * `col_map` : map for column vectors
        * `row_map` : map for row vectors
* Automatic Differentiation
    * Dual number system - for 1st order AD
    * Hyper dual number system - for 2nd order AD
    * Exact jacobian
    * `Real` trait to constrain for `f64` and `Dual`
    * `Number` structure to unify `f64` and `Dual`
* Numerical Analysis
    * Lagrange interpolation
    * Cubic spline
    * Non-linear regression
        * Gradient Descent
        * Gauss Newton
        * Levenberg Marquardt
    * Ordinary Differential Equation
        * Euler
        * Runge Kutta 4th order
        * Backward Euler
        * Gauss Legendre 4th order
* Statistics
    * More easy random with `rand` crate
    * Probability Distributions
        * Bernoulli
        * Uniform
        * Normal
        * Gamma
        * Beta
    * RNG algorithms
        * Acceptance Rejection
        * Marsaglia Polar
        * Ziggurat
* Special functions
    * Wrapper for `special` crate
* Utils
    * R-like macro & functions
    * Matlab-like macro & functions
    * Numpy-like macro & functions
    * Julia-like macro & functions
* Plotting
    * With `pyo3` & `matplotlib`


## Example

### Basic Runge-Kutta 4th order with inline-python

M RELEASES.md => RELEASES.md +6 -0
@@ 1,3 1,9 @@
# Release 0.12.4 (2019-08-09)

* Add `normalize` for `Vec<f64>`
* Add `col_map` for `Matrix`
* Add `row_map` for `Matrix`

# Release 0.12.3 (2019-07-31)

* Add `get_error` for `Optimizer`

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

M src/structure/dual.rs => src/structure/dual.rs +4 -0
@@ 625,6 625,10 @@ impl VecOps for Vec<Dual> {
    fn norm(&self) -> Self::Scalar {
        unimplemented!()
    }

    fn normalize(&self) -> Self {
        unimplemented!()
    }
}

// =============================================================================

M src/structure/matrix.rs => src/structure/matrix.rs +42 -0
@@ 1851,6 1851,12 @@ pub trait FP {
    fn fmap<F>(&self, f: F) -> Matrix
    where
        F: Fn(f64) -> f64;
    fn col_map<F>(&self, f: F) -> Matrix
    where
        F: Fn(Vec<f64>) -> Vec<f64>;
    fn row_map<F>(&self, f: F) -> Matrix
    where
        F: Fn(Vec<f64>) -> Vec<f64>;
    fn reduce<F, T>(&self, init: T, f: F) -> f64
    where
        F: Fn(f64, f64) -> f64,


@@ 1938,6 1944,42 @@ impl FP for Matrix {
        matrix(result, self.row, self.col, self.shape)
    }

    fn col_map<F>(&self, f: F) -> Matrix
    where
        F: Fn(Vec<f64>) -> Vec<f64>,
    {
        let mut result = Matrix {
            data: vec![0f64; self.row * self.col],
            row: self.row,
            col: self.col,
            shape: Col
        };

        for i in 0 .. self.row {
            result.subs_col(i, f(self.col(i)));
        }

        result
    }

    fn row_map<F>(&self, f: F) -> Matrix
    where
        F: Fn(Vec<f64>) -> Vec<f64>
    {
        let mut result = Matrix {
            data: vec![0f64; self.row * self.col],
            row: self.row,
            col: self.col,
            shape: Row
        };

        for i in 0 .. self.col {
            result.subs_row(i, f(self.row(i)));
        }

        result
    }

    fn reduce<F, T>(&self, init: T, f: F) -> f64
    where
        F: Fn(f64, f64) -> f64,

M src/structure/vector.rs => src/structure/vector.rs +12 -5
@@ 525,6 525,7 @@ pub trait VecOps {
    fn div(&self, other: &Self) -> Self;
    fn dot(&self, other: &Self) -> Self::Scalar;
    fn norm(&self) -> Self::Scalar;
    fn normalize(&self) -> Self;
}

/// Convenient Vector Operations (No Clone, No Copy)


@@ 532,27 533,27 @@ impl VecOps for Vector {
    type Scalar = f64;

    /// Addition
    fn add(&self, other: &Vector) -> Vector {
    fn add(&self, other: &Self) -> Self {
        self.zip_with(|x, y| x + y, other)
    }

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

    /// Multiplication
    fn mul(&self, other: &Vector) -> Vector {
    fn mul(&self, other: &Self) -> Self {
        self.zip_with(|x, y| x * y, other)
    }

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

    /// Dot product
    fn dot(&self, other: &Vector) -> f64 {
    fn dot(&self, other: &Self) -> f64 {
        zip_with(|x,y| x * y, &self, other).reduce(0, |x, y| x + y)
    }



@@ 560,4 561,10 @@ impl VecOps for Vector {
    fn norm(&self) -> f64 {
        self.dot(&self).sqrt()
    }

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

M tests/matrix.rs => tests/matrix.rs +16 -0
@@ 59,3 59,19 @@ fn test_print() {
    let op = Bernoulli(0);
    op.print();
}

#[test]
fn test_row_map() {
    let m = ml_matrix("1 2;3 4");
    let n = m.row_map(|v| v.normalize());
    let o = matrix(vec![1f64/5f64.sqrt(), 2f64/5f64.sqrt(), 3f64 / 5f64, 4f64 / 5f64], 2, 2, Row);
    assert_eq!(n, o);
}

#[test]
fn test_col_map() {
    let m = ml_matrix("1 3;2 4");
    let n = m.col_map(|v| v.normalize());
    let o = matrix(vec![1f64/5f64.sqrt(), 2f64/5f64.sqrt(), 3f64 / 5f64, 4f64 / 5f64], 2, 2, Col);
    assert_eq!(n, o);
}
\ No newline at end of file