Conditions on types for Matrixmultiplication in nalgebra

27 Views Asked by At

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.

0

There are 0 best solutions below