Examples on ndarray-linalg

Hello All,

I'm trying to get started on using rust, and in particular the available linear algebra libraries.
From what I've found the best resource seems to be ndarray-linalg. I've tried running some of their examples codes, found here, but none of them seem
to be functional.

Considering the example function

// Solve `Ax=b` for tridiagonal matrix
fn solve() -> Result<(), error::LinalgError> {
    let mut a: Array2<f64> = random((3, 3));
    let b: Array1<f64> = random(3);
    a[[0, 2]] = 0.0;
    a[[2, 0]] = 0.0;
    let _x = a.solve_tridiagonal(&b)?;
    Ok(())
}

it seems that "solve_tridiagonal" is not defined on an Array2 type. Could you please point me
into some direction? The trait SolveTridiagonal is implemented for a range of Array types and
I would like to understand how I may use it.

Best wishes,

Choeppke

Import that trait to use it in your code.

1 Like

Hello RedDoc,

I've imported the trait via use, resulting in

use ndarray::*;
use ndarray_linalg::*;
use ndarray_rand::*;
use ndarray_rand::rand_distr::Uniform;
use ndarray_linalg::tridiagonal::SolveTridiagonal;

// Solve `Ax=b` for tridiagonal matrix
fn solve() {
    let mut a: Array2<f64> = Array::random((3, 3), Uniform::new(0.0, 1.0));
    let b: Array1<f64> = Array::random(3, Uniform::new(0.0, 1.0));
    a[[0, 2]] = 0.0;
    a[[2, 0]] = 0.0;
    let res = a.solve_tridiagonal(&b)?;
    println!("{:?}", a);
    println!("{:?}", b);
    println!("{:?}", c);
}

fn main() {
    solve();
}

Could you please explain what you mean by how I can use it?

Best,
Choeppke

Hi @choeppke,

I hope this helps, even if it's a bit late.

I was able to make your code compile with two small modifications; your last println! needs to be commented out (c doesn't exist) and changing the ? to unwrap() (solve() doesn't return errors). The full code is below:

use ndarray::*;
use ndarray_linalg::*;
use ndarray_rand::*;
use ndarray_rand::rand_distr::Uniform;
use ndarray_linalg::tridiagonal::SolveTridiagonal;

// Solve `Ax=b` for tridiagonal matrix
fn solve() {
    let mut a: Array2<f64> = Array::random((3, 3), Uniform::new(0.0, 1.0));
    let b: Array1<f64> = Array::random(3, Uniform::new(0.0, 1.0));
    a[[0, 2]] = 0.0;
    a[[2, 0]] = 0.0;
    let res = a.solve_tridiagonal(&b).unwrap();
    println!("{:?}", a);
    println!("{:?}", b);
    // println!("{:?}", c);
}

fn main() {
    solve();
}

For completeness, here's my Cargo.toml:

[package]
name = "linalg"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ndarray = "0.15.4"
ndarray-linalg = { version = "0.14.1", features = ["openblas-system"] }
ndarray-rand = "0.14.0"

Note that I'm using the openblas-system feature for ndarray-linalg. You should choose what works for you based on this page.

My results of cargo run:

warning: unused import: `ndarray_linalg::*`
 --> src/main.rs:2:5
  |
2 | use ndarray_linalg::*;
  |     ^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused variable: `res`
  --> src/main.rs:13:9
   |
13 |     let res = a.solve_tridiagonal(&b).unwrap();
   |         ^^^ help: if this is intentional, prefix it with an underscore: `_res`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: `linalg` (bin "linalg") generated 2 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/linalg`
[[0.9663789024107372, 0.35955842232653223, 0.0],
 [0.006253186281878653, 0.3396009826675137, 0.2136267149637281],
 [0.0, 0.7372859347625886, 0.24160310345096114]], shape=[3, 3], strides=[3, 1], layout=Cc (0x5), const ndim=2
[0.7127561709438837, 0.9017411157024657, 0.24626367229188184], shape=[3], strides=[1], layout=CFcf (0xf), const ndim=1

Thank you @chjordan for this great solution! I've found that many examples, specifically on ndarray and ndarray-linalg, seem to be out of date and don't compile anymore when copy-pasted, so this leg-up is much appreciated.

You're welcome. I don't check out the Rust forums too often, but it is a good community, and I encourage you to keep learning. It can be difficult to wrap your head around things but I've found the effort well worth it.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.