`l2Norm` and derivatives incorrect for complex valued matrices

Issue #227 resolved
Richard Shaw created an issue

I think the implementations for the L2 norm and variants are incorrect for complex valued matrices. This test code demonstrates the issues:

#include <iostream>
#include <fstream>

#include <complex>
#include <blaze/Blaze.h>

using namespace std::complex_literals;
using cfloat = std::complex<float>;

int main(int argc, char** argv)
{
    size_t n = 2;

    blaze::DynamicMatrix<cfloat, blaze::columnMajor> m(n, n);

    m = 1.0if;

    std::cout << blaze::sqrNorm(m) << std::endl; // Prints: (-4,0)
    std::cout << blaze::l2Norm(m) << std::endl; // Prints (1.50996e-07,2)
}

In this case the outputs should be 4 and 2 respectively. It is clear that a normal square, i.e. z*z is being used instead of |z|^2.

I think the problem is the specialisations found in blaze/math/expressions/DMatNormExpr.h (for example here) that replace the Abs with a Noop which is only a correct optimisation for real types.

One solution might be to replace the Pow2 call with a replacement Abs2 that is specialised appropriately for complex numbers. That would retain the optimisation for both real and complex numbers, but would have the appropriate behaviour.

I'd be happy to put in a PR if needed but I could do with some guidance as to where are the places I'd need to add something like Abs2 particularly in terms of the SIMD versions.

Comments (7)

  1. Klaus Iglberger

    Hi Richard!

    Thanks a lot for pointing out this defect. You are correct, both the sqrNorm() and the l2Norm() should produce other results for complex numbers. Also thanks for volunteering to create a PR, but this should not cause a lot of effort. We will take care of this as quickly as possible. Thanks again,

    Best regards,

    Klaus!

  2. Klaus Iglberger

    Commit a292f43 resolves the issue of the norm(), sqrNorm(), l2Norm() and l4Norm() functions with complex numbers. The fix is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.5.

  3. Log in to comment