No match for 'operator*' in matrix multiplication

Hello!
I am new to Arduino, array multiplication in Arduino is quite confusing for me therefore I am trying to use BasicLinearAlgebra library.

here I tried to multiply (variable name: vReal) 4 x 1 array to defined matrix (variable name: B) 2 x 4 array, vReal and B are both a double) but I got errors:

Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"





















D:\Chika\TA\ArduinoMindwave2\Mindwave\Mindwave.ino: In function 'void loop()':

Mindwave:59:37: error: no match for 'operator*' (operand types are 'BLA::Matrix<2, 4>' and 'double [4]')

             BLA::Matrix<2, 1> D = B * vReal;

                                   ~~^~~~~~~

In file included from sketch\Toeplitz32x64.h:4:0,

                 from D:\Chika\TA\ArduinoMindwave2\Mindwave\Mindwave.ino:4:

D:\MyDocuments\Arduino\libraries\BasicLinearAlgebra/BasicLinearAlgebra.h:84:80: note: candidate: template<int operandCols, class opMemT> BLA::Matrix<rows, operandCols, BLA::Array<rows, operandCols, typename MemT::elem_t> > BLA::Matrix<rows, cols, MemT>::operator*(const BLA::Matrix<cols, operandCols, opMemT>&) const [with int operandCols = operandCols; opMemT = opMemT; int rows = 2; int cols = 4; MemT = BLA::Array<2, 4, float>]

     Matrix<rows, operandCols, Array<rows, operandCols, typename MemT::elem_t>> operator*(

                                                                                ^~~~~~~~

D:\MyDocuments\Arduino\libraries\BasicLinearAlgebra/BasicLinearAlgebra.h:84:80: note:   template argument deduction/substitution failed:

D:\Chika\TA\ArduinoMindwave2\Mindwave\Mindwave.ino:59:39: note:   mismatched types 'const BLA::Matrix<4, operandCols, opMemT>' and 'double [4]'

             BLA::Matrix<2, 1> D = B * vReal;

                                       ^~~~~

In file included from D:\MyDocuments\Arduino\libraries\BasicLinearAlgebra/BasicLinearAlgebra.h:140:0,

                 from sketch\Toeplitz32x64.h:4,

                 from D:\Chika\TA\ArduinoMindwave2\Mindwave\Mindwave.ino:4:

D:\MyDocuments\Arduino\libraries\BasicLinearAlgebra/impl/BasicLinearAlgebra.h:287:62: note: candidate: BLA::Matrix<rows, cols, BLA::Array<rows, cols, typename MemT::elem_t> > BLA::Matrix<rows, cols, MemT>::operator*(typename MemT::elem_t) const [with int rows = 2; int cols = 4; MemT = BLA::Array<2, 4, float>; typename MemT::elem_t = float; typename MemT::elem_t = float]

 Matrix<rows, cols, Array<rows, cols, typename MemT::elem_t>> Matrix<rows, cols, MemT>::operator*(

                                                              ^~~~~~~~~~~~~~~~~~~~~~~~

D:\MyDocuments\Arduino\libraries\BasicLinearAlgebra/impl/BasicLinearAlgebra.h:287:62: note:   no known conversion for argument 1 from 'double [4]' to 'BLA::Array<2, 4, float>::elem_t {aka float}'

Multiple libraries were found for "arduinoFFT.h"

 Used: D:\MyDocuments\Arduino\libraries\arduinoFFT

 Not used: C:\Program Files (x86)\Arduino\libraries\arduinoFFT-1.5.6

exit status 1

no match for 'operator*' (operand types are 'BLA::Matrix<2, 4>' and 'double [4]')



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

the code itself is quite long, therefore I will just show the problems

here is the code for 2 x 4 matrix (matrix2x4.h)

#include <BasicLinearAlgebra.h>

using namespace BLA;

BLA::Matrix<2, 4,Array<2,4,double> > B = {-0.125, 0.125, -0.125, 0.125, -0.125, 0.125, -0.125, 0.125};
#endif

here is the main program

 FFT.Compute(vReal, vImag, samples, FFT_FORWARD);
      for (int r = 0; r < 4; r++){
            BLA::Matrix<4,1> vReal[r];
            BLA::Matrix<2,4>B;
            BLA::Matrix<2, 1> D = B * vReal;
            Serial << "D: " << D << '\n';
      }

how to fix it? thank you in advance

Typically square brackets are used to declare an array. Assuming that's true the line above declares an array of 0 to 3 in size with each element of the array being a BLA::Matrix<4,1>. Give the rest of the syntax and operator overloading I suspect that should not be an array...

            BLA::Matrix<4,1> vReal;

But, it does beg the question: How are BLA::Matrix initialized?

I changed this part

BLA::Matrix<4,1> vReal[r];

into this

BLA::Matrix<4,1> vReal;

there is no longer error detected but it has no vReal values but instead it prints 4 x 4 zero matrix

here is how I initialized BLA::Matrix:

void setup() 
{
  Serial.begin( 9600 ); // USB serial monitor to Arduino
  bluetoothSerial.begin( 57600 ); // bluetooth serial to NeuroSky MindWave
  THINKGEAR_initParser(&parser, handleDataValueFunc, NULL); // assign the handlers for the parser
  Serial.flush();
  A = 0;
  x = 0;
}

void loop() 
{
  coba = x;
  handleDataValueFunc;
  while (!bluetoothSerial.available()) delay(4); // wait for a byte from the bluetooth connection
  THINKGEAR_parseByte(&parser, bluetoothSerial.read()); // forward the byte to the stream parser
  if(coba!=x){
    
    if(coba<samples){
      prtValue(A);
      vReal[coba]=A;
      total=total+vReal[x];
    }
    else if(coba == samples){
      mean=total/samples;
      for (int i=0; i<samples; i++){
        vReal[i]=vReal[i]-mean;
        vImag[i]=0;
      }
      FFT.Compute(vReal, vImag, samples, FFT_FORWARD);
            BLA::Matrix<4> vReal;
            BLA::Matrix<2,4>B;
            BLA::Matrix<2, 1> D = B * vReal;
            Serial << "vReal: " << B << '\n';
}

...very likely has no side effects. I suspect it's missing some parenthesis.

My gut tells me the code presented does not compile. Is there more?

everything works fine serial monitor can print output from the sensor and also from vReal except when I tried to multiply it.

handleDataValueFunc;

is in other void. everything is working well except the multiplication. I tried to multiplied it with for loop

      FFT.Compute(vReal, vImag, samples, FFT_FORWARD);
      double tmp;
      double C[1][2];
      for(double k = 0; k < 4; k++) {
        for(double i = 0; i < 2; i++) {
          tmp = dtoeplitz[i][k];
              for(double j = 0; j < 2; j++) {
                 C[i][j] = C[i][j] + tmp * vReal[k][j];
        }
    }
}

but I got errors like this:

Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"

D:\Chika\TA\ArduinoMindwave2\Mindwave\Mindwave.ino: In function 'void loop()':

Mindwave:60:28: error: invalid types 'double [2][4][double]' for array subscript

           tmp = dtoeplitz[i][k];

                            ^

Mindwave:62:21: error: invalid types 'double [2][2][double]' for array subscript

                  C[i][j] = C[i][j] + tmp * vReal[k][j];

                     ^

Mindwave:62:31: error: invalid types 'double [2][2][double]' for array subscript

                  C[i][j] = C[i][j] + tmp * vReal[k][j];

                               ^

Mindwave:62:51: error: invalid types 'double [4][double]' for array subscript

                  C[i][j] = C[i][j] + tmp * vReal[k][j];

                                                   ^

Multiple libraries were found for "arduinoFFT.h"

 Used: D:\MyDocuments\Arduino\libraries\arduinoFFT

 Not used: C:\Program Files (x86)\Arduino\libraries\arduinoFFT-1.5.6

exit status 1

invalid types 'double [2][4][double]' for array subscript



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

shouldn't these indices be "int", not "double"?

int indices also doesn't work

the program doesn't work or doesn't compile? (you'll get more help by being more precise, may even be able to solve the problem yourself)

the following compiles

#define N_ROW   2
#define N_COL   4

double dtoeplitz [N_ROW][N_COL];
double vReal     [N_ROW][N_COL];

void
func ()
{
    double tmp;
    double C[1][2];

    for (int k = 0; k < 4; k++) {
        for (int i = 0; i < 2; i++) {
            tmp = dtoeplitz[i][k];
            for (int j = 0; j < 2; j++) {
                C[i][j] = C[i][j] + tmp * vReal[k][j];
            }
        }
  }
}

void setup ()
{
    Serial.begin (9600);// USB serial monitor to Arduino
}

void loop ()
{
}

Do you have a very recent version of the library?
I notice that there was a bugfix only 8 days ago: Fix operator* · tomstewart89/BasicLinearAlgebra@68e9078 · GitHub

Also, in the library code, there are a bunch of things like:

template <int rows, int cols, class MemT>
Matrix<rows, cols, Array<rows, cols, typename MemT::elem_t>> Matrix<rows, cols, MemT>::operator-() const {
    Matrix<rows, cols, Array<rows, cols, typename MemT::elem_t>> ret;

    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++) ret(i, j) = -(*this)(i, j);

    return ret;
}

Isn't "ret" a short-lived object allocated on the stack? Not proper to "return" it? (Is there something magic about operators that has a longer lifetime for local objects or something?)

What's wrong with returning a local variable?

The function operator-() is returning a Matrix object, not a pointer or reference to an object. Like any function that returns an object (or a simple type), it returns a copy of 'ret'. An rvalue, I think.