user69514: I wrote a simple multiplication function for matrices. Originally my matrices are stored in a single array in format (row, column):
(row0, col0), (row0, col1), (row0, colN), (row1, col0), ... (rowN, col0).
so a 2x2 identity matrix would look like
float eye[4] = {1, 0, 0, 1};

In the actual function I put the 2 array matrices being multiplied into 2d arrays (easy human readable) and then do the multiplication to get the new matrix output. Then convert back to single array. I am only dealing with 3x3, 3x1, and 1x3 matrices. So my code is not be 100% compatible with every matrix possibility. I have global arrays temp3 for my 3x1 and 1x3 matrices, and temp3x3 to hold 3x3 matrices. I use a global bool squared to determine which one the new output will go to.
I get that my code is not perfect, but my question is, why do I get overflow for simple operations? My code is as follows:
#include <math.h>
#include <WString.h>

#define FLOAT sizeof(float)
void multiplyMatrixAxB(const uint8_t rows1, const uint8_t cols1, const uint8_t size1, float matrix1[], const uint8_t rows2, const uint8_t cols2, const uint8_t size2, float matrix2[]);

float K[3]; // 3x1
float dgdn[3]; // 1x3

bool squared = false;
// Temp Variable to hold matrixes
float temp3x3[9];
float temp3[3];

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Starting Matrix Test Program\n"));
  
  uint8_t i;
  K[0] = 1.0;
  K[1] = 2.0;
  K[2] = 3.0;

  dgdn[0] = 0.0;
  dgdn[1] = 0.0;
  dgdn[2] = 1.0;

  Serial.println(F("Matrix K setup as:"));
  for(i = 0; i < sizeof(K)/FLOAT; i++)
  {
    Serial.print(K[i]);
    Serial.print(F("\n"));
  }

  Serial.println(F("Matrix dgdn setup as:"));
  for(i = 0; i < sizeof(dgdn)/FLOAT; i++)
  {
    Serial.print(dgdn[i]);
    Serial.print(F("\t"));
  }
}

void loop()
{
  squared = true;
  Serial.println(F("\n\nA 3x1 times a 1x3 should give 3x3"));
  multiplyMatrixAxB(3,1, sizeof(K)/FLOAT, K, 1, 3, sizeof(dgdn)/FLOAT, dgdn);
  for(i = 0; i < 9; i++)
  {
    Serial.print(*(temp3x3 + i), 6);
    if(!((i+1)%3))
    {
      Serial.println();
    }
    else
    {
      Serial.print(F("\t"));
    }
  }

  Serial.print(F("\n\n"));
  Serial.println(F("End of Test"));
  while(1){delay(1000);}
}

void multiplyMatrixAxB(const uint8_t rows1, const uint8_t cols1, const uint8_t size1, float matrix1[], const uint8_t rows2, const uint8_t cols2, const uint8_t size2, float matrix2[])
{
  if(cols1 != rows2)
  {
    Serial.println(F("Multiplying Invalid Matrixes. Check ColsA and RowsB"));
    while(1){delay(1000);}
  }
  
  if(size1 != rows1*cols1)
  {
    Serial.println(F("rows and columns do not match size of matrix A"));
    while(1){delay(1000);}
  }
  
  if(size2 != rows2*cols2)
  {
    Serial.println(F("rows and columns do not match size of matrix B"));
    while(1){delay(1000);}
  }
  
  uint8_t row, column, k, i;
  double mat1[rows1][cols1];
  double mat2[rows2][cols2];
  double newMat[rows1][cols2];

  // place matrix1 into 2d array
  row = 0;
  for(row = 0; row < rows1; row++)
  {
    column = 0;
    for(column = 0; column < cols1; column++)
    {
      mat1[row][column] = matrix1[row*cols1 + column];
    }
  }

  // place matrix2 into 2d array
  row = 0;
  for(row = 0; row < rows2; row++)
  {
    column = 0;
    for(column = 0; column < cols2; column++)
    {
      mat2[row][column] = matrix2[row*cols2 + column];
    }
  }

  // get new array with multiplied values
  row = 0;
  for(row = 0; row < rows1; row++)
  {
    column = 0;
    for(column = 0; column < cols2; column++)
    {
      k = 0;
      for(k = 0; k < cols1; k++)
      {
        newMat[row][column] += mat1[row][k]*mat2[k][column];
      }
    }
  }

  row = 0;
  i = 0;
  // Place new matrix into single array format
  for(row = 0; row < rows1; row++)
  {
    column = 0;
    for(column = 0; column < cols2; column++)
    {
      if(squared)
      {
        temp3x3[i] = newMat[row][column];
      }
      else
      {
        temp3[i] = newMat[row][column];
      }
      i++;
    }
  }
}

