We can build matrices in nalgebra with arbitrary types. I would expect that if I have a Matrix A with entries of Type TypeA and a Matrix B with entries of Type TypeB and I have a TypeC such that
TypeA : Mul<TypeB,Output=TypeC>,
TypeC : Add<TypeC,Output=TypeC>,
I can multiply A with B and get a Matrix C with entries of TypeC. However this does not seem to be the case as this code does not compile
struct TypeA;
struct TypeB;
struct TypeC;
impl std::ops::Mul<TypeB> for TypeA {
type Output=TypeC;
fn mul(self, _: TypeB) -> Self::Output {
TypeC
}
}
impl std::ops::Add<TypeC> for TypeC {
type Output=TypeC;
fn add(self, _:TypeC) -> Self::Output {
TypeC
}
}
fn main() {
let A:SMatrix<TypeA,2,2>=matrix![TypeA,TypeA;TypeA,TypeA];
let B:SMatrix<TypeB,2,2>=matrix![TypeB,TypeB;TypeB,TypeB];
let C=A*B;
}
the error is:
cannot multiply Matrix<TypeA, Const<2>, Const<2>, ArrayStorage<TypeA, 2, 2>> by Matrix<TypeB, Const<2>, Const<2>, ArrayStorage<TypeB, 2, 2>>
To also have a more realistic "application" assume that we want to multiply a rotation matrix with Vector of Lengths.
use nalgebra::{geometry::Rotation2, vector, SVector};
use measurements::Length;
fn main() {
let R:Rotation2<f64>=Rotation2::new(0.1);
let v:SVector<Length,2>=vector![Length::from_meters(1.0),Length::from_meters(2.0)];
let Rv=R.matrix()*v;
}
the error message is
cannot multiply &Matrix<f64, Const<2>, Const<2>, ArrayStorage<f64, 2, 2>> by Matrix<Length, Const<2>, Const<1>, ArrayStorage<Length, 2, 1>>
the trait Mul<Matrix<Length, Const<2>, Const<1>, ArrayStorage<Length, 2, 1>>> is not implemented for &Matrix<f64, Const<2>, Const<2>, ArrayStorage<f64, 2, 2>>
Is there some additional requirements such that this works?
Due to the orphan rule I can not implement Mul<SMatrix<Length,2,1>> for SMatrix<f64,2,2>. However I guess I could wrap the SMatrix and then implement it for the wrapper, but this seems a bit cumbersome.
Of course I could also transform my length matrix/vector to a f64-matrix/vector, perform the multiplication and then transform it back to a length matrix/vector, but this seems also a bit cumbersome.