I'm trying to transpose and multiply some matrices, basically
I get 2 matrices, matrixA and matrixB the action to be performed is trace(transpose(matrixA)*matrixB).
I managed to get this working for nxn matrices but I can't get it to work with mxn where (n>m or m>n).
I've looked online for solutions but I can't implement theirs solution into mine.
I removed almost all the code to simplify reading, if you prefer the entire code I linked it here.
If you do want to run the entire code, to recreate the problem use the following commands:
zeroes matrixA 2 3
zeroes matrixB 2 3
set matrixA
1 2 3 4 5 6
set matrixB
6 5 4 3 2 1
frob matrixA matrixB
The above commands should return Sum 56 but instead I get Sum 18
int* matrixATransposed = (int*) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
for (int i = 0; i < matrixARowLenght; i++)
{
for (int j = 0; j < matrixAColLenght; j++)
{
*(matrixATransposed + i * matrixAColLenght + j) = *(matrixA + j * matrixAColLenght + i);
}
}
// Multiply
int* mulRes = (int*)malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
for (int i = 0; i < matrixAColLenght; i++) {
for (int j = 0; j < matrixBColLenght; j++) {
*(mulRes + i * matrixARowLenght + j) = 0;
for (int k = 0; k < matrixARowLenght; k++)
*(mulRes + i * matrixAColLenght + j) += *(matrixATransposed + i * matrixAColLenght + k) * *(matrixB + k * matrixBColLenght + j);
}
}
// Sum the trace
int trace = 0;
for (int i = 0; i < matrixARowLenght; i++) {
for (int j = 0; j < matrixAColLenght; j++) {
if (i == j) {
trace += *(mulRes + i * matrixAColLenght + j);
}
}
}
printf_s("Sum: %d\n", trace);
Your array indices for calculating the transpose, multiplication, and the trace seem to be incorrect. I've corrected them in the following program:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
int matrixARowLenght = 2;
int matrixAColLenght = 3;
int matrixA[] = {1,2,3,4,5,6};
int matrixBRowLenght = 2;
int matrixBColLenght = 3;
int matrixB[] = {6,5,4,3,2,1};
// Transpose
int* matrixATransposed = (int *) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
for (int i = 0; i < matrixAColLenght; i++) {
for (int j = 0; j < matrixARowLenght; j++) {
*(matrixATransposed + i * matrixARowLenght + j) = *(matrixA + j * matrixAColLenght + i);
}
}
// Multiply
int *mulRes = (int *) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
for (int i = 0; i < matrixAColLenght; ++i) {
for (int j = 0; j < matrixAColLenght; ++j) {
*(mulRes + (i * matrixAColLenght) + j) = 0;
for (int k = 0; k < matrixARowLenght; ++k) {
*(mulRes + (i * matrixAColLenght) + j) += *(matrixATransposed + (i * matrixARowLenght) + k) * *(matrixB + (k * matrixAColLenght) + j);
}
}
}
free(matrixATransposed);
// Sum the trace
int trace = 0;
for (int i = 0; i < matrixAColLenght; i++) {
for (int j = 0; j < matrixAColLenght; j++) {
if (i == j) {
trace += *(mulRes + i * matrixAColLenght + j);
}
}
}
printf("Sum: %d\n", trace);
free(mulRes);
return 0;
}
The above program will output your expected value:
Sum: 56
** UPDATE **
As pointed by MFisherKDX, the above code will not work if the result matrix is not a square matrix. The following code fixes this issue:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
int matrixARowLenght = 2;
int matrixAColLenght = 3;
int matrixA[] = {1,2,3,4,5,6};
int matrixBRowLenght = 2;
int matrixBColLenght = 4;
int matrixB[] = {8,7,6,5,4,3,2,1};
// Transpose
int* matrixATransposed = (int *) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
for (int i = 0; i < matrixAColLenght; i++) {
for (int j = 0; j < matrixARowLenght; j++) {
*(matrixATransposed + i * matrixARowLenght + j) = *(matrixA + j * matrixAColLenght + i);
}
}
// Multiply
int *mulRes = (int *) malloc(matrixAColLenght * matrixBColLenght * sizeof(int));
for (int i = 0; i < matrixAColLenght; ++i) {
for (int j = 0; j < matrixBColLenght; ++j) {
*(mulRes + (i * matrixBColLenght) + j) = 0;
for (int k = 0; k < matrixARowLenght; ++k) {
*(mulRes + (i * matrixBColLenght) + j) += *(matrixATransposed + (i * matrixARowLenght) + k) * *(matrixB + (k * matrixBColLenght) + j);
}
}
}
free(matrixATransposed);
// Sum the trace
int trace = 0;
for (int i = 0; i < matrixAColLenght; i++) {
for (int j = 0; j < matrixBColLenght; j++) {
if (i == j) {
trace += *(mulRes + i * matrixBColLenght + j);
}
}
}
printf("Sum: %d\n", trace);
free(mulRes);
return 0;
}
This code will output the following as expected:
Sum: 83
Related
I'm trying to write a function that does naive matrix multiplication of two contiguous, row-major arrays. But when I attempt to print each value at the end I get garbage. I'm guessing it's because I've mixed up the proper iterations and scaling needed to jump rows/columns. Does anyone have any advice?
Full code necessary is below:
#include <stdio.h>
#include <stdlib.h>
void dmatmul(double *a, double *b, double *c, int astride, int bstride, int cdim_0, int cdim_1) {
int i, j, p;
for (i = 0; i < cdim_0; i++) {
for (j = 0; j < cdim_1; j++) {
c[i * cdim_1 + j] = 0.0;
for (p = 0; p < (astride); p++) {
c[i * cdim_1 + j] += a[i * (astride) + p] * b[p * (bstride) + j];
}
}
}
}
int main(void) {
double *x, *y, *z;
int xdim_0, xdim_1, ydim_0, ydim_1, zdim_0, zdim_1, i, j;
xdim_0 = 2;
xdim_1 = 4;
ydim_0 = 4;
ydim_1 = 2;
zdim_0 = 2;
zdim_1 = 2;
x = (double *) malloc (xdim_0 * xdim_1 * sizeof(double));
y = (double *) malloc (ydim_0 * ydim_1 * sizeof(double));
z = (double *) malloc (zdim_0 * zdim_1 * sizeof(double));
for (i = 0; i < xdim_0 * xdim_1; i++) {
x[i] = i + 1;
y[i] = 2 * (i + 1);
}
dmatmul(x, y, z, xdim_1, ydim_1, zdim_0, zdim_1);
printf("\nMatrix product of X and Y dimensions: (%d, %d)\n", zdim_0, zdim_1);
printf("Matrix product of X and Y values:");
for (i = 0; i < zdim_0; i++) {
printf("\n");
for (j = 0; j < zdim_1; i++) {
printf("\t%f", z[i * zdim_1 + j]);
}
}
return 0;
}
The primary problem is a typo in the inner for loop doing the printing. You have:
for (j = 0; j < zdim_1; i++)
but you ned to increment j, not i:
for (j = 0; j < zdim_1; j++)
Here's my code, which has an independent matrix printing function appropriate for the arrays you're using:
/* SO 7516-7451 */
#include <stdio.h>
#include <stdlib.h>
static void dmatmul(double *a, double *b, double *c, int astride, int bstride, int cdim_0, int cdim_1)
{
int i, j, p;
for (i = 0; i < cdim_0; i++)
{
for (j = 0; j < cdim_1; j++)
{
c[i * cdim_1 + j] = 0.0;
for (p = 0; p < (astride); p++)
{
c[i * cdim_1 + j] += a[i * (astride) + p] * b[p * (bstride) + j];
}
}
}
}
static void mat_print(const char *tag, int rows, int cols, double *matrix)
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%4.0f", matrix[i * cols + j]);
putchar('\n');
}
}
int main(void)
{
int xdim_0 = 2;
int xdim_1 = 4;
int ydim_0 = 4;
int ydim_1 = 2;
int zdim_0 = 2;
int zdim_1 = 2;
double *x = (double *)malloc(xdim_0 * xdim_1 * sizeof(double));
double *y = (double *)malloc(ydim_0 * ydim_1 * sizeof(double));
double *z = (double *)malloc(zdim_0 * zdim_1 * sizeof(double));
for (int i = 0; i < xdim_0 * xdim_1; i++)
{
x[i] = i + 1;
y[i] = 2 * (i + 1);
}
mat_print("X", xdim_0, xdim_1, x);
mat_print("Y", ydim_0, ydim_1, y);
dmatmul(x, y, z, xdim_1, ydim_1, zdim_0, zdim_1);
mat_print("Z", zdim_0, zdim_1, z);
printf("\nMatrix product of X and Y dimensions: (%d, %d)\n", zdim_0, zdim_1);
printf("Matrix product of X and Y values:\n");
for (int i = 0; i < zdim_0; i++)
{
for (int j = 0; j < zdim_1; j++)
printf("\t%f", z[i * zdim_1 + j]);
printf("\n");
}
return 0;
}
I've also initialized the variables as I declared them. The code should, but does not, check that the memory was allocated.
When I ran this code without your printing, I got the correct result, so then I took a good look at that and saw the problem.
X (2x4):
1 2 3 4
5 6 7 8
Y (4x2):
2 4
6 8
10 12
14 16
Z (2x2):
100 120
228 280
Matrix product of X and Y dimensions: (2, 2)
Matrix product of X and Y values:
100.000000 120.000000
228.000000 280.000000
I have a task where I'm supposed to multiply two quadratic matrices of size n in C, using pointers as function parameters and return value. This is the given function head: int** multiply(int** a, int** b, int n). Normally, I would use three arrays (the two matrices and the result) as parameters, but since I had to do it this way, this is what I came up with:
#include <stdio.h>
#include <stdlib.h>
int** multiply(int** a, int** b, int n) {
int **c = malloc(sizeof(int) * n * n);
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
for (int k = 0; i < n; k++) {
*(*(c + i) + j) += *(*(a + i) + k) * *(*(b + k) + j);
}
}
}
return c;
}
int main() {
int **a = malloc(sizeof(int) * 2 * 2);
int **b = malloc(sizeof(int) * 2 * 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; i < 2; j++) {
*(*(a + i) + j) = i - j;
*(*(b + i) + j) = j - i;
}
}
int **c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
I have not worked much with pointers before, and am generally new to C, so I have no idea why this doesn't work or what I'd have to do instead. The error I'm getting when trying to run this program is segmentation fault (core dumped). I don't even know exactly what that means... :(
Can someone please help me out?
There's lots of fundamental problems in the code. Most notably, int** is not a 2D array and cannot point at one.
i<2 typo in the for(int j... loop.
i < n in the for(int k... loop.
To allocate a 2D array you must do: int (*a)[2] = malloc(sizeof(int) * 2 * 2);. Or if you will malloc( sizeof(int[2][2]) ), same thing.
To access a 2D array you do a[i][j].
To pass a 2D array to a function you do void func (int n, int arr[n][n]);
Returning a 2D array from a function is trickier, easiest for now is just to use void* and get that working.
malloc doesn't initialize the allocated memory. If you want to do += on c you should use calloc instead, to set everything to zero.
Don't write an unreadable mess like *(*(c + i) + j). Write c[i][j].
I fixed these problems and got something that runs. You check if the algorithm is correct from there.
#include <stdio.h>
#include <stdlib.h>
void* multiply(int n, int a[n][n], int b[n][n]) {
int (*c)[n] = calloc(1, sizeof(int[n][n]));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
int main() {
int (*a)[2] = malloc(sizeof(int[2][2]));
int (*b)[2] = malloc(sizeof(int[2][2]));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = i - j;
b[i][j] = j - i;
}
}
int (*c)[2] = multiply(2, a, b);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
From the updated requirement, the actual function prototype is int *multiply(int *a, int *b, int n); so the code should use a "flattened" matrix representation consisting of a 1-D array of length n * n.
Using a flattened representation, element (i, j) of the n * n matrix m is accessed as m[i * n + j] or equivalently using the unary * operator as *(m + i * n + j). (I think the array indexing operators are more readable.)
First, let us fix some errors in the for loop variables. In multiply:
for (int k = 0; i < n; k++) {
should be:
for (int k = 0; k < n; k++) {
In main:
for (int j = 0; i < 2; j++) {
should be:
for (int j = 0; j < 2; j++) {
The original code has a loop that sums the terms for each element of the resulting matrix c, but is missing the initialization of the element to 0 before the summation.
Corrected code, using the updated prototype with flattened matrix representation:
#include <stdio.h>
#include <stdlib.h>
int* multiply(int* a, int* b, int n) {
int *c = malloc(sizeof(int) * n * n);
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
c[i * n + j] = 0;
for (int k = 0; k < n; k++) {
c[i * n + j] += a[i * n + k] * b[k * n + j];
}
}
}
return c;
}
int main() {
int *a = malloc(sizeof(int) * 2 * 2);
int *b = malloc(sizeof(int) * 2 * 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i * 2 + j] = i - j;
b[i * 2 + j] = j - i;
}
}
int *c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i * 2 + j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
You need to fix multiple errors here:
1/ line 5/24/28: int **c = malloc(sizeof(int*) * n )
2/ line 15: k<n
3/ Remark: use a[i][j] instead of *(*(a+i)+j)
4/ line 34: j<2
5/ check how to create a 2d matrix using pointers.
#include <stdio.h>
#include <stdlib.h>
int** multiply(int** a, int** b, int n) {
int **c = malloc(sizeof(int*) * n );
for (int i=0;i<n;i++){
c[i]=malloc(sizeof(int) * n );
}
// Rows of c
for (int i = 0; i < n; i++) {
// Columns of c
for (int j = 0; j < n; j++) {
// c[i][j] = Row of a * Column of b
for (int k = 0; k < n; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}
int main() {
int **a = malloc(sizeof(int*) * 2);
for (int i=0;i<2;i++){
a[i]=malloc(sizeof(int)*2);
}
int **b = malloc(sizeof(int) * 2);
for (int i=0;i<2;i++){
b[i]=malloc(sizeof(int)*2);
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
a[i][j] = i - j;
b[i][j] = i - j;
}
}
int **c = multiply(a, b, 2);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("c[%d][%d] = %d\n", i, j, c[i][j]);
}
}
free(a);
free(b);
free(c);
return 0;
}
I'm having a memory related issue. Very strange behavior where initializing a for loop with stack variables is somehow changing values in heap memory. Never seen anything like this.
I have this main loop where I set some things up in heap and call some functions.
int main()
{
double **A = malloc(4 * sizeof(double *));
A[0] = malloc(4 * sizeof(double));
A[1] = malloc(4 * sizeof(double));
A[2] = malloc(4 * sizeof(double));
A[3] = malloc(4 * sizeof(double));
double **I = malloc(4 * sizeof(double *));
I[0] = malloc(4 * sizeof(double));
I[1] = malloc(4 * sizeof(double));
I[2] = malloc(4 * sizeof(double));
I[3] = malloc(4 * sizeof(double));
int *P = malloc(5 * sizeof(int));
A[0][0] = -1; A[0][1] = 8; A[0][2] = 9; A[0][3] = -6;
A[1][0] = 3; A[1][1] = 4; A[1][2] = 0; A[1][3] = 1;
A[2][0] = 0; A[2][1] = 2; A[2][2] = 0; A[2][3] = 0;
A[3][0] = 0; A[3][1] = 0; A[3][2] = -3; A[3][3] = 1;
LUPDecompose(A, 4, P);
LUPInvert(A, P, 4, I);
return EXIT_SUCCESS;
}
The functions I call are the following two. They're pretty complicated but seem totally fine.
void LUPDecompose(double **A, int N, int *P)
{
int i, j, k, imax;
double maxA, *ptr, absA;
for (i = 0; i <= N; i++)
P[i] = i;
for (i = 0; i < N; i++) {
maxA = 0.0;
imax = i;
for (k = i; k < N; k++)
if ((absA = fabs(A[k][i])) > maxA) {
maxA = absA;
imax = k;
}
if (imax != i) {
j = P[i];
P[i] = P[imax];
P[imax] = j;
ptr = A[i];
A[i] = A[imax];
A[imax] = ptr;
P[N]++;
}
for (j = i + 1; j < N; j++) {
A[j][i] /= A[i][i];
for (k = i + 1; k < N; k++)
A[j][k] -= A[j][i] * A[i][k];
}
}
}
void LUPInvert(double **A, int *P, int N, double **IA)
{
for (int j = 0; j < N; j++) {
for (int i = 0; i < N; i++) {
if (P[i] == j)
IA[i][j] = 1.0;
else
IA[i][j] = 0.0;
for (int k = 0; k < i; k++) {
IA[i][j] -= A[i][k] * IA[k][j];
}
}
printf("observe... %f (j %d)\n", IA[3][0], j);
for (int i = N - 1; i >= 0; i--) {
for (int k = i + 1; k < N; k++) {
printf("N %d k %d ...magic %f (j %d)\n", N, k, IA[3][0], j);
IA[i][j] -= A[i][k] * IA[k][j];
}
IA[i][j] = IA[i][j] / A[i][i];
}
}
}
When running this code, the for loop in the function LUPInvert initializes with k as N - 1 instead of N. Also the heap value AI[3][0] gets modified there. It gets modified to 0xbec00000 which sure seems like some memory overflow issue as it's full of zeroes, but I don't see it.
Can run this code and see the behavior here https://onlinegdb.com/SkZUlpmDD.
Sample of stdout:
observe... -0.214286 (j 0)
N 4 k 3 ...magic -0.375000 (j 0)
N 4 k 2 ...magic -0.375000 (j 0)
N 4 k 3 ...magic -0.375000 (j 0)
N 4 k 1 ...magic -0.375000 (j 0)
N 4 k 2 ...magic -0.375000 (j 0)
N 4 k 3 ...magic -0.375000 (j 0)
observe... -0.375000 (j 1)
N 4 k 3 ...magic -0.375000 (j 1)
N 4 k 2 ...magic -0.375000 (j 1)
It's as if it's forcing the loop to start (even tho it shouldn't as pointed out in comments), but in order to do so it has to set its values weirdly that causes this corruption.
I have written the below code for Strassen matrix multiplication. I know it's big but you don't need to go through the whole thing. My problem is that during compile time, the Strassen function with parameters of a[][num],b[][num] and c[][num] doesn't have a fixed value of num. This is where i am going wrong. I need to take the input of num in the main and that is why it cannot be globally given a value. How can i fix this? My code:
#include <stdio.h>
int num;
void strassen(int a[][num], int b[][num], int c[][num], int size) {
int p1[size/2][size/2], p2[size/2][size/2], p3[size/2][size/2], p4[size/2][size/2], p5[size/2][size/2], p6[size/2][size/2], p7[size/2][size/2];
int temp1[size/2][size/2], temp2[size/2][size/2];
int q1, q2, q3, q4, q5, q6, q7, i, j;
if(size >= 2) { //give recursive calls
//p1
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp1[i][j] = a[i][j] + a[i + size / 2][j + size / 2];
}
}
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp2[i][j] = b[i][j] + b[i + size / 2][j + size / 2];
}
}
num = size / 2;
strassen(temp1, temp2, p1, size / 2);
//p2
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp1[i][j] = a[i + size / 2][j] + a[i + size / 2][j + size / 2];
}
}
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp2[i][j] = b[i][j];
}
}
num = size / 2;
strassen(temp1, temp2, p2, size / 2);
//p3
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp1[i][j] = a[i][j];
}
}
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp2[i][j] = b[i][j + size / 2] - b[i + size / 2][j + size / 2];
}
}
num = size / 2;
strassen(temp1, temp2, p3, size / 2);
//p4
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp1[i][j] = a[i + size / 2][j + size / 2];
}
}
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp2[i][j] = b[i + size / 2][j] - b[i][j];
}
}
num = size / 2;
strassen(temp1, temp2, p4, size / 2);
//p5
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp1[i][j] = a[i][j] + a[i][j + size / 2];
}
}
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp2[i][j] = b[i + size / 2][j + size / 2];
}
}
num = size / 2;
strassen(temp1, temp2, p5, size / 2);
//p6
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp1[i][j] = a[i + size / 2][j] - a[i][j];
}
}num = size / 2;
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp2[i][j] = b[i][j] + b[i][j + size / 2];
}
}
num = size / 2;
strassen(temp1, temp2, p6, size / 2);
//p7
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp1[i][j] = a[i][j + size / 2] - a[i + size / 2][j + size / 2];
}
}
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
temp2[i][j] = b[i + size / 2][j] + b[i + size / 2][j + size / 2];
}
}
num = size / 2;
strassen(temp1, temp2, p7, size / 2);
//c11
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
c[i][j] = p1[i][j] + p4[i][j] - p5[i][j] + p7[i][j];
}
}
//c12
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
c[i][j + size / 2] = p3[i][j] + p5[i][j];
}
}
//c21
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
c[i + size / 2][j] = p2[i][j] + p4[i][j];
}
}
//c22
for(i = 0; i < size / 2; i++) {
for(j = 0; j < size / 2; j++) {
c[i + size / 2][j + size / 2] = p1[i][j] + p3[i][j] - p2[i][j] + p6[i][j];
}
}
}
else if(size == 1) {
c[0][0] = a[0][0] * b[0][0];
}
}
int padding(int num) {
int original_num = num, lower_power = 0, i, actual_num = 1;
if(num == 1)
return 1;
while(num > 1) {
lower_power++;
num /= 2;
}
for(i = 0; i < lower_power; i++) {
actual_num *= 2;
}
if(actual_num == original_num)
return original_num;
else
return actual_num * 2;
}
int main() {
int i, j, temp;
printf("Enter the size of nxn matrix:\n");
scanf("%d", &num);
temp = num;
if(num <= 0)
return 0;
num = padding(num);
int a[num][num], b[num][num], c[num][num];
printf("Enter matrix a:\n"); //accept inputs for a and b from the user
for(i = 0; i < temp; i++) {
for(j = 0; j < temp; j++) {
scanf("%d", &a[i][j]);
}
for(j = temp; j < num; j++) {
a[i][j] = 0;
}
}
for(i = temp; i < num; i++)
for(j = 0; j < num; j++)
a[i][j] = 0;
printf("\nEnter matrix b:\n");
for(i = 0; i < temp; i++) {
for(j = 0; j < temp; j++) {
scanf("%d", &b[i][j]);
}
for(j = temp; j < num; j++) {
b[i][j] = 0;
}
}
for(i = temp; i < num; i++)
for(j = 0; j < num; j++)
b[i][j] = 0;
printf("Matrix a:\n"); //printing the actual matrices for strassen's multiplication
for(i = 0; i < num; i++) {
for(j = 0; j < num; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
printf("\nMatrix b:\n");
for(i = 0; i < num; i++) {
for(j = 0; j < num; j++) {
printf("%d ", b[i][j]);
}
printf("\n");
}
strassen(a, b, c, num);
printf("\nMatrix c is:\n");
for(i = 0; i < temp; i++) {
for(j = 0; j < temp; j++) {
printf("%d ", c[i][j]);
}
printf("\n");
}
return 0;
}
You can (perhaps even should) use int ** instead, and pass num as an argument. As a simplified example, here is how you might compute the sum of a dynamically sized array:
int sum(int *in, int len) {
int out = 0;
for(int i = 0; i < len; i++)
out += in[i];
return out;
}
#include <stdio.h>
#include <stdlib.h>
float average_score(int** array_score)
{
int i, j;
int sum = 0;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
sum += *(*(array_score + i) + j);
}
}
printf("sum / 16 = %d\n", sum / 16);
return (float) sum / 16;
}
int lowest_score(int** array_score)
{
int i, j;
int temp = **array_score;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(temp > *(*(array_score + i) + j))
//------
temp = *(*(array_score + i) + j);
printf("%d ",*(*(array_score + i) + j));
}
//--
printf("\n");
}
printf("low_score = %d\n", temp);
return temp;
}
int main(int argc, char** argv)
{
int **array_score = NULL;
int i = 0;
int j = 0;
//Create a two-dimensional array
array_score = (int **) malloc(4 * sizeof(int *));
for(i = 0; i <= 4; i++)
array_score[i] = (int *)malloc(4 * sizeof(int));
//--
for(i = 0; i < 4; i++)
{
printf("Please enter the student_%d four grades, (separated with a space )\n", i+1);
int ret = scanf("%d %d %d %d", (*(array_score + i) + 0), (*(array_score + i) + 1),
(*(array_score + i) + 2), (*(array_score + i) + 3));
fflush(stdin);
if(4 != ret)
i--;
}
//There is something wrong with the function return value
float ave_score = average_score(array_score);
//--
int low_score = lowest_score(array_score);
//The output
printf("average score: %d\n lowest score: %d\n", ave_score, low_score);
return 0;
}
This allocates space for 4 pointers and then writes 5, since i takes on the values 0, 1, 2, 3 and 4:
array_score = (int **) malloc(4 * sizeof(int *));
for(i = 0; i <= 4; i++)
array_score[i] = (int *)malloc(4 * sizeof(int));
Note that in C you shouldn't cast the return from malloc. There's an answer on Stackoverflow telling all the details why this is not helpful.