sparsemat / sprs

sparse linear algebra library for rust
Apache License 2.0
381 stars 45 forks source link

Matrix multiplication discrepancy #336

Closed jlogan03 closed 9 months ago

jlogan03 commented 9 months ago
          I will piggy back off of this comment, I think there might be a bug in how matrix multiplication is performed by the crate?

I have this snippet:

 let laplacian: CsMat<_> = triplets.to_csr();

    let mut dbg_check = HashMap::new();
    for (v, (r, c)) in laplacian.iter()
    {
        if dbg_check.contains_key(&(c, r))
        {
            let o = *dbg_check.get(&(c, r)).unwrap();
            assert!(o == v, "{} {} {} {}", v, o, r, c);
        }
        dbg_check.insert((r, c), v);
    }

    let mass: CsMat<_> = mass.to_csr();

    for (_, (r, c)) in mass.iter()
    {
        assert!(r == c);
    }

    let high_laplacian = &mass * &laplacian;

    let mut dbg_check = HashMap::new();
    for (v, (r, c)) in high_laplacian.iter()
    {
        if dbg_check.contains_key(&(c, r))
        {
            let o = *dbg_check.get(&(c, r)).unwrap();
            assert!(o == v, "{} {} {} {}", v, o, r, c);
        }
        dbg_check.insert((r, c), v);
    }

According to the first check, the matrix laplacian is symmetric. Accordfing to the mid check, the matrix mass is diagonal. But the last check fails with:

 thread 'convex_polytope::tests::test_topologize_skeleton' panicked at '0.2576181530716957 0.12738811865592223 512 0', src/differential_geometry.rs:270:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: test failed, to rerun pass `--lib`

So the product &mass * &laplacian is producing a non-symmetric matrix despite being the product of a diagonal and a syemmtric matrix?

How is that possible?

Originally posted by @Makogan in https://github.com/sparsemat/sprs/issues/335#issuecomment-1720213112

mulimoen commented 9 months ago

@Makogan counterexample

M = [0, 1; 1, 0]
D = [1, 0; 0, 9]
M*D
% ans = [0, 9; 1, 0]