NOTE: rapl
requires Nightly and is strictly intended for non-production purposes only. rapl
utilizes certain unstable features that may result in unexpected behavior, and is not optimized for performance.
rapl
is an experimental numerical computing Rust library that provides a simple way of working with N-dimensional array, along with a wide range of mathematical functions to manipulate them. It takes inspiration from NumPy and APL, with the primary aim of achieving maximum ergonomics and user-friendliness while maintaining generality. Our goal is to make Rust a viable option for scripting and numerical analysis by creating a versatile and user-friendly tools.
```Rust
use rapl::*; fn main() { let a = Ndarr::from([1, 2, 3]); let b = Ndarr::from([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); let r = a + b - 1; assert_eq!(r, Ndarr::from([[1, 3, 5], [4, 6, 8], [7, 9, 11]])); } ```
There are multiple handy ways of initializing N-dimensional arrays (or Ndarr
).
- From Native Rust arrays to Ndarr
.
Rust
let a = Ndarr::from(["a","b","c"]);
let b = Ndarr::from([[1,2],[3,4]]);
- From ranges.
Rust
let a = Ndarr::from(1..7).reshape(&[2,3])
- From &str
Rust
let chars = Ndarr::from("Hello rapl!"); //Ndarr<char,1>
- Others:
Rust
let ones: Ndarr<f32, 2> = Ndarr::ones(&[4,4]);
let zeros : Ndarr<i32, 3>= Ndarr::zeros(&[2,3,4]);
let letter_a = Ndarr::fill("a", &[5]);
let fold = Ndarr::new(data: &[0, 1, 2, 3], shape: [2, 2]).expect("Error initializing");
Rust
let ones: Ndarr<i32, 2> = Ndarr::ones(&[4,4]);
let twos = ones + 1;
let sixes = twos * 3;
Ndarr
s,
```Rust
let a = Ndarr::from([[1,2],[3,4]]);
let b = Ndarr::from([[1,2],[-3,-4]]);asserteq!(a + b, Ndarr::from([[2,4],[0,0]]))
Note: If the shapes are not equal `rapl` will automatically broadcast the arrays into a compatible shape (if it exist) and perform the operation.
- Math operations including trigonometric functions
Rust
let x = Ndarr::from([-1.0 , -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0]);
let sinx = &x.sin();
let cosx = &x.cos();
let tanhx = &x.tanh();
let abs_x = x.abs();
- Map function
Rust
let a = Ndarr::from([[1,2],[3,4]]);
let mapped = a.map(|x| x*2-1);
```
Rust
let arr = Ndarr::from([[1,2,3],[4,5,6]]);
assert_eq!(arr.shape(), [2,3]);
assert_eq!(arr.clone().t().shape, [3,2]); //transpose
Rust
let a = Ndarr::from(1..7).reshape(&[2,3]).unwrap();
asserteq!(arr.sliceat(1)[0], Ndarr::from([1,3]))
- Reduce
Rust
let sumaxis = arr.clone().reduce(1, |x,y| x + y).unwrap();
asserteq!(sumaxis, Ndarr::from([6, 15])); //sum reduction
- Scan right an left
Rust
let s = Ndarr::from([1,2,3]);
let cumsum = s.scanr( 0, |x,y| x + y);
asserteq!(cumsum, Ndarr::from([1,3,6]));
```
Rust
use rapl::*
use rapl::ops::{mat_mul};
let a = Ndarr::from(1..7).reshape(&[2,3]).unwrap();
let b = Ndarr::from(1..7).reshape(&[3,2]).unwrap();
let matmul = mat_mul(a, b))
``` - Outer Product.
```Rust let suits = Ndarr::from(["♣","♠","♥","♦"]); let ranks = Ndarr::from(["2","3","4","5","6","7","8","9","10","J","Q","K","A"]);
let addstr = |x: &str, y: &str| (x.toowned() + y);
let deck = ops::outerproduct( addstr, ranks, suits).flatten(); //All cards in a deck ```
You can ergonomically do operations between native numeric types and complex types C<T>
with a simple and clean interface.
Rust
use rapl::*;
// Complex sclars
let z = 1 + 2.i();
assert_eq!(z, C(1,2));
assert_eq!(z - 3, -2 + 2.i());
Seamlessly work with complex numbers, and complex tensors.
Rust
use rapl::*;
// Complex tensors
let arr = Ndarr::from([1, 2, 3]);
let arr_z = arr + -1 + 2.i();
assert_eq!(arr_z, Ndarr::from([C(0,2), C(1,2), C(2,2)]));
assert_eq!(arr_z.im(), Ndarr::from([2,2,2]));
You can easily work with images of almost any format. rapl
provides helpful functions to open images as both RGB and Luma Ndarr
, and also save them to your preferred format.
```Rust use rapl::*; use rapl::utils::rapl_img;
fn main() {
//open RGB image as Ndarr