Expand description
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
-
Compatibility with
Vec<f64>, as well as types fromnalgebra,ndarray, andfaer.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.
ndarrayoverloads*for elementwise multiplication, whilenalgebraoverloads*for matrix multiplication). This means that anyone writing generic linear algebra code usinglinalg-traitsshould use the arithmetic methods defined on theVectorandMatrixtraits. -
Compatibility with both statically-sized and dynamically-sized types.
types (e.g.
nalgebra::SVector) may also implement theCopytrait, which is often preferable to use for those types. However, it can be unsafe to copy dynamically-sized types, so to keepVectorandMatrixcompatible with both statically and dynamically-sized linear algebra types, they only require thatClonebe implemented.
§Linear Algebra Traits
This crate provides the following traits along with their implementations for the following types:
| Trait | Implementations on Foreign Types | Implementations on Local Types |
|---|---|---|
Scalar | f64 and all other types that satisfy its trait bounds. | N/A |
Vector | Vec<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 |
Matrix | nalgebra::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”.