Custom complex type and possible implications

Issue #180 wontfix
Santiago Peñate Vera created an issue

Hi,

Recently I discovered that a std::complex<double> cannot be multiplied by a std::size_t, int or other than a double. Apparently the C++ committee considers this a borderline case which is proposed for C++20.

I am programming an electrical circuit library that could be used with potentially several millions of electrical nodes. This translates into millions by millions sparse matrices.

In circuit theory there are a number of graph adjacency matrices that ideally are represented by ones and zeros (either bool or int types). Later in the circuit construction those matrices are multiplied by complex number vectors to get the calculation matrices in complex numbers. So in the end I'd like to have: complex matrix = bool matrix * complex vector. I have this working in a python prototype.

At the moment, those adjacency matrices are being declared as CompressedMatrix<double, columnMajor> but I am concerned with keeping the memory requirements as low as possible. Therefore I'd like to declare those adjacency matrices as bool or int and still be able to multiply them by a complex vector.

I have seen here that blaze would not use BLAS for sparse matrix operations.

My questions are:

  • Is here anything in Blaze preventing me from programming my own complex number class that allows complex * int or complex * bool operations?

  • Would there be a loss of performance? (apart from the one caused by my implementation of the complex number)?

Comments (6)

  1. Klaus Iglberger

    Hi Santiago!

    For your application it is not necessary to write a new class, but adding a simple (free) function is enough:

    inline constexpr std::complex<double> operator*( const std::complex<double>& c, int s ) noexcept
    {
       return std::complex<double>( real(c)*s, imag(c)*s );
    }
    

    This function extends the interface of std::complex<double> and "teaches" it what it means to be scaled by an integer (with all the potential problems involving conversions). This approach would allow you to use std::complex as data type for all Blaze vectors and matrices without loosing all the benefits of the standard functionality and without loosing any kind of performance (e.g. potential vectorization).

    For a short discussion about the memory requirements of a CompressedMatrix<bool>, see issue #171. For now Blaze does unfortunately not provide a data structure that would minimize the memory footprint for your kind of application.

    I hope this solves your problem,

    Best regards,

    Klaus!

  2. Santiago Peñate Vera reporter

    Hi Klaus,

    The function by itself did not do the trick. I overloaded the product and then the compiler asked me to overload "+=" I desisted and left the adjacency matrices as double.

    I still believe that I need to create a custom complex class.

  3. Klaus Iglberger

    Hi Santiago!

    You are correct, a single function will not do the trick. You will have to write several functions to cover all possible operations. The given operator*() was intended as an example of how it would be done. Please note that it is possible to implement compound assignment operators (e.g. operator+=()) as free functions as well. Only pure assignment (i.e. operator=()) is required to be a member function. Therefore I still believe that it would be possible to extend the existing std::complex class template.

    Since this issue is primarily focused on finding a viable solution/design for your application and does not suggest any new feature or extension for Blaze I closed the issue.

    Best regards

    Klaus!

  4. Klaus Iglberger

    If you want to continue the discussion, please feel free to connect via LinkedIn. I'm sure we can find a perfect design that requires a minimum of effort but provides a maximum of performance.

  5. Log in to comment