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.