e1ba8c10c8006921a2cf1a171d4dd36dfe536bbf — axect 4 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