Crate linalg_traits

Crate linalg_traits 

Source
Expand description

githubcrates-iodocs-rs

Traits for generic linear algebra.

§Purpose

The purpose of this crate is to provide traits defining common interfaces for linear algebra types defined in various popular numerical computing crates in the Rust ecosystem. This is to facilitate the development of crates requiring some linear algebra features (e.g. ODE solvers, state estimation, etc.) without forcing users to use a specific numerical computing crate.

See Additional notes on use cases.

§Constraints
  1. Compatibility with Vec<f64>, as well as types from nalgebra, ndarray, and faer.

    As a result, this crate does not require any operator overloads to be implemented for linear alegebra types. Different numerical computing crates may have different implementations for operator overloads (e.g. ndarray overloads * for elementwise multiplication, while nalgebra overloads * for matrix multiplication). This means that anyone writing generic linear algebra code using linalg-traits should use the arithmetic methods defined on the Vector and Matrix traits.

  2. Compatibility with both statically-sized and dynamically-sized types.

    types (e.g. nalgebra::SVector) may also implement the Copy trait, which is often preferable to use for those types. However, it can be unsafe to copy dynamically-sized types, so to keep Vector and Matrix compatible with both statically and dynamically-sized linear algebra types, they only require that Clone be implemented.

§Linear Algebra Traits

This crate provides the following traits along with their implementations for the following types:

TraitImplementations on Foreign TypesImplementations on Local Types
Scalarf64 and all other types that satisfy its trait bounds.N/A
VectorVec<S>
nalgebra::DVector<S>
nalgebra::SVector<S, N>
ndarray::Array1<T>
faer::Mat<U>

Note:
S: Scalar
T: Scalar + ndarray::ScalarOperand + ndarray::LinalgScalar
U: Scalar + faer_traits::RealField
N: usize
N/A
Matrixnalgebra::DMatrix<S>
nalgebra::SMatrix<S, M, N>
ndarray::Array2<T>
faer::Mat<U>

Note:
S: Scalar
T: Scalar + ndarray::ScalarOperand + ndarray::LinalgScalar
U: Scalar + faer_traits::RealField
M: usize
N: usize
Mat<S>

Note:
S: Scalar

See the Using with nalgebra, ndarray, and faer section further down on this page for information on using the linalg-traits crate with types defined in nalgebra and/or ndarray.

§Example

Let’s define a function that takes in a vector and returns a new vector with all the elements repeated twice. Using the Scalar and Vector traits, we can write it in a way that makes it independent of what types we use to represent scalars and vectors.

use linalg_traits::{Scalar, Vector};
use ndarray::{array, Array1};
use numtest::*;

// Define the function for repeating the elements.
fn repeat_elements<S: Scalar, V: Vector<S>>(v: &V) -> V {
    // Create a new vector of the same type but with twice the length.
    let mut v_repeated = V::new_with_length(v.len() * 2);

    // Populate the vector.
    for i in 0..v.len() {
        v_repeated.vset(2 * i, v.vget(i));
        v_repeated.vset(2 * i + 1, v.vget(i));
    }

    v_repeated
}

// Define the vector to be repeated.
let v: Array1<f64> = array![1.0, 2.0, 3.0];

// Repeat the elements.
let v_repeated: Array1<f64> = repeat_elements(&v);

// Check that the elements were properly repeated.
assert_arrays_equal!(v_repeated, [1.0, 1.0, 2.0, 2.0, 3.0, 3.0]);

§Using with nalgebra, ndarray, and faer

linalg-traits provides implementations of the Vector and Matrix traits for linear algebra types defined by nalgebra, ndarray, and faer. However, since you may not want to use some or any of these crates in your project, linalg-traits specifies nalgebra, ndarray, and faer as optional dependencies.

If you are using any of these crates in your project and want linear algebra types defined by these crates to be identified as either Vectors or Matrixes, you should specify these crates as features in the linalg-traits dependency in your Cargo.toml:

[dependencies]
linalg-traits = { version = "x.y.z", features = ["nalgebra", "ndarray", "faer", "faer-traits"] }

Note that the faer-traits feature is also required when using faer.

§Additional notes on use cases

Say I have an ODE solver crate my-ode-solver. I want this crate to be compatible with ndarray, nalgebra, and faer. In the backend, I implement everything requiring vectors/matrices in my-ode-solver using generic types with trait bounds on either Vector or Matrix (e.g. T: Vector, T: Matrix). Now, any downstream user of my-ode-solver can choose whether they want to use ndarray, nalgebra, faer, or any combination of the three. Alternatively, if they have some custom linear algebra types, they could implement Vector and Matrix for those custom types and use them directly with my-ode-solver.

This crate is not trying to replace existing APIs in all situations. Continuing the example from above, my-ode-solver will use the methods defined by the traits in linalg-traits. However, if I’m a user of my-ode-solver and I’m using it with ndarray, in my project I should still use the APIs defined by ndarray (and not those defined by linalg-traits).

Structs§

Mat
Extremely basic matrix type, written as Mat<S>, short for “matrix”.

Traits§

Matrix
Trait defining a generic matrix type.
Scalar
Trait defining a generic scalar type.
Vector
Trait defining a generic vector type.