peroxide 0.9.1

Rust numeric library contains linear algebra, numerical analysis, statistics and machine learning tools with R, MATLAB, Python like macros
Documentation
# Peroxide

[![On crates.io](https://img.shields.io/crates/v/peroxide.svg)](https://crates.io/crates/peroxide)
[![On docs.rs](https://docs.rs/peroxide/badge.svg)](https://docs.rs/peroxide/)
[![travis](https://api.travis-ci.org/Axect/Peroxide.svg?branch=master)](https://travis-ci.org/Axect/Peroxide)  
![maintenance](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg)

Pure Rust numeric library contains linear algebra, numerical analysis, statistics and machine learning tools with R, MATLAB, Python like macros.

## Latest README version

Corresponding to `0.8.7`.

## Install

* Add next line to your `cargo.toml`
```toml
peroxide = "0.8"
```

## Module Structure

- __src__
  - __bin__ : For test some libraries
    - [dual.rs]src/bin/dual.rs : Test automatic differentiation
    - [oxide.rs]src/bin/oxide.rs : Test any
    - [poly.rs]src/bin/poly.rs : Test polynomial
    - [lotka.rs]src/bin/lotka.rs : Solve lotka-volterra equation
    - [mlp.rs]src/bin/mlp.rs : Multi-layer perceptron example
    - [tov.rs]src/bin/tov.rs : Solve Tolman-Oppenheimer-Volkoff equation
  - [lib.rs]src/lib.rs : `mod` and `re-export`
  - __ml__ : For machine learning (*Beta*)
    - [mod.rs]src/ml/mod.rs
    - [reg.rs]src/ml/reg.rs : Regression tools
  - __macros__ : Macro files
    - [matlab_macro.rs]src/macros/matlab_macro.rs : MATLAB like macro
    - [mod.rs]src/macros/mod.rs
    - [r_macro.rs]src/macros/r_macro.rs : R like macro
  - __numerical__ : To do numerical things
    - [bdf.rs]src/numerical/bdf.rs : Backward Differentiation Formula
    - [gauss_legendre.rs]src/numerical/gauss_legendre.rs : Gauss-Legendre 4th order
    - [interp.rs]src/numerical/interp.rs : Interpolation
    - [mod.rs]src/numerical/mod.rs
    - [newton.rs]src/numerical/newton.rs : Newton's Method
    - [ode.rs]src/numerical/ode.rs : Merge all ODE algorithm to one module
    - [runge_kutta.rs]src/numerical/runge_kutta.rs : Runge Kutta 4th order
    - [spline.rs]src/numerical/spline.rs : Natural Spline
    - [utils.rs]src/numerical/utils.rs : Utils to do numerical things (e.g. jacobian)
  - __operation__ : To define general operations
    - [extra_ops.rs]src/operation/extra_ops.rs
    - [mod.rs]src/operation/mod.rs
  - __statistics__ : Statistical Tools
    - [mod.rs]src/statistics/mod.rs
    - [dist.rs]src/statistics/dist.rs : Probability distributions
    - [rand.rs]src/statistics/rand.rs : Wrapper for `rand` crate
    - [stat.rs]src/statistics/stat.rs : Statistical tools
  - __structure__ : Fundamental data structures
    - [dataframe.rs]src/structure/dataframe.rs : Not yet implemented
    - [dual.rs]src/structure/dual.rs : Dual number system for automatic differentiation
    - [matrix.rs]src/structure/matrix.rs : Matrix
    - [multinomial.rs]src/structure/multinomial.rs : For multinomial (*Beta*)
    - [mod.rs]src/structure/mod.rs
    - [polynomial.rs]src/structure/polynomial.rs : Polynomial
    - [vector.rs]src/structure/vector.rs : Extra tools for `Vec<f64>`
  - __util__
    - [mod.rs]src/util/mod.rs
    - [api.rs]src/util/api.rs : Matrix constructor for various language style 
    - [non_macro.rs]src/util/non_macro.rs : Primordial version of macros
    - [print.rs]src/util/print.rs : To print conveniently
    - [useful.rs]src/util/useful.rs : Useful utils to implement library


## Documentation

There is [Peroxide Gitbook](https://axect.github.io/Peroxide_Gitbook)


## Not yet documentized contents

### Polynomial

```rust
// Peroxide
extern crate peroxide;
use peroxide::*;

fn main() {
    // Declare polynomial
    let a = poly(c!(1,3,2));
    a.print(); // x^2 + 3x + 2
    a.eval(1); // Evaluate when x = 1 -> 6.0
    
    let b = poly(c!(1,2,3,4));       // x^3 + 2x^2 + 3x + 4
    (a.clone() + b.clone()).print(); // x^3 + 3x^2 + 6x + 6
    (a.clone() - b.clone()).print(); // -x^3 - x^2 - 2
    (a.clone() * b.clone()).print(); // x^5 + 5x^4 + 11x^3 + 17x^2 + 18x + 8
    
    let c = poly(c!(1, -1));
    c.print();                       // x - 1
    c.pow(2).print();                // x^2 - 2x + 1
}
```

### Interpolation (Beta)

* Lagrange polynomial interpolation
* Chebyshev nodes

```rust
// Peroxide
extern crate peroxide;
use peroxide::*;

fn main() {
    let a = c!(-1, 0, 1);
    let b = c!(1, 0, 1);

    let l = lagrange_polynomial(a, b);
    l.print(); // x^2
}
```

### Spline (Beta)

* Natural cubic spline

```rust
// Peroxide
extern crate peroxide;
use peroxide::*;

fn main() {
    let x = c!(0.9, 1.3, 1.9, 2.1);
    let y = c!(1.3, 1.5, 1.85, 2.1);

    let s = cubic_spline(x, y);

    for i in 0 .. s.len() {
        s[i].print();
    }
    
    // -0.2347x^3 + 0.6338x^2 - 0.0329x + 0.9873
    // 0.9096x^3 - 3.8292x^2 + 5.7691x - 1.5268
    // -2.2594x^3 + 14.2342x^2 - 28.5513x + 20.2094
}
```

### MATLAB like macro

* `zeros` - zero vector or matrix
* `eye` - identity matrix
* `rand` - random matrix (range from 0 to 1)

### Automatic Differentiation

* Implemented AD with dual number structure.
* Available functions
    * `sin, cos, tan`
    * `pow, powf`
    * `+,-,x,/`
    * `exp, ln`

```rust
extern crate peroxide;
use peroxide::*;

fn main() {
    let a = dual(0, 1); // x at x = 0
    a.sin().print();    // sin(x) at x = 0
    
    // value: 0  // sin(0) = 0
    // slope: 1  // cos(0) = 1
}
```

### Jacobian

* Implemented by AD - Exact Jacobian

```rust
extern crate peroxide;
use peroxide::*;

fn main() {
    let xs = c!(1, 1);
    jacobian(xs, f).print();
    
    //      c[0] c[1]
    // r[0]    6    3
}

// f(t, x) = 3t^2 * x
fn f(xs: Vec<Dual>) -> Vec<Dual> {
    let t = xs[0];
    let x = xs[1];

    vec![t.pow(2) * 3. * x]
}
```

### Ordinary Differential Equation

* Solve 1st order ODE with various methods
* Explicit Method
    * `RK4`: Runge-Kutta 4th order
* Implicit Method
    * `BDF1`: Backward Euler
    * `GL4`: Gauss-Legendre 4th order
    
**Caution**

* input function should have form `(Dual, Vec<Dual>) -> Vec<Dual>`    
    
```rust
// Lotka-Volterra
extern crate peroxide;
use peroxide::*;

fn main() {
    // t = 0, x = 2, y = 1
    let xs = c!(2, 1);
    let rk4_records = solve(lotka_volterra, xs.clone(), (0, 10), 1e-3, RK4);
    let bdf_records = solve(lotka_volterra, xs.clone(), (0, 10), 1e-3, BDF1(1e-15));
    let gl4_records = solve(lotka_volterra, xs, (0, 10), 1e-3, GL4(1e-15));
    //rk4_records.write_with_header("example_data/lotka_rk4.csv", vec!["t", "x", "y"]);
    //bdf_records.write_with_header("example_data/lotka_bdf.csv", vec!["t", "x", "y"]);
    gl4_records.write_with_header("example_data/lotka_gl4.csv", vec!["t", "x", "y"]);
}

fn lotka_volterra(_t: Dual, xs: Vec<Dual>) -> Vec<Dual> {
    let a = 4.;
    let c = 1.;

    let x = xs[0];
    let y = xs[1];

    vec![
        a * (x - x*y),
        -c * (y - x*y)
    ]
}
```

## Version Info

To see [RELEASES.md](./RELEASES.md)

## TODO

To see [TODO.md](./TODO.md)