Hopefully that covered everything. I have more code, but it is all mostly commented out. At worst I missed a variable declaration here, but I will mention that in the IDE it compiles fine and runs. My output looks like this:
Starting Matrix Test Program

Matrix K setup as:
1.00
2.00
3.00
Matrix dgdn setup as:
0.00    0.00    1.00    

A 3x1 times a 1x3 should give 3x3
0.000000    0.000000    1.000000
ovf 0.000000    2.000000
0.000000    0.000000    3.000000


End of Test

Where does this ovf come from? I have tried printing out in the multiplication statement in the for loop the index of mat1 x the index of mat2 = "result". This will actually print out exactly what I expect to see and then my output in the main loop will be ok. What is going on? I tried some delays to see if that was the issue between calculations as well. No good.
what I mean is placing in the inner most for loop (k loop):
'''
Serial.print(mat1[row][k]); Serial.print(" x "); Serial.print(mat2[k][column]); Serial.print(" + ");
'''
And then just outside it,
'''
Serial.print(" = "); Serial.println(newMat[row][column]);
'''
I will not get any overflow in this scenario.

user7508: newMat is first declared:
double newMat[rows1][cols2];

and then updated:
newMat[row][column] += mat1[row][k]*mat2[k][column];

However, it has never been initialized. Non-static local variables are
not implicitly initialized: newMat starts its life containing whatever
garbage was in RAM at this location. You should initialize every
element to zero before you start accumulating the sum of products.

Edit: Regarding the initialization as
float newMat[rows1][cols2] = {{0},{0}};

I would expect that to initialize the whole matrix to all zeros, but my
experiment shows that it only initializes the first element of the first
two rows, and the entire third row. Initializing an array with a list
shorter than that array is supposed to initialize the other elements to
zero. However, this appears to not work recursively with the inner
arrays. I do not know whether it is a compiler bug or normal behavior.
The following, however, does work:
float newMat[rows1][cols2] = {};  // zero-initialize

Regarding the copies within multiplyMatrixAxB(), you can completely
avoid them by using pointers. For example,
double (*mat1)[cols1];

declares mat1 as a pointer to arrays of length cols1 of double.
This would be equivalent to double mat1[][cols1] within a parameter
list, and is compatible with a 2D array of width cols1 and unspecified
height. If you make this point to matrix1:
double (*mat1)[cols1] = (double (*)[cols1]) matrix1;

you can then use mat1 as a different view of matrix1: you view it
as an array of arrays of numbers, rather than a 1D array of numbers. You
can then use mat1 as you do now, and it will work by accessing the
original data, without needing an extra copy.
Using this trick, the body of multiplyMatrixAxB() can be reduced to
the following (skipping error checking):
// View the vectors as matrices.
double (*mat1)[cols1] = (double (*)[cols1]) matrix1;
double (*mat2)[cols2] = (double (*)[cols2]) matrix2;;
double (*newMat)[cols2];
if (squared)
  newMat = (double (*)[cols2]) temp3x3;
else
  newMat = (double (*)[cols2]) temp3;

// Matrix multiplication.
for (int i = 0; i < rows1; i++)
  for (int j = 0; j < cols2; j++) {
    newMat[i][j] = 0;
    for (int k = 0; k < cols1; k++)
      newMat[i][j] += mat1[i][k] * mat2[k][j];
  }


69514: <p>I wrote a simple multiplication function for matrices. Originally my matrices are stored in a single array in format (row, column):</p>
<p>(row0, col0), (row0, col1), (row0, colN), (row1, col0), ... (rowN, col0).</p>
<p>so a 2x2 identity matrix would look like</p>
<pre><code>float eye[4] = {1, 0, 0, 1};
</code></pre>
<p>In the actual function I put the 2 array matrices being multiplied into 2d arrays (easy human readable) and then do the multiplication to get the new matrix output. Then convert back to single array. I am only dealing with 3x3, 3x1, and 1x3 matrices. So my code is not be 100% compatible with every matrix possibility. I have global arrays temp3 for my 3x1 and 1x3 matrices, and temp3x3 to hold 3x3 matrices. I use a global bool squared to determine which one the new output will go to.</p>
<p>I get that my code is not perfect, but my question is, why do I get overflow for simple operations? My code is as follows:</p>
<pre><code>#include &lt;math.h&gt;
#include &lt;WString.h&gt;

