Reputation:
Trying to raise a matrix to the power of p, but I dont find the mistake. Can anyone help and explain the problem? I just got started in programming in C so thank you very much for your help. The user should enter a matrix and it should be raised to the power of p.
int main() {
int n, p;
printf("Number of Rows/Colums of square matrix: ");
scanf("%d", &n);
printf("to the power of: ");
scanf("%d", &p);
int m[n][n];
int r[n][n];
printf("Elements\n");
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
printf("[%d][%d] = ", b + 1, d + 1);
scanf("%d", &m[b][d]);
}
}
int sum = 0;
for (int i = 0; i < p; i++) {
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
for (int k = 0; k < n; k++) {
sum += m[b][k] * m[k][d];
}
r[b][d] = sum;
sum = 1;
}
}
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
m[b][d] = r[b][d];
r[b][d] = 0;
}
}
}
printf("RESULT:-\n");
for (int c = 0; c < n; c++) {
for (int d = 0; d < n; d++) {
printf("%d ", m[c][d]);
}
printf("\n");
}
getch();
return 0;
}
Upvotes: 2
Views: 8820
Reputation: 144715
There are multiple issues in your code:
t
to compute the result of r * m
and copy that to r
before the next step.sum
should be re-initialized to 0
, or better, initialized to 0
before the k
loop.Here is a corrected version:
#include <stdio.h>
int main() {
int n, p;
printf("Number of Rows/Colums of square matrix: ");
if (scanf("%d", &n) != 1 || n <= 0)
return 1;
printf("to the power of: ");
if (scanf("%d", &p) != 1 || p < 0)
return 1;
int m[n][n];
int r[n][n];
int t[n][n];
printf("Elements\n");
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
printf("[%d][%d] = ", b + 1, d + 1);
if (scanf("%d", &m[b][d]) != 1)
return 1;
r[b][d] = b == d; // initialize r to identity matrix
}
}
for (int i = 0; i < p; i++) {
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
int sum = 0;
for (int k = 0; k < n; k++) {
sum += r[b][k] * m[k][d];
}
t[b][d] = sum;
}
}
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
r[b][d] = t[b][d];
}
}
}
printf("RESULT:\n");
for (int c = 0; c < n; c++) {
for (int d = 0; d < n; d++) {
printf("%3d ", r[c][d]);
}
printf("\n");
}
return 0;
}
Notes:
The above code works for positive powers, including 0
which produces the identity matrix.
Note however that this method is inefficient for large powers and int
is likely to overflow for large powers anyway.
Upvotes: 1
Reputation: 308763
I'd recommend that you decompose this complex problem into smaller problems.
Create smaller functions, test them to make sure they're working, and then take the next step calling those until you have the full set.
You need to start with a matrix: a[m][n]
. Should the values it holds be integers, floats, doubles? Make sure you can create a matrix of different sizes. What should your restrictions on rows and columns be?
Begin with methods to read and write your matrix.
Next is a method to multiple two matricies together: c[m][n] = a[m][k]*b[k][n]
. The number of columns in a
has match the number of rows in b
or you can't multiply.
Raising a matrix to an integer power p > 1
means multiplying the starting matrix by itself p
times. Can you see that one requirement is that the starting matrix has to be square? (# rows == # columns) If that's not true, you can't raise to an integer power.
You'll need a loop to raise to a power p times. You will call your matrix multiplication method c = mult(a, b)
each time through the loop. Each pass through will take the output from the previous call and make it the first matrix in the call: c = mult(c, b)
.
If you attack the problem this way you should be able to solve it. Be sure to test each step carefully before you move on.
This is called decomposition. It's bedrock for problem solving in general and computer science in particular.
Upvotes: 2
Reputation: 50775
Your program logic is wrong at several levels.
This is your corrected program. There is still room for improvement (breaking the code down into functions, using better variable naming, using a more efficient algorithm than brute matrix multiplication, treating correctly the case where p is 0), but I tried to stick as much as possible to the original wrong implementation.
This is the approach: we have three matrixes: r
the result, m
the matrix provided by user, and temp
a temporary matrix.
m
into r
, this is the result for p = 1
p - 1
times r
and m
and put the result into temp
temp
into r
r
contains the m
elevated to the power of p
.#include <stdio.h>
int main() {
int n, p;
printf("Numer of Rows/Colums of sq matrix: ");
scanf("%d", &n);
printf("to the power of: ");
scanf("%d", &p);
int m[n][n];
int r[n][n];
int temp[n][n];
printf("Elements\n");
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
printf("[%d][%d] = ", b + 1, d + 1);
scanf("%d", &m[b][d]);
}
}
// r = m
// temp = m
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
r[b][d] = m[b][d];
}
}
for (int i = 0; i < p - 1; i++) // p - 1 because for p = 1, r already
{ // contains the result
int sum = 0;
// temp = r * m
for (int b = 0; b < n; b++)
{
for (int d = 0; d < n; d++)
{
for (int k = 0; k < n; k++)
{
sum += m[b][k] * r[k][d];
}
temp[b][d] = sum;
sum = 0;
}
}
// r = temp
for (int b = 0; b < n; b++) {
for (int d = 0; d < n; d++) {
r[b][d] = temp[b][d];
}
}
}
printf("RESULT:\n");
for (int c = 0; c < n; c++)
{
for (int d = 0; d < n; d++)
{
printf("%d ", r[c][d]);
}
printf("\n");
}
return 0;
}
Upvotes: 2
Reputation: 648
I think you have various logical problems in your code.
The outer loop is wrong since you loop one time less the power quantity.
Secondly you need a buffer matrix the way you wrote your code.
Another problem is that when you multiply the row/column values, you always use the original matrix. This is logically wrong, you need to multiply the matrix computed up the current power by the original matrix.
I also don't understand why you reset the sum
variable to 1 and not 0.
Something like this should work:
#include <stdio.h>
int main() {
int n, p;
printf("Numer of Rows/Colums of sq matrix: ");
scanf("%d", &n);
printf("to the power of: ");
scanf("%d", &p);
int m[n][n];
int r[n][n];
int tmp[n][n];
printf("Elements\n");
for ( int b = 0 ; b < n ; b++ ) {
for ( int d = 0 ; d < n ; d++ ) {
printf("[%d][%d] = ", b+1, d+1);
scanf("%d", &m[b][d]);
r[b][d] = m[b][d];
}
}
int sum = 0;
//you loop 1 time less of the power
for (int i = 0; i < p - 1; i++)
{
for ( int b = 0 ; b < n ; b++ )
{
for (int d = 0 ; d < n ; d++ )
{
for (int k = 0 ; k < n ; k++ )
{
sum += r[b][k]*m[k][d];
}
tmp[b][d] = sum;
sum = 0;
}
}
for ( int b = 0 ; b < n ; b++ ) {
for ( int d = 0 ; d < n ; d++ ) {
//m[b][d] = r[b][d];
r[b][d] = tmp[b][d];
}
}
}
printf("RESULT:-\n");
for (int c = 0 ; c < n ; c++ )
{
for (int d = 0 ; d < n ; d++ )
{
printf("%d ", r[c][d]);
}
printf("\n");
}
getchar();
return 0;
}
I would just point out that this solution probably does not work with p < 1
Upvotes: 2