This code is meant to find the inverse of a matrix, it almost does this. The last row of numbers is incorrect and I am not sure why.
This is not the best way to find the inverse, however it is how I need to do it for my homework assignment.
I have reworked the power function a couple times, so it should be correct now.
The method being used is B=I-A, A^-1 = I+B+B^2+B^3...(all the way to B^20).
#include <iostream>
#include <iomanip>
using namespace std;
void multiplinator(double invA[][3], double A[][3], double y[][3]) //multiplies the matrix
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
y[i][j] = 0;
for(int k = 0; k < 3; k++)
{
y[i][j] += invA[i][k] * A[k][j];
}
}
}
}
void printinator(double a[3][3]) //prints a matrix
{
for(int i=0; i<=2; i++)
{
for(int j=0; j<=2; j++)
cout << fixed << setprecision(2) << setw(12) << a[i][j] << " ";
cout << endl;
}
cout << endl;
}
void substitinator(double I[][3], double A[][3], double B[][3]) //Matrix subtraction
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
B[i][j] = I[i][j] - A[i][j];
}
void additinator(double I[3][3], double B[][3], double invA[][3]) //Matrix addition
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
invA[i][j] = I[i][j] + B[i][j];
}
void powernator(double B[][3],double pB[][3], int p) //function which is supposed to raise a matrix to a certain power
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int i,j,w,k;
for(i = 0 ; i < 2 ; ++ i )
for(j = 0 ; j < 2 ; ++ j )
pB[i][j] = ( i == j ) ;
for(w = 0; w < p; w++)
{
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
temp[i][j]=0;
for(k=0;k<2;k++)
{
temp[i][j] += pB[i][k] * B[k][j];
}
}
}
for(i = 0; i < 2; i++){
for(j = 0; j < 2; j++)
{
pB[i][j] = temp[i][j];
}
}
}
}
void gettem(double pB[][3], double invA[][3]) //Matrix addition of power of B
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
invA[i][j] += pB[i][j];
}
int main()
{
double A[3][3] = { {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double invA[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double I[3][3] = { {1, 0, 0} , {0, 1, 0} , {0, 0, 1} };
double B[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double pB[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double y[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
substitinator(I,A,B);
additinator(I,B,invA);
for(int p = 2; p <= 20; p++)
{
powernator(B,pB,p);
gettem(pB, invA);
}
cout << "\n\t\t Inverse:" << endl;
printinator(invA);
cout << "\n\t\t invA * A:" << endl;
multiplinator(invA, A, y);
printinator(y);
}
I agree with the #1201ProgramAlarm, your powernator() function is wrong, you should make sure all the for loop condition is < 3 not < 2
void powernator(double B[3][3],double pB[3][3], int p) //function which is supposed to raise a matrix to a certain power
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int i,j,w,k;
for(i = 0 ; i < 3 ; ++ i )
for(j = 0 ; j < 3 ; ++ j )
pB[i][j] = ( i == j ) ;
for(w = 0; w < p; w++)
{
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
temp[i][j]=0;
for(k=0;k<3;k++)
{
temp[i][j] += pB[i][k] * B[k][j];
}
}
}
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++)
{
pB[i][j] = temp[i][j];
}
}
}
}
The results are:
Inverse:
2.00 -3.00 0.00
0.00 1.50 0.00
1.50 0.00 1.50
invA * A:
1.00 0.00 0.00
0.00 1.00 0.00
-0.00 0.00 1.00
Hope this helps.
Related
I set a vector list, for example :
vector<VectorXi> Test;
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2));
Test.push_back(VectorXi(0));
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2,3));
PrintAllCombins(Test)
And now I want to get all combinations of indexes :
0, 0, 0, 0, 0
0, 0, 0, 0, 1
0, 0, 0, 0, 2
0, 0, 0, 0, 3
0, 0, 0, 1, 0
0, 0, 0, 1, 1
0, 0, 0, 1, 2
0, 0, 0, 1, 3
0, 0, 1, 0, 0
0, 0, 1, 0, 1
0, 0, 1, 0, 2
0, 0, 1, 0, 3
... and so on
If i use for or while loop suitably, then it works I guess, but I encounter limitation. Is there any idea? I'm writing code in c and c++
--------------------- code : this is an example code that im using.
vector<VectorXi> Test;
VectorXi a0(2); a0[0] = 0; a0[1] = 1;
VectorXi a1(3); a1[0] = 0; a1[1] = 1; a1[2] = 2;
VectorXi a2(2); a2[0] = 0; a2[1] = 1;
VectorXi a3(4); a3[0] = 0; a3[1] = 1; a3[2] = 2; a3[3] = 3;
VectorXi a5(1); a5[0] = 0;
Test.push_back(a0);
Test.push_back(a1);
Test.push_back(a5);
Test.push_back(a2);
Test.push_back(a3);
VectorXi index(5);
for (int i = 0; i < 5; i++)
index[i] = 0;
int IndexTemp = Test.size()-1;
vector<VectorXi> result;
bool c = true;
while (c == true)
{
if (index[IndexTemp] < Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
index[IndexTemp] ++;
}
else if (index[IndexTemp] == Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
IndexTemp--;
if (IndexTemp < 0)
break;
index[IndexTemp] ++;
}
}
for (unsigned int i = 0; i < result.size(); i++)
{
cout << i << " : ";
for (unsigned int j = 0; j < result[i].size(); j++)
{
cout << result[i](j) << " ";
}
cout << endl;
}
It does not show all combinations now..
If I make code to work only to this example (Test.size() == 5)
I just use for loop five times like :
for(Test[0].size())
for(Test[1].size())
for(Test[2].size())
for(Test[3].size())
for(Test[4].size())
cout << ~~~~~
Then it gives all combinations.
However if the Test.size() increased, I cannot write all for loops manually.
You may do:
bool increase(const std::vector<std::vector<int>>& v, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] >= v[index].size()) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void do_job(const std::vector<std::vector<int>>& v,
const std::vector<std::size_t>& it)
{
for (std::size_t i = 0; i != it.size(); ++i) {
// TODO: manage case where v[i] is empty if relevant.
std::cout << v[i][it[i]] << " ";
}
std::cout << std::endl;
}
void iterate(const std::vector<std::vector<int>>& v)
{
std::vector<std::size_t> it(v.size(), 0u);
do {
do_job(v, it);
} while (increase(v, it));
}
Live Demo
I am working on a matrix inverter and I have it almost done but for some reason the function that is supposed to raise the matrix to a certain value is not working, I have isolated the function on its own and it has worked just fine. But for some reason is not working in this program
Isolated
#include <iomanip>
#include <stdio.h>
using namespace std;
void printano(double a[3][3])
{
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
cout << fixed << setprecision(2) << setw(12) << a[i][j] << " ";
cout << endl;
}
}
void powernator(double r[][3],double B[][3], int p)
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
int main()
{
double B[3][3] = { {1, 2, 3} , {4, 5, 6} , {7, 8, 9} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
powernator(r,B,3);
printano(r);
}
The actual code
#include <iostream>
#include <iomanip>
#include <cmath>
#include <stdio.h>
using namespace std;
void multiplinator(double x[][3], double y[][3], double z[][3]) //At the end I double check to make sure the value is correct as it needs to equal the identity matrix
{
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = 0; k < 3; k++)
{
z[i][j] += x[i][k] * y[k][j];
}
}
}
}
void printinator(double a[3][3]) //prints a matrix
{
for(int i=0; i<=2; i++)
{
for(int j=0; j<=2; j++)
cout << fixed << setprecision(4) << setw(12) << a[i][j] << " ";
cout << endl;
}
cout << endl;
}
void sub(double as[3][3], double in[][3], double B[][3]) //Matrix subtraction
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
B[i][j] = in[i][j] - as[i][j];
}
void powernator(double r[][3],double B[][3], int p) //Array which is supposed to raise a matrix to a certain power
{
double temp[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
int n = 3;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = B[b][d];
}
}
for (int i = 0; i < p - 1; i++)
{
int sum = 0;
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += B[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
r[b][d] = temp[b][d];
}
}
}
}
void gettem(double r[][3], double in[][3], double inm[][3]) //Supposed to return the final value, aka, the inverse matrix, as a^-1 = I + B^1 +B^2...
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
inm[i][j] = in[i][j] + r[i][j];
}
}
int main()
{
double a[3][3] = { {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double as[3][3] ={ {1./2, 1, 0} , {0, 2./3, 0} , {-1./2, -1, 2./3} };
double in[3][3] = { {1, 0, 0} , {0, 1, 0} , {0, 0, 1} };
double B[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double r[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double inm[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
double z[3][3] = { {0, 0, 0} , {0, 0, 0} , {0, 0, 0} };
cout << "\n\t\t Original : " << endl;
printinator(a);
sub(as,in,B);
printinator(B);
powernator(r,B,2);
printinator(r); //testing the power function, not working
/*for(int n = 0; n < 20; n++) //Final part of the code commented out for debug, this loop is meant to add up B^n where n is from 1 - 20
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
r[i][j] += B[i][j];
}
gettem(r,in,inm);
cout << "\n\t\t Inverse: " << endl;
printinator(inm);
multiplinator(as,a,z);
cout << "\n\t\t multi: " << endl;
printinator(z);
*/
}
Isolated Code
powernator(r,B,3);
Actual Code.
powernator(r,B,2);
parameter p is differ..
I set a vector list, for example :
vector<VectorXi> Test;
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2));
Test.push_back(VectorXi(0));
Test.push_back(VectorXi(0,1));
Test.push_back(VectorXi(0,1,2,3));
PrintAllCombins(Test)
And now I want to get all combinations of indexes :
0, 0, 0, 0, 0
0, 0, 0, 0, 1
0, 0, 0, 0, 2
0, 0, 0, 0, 3
0, 0, 0, 1, 0
0, 0, 0, 1, 1
0, 0, 0, 1, 2
0, 0, 0, 1, 3
0, 0, 1, 0, 0
0, 0, 1, 0, 1
0, 0, 1, 0, 2
0, 0, 1, 0, 3
... and so on
If i use for or while loop suitably, then it works I guess, but I encounter limitation. Is there any idea? I'm writing code in c and c++
--------------------- code : this is an example code that im using.
vector<VectorXi> Test;
VectorXi a0(2); a0[0] = 0; a0[1] = 1;
VectorXi a1(3); a1[0] = 0; a1[1] = 1; a1[2] = 2;
VectorXi a2(2); a2[0] = 0; a2[1] = 1;
VectorXi a3(4); a3[0] = 0; a3[1] = 1; a3[2] = 2; a3[3] = 3;
VectorXi a5(1); a5[0] = 0;
Test.push_back(a0);
Test.push_back(a1);
Test.push_back(a5);
Test.push_back(a2);
Test.push_back(a3);
VectorXi index(5);
for (int i = 0; i < 5; i++)
index[i] = 0;
int IndexTemp = Test.size()-1;
vector<VectorXi> result;
bool c = true;
while (c == true)
{
if (index[IndexTemp] < Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
index[IndexTemp] ++;
}
else if (index[IndexTemp] == Test[IndexTemp].size()-1)
{
VectorXi T;
T.resize(Test.size());
for (int j = 0; j<Test.size(); j++)
{
T[j] = Test[j](index[j]);
}
result.push_back(T);
IndexTemp--;
if (IndexTemp < 0)
break;
index[IndexTemp] ++;
}
}
for (unsigned int i = 0; i < result.size(); i++)
{
cout << i << " : ";
for (unsigned int j = 0; j < result[i].size(); j++)
{
cout << result[i](j) << " ";
}
cout << endl;
}
It does not show all combinations now..
If I make code to work only to this example (Test.size() == 5)
I just use for loop five times like :
for(Test[0].size())
for(Test[1].size())
for(Test[2].size())
for(Test[3].size())
for(Test[4].size())
cout << ~~~~~
Then it gives all combinations.
However if the Test.size() increased, I cannot write all for loops manually.
You may do:
bool increase(const std::vector<std::vector<int>>& v, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] >= v[index].size()) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void do_job(const std::vector<std::vector<int>>& v,
const std::vector<std::size_t>& it)
{
for (std::size_t i = 0; i != it.size(); ++i) {
// TODO: manage case where v[i] is empty if relevant.
std::cout << v[i][it[i]] << " ";
}
std::cout << std::endl;
}
void iterate(const std::vector<std::vector<int>>& v)
{
std::vector<std::size_t> it(v.size(), 0u);
do {
do_job(v, it);
} while (increase(v, it));
}
Live Demo
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm working on a program to multiply two 3X3 matrices together. I have hit a few problems and I can't figure out the problems. Any help would be appreciated :D
#include <iostream>
using namespace std;
int main(){
int matrix1[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int matrix2[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int results[3][3];
int product = 0;
int i;
int j;
for (i = 1; i <= 3; i++){
for (j = 1; j <= 3; j++){
product += matrix1[i][j] * matrix2[j][i];
cout << product << endl;
}
results[i][j] = product;
product = 0;
}
cout << endl << "Output Matrix: " << endl;
for (int i = 1; i < 4; i++){
for (int j = 1; j < 4; j++){
cout << results[i][j];
}
cout << endl;
}
system("pause");
return 0;
}
And this is the result I get out of it:
25
73
-1717986851
48
129
-858993331
-1867771963
1566576709
1595991863
Output Matrix:
-858993460-858993460-858993460
-1717986851-858993460-858993460
-85899333112
Press any key to continue . . .
Thanks again in advance! :D
So to begin with you don't need the int i, j; lines at the beginning. If you didn't have them there the compiler would correctly told you that results[i][j] = product; is in the wrong place. Also arrays' first value isn't at A[1] but at A[0]. And for the matrix multiplication I suggest you to read this.
Therefore the solution should look like this:
int matrix1[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int matrix2[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int results[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
for (int u = 0; u < 3; u++)
results[i][j] += matrix1[i][u] * matrix2[u][j];
}
cout << endl << "Output Matrix: " << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << results[i][j] << ".";
}
cout << endl;
}
Your code for matrix multiplication is wrong. Look at this literal implementation:
for (i = 0; i < 3; i++){
for (j = 0; j < 3; j++){
product = 0;
for (k = 0; k < 3; k++){
product += matrix1[i][k] * matrix2[k][j];
}
matrix3[i][j] = product;
}
}
Matrix multiplication is implemented the following way (for 2 N x N matrices):
for i = 1..N
for j = 1..N
result[i][j] = 0.
for k = 1..N
result[i][j] += matrix1[i][k] * matrix2[j][k] // "row times column"
end for
end for
end for
This will return you the product result = matrix1 * matrix2. In C++ you have to use e.g.
for (int i = 0; i < N; i++)
for a loop. You have to start with 0 and end with N-1 (that's why you use < and not <=). In your example set int N = 3.
You only use a delete for every new. So you do not need to delete arrays if you do not allocate the matrix dynamically.
I have created the code, and for some reason the elements C[0,3] and C[1,3] are returning the wrong result, although all other elements of the matrix are correct. Not sure why this is happening. Thanks!
#include <iostream>
#include <iomanip>
using namespace std;
const int ROWSA = 4,
COLSA = 3,
ROWSB = 3,
COLSB = 2;
void calc_AB(double [][COLSA], double B[][COLSB], double C[][ROWSA], int, int, int);
void display_C(double [][ROWSA], int);
int main()
{
double A[ROWSA][COLSA] = { { 5.2, 1, 9 },
{ 3.6, 7.5, 0 },
{ 8, 0, 4.4 },
{ 0.1, 2.7, 10 } },
B[ROWSB][COLSB] = { {12, 7.8},
{11, 8.9},
{10, 0.2} },
C[COLSB][ROWSA];
calc_AB(A, B, C, ROWSA, COLSB, COLSA);
display_C(C, COLSB);
return 0;
}
void calc_AB(double A[][COLSA], double B[][COLSB], double C[][ROWSA], int ROWSA, int COLSB, int COLSA)
{
for (int i = 0; i < ROWSA; i++)
{
for (int j = 0; j < COLSB; j++)
{
C[i][j] = 0;
for (int k = 0; k < COLSA; k++)
{
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
void display_C(double C[][ROWSA], int COLSB)
{
for (int i = 0; i < ROWSA; i++)
{
for (int j = 0; j < COLSB; j++)
{
cout << setw(4) << C[i][j] << " ";
}
cout << endl;
}
}