Home > Back-end >  How to store result of Matrix Multiplication(using a custom function which returns an array) in a di
How to store result of Matrix Multiplication(using a custom function which returns an array) in a di

Time:11-24

So, I am trying to multiply 2 matrices. I have to do this multiplication a bunch of times so I created a function float multiply_,matrix(float mat_1[R][C1], float mat_2[R][C2]). This function returns an array which I want to store in an array declared in main. But It's giving a "not modifiable lvalue" error. How can I store result of the function in a different array?

Fucntion :

float multiply_matrix(float mat_1[N][R1], float mat_2[N][R2]){
    float temp[N][C2]; // temporary matrix
    for (int i = 0; i < N; i  ){
        for (int j = 0; j < R2; j  ){   //since stress matrix has only one coloumn
            temp[i][j] = 0;
            for (int a = 0; a < N; a  ){ //N here is the number of rows of the 2nd matrix
                temp[i][j]  = mat_1[i][a]*mat_2[a][j];
            }
        }     
    }
    return temp[N][C2];
}

The way I'm trying to store the value in the main function:

float stress_12[N][R2];
stress_12 = multiple_matrix(T,stress_12);

I was expecting the array to be directly stored, but it gave an "expression must be an lvalue" error. I did understand what an lvalue error is from here, but I couldn't think of a way to store the result of the function.

CodePudding user response:

Purely from a programming standpoint your code has a few breaking errors. First of all, when declaring the multiply_matrix function, your arguments can't be mat_1[N][R1] and mat_2[N][R2] because N, R1 and R2 are not defined (and these arrays would be dynamically sized, which c doesn't allow, for that you need to make a pointer to an array such as: float* array = new float[x] // x is a variable or constant value)

Assuming you are going to hard code N, you should declare temp like this:

std::vector<std::vector<float> > temp(N, std::vector<float>(C2))

Instead you should use std::vector which is a dynamically sized array so your function would look like this:

    #include <vector>
    //std::vector<std::<vector<float> > is just a vector of vector or a 2 dimensional array of floats
    std::vector<std::vector<float> > multiply_matrix(std::vector<std::vector<float> > mat_1, std::vector<std::vector<float> > mat_2){
    //your code here
    }

Your function also returns a float (meaning one floating point number, not an array) so the return type should be a vector<vector<float> >(a dynamic array of floats)

And lastly, you try to return temp[N][C2] which is not an array but a float (N-1th row, C2-1th column) and stress_12 is an array (also should be a vector).

Hope this helps.

CodePudding user response:

The code in the question has multiple issues. I will assume that the matrix dimensions N, R1, R2, C2 are known at compile-time. If that is not the case, it should be stated in your question. I would replace all occurrences on the form

float matrix[M][N]

by

Matrix<M, N> matrix

with Matrix being defined as

#include <array>

template <std::size_t M, std::size_t N>
using Matrix = std::array<std::array<float, N>, M>;

This has the benefit that you can copy your matrix, return it as a value from a function, etc. In other words, it works just like any other value be it a struct or an int.

There are a few issues with incompatible matrix dimensions in the function multiply_matrix. I would reimplement that function as a template function with the matrix dimensions being compile-time parameters. Note that I corrected the dimensions of mat_1 and mat_2 so that mat_1 has as many columns as mat_2 has rows and the result matrix has as many rows as mat_1 and as many columns as mat_2. Any attempt at passing matrices with incompatible dimensions will be caught at compile-time:

template <std::size_t M, std::size_t K, std::size_t N>
Matrix<M, N> multiply_matrix(
  const Matrix<M, K>& mat_1, const Matrix<K, N>& mat_2) {
    Matrix<M, N> temp;
    for (int i = 0; i < M; i  ){
        for (int j = 0; j < N; j  ) {
            temp[i][j] = 0;
            for (int a = 0; a < K; a  ) {
                temp[i][j]  = mat_1[i][a]*mat_2[a][j];
            }
        }     
    }
    return temp;
}

Also note that the last line is return temp; instead of return temp[N][C2];.

Then I can use it like this...

Matrix<3, 3> T /* = ... */;
Matrix<3, 2> stress_12 /* = ... */;
stress_12 = multiply_matrix(T, stress_12);

If you plan on doing a lot of matrix maths, you may want to consider using a good matrix library such as Eigen instead of reinventing your own stuff.

  •  Tags:  
  • c
  • Related