This notebook used evcxr-jupyter
These examples correspond to peroxide = 0.6.4
extern crate peroxide;
use peroxide::*;
├── macros
│ ├── matlab_macro.rs
│ ├── mod.rs
│ └── r_macro.rs
├── ml
│ ├── mod.rs
│ └── reg.rs
├── numerical
│ ├── interp.rs
│ ├── mod.rs
│ └── spline.rs
├── operation
│ ├── extra_ops.rs
│ └── mod.rs
├── statistics
│ ├── mod.rs
│ ├── rand.rs
│ └── stat.rs
├── structure
│ ├── dual.rs
│ ├── matrix.rs
│ ├── mod.rs
│ ├── polynomial.rs
│ └── vector.rs
└── util
├── mod.rs
├── non_macro.rs
└── print.rs
Vec<f64>
)¶You can declare vector rust-way
let a: Vec<f64> = vec![1.,2.,3.,4.];
a.print(); // Convenient to print
[1, 2, 3, 4]
And also R-way
let b = c!(1,2,3,4); // R-like macro to declare Vec<f64>
b.print();
[1, 2, 3, 4]
And you can use R's seq
function
let c = seq!(1,10,2); // start, end, step
c.print();
[1, 3, 5, 7, 9]
This is original rust way to FP
a.clone().into_iter().map(|x| x + 1.).collect::<Vector>().print();
[2, 3, 4, 5]
This is Peroxide
way
a.fmap(|x| x + 1.).print();
[2, 3, 4, 5]
You can use fmap, reduce, zip_with
as follows
// reduce
a.reduce(0, |x, y| x + y).print();
// zip_with
a.zip_with(|x, y| x + y, &b).print();
10 [2, 4, 6, 8]
There is VectorOps Trait
pub trait VecOps {
type Scalar;
fn add(&self, other: &Self) -> Self;
fn sub(&self, other: &Self) -> Self;
fn mul(&self, other: &Self) -> Self;
fn div(&self, other: &Self) -> Self;
fn dot(&self, other: &Self) -> Self::Scalar;
}
// Addition
a.add(&b).print();
a.sub(&b).print();
a.mul(&b).print();
a.div(&b).print();
a.dot(&b).print();
[2, 4, 6, 8] [0, 0, 0, 0] [1, 4, 9, 16] [1, 1, 1, 1] 30
There are various ways to declare matrix. Belows are all same
// Function way
let m1 = matrix(vec![1,2,3,4], 2, 2, Row);
let m2 = matrix(c!(1,2,3,4), 2, 2, Row);
let m2_2 = matrix(c!(1,3,2,4), 2, 2, Col);
let m3 = matrix(seq!(1, 4, 1), 2, 2, Row);
// Macro way
let m4 = matrix!(1;4;1, 2, 2, Row);
m4.print();
c[0] c[1] r[0] 1 2 r[1] 3 4
Peroxide allows smart print (But it's not applied to Jupyter)
let m0 = matrix(c!(1.99999, 1, 2, 3), 2, 2, Row);
m0.print();
c[0] c[1] r[0] 2.0000 1 r[1] 2 3
let a = matrix!(1;4;1, 2, 2, Col);
let b = matrix(c!(5, 6), 2, 1, Col);
let c = cbind!(a, b);
c.print();
c[0] c[1] c[2] r[0] 1 3 5 r[1] 2 4 6
let d = matrix!(1;4;1, 2, 2, Row);
let e = matrix(c!(5, 6), 1, 2, Row);
let f = rbind!(d, e);
f.print();
c[0] c[1] r[0] 1 2 r[1] 3 4 r[2] 5 6
Caution: std::ops
consume value. If you want to re-use the value, use clone
let a = matrix!(1;4;1, 2, 2, Row);
let b = matrix!(1;4;1, 2, 2, Col);
println!("Addition");
(a.clone() + b.clone()).print();
println!("");
println!("Subtraction");
(a.clone() - b.clone()).print();
println!("");
println!("Component-wise multiplication");
(a.clone() * b.clone()).print(); // Component-wise multiplication
println!("");
println!("Matrix multiplication");
(a.clone() % b.clone()).print(); // Matrix multiplication
Addition c[0] c[1] r[0] 2 5 r[1] 5 8 Subtraction c[0] c[1] r[0] 0 -1 r[1] 1 0 Component-wise multiplication c[0] c[1] r[0] 1 6 r[1] 6 16 Matrix multiplication c[0] c[1] r[0] 5 11 r[1] 11 25
let a = matrix!(1;4;1, 2, 2, Row);
let pqlu = a.lu(); // Option<PQLU>
// Unwrap process
match pqlu {
None => println!("No LU Decomposition"),
Some(abcd) => {
let (p, q, l, u) = (abcd.p, abcd.q, abcd.l, abcd.u);
println!("Column Permutation: {:?}", p);
println!("Row Permutation: {:?}", q);
println!("Lower Triangular Matrix:\n {}", l);
println!("Upper Triangular Matrix:\n {}", u);
}
}
Column Permutation: [(0, 1)] Row Permutation: [(0, 1)] Lower Triangular Matrix: c[0] c[1] r[0] 1 0 r[1] 0.5 1 Upper Triangular Matrix: c[0] c[1] r[0] 4 3 r[1] 0 -0.5
()
let a = matrix!(1;4;1, 2, 2, Row);
a.det().print();
-2
a.inv().unwrap().print();
// or
println!("");
match a.inv() {
None => println!("No inverse!"),
Some(m) => m.print(),
}
c[0] c[1] r[0] -2 1 r[1] 1.5 -0.5 c[0] c[1] r[0] -2 1 r[1] 1.5 -0.5
()
let a = matrix!(1;4;1, 2, 2, Row);
a.col(0).print();
a.col(1).print();
a.row(0).print();
a.row(1).print();
[1, 3] [2, 4] [1, 2] [3, 4]
a.fmap(|x| x + 1f64).print();
c[0] c[1] r[0] 2 3 r[1] 4 5