#define FLOAT sizeof(float)
void multiplyMatrixAxB(const uint8_t rows1, const uint8_t cols1, const uint8_t size1, float matrix1[], const uint8_t rows2, const uint8_t cols2, const uint8_t size2, float matrix2[]);

float K[3]; // 3x1
float dgdn[3]; // 1x3

bool squared = false;
// Temp Variable to hold matrixes
float temp3x3[9];
float temp3[3];

void setup()
{
  Serial.begin(115200);
  Serial.println(F(&quot;Starting Matrix Test Program\n&quot;));
  
  uint8_t i;
  K[0] = 1.0;
  K[1] = 2.0;
  K[2] = 3.0;

  dgdn[0] = 0.0;
  dgdn[1] = 0.0;
  dgdn[2] = 1.0;

  Serial.println(F(&quot;Matrix K setup as:&quot;));
  for(i = 0; i &lt; sizeof(K)/FLOAT; i++)
  {
    Serial.print(K[i]);
    Serial.print(F(&quot;\n&quot;));
  }

  Serial.println(F(&quot;Matrix dgdn setup as:&quot;));
  for(i = 0; i &lt; sizeof(dgdn)/FLOAT; i++)
  {
    Serial.print(dgdn[i]);
    Serial.print(F(&quot;\t&quot;));
  }
}

void loop()
{
  squared = true;
  Serial.println(F(&quot;\n\nA 3x1 times a 1x3 should give 3x3&quot;));
  multiplyMatrixAxB(3,1, sizeof(K)/FLOAT, K, 1, 3, sizeof(dgdn)/FLOAT, dgdn);
  for(i = 0; i &lt; 9; i++)
  {
    Serial.print(*(temp3x3 + i), 6);
    if(!((i+1)%3))
    {
      Serial.println();
    }
    else
    {
      Serial.print(F(&quot;\t&quot;));
    }
  }

  Serial.print(F(&quot;\n\n&quot;));
  Serial.println(F(&quot;End of Test&quot;));
  while(1){delay(1000);}
}

void multiplyMatrixAxB(const uint8_t rows1, const uint8_t cols1, const uint8_t size1, float matrix1[], const uint8_t rows2, const uint8_t cols2, const uint8_t size2, float matrix2[])
{
  if(cols1 != rows2)
  {
    Serial.println(F(&quot;Multiplying Invalid Matrixes. Check ColsA and RowsB&quot;));
    while(1){delay(1000);}
  }
  
  if(size1 != rows1*cols1)
  {
    Serial.println(F(&quot;rows and columns do not match size of matrix A&quot;));
    while(1){delay(1000);}
  }
  
  if(size2 != rows2*cols2)
  {
    Serial.println(F(&quot;rows and columns do not match size of matrix B&quot;));
    while(1){delay(1000);}
  }
  
  uint8_t row, column, k, i;
  double mat1[rows1][cols1];
  double mat2[rows2][cols2];
  double newMat[rows1][cols2];

  // place matrix1 into 2d array
  row = 0;
  for(row = 0; row &lt; rows1; row++)
  {
    column = 0;
    for(column = 0; column &lt; cols1; column++)
    {
      mat1[row][column] = matrix1[row*cols1 + column];
    }
  }

  // place matrix2 into 2d array
  row = 0;
  for(row = 0; row &lt; rows2; row++)
  {
    column = 0;
    for(column = 0; column &lt; cols2; column++)
    {
      mat2[row][column] = matrix2[row*cols2 + column];
    }
  }

  // get new array with multiplied values
  row = 0;
  for(row = 0; row &lt; rows1; row++)
  {
    column = 0;
    for(column = 0; column &lt; cols2; column++)
    {
      k = 0;
      for(k = 0; k &lt; cols1; k++)
      {
        newMat[row][column] += mat1[row][k]*mat2[k][column];
      }
    }
  }

  row = 0;
  i = 0;
  // Place new matrix into single array format
  for(row = 0; row &lt; rows1; row++)
  {
    column = 0;
    for(column = 0; column &lt; cols2; column++)
    {
      if(squared)
      {
        temp3x3[i] = newMat[row][column];
      }
      else
      {
        temp3[i] = newMat[row][column];
      }
      i++;
    }
  }
}
</code></pre>
<p>Hopefully that covered everything. I have more code, but it is all mostly commented out. At worst I missed a variable declaration here, but I will mention that in the IDE it compiles fine and runs. My output looks like this:</p>
<pre><code>Starting Matrix Test Program

