How to multiply two dynamic matrices

Hello, I have two Matrices of type

type EdgeMappingMatrix = Matrix<EdgeMappingMatrixValue,
    Dynamic,
    Dynamic,
    VecStorage<EdgeMappingMatrixValue, Dynamic, Dynamic>>

where EdgeMappingMatrixValue implements Add, Mul and num_traits::Zero and num_traits::One.

I create them like this:

let mut connecting_left_matrix =
    EdgeMappingMatrix::from_element(
        connecting_edges.len(),
        incoming.len(),
        false.into()); // EdgeMappingMatrixValue implements From<bool>

let mut connecting_right_matrix =
    EdgeMappingMatrix::from_element(
        outgoing.len(),
        connecting_edges.len(),
        false.into());

connecting_edges
    .iter()
    .enumerate()
    .for_each(|(i,(left_matrix_index, right_matrix_index))| {
        connecting_left_matrix.set_row(i, &reduced_left_matrix.row(*left_matrix_index));
        connecting_right_matrix.set_column(i, &reduced_right_matrix.column(*right_matrix_index));
    });

and want to multiply them like this:

let new_matrix = &connecting_right_matrix * &connecting_left_matrix;

connecting_right_matrix has connecting_edges.len() number of rows, and connecting_right_matrix has the same number of columns, so the multiplication should always succeed.

Unfortunately I am getting this compiler error:

error[E0369]: cannot multiply `&nalgebra::Matrix<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic, nalgebra::VecStorage<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic>>` to `&nalgebra::Matrix<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic, nalgebra::VecStorage<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic>>`
   --> interpreter/src/graph/path.rs:259:51
    |
259 |         let new_matrix = &connecting_right_matrix * &connecting_left_matrix;
    |                          ------------------------ ^ ----------------------- &nalgebra::Matrix<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic, nalgebra::VecStorage<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic>>
    |                          |
    |                          &nalgebra::Matrix<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic, nalgebra::VecStorage<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic>>
    |
    = note: an implementation of `std::ops::Mul` might be missing for `&nalgebra::Matrix<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic, nalgebra::VecStorage<graph::edge_mapping::EdgeMappingMatrixValue, nalgebra::Dynamic, nalgebra::Dynamic>>`

And I can’t figure out why. The documentation writes about an implementation of Mul which I thought should match:

impl<'a, N, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<Matrix<N, R2, C2, SB>> for &'a Matrix<N, R1, C1, SA>
where
    N: Scalar + Zero + One + ClosedAdd + ClosedMul,
    SB: Storage<N, R2, C2>,
    SA: Storage<N, R1, C1>,
    DefaultAllocator: Allocator<N, R1, C2>,
    ShapeConstraint: AreMultipliable<R1, C1, R2, C2>,

I have also tried all combinations of taking references of the matricies, so that should not be the issue.
If someone could help me with multiplying these matricies, I would be very grateful.

Sincerely

Hi!

This is surprising. Did you paste the complete error message here or is there something more?
Could you provide the complete definition of the EdgeMappingMatrixValue type?

Also note that your type alias can equivalently be written as:

type EdgeMappingMatrix = DMatrix<EdgeMappingMatrixValue>;

It is basically just a wrapper around bool to implement some traits. The matrix is supposed to be an adjacency matrix.

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct EdgeMappingMatrixValue {
    val: bool
}
impl Mul for EdgeMappingMatrixValue {
    type Output = Self;
    fn mul(self, o: Self) -> Self::Output {
        Self::from(self.val && o.val)
    }
}
impl Add for EdgeMappingMatrixValue {
    type Output = Self;
    fn add(self, o: Self) -> Self::Output {
        Self::from(self.val || o.val)
    }
}
impl num_traits::Zero for EdgeMappingMatrixValue {
    fn zero() -> Self {
        Self { val: false }
    }
    fn is_zero(&self) -> bool {
        !self.val
    }
}
impl num_traits::One for EdgeMappingMatrixValue {
    fn one() -> Self {
        Self { val: true }
    }
    fn is_one(&self) -> bool {
        self.val
    }
}
impl From<bool> for EdgeMappingMatrixValue {
    fn from(val: bool) -> Self {
        Self { val }
    }
}
impl Into<bool> for EdgeMappingMatrixValue {
    fn into(self) -> bool {
        self.val
    }
}
impl Display for EdgeMappingMatrixValue {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{}", match self.val {
            true => "I",
            false => "O",
        })
    }
}

And that was the whole error message.

It might be because the impl Mul for Matrix requires the values to implement ClosedAdd and ClosedMul from the alga crate. I have not tried this because I am performing the multiplication manually right now, and have moved on since, but I found this when looking at the latest documentation at docs.rs. I will try it tomorrow.

Actually, you don’t need to implement ClosedAdd (and ClosedMul) explicitly. There is a blanket impl for types that implement both Add and AddAssign (and Mul, MulAssign).

So you are just missing the std::ops::AddAssign and MulAssign implementations here.

1 Like

Yes, that was it. Thank you for helping!