How to work with array?

Hello guys, is there some easy way how to work with array?
For example if I have array

a = [1 2 3]
b = [4]
[5]
[6]

How can I do c=ab? In matlab command (c=ab) works fine but in arduino it doesn't work like that.
Basically I need some basic operations with matrix. Multiplication, transpose etc.

I found some libraries which allows that. But can I do that without library? Or it's just easier to download some library and learn how to work with that library?

Arrays are NOT matrices :wink: Aka, all things like transpose etc goes out the window.

You could however make functions to do it with arrays but that's a different story. And because of the fixed size of arrays at compiler time (C/C++ thing) not all that easy on an Arduino.

Your notation is not legal C++ code for an Arduino.

You can define two arrays like this

int arrayA[3] = {12,13,14}; // creates an array with three elements and gives then the values 12, 13 amd 14
int arrayB[1];  // creates an array with one element but does not give it a value so it will default to 0
int valC = 0;  // creates a variable with an initial value of 0

void setup() {
   arrayB[0] = 23; // puts the value 23 in the 1st (and only) element of arrayB
   valC = arrayA[0] + arrayB[0]; adds the 1st elements from the two arrays and puts the value 35 into the variable valC
}

void loop() {

}

I suspect that is not exactly what you want to do, but you have not explained yourself clearly.

...R

Basically I will have my arduino DUE connected to another system which generates inputs and outputs. Then I will identify this data using recursive least square method. In recursive least square method is used for loop which stores previous data.

In matlab it looks like this:

y is output
u is input
N=length(y)
for n=2:N
    for i=1:1
        W(i) = y(n-i);          %output
    end
    for i=1:3
        V(i) = u(n-i+1);        %input
    end
end

This should be possible to recreate in arduino.

But then I have these lines in my code in matlab:

z = [V';W'];
P = (P - ( (P*z*z'*P)/( lamda+(z'*P*z) ) ))/lamda;
 C = C + (P*z* (sample_out - (z'*C) ) );

where lamda =1
C is array 4x1
P is array 4x1
z is 4x4
' means transpose

So I'm trying to find way how to make operations which are mentioned above, before I can connect it to the system.

Alex12345:
So I'm trying to find way how to make operations which are mentioned above, before I can connect it to the system.

It seems to me you have completely ignored the Replies you have already received.

I have never used Matlab and I have no idea what your Matlab code does. C++ is not specialized for the mathematical tricks that are common in Matlab. Can you write the Matlab code as a series of instructions that could be done with a calculator and pencil and paper?

...R

I too have never used Matlab, but here is the skeleton of an Arduino program

/*
where lamda =1
C is array 4x1  ?? 4 rows of values or 1 row of 4 values ?
P is array 4x1
z is 4x4
*/

int lambda = 1;
int C[4] = {0, 1, 2, 3};      //1 row of 4 values
int P[4] = {10, 11, 12, 13};
int z[4][4] =
{
  {0, 0, 0, 0},
  {0, 0, 0, 0},
  {0, 0, 0, 0},
  {0, 0, 0, 0},
}
                ;    //4 rows each of 4 values initialsed to zero

void setup()
{
  Serial.begin(115200);
}

void loop()
{
}

I assume that the data in the first 2 arrays is manipulated and put into the third one. If so, then what should the third one hold after the manipulation ?

Thing is, in Matlab you DON’T have arrays, you have matrices. Two things with arrays in C/C++

  1. The size of an array is defined at compiler time
  2. Although possible by making a [1] size array, there isn’t a real difference between a vertical and a horizontal array as there is with a matrix.

And a major thing you can’t do with an array (at least ot with operators) is preform matrix multiplication. Aka, P*z in Matlab is the outer product and there is no such thing in C/C++. There only exists scalar math. And as you know from the definition, you can do it with scalar math but you have to define it yourself in some sort of function method. Maybe someone made a fancy library for it but if you want to really do matrix stuff on an Arduino…

In C/C++ to mimic an outer multiplication you would have something like (untested):

void outer(byte u[][1], byte v[], byte m, byte n, byte* output){
  for(byte i = 0; i < m; i++){
    for(byte j = 0; j < n; j++){
      output[i * n + j] = u[i][1]  * v[j];
    }
  }
}

I think that what he is looking for is not outer product, but a normal matrix multiplication (the one that involves saturating indexes).
For example, if you are multiplying a matrix A (2x3) times a vector v, this is possible only if the vector is a column vector with 3 elements, i.e. a transpose of a row 3-elements vector.

When you want to translate this into a C/C++ code, you don’t really need to realise a vector transpose. All you need to do is to be careful with the index you want to saturate. In the above example, A*v = w, where w is a (2x1) vector.

Therefore, the matrix times vector product would look like this:

int A[2][3] =
{
  {0, 0, 0},
  {0, 0, 0},
};

int v = {0, 0, 0};

/* fill them as you wish */

int w = {0, 0};

for (int i = 0, i < 2, i++){
  for  (int j = 0, j < 3, j++){
    w[i] += A[i][j] * v[j];
  }
}

where you are saturating over the A columns.

If in your operation you need to transpose a matrix, then you need to create a new one, with inversed number of row and columns, and define its elements one by one in a similar double loop, swapping the index with respect to the original matrix.
Or, you can simply loop like in the previous example, but first over the matrix columns, rather than over the matrix rows as I did in my example.

DavidePer I tried your code but it didn’t work. It showed me the error: expected initializer before v,w token so I tried to fix it. Like this:

int A[2][3] =
{
  {0, 0, 0},
  {0, 0, 0},
};

int v[3]= {1, 2, 3};

/* fill them as you wish */

int w[2] = {0, 0};

for (int i = 0, i < 2, i++){
  for  (int j = 0, j[3] < 3, j++){
    w[i] += A[i][j] * v[j];
  }
}

And then I received error: expected initializer before ‘<’ token. Which I dunno how to fix it.

for (int i = 0, i < 2, i++){Wrong syntax. Read up on for loops

Hello guys I have 3x3 array and I want to multiply it by one number.

For example:

float C[3][3] = {{1, 2, 3},      
                {4, 5, 6},      
                {7, 8, 9}};
float A = 2;

x = C*A;

It should give me this result:

              {{2, 4, 6},      
                {8, 10, 12},      
                {14, 16, 18}};

But function which I have, returns me:

                 {{2, 4, 6},      
                {0, 0, 0},      
                {0, 0, 0}};

So can you guys please help me how to do that? I can post here function which I currently using, if necessary.

But function which I have, returns me:

We would need to see that function, to tell you how to fix it.

I’m using function which is below. It works when I have 2 arrays 3x3. But dunno how to modify it for just one number.

void Multiply(float* A, float* B, int m, int p, int n, float* C)
{
  // A = input matrix (m x p)
  // B = input matrix (p x n)
  // m = number of rows in A
  // p = number of columns in A = number of rows in B
  // n = number of columns in B
  // C = output matrix = A*B (m x n)
  int i, j, k;
  for (i = 0; i < m; i++)
    for(j = 0; j < n; j++)
    {
      C[n * i + j] = 0;
      for (k = 0; k < p; k++)
        C[n * i + j] = C[n * i + j] + A[p * i + k] * B[n * k + j];
    }
}
float input[3][3] = {{1.0, 2.0, 3.0},
  {4.0, 5.0, 6.0},
  {7.0, 8.0, 9.0}
};
float output[3][3];

float A = 2.0;

void setup()
{
  Serial.begin(115200);
  multiply(2);
  show();
}

void loop()
{
}

void multiply(float A)
{
  for (int row = 0; row < 3; row ++)
  {
    for (int col = 0; col < 3; col++)
    {
      output[row][col] = input[row][col] * A;
    }
  }
}

void show()
{
  for (int row = 0; row < 3; row ++)
  {
    for (int col = 0; col < 3; col++)
    {
      Serial.print(output[row][col]);
      Serial.print("\t");
    }
    Serial.println();
  }
}

It works when A=2; But my A comes from previous calculation and it's defined like this.

float A[1];

When I try use your code on for option above. I receive error cannot convert 'float*' to 'float' for argument '1' to 'void multiply(float)'

float A[1];

You have declared A as an array with one element. That makes no sense, nor is it what you said you wanted to do.

You said

float C[3][3] = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
float A = 2;

x = C*A;

It should give me this result:

{{2, 4, 6},
{8, 10, 12},
{14, 16, 18}};

which is what my code does.

It will also work if you declare A like this

float A[1];

where its single value is assigned somewhere before it is used in the calculation but then you must use A[0] as the multiplier rather than A, which is a pointer to the array, hence the error message.

Please post your code that produced the error.

I have data

float C[3][3] = {{1, 2, 3},      
                {4, 5, 6},      
                {7, 8, 9}};
float P[3][1] = {{2},      
                {3},      
                {4}};       
float z[3][1] = {{5},      
                {6},      
                {7}};

float  lamda[1]={1};
float   delta=0.05;
float  y = 5;                
float  rk[1][1] = {-4*(delta*delta)*y};

And I have to do this calculation:

 C = (C - ( (C*z*z'*C)/( lamda+(z'*C*z) ) ))/lamda;
 P = P + C*z*(rk - (z'*P))/(lamda+(z'*C*z));

I’m using functions from MatrixMath.h library, because there some operations which works with array.
Every operation such as multiply, subtract, add is working. Except dividing.
I have to make all the calculations in steps.

After while I’ll get:

A = (C*z*z'*C) = 2964        3648        4332
                          7176        8832       10488
                         11388       14016       16644
So A is array 3x3

B=( lamda+(z'*C*z) ) = 1765

B should be array 1x1 because i work with arrays.

now I have to do x = A/B;  which is basically x=A * (inversion of B)

B is again array [1][1]

So I have to multiply array 3x3 by one number which is also array.

I know that all my previous calculations are correct because I use matlab for results control.

Below is code which I use for multiplying A*(inversion of B). I can post here full code with previous calculation steps, but it’s kinda hard to understand it.

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
    Multiply((float*)A, (float*)B, 3,3,3, (float*)output); //(C*z*z'*C)/(lamda+(z'*C*z))
    Print((float*)output, 3, 3, "output");
}
void loop() {

}

void Multiply(float* A, float* B, int m, int p, int n, float* C)
{
  // A = input matrix (m x p)
  // B = input matrix (p x n)
  // m = number of rows in A
  // p = number of columns in A = number of rows in B
  // n = number of columns in B
  // C = output matrix = A*B (m x n)
  int i, j, k;
  for (i = 0; i < m; i++)
    for(j = 0; j < n; j++)
    {
      C[n * i + j] = 0;
      for (k = 0; k < p; k++)
        C[n * i + j] = C[n * i + j] + A[p * i + k] * B[n * k + j];
    }
}

void Print(float* A, int m, int n, String label)
{
  // A = input matrix (m x n)
  int i, j;
  Serial.println();
  Serial.println(label);
  for (i = 0; i < m; i++)
  {
    for (j = 0; j < n; j++)
    {
      Serial.print(A[n * i + j]);
      Serial.print("\t");
    }
    Serial.println();
  }
}

The first thing that I would suggest is that you use better names for your variables. Using names that indicate their meaning would make the code much more readable rather than having to remember that m is the number of rows in array A etc

It would also help if you posted a complete program that compiled and ran

Here is my full code:

float C[3][3] = {{1, 2, 3},      
                {4, 5, 6},      
                {7, 8, 9}};
float P[3][1] = {{2},      
                {3},      
                {4}};       
float z[3][1] = {{5},      
                {6},      
                {7}};
float  lamda[1]={1};
float   delta=0.05;
float  y = 5;                
float  rk[1][1] = {-4*(delta*delta)*y};
                
//OUTPUTS               
double zT[1][3];
double zz[3][3];
double Czz[3][3];
float CzzC[3][3];
float zTC[1][3];
float zTCz[1][3];
float jmen[1][1];
float jmen2[1][1];
float vn[3][3];
float ode[3][3];
float Cz[3][1];
float zTP[1][1];
float jmen3[3][3];
float ode3[1][1];
float na[3][3];
float leva[3][1];
float output[3][3];

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  //Calculation of C; C = (C - ( (C*z*z'*C)/( lamda+(z'*C*z) ) ))/lamda;
    
    Transposition((float*)z, 3, 1, (float*)zT); //z'
    Print((float*)zT, 1, 3, "zT");
    Multiply((float*)z, (float*)zT, 3, 1, 3, (float*)zz); //z*z'
    Print((float*)zz, 3, 3, "zz");
    Multiply((float*)C, (float*)zz, 3, 3, 3, (float*)Czz); //C*z*z'
    Print((float*)Czz, 3, 3, "Czz");
    Multiply((float*)Czz, (float*)C, 3, 3, 3, (float*)CzzC); //C*z*z'*C
    Print((float*)CzzC, 3, 3, "CzzC");
    Multiply((float*)zT, (float*)C, 1, 3, 3, (float*)zTC); //z'*C
    Print((float*)zTC, 1, 3, "zTC");
    Multiply((float*)zTC, (float*)z, 1, 3, 1, (float*)zTCz); //z'*C*z
    Print((float*)zTCz, 1, 1, "zTCz");
    Add((float*) lamda, (float*) zTCz, 1, 1, (float*) jmen); //lamda+(z'*C*z)
    Print((float*)jmen, 1, 1, "jmen");
    Add((float*) lamda, (float*) zTCz, 1, 1, (float*) jmen2); //lamda+(z'*C*z)
    Inversion((float*)jmen2, 1);
    Print((float*)jmen2, 1, 1, "jmen2"); 
    
    // this is the part which doesn't work    
    Multiply((float*)CzzC, (float*)jmen2, 3,1,1, (float*)vn); //(C*z*z'*C)/(lamda+(z'*C*z))
    Print((float*)vn, 3, 3, "vn");
//    multiply2(jmen2);
//    show();

    //Calculation of P;  P = P + C*z*(rk - (z'*P))/(lamda+(z'*C*z));
    
    Multiply((float*)C, (float*)z, 3, 3, 1, (float*)Cz); //C*z
    Print((float*)Cz, 3, 1, "Cz");
    Multiply((float*)zT, (float*)P, 3, 3, 1, (float*)zTP); //z'*P
    Print((float*)zTP, 1, 1, "zTP");
    Subtract((float*) rk, (float*) zTP, 1, 1, (float*) ode3); //(rk - (z'*P))
    Print((float*)ode3, 1, 1, "ode3");
    
    Multiply((float*)Cz, (float*)ode3, 3, 1, 1, (float*)na); //C*z*(rk - (z'*P))
    Print((float*)na, 3, 1, "na");
    Add((float*) P, (float*) na, 3, 1, (float*) leva); //P + C*z*(rk - (z'*P))
    Print((float*)leva, 3, 1, "leva");
    delay(10000);
}

void multiply2(float A)
{
  for (int row = 0; row < 3; row ++)
  {
    for (int col = 0; col < 3; col++)
    {
//      output[row][col] = CzzC[row][col] * jmen2;
    }
  }
}

void show()
{
  for (int row = 0; row < 3; row ++)
  {
    for (int col = 0; col < 3; col++)
    {
      Serial.print(output[row][col]);
      Serial.print("\t");
    }
    Serial.println();
  }
}

void Subtract(float* A, float* B, int m, int n, float* C)
{
  // A = input matrix (m x n)
  // B = input matrix (m x n)
  // m = number of rows in A = number of rows in B
  // n = number of columns in A = number of columns in B
  // C = output matrix = A-B (m x n)
  int i, j;
  for (i = 0; i < m; i++)
    for(j = 0; j < n; j++)
      C[n * i + j] = A[n * i + j] - B[n * i + j];
}

void Add(float* A, float* B, int m, int n, float* C)
{
  // A = input matrix (m x n)
  // B = input matrix (m x n)
  // m = number of rows in A = number of rows in B
  // n = number of columns in A = number of columns in B
  // C = output matrix = A+B (m x n)
  int i, j;
  for (i = 0; i < m; i++)
    for(j = 0; j < n; j++)
      C[n * i + j] = A[n * i + j] + B[n * i + j];
}

void Multiply(float* A, float* B, int m, int p, int n, float* C)
{
  // A = input matrix (m x p)
  // B = input matrix (p x n)
  // m = number of rows in A
  // p = number of columns in A = number of rows in B
  // n = number of columns in B
  // C = output matrix = A*B (m x n)
  int i, j, k;
  for (i = 0; i < m; i++)
    for(j = 0; j < n; j++)
    {
      C[n * i + j] = 0;
      for (k = 0; k < p; k++)
        C[n * i + j] = C[n * i + j] + A[p * i + k] * B[n * k + j];
    }
}

void Transposition(float* A, int m, int n, float* C)
{
  // A = input matrix (m x n)
  // m = number of rows in A
  // n = number of columns in A
  // C = output matrix = the transpose of A (n x m)
  int i, j;
  for (i = 0; i < m; i++)
    for(j = 0; j < n; j++)
      C[m * j + i] = A[n * i + j];
}

void Print(float* A, int m, int n, String label)
{
  // A = input matrix (m x n)
  int i, j;
  Serial.println();
  Serial.println(label);
  for (i = 0; i < m; i++)
  {
    for (j = 0; j < n; j++)
    {
      Serial.print(A[n * i + j]);
      Serial.print("\t");
    }
    Serial.println();
  }
}

int Inversion(float* A, int n)
{
  // A = input matrix AND result matrix
  // n = number of rows = number of columns in A (n x n)
  int pivrow;   // keeps track of current pivot row
  int k, i, j;    // k: overall index along diagonal; i: row index; j: col index
  int pivrows[n]; // keeps track of rows swaps to undo at end
  float tmp;    // used for finding max value and making column swaps

  for (k = 0; k < n; k++)
  {
    // find pivot row, the row with biggest entry in current column
    tmp = 0;
    for (i = k; i < n; i++)
    {
      if (abs(A[i * n + k]) >= tmp) // 'Avoid using other functions inside abs()?'
      {
        tmp = abs(A[i * n + k]);
        pivrow = i;
      }
    }

    // check for singular matrix
    if (A[pivrow * n + k] == 0.0f)
    {
      Serial.println("Inversion failed due to singular matrix");
      return 0;
    }

    // Execute pivot (row swap) if needed
    if (pivrow != k)
    {
      // swap row k with pivrow
      for (j = 0; j < n; j++)
      {
        tmp = A[k * n + j];
        A[k * n + j] = A[pivrow * n + j];
        A[pivrow * n + j] = tmp;
      }
    }
    pivrows[k] = pivrow;  // record row swap (even if no swap happened)

    tmp = 1.0f / A[k * n + k];  // invert pivot element
    A[k * n + k] = 1.0f;    // This element of input matrix becomes result matrix

    // Perform row reduction (divide every element by pivot)
    for (j = 0; j < n; j++)
    {
      A[k * n + j] = A[k * n + j] * tmp;
    }

    // Now eliminate all other entries in this column
    for (i = 0; i < n; i++)
    {
      if (i != k)
      {
        tmp = A[i * n + k];
        A[i * n + k] = 0.0f; // The other place where in matrix becomes result mat
        for (j = 0; j < n; j++)
        {
          A[i * n + j] = A[i * n + j] - A[k * n + j] * tmp;
        }
      }
    }
  }

  // Done, now need to undo pivot row swaps by doing column swaps in reverse order
  for (k = n - 1; k >= 0; k--)
  {
    if (pivrows[k] != k)
    {
      for (i = 0; i < n; i++)
      {
        tmp = A[i * n + k];
        A[i * n + k] = A[i * n + pivrows[k]];
        A[i * n + pivrows[k]] = tmp;
      }
    }
  }
  return 1;
}

Now results, which I print into serial port:

zT
5.00	6.00	7.00	
zz
25.00	30.00	35.00	
30.00	36.00	42.00	
35.00	42.00	49.00	
Czz
190.00	228.00	266.00	
460.00	552.00	644.00	
730.00	876.00	1022.00	
CzzC
2964.00	3648.00	4332.00	
7176.00	8832.00	10488.00	
11388.00	14016.00	16644.00	
zTC
78.00	96.00	114.00	
zTCz
1764.00	
jmen
1765.00	
jmen2
0.00	
vn
1.68	2.07	2.45	
0.00	0.00	0.00	
0.00	0.00	0.00	

Cz
38.00	
92.00	
146.00	
zTP
56.00	
ode3
-56.05	
na
-2129.90	
-5156.60	
-8183.30	
leva
-2127.90	
-5153.60	
-8179.30

Output vn should be:
1.6793 2.0669 2.4544
4.0657 5.0040 5.9422
6.4521 7.9411 9.4300

When I use your function i get this:
exit status 1
cannot convert ‘float (*)[1]’ to ‘float’ for argument ‘1’ to ‘void multiply2(float)’

eng.ino (6.9 KB)

When I use your function i get this:
exit status 1
cannot convert ‘float (*)[1]’ to ‘float’ for argument ‘1’ to ‘void multiply2(float)’

As I speculated in an earlier reply

float jmen2[1][1];

jmen2 is an array

 multiply2(jmen2);

you pass a pointer to the array to the function

void multiply2(float A)
{
  for (int row = 0; row < 3; row ++)
  {
    for (int col = 0; col < 3; col++)
    {
      //      output[row][col] = CzzC[row][col] * jmen2;
    }
  }
}

but the function expects a scalar variable, hence the error message
Mind you, the function makes no attempt to use the value passed to it so why bother ?