Matrix K setup as:
1.00
2.00
3.00
Matrix dgdn setup as:
0.00    0.00    1.00    

A 3x1 times a 1x3 should give 3x3
0.000000    0.000000    1.000000
ovf 0.000000    2.000000
0.000000    0.000000    3.000000


End of Test
</code></pre>
<p>Where does this ovf come from? I have tried printing out in the multiplication statement in the for loop the index of mat1 x the index of mat2 = &quot;result&quot;. This will actually print out exactly what I expect to see and then my output in the main loop will be ok. What is going on? I tried some delays to see if that was the issue between calculations as well. No good.</p>
<p>what I mean is placing in the inner most for loop (k loop):</p>
<p>'''
Serial.print(mat1[row][k]); Serial.print(&quot; x &quot;); Serial.print(mat2[k][column]); Serial.print(&quot; + &quot;);
'''
And then just outside it,</p>
<p>'''
Serial.print(&quot; = &quot;); Serial.println(newMat[row][column]);
'''</p>
<p>I will not get any overflow in this scenario.</p>
 7508: <p><code>newMat</code> is first declared:</p>
<pre class="lang-cpp prettyprint-override"><code>double newMat[rows1][cols2];
</code></pre>
<p>and then updated:</p>
<pre class="lang-cpp prettyprint-override"><code>newMat[row][column] += mat1[row][k]*mat2[k][column];
</code></pre>
<p>However, it has never been initialized. Non-static local variables are
not implicitly initialized: <code>newMat</code> starts its life containing whatever
garbage was in RAM at this location. You should initialize every
element to zero before you start accumulating the sum of products.</p>
<hr />
<p><strong>Edit</strong>: Regarding the initialization as</p>
<pre class="lang-cpp prettyprint-override"><code>float newMat[rows1][cols2] = {{0},{0}};
</code></pre>
<p>I would expect that to initialize the whole matrix to all zeros, but my
experiment shows that it only initializes the first element of the first
two rows, and the entire third row. Initializing an array with a list
shorter than that array is supposed to initialize the other elements to
zero. However, this appears to not work recursively with the inner
arrays. I do not know whether it is a compiler bug or normal behavior.
The following, however, does work:</p>
<pre class="lang-cpp prettyprint-override"><code>float newMat[rows1][cols2] = {};  // zero-initialize
</code></pre>
<p>Regarding the copies within <code>multiplyMatrixAxB()</code>, you can completely
avoid them by using pointers. For example,</p>
<pre class="lang-cpp prettyprint-override"><code>double (*mat1)[cols1];
</code></pre>
<p>declares <code>mat1</code> as a pointer to arrays of length <code>cols1</code> of <code>double</code>.
This would be equivalent to <code>double mat1[][cols1]</code> within a parameter
list, and is compatible with a 2D array of width <code>cols1</code> and unspecified
height. If you make this point to <code>matrix1</code>:</p>
<pre class="lang-cpp prettyprint-override"><code>double (*mat1)[cols1] = (double (*)[cols1]) matrix1;
</code></pre>
<p>you can then use <code>mat1</code> as a different <em>view</em> of <code>matrix1</code>: you view it
as an array of arrays of numbers, rather than a 1D array of numbers. You
can then use <code>mat1</code> as you do now, and it will work by accessing the
original data, without needing an extra copy.</p>
<p>Using this trick, the body of <code>multiplyMatrixAxB()</code> can be reduced to
the following (skipping error checking):</p>
<pre class="lang-cpp prettyprint-override"><code>// View the vectors as matrices.
double (*mat1)[cols1] = (double (*)[cols1]) matrix1;
double (*mat2)[cols2] = (double (*)[cols2]) matrix2;;
double (*newMat)[cols2];
if (squared)
  newMat = (double (*)[cols2]) temp3x3;
else
  newMat = (double (*)[cols2]) temp3;

// Matrix multiplication.
for (int i = 0; i &lt; rows1; i++)
  for (int j = 0; j &lt; cols2; j++) {
    newMat[i][j] = 0;
    for (int k = 0; k &lt; cols1; k++)
      newMat[i][j] += mat1[i][k] * mat2[k][j];
  }
</code></pre>
