Time for some updates on this! You will see the work done so far on the nexgen branch. This is basically a full rewrite of the library internals with lots of added features (and a few removed).
Also, I'd appreciate some help for whoever would be interested in working on integrating Blas/Lapack/matrixmultiply. All the relevant code to be modified are in the
Main modifications and new features
(Almost) everything is generic wrt. the dimension.
For example a 3x3 matrix is
Matrix<f32, U3, U3, S> while a (column) vector is
Matrix<f32, U3, U1, S>. In both cases
S is some other type parameter that represents the matrix data storage type (more on this later). Of course, many type aliases are defined for, e.g., low dimensional matrices and vectors. For example,
Vector6 are provided, as well as all square and rectangular matrices from
Matrix6 (for example a 2x3 matrix type alias is
Dynamically-sized matrix and vectors
Dynamical-sized matrices and vectors are declared just like statically-sized matrices, but with a special value for its dimension, i.e.,
Matrix<f32, Dynamic, Dynamic, S> and
Matrix<f32, Dynamic, U1, S> (for dynamically-sized vectors). This is actually much like Eigen. This is where the last type parameter
S (which you don't have to worry about as long as you use the type aliases) plays its main role: dynamic entities will store their data as
Vec while statically-sized matrices will use
Thus, because dynamic and static matrices use the same base type (
Matrix<...>), they both share the same code.
It is now possible to take references to parts of a vector or matrix. For example, it is possible to extract a 2x2 submatrix from a 3x3 matrix using:
let m3 = Matrix3::new(...);
let m2 = m3.fixed_slice::<U2, U2>(0, 0);
m2 will a 2D submatrix of
m3 starting with its top-left component. Because this slice is simply a
Matrix<f32, U2, U2, S> with some special value for the
S storage parameter (which contain an internal reference to
m3), they share most capabilities of non-slice matrices (e.g. matrix/matrix or matrix/vector multiplication, etc.)
Mutable slices, slices-of-slices, and custom strides are also possible.
If the slice size is not known at compile-time, it is possible to write, e.g.:
let m2 = m3.slice((0, 0), (2, 2));
m2 is a dynamically-sized slice and its type is
Matrix<f32, Dynamic, Dynamic, S> with some special value of the
S storage parameter which contain an internal reference to
The whole set of common transformations are now included in nalgebra. In particular, we have types for:
- Rotation matrix
- Unit quaternion (3D rotation)
- Unit complex (2D rotation)
- Isometry (translation × rotation)
- Similarity (translation × rotation × uniform scale)
- Affine (translation × rotation × non-uniform scale × rotation)
- Projective (arbitrary invertible transformation).
They can be used in generic code as they implement transformations traits from alga.
If you don't care about generic programming, you should not have to import tons of traits to use algebraic operators. That's why most operators are now implemented as struct methods. Use traits from alga for generic programming.
A few feature still have to be added or polished. Then, the next steps are:
I'm working on a new website (much like the one for ncollide) that will document all those features. The rustdoc-generated doc put too much emphasis on trait bounds, making it very hard to read.
We basically need to integrate matrixmultiply, Blas and Lapack. Any contribution on that would be strongly appreciated. We also need to check that we did not regress from the previous version of nalgebra.
I get a lot of
Broken MIR errors when compiling tests of benchmarks (mostly because it fails to recognize that an associated type is equal to some other exact type). I am not sure how to decrease the code base to report this as an issue to the rust compiler repo.