nalgebra icon indicating copy to clipboard operation
nalgebra copied to clipboard

Matrix multiplication does not work over all generics, with misleading compiler error

Open nanaknihal opened this issue 2 years ago • 1 comments

Hi,

It seems matrix multiplcation only works over standard types, e.g. u32, u64... The following code compiles:

let m1 = Matrix2x4::<u32>::zeros();
let m2 = Matrix4x2::<u32>::zeros();
let should_be_zeros = m1 * m2;

But replacing u32 with Fr gives the compilation error:

let m1 = Matrix2x4::<Fr>::zeros();
let m2 = Matrix4x2::<Fr>::zeros();
let should_be_zeros = m1 * m2;

This gives the compile error mismatched types expected struct 'Fr' found struct 'Matrix<Fr, nalgebra::Const<4>, nalgebra::Const<2>, ArrayStorage<Fr, 4, 2>>'

For reproducibility and context, Fr is a struct defined as

use ff::Field;
#[macro_use]
extern crate ff;
use crate::ff::PrimeField;

#[derive(PrimeField)]
#[PrimeFieldModulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"]
#[PrimeFieldGenerator = "7"]
#[PrimeFieldReprEndianness = "big"]
pub struct Fr([u64; 4]);

using nalgebra version 0.32.3 and ff version 0.13.

I am guessing there could be some important trait Fr doesn't implement. However, It is hard to discern what the cause of the error is ebcuase the error message implies mul() only works when RHS is a scalar.

nanaknihal avatar Nov 13 '23 00:11 nanaknihal

Update: this was fixed by implementing the Zero and One traits for Fr. Fr just did not have the traits. It would be great to show this in the compiler error!

If anyone else has this problem, the list of traits it needs to succeed in version 0.32.3 appears in this impl block of Mul in ops.rs:

// Matrix × Matrix
impl<'a, 'b, T, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<&'b Matrix<T, R2, C2, SB>>
    for &'a Matrix<T, R1, C1, SA>
where
    T: Scalar + Zero + One + ClosedAdd + ClosedMul
   ...

nanaknihal avatar Nov 13 '23 10:11 nanaknihal