Multiplying two matrixes in C - c

I'm trying to multiply two matrixes in C but the result gives me:
\23 23\
\23 23\
instead of
\23 20\
\55 48\
1x1 of the matrix keeps repeating and it seems like the matResult[i][j]=sum isn't taking in the sum. The number of rows and columns are defined and there are no scans. I also used a function to calculate the multiplication of the matrix so that I could later use it in the main.
#include <stdio.h>
#define M 2 // m is the number of rows
#define N 2 // n is the number of columns
int i;
int j;
int k;
int sum;
/*
Function to calculate the multiplication of 2 matrixes
*/
int multiMat(int mat1[M][N], int mat2[M][N], int matResult[M][N]) {
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
sum = sum + (mat1[i][k] * mat2[k][j]);
}
matResult[i][j] = sum;
sum = 0;
}
}
return matResult[i][j];
}
int main(void) {
int mat1[M][N] = {{1, 2}, {3, 4}};
int mat2[M][N] = {{9, 8}, {7, 6}};
int matResult[M][N];
printf("\n\n RESULT ");
printf("\n ===============\n");
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
printf(" %d\t", multiMat(mat1, mat2, matResult));
}
printf("\n");
}
return 0;
}

Here's my version of your code cleaned up. I've removed M as your matrices are square and your code won't easily adapt to multiplying two non-square matrices (though, as I noted in a comment, you can multiply an M×N matrix by an N×P matrix, and the result is an M×P matrix).
#include <stdio.h>
#define N 2 // n is the size of the square matrices
static void multiMat(int mat1[N][N], int mat2[N][N], int matResult[N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
int sum = 0;
for (int k = 0; k < N; k++)
{
sum = sum + (mat1[i][k] * mat2[k][j]);
}
matResult[i][j] = sum;
}
}
}
static void printMat(const char *tag, int mat[N][N])
{
printf("%s (%dx%d):\n", tag, N, N);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
printf(" %3d", mat[i][j]);
}
printf("\n");
}
}
int main(void)
{
int mat1[N][N] = {{1, 2}, {3, 4}};
int mat2[N][N] = {{9, 8}, {7, 6}};
int mat3[N][N];
multiMat(mat1, mat2, mat3);
printMat("Mat1", mat1);
printMat("Mat2", mat2);
printMat("Mat3", mat3);
return 0;
}
When run, it produces the output:
Mat1 (2x2):
1 2
3 4
Mat2 (2x2):
9 8
7 6
Mat3 (2x2):
23 20
55 48
The result (renamed Mat3 in this code) is what you wanted. It's often a good idea to print the inputs as well as the output — it ensures that the computer is thinking about things the same way you are. It also encourages writing functions like printMat(). It is possible to provide the dimensions of the matrices to the functions using VLA (variable-length array) notation. For example, a more general matrix multiply function might be:
void MatrixMuliply(size_t M, size_t N, size_t P, int mat1[M][N], int mat2[N][P], int mat3[M][P])
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < P; j++)
{
int sum = 0;
for (int k = 0; k < N; k++)
sum += mat1[i][k] * mat2[k][j];
mat3[i][j] = sum;
}
}
}

Related

Finding the origin of a calculation before it got sorted?

I wanted to find the sum of each row and then sort it. I managed to do this but to make it more complicated I decided to find from which row the min sum and the max sum was originated.
Example: The row with the min sum is the 3rd and the row with the max sum is is the 5th.
The main issue in my approach that I attempted was that the b[] array (in the sortfunction below) which I used to store the initial sum of each row is now replaced with the sorted values and I cannot work with the unsorted values which would show the rows that are needed.
#include<stdio.h>
#define ROWS 5
#define COLS 3
void printnumbers(int arr[][COLS]);
void sortfunction(int arr[][COLS]);
int main() {
int arr[ROWS][COLS] = {{1, 2, 3},
{2, 3, 4},
{3, 1, 1},
{5, 5, 6},
{35, 335, 6}};
printnumbers(arr);
sortfunction(arr);
return 0;
}
void printnumbers(int arr[][COLS]){
int i,j;
for(i = 0; i<ROWS; i++)
{
printf("\n");
for(j = 0; j<COLS; j++)
{
printf("%d\t", arr[i][j]);
}
}
}
//swap function below
void swap(int* xp, int* yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
// sort function
void sortfunction(int arr[][COLS]) {
int i, j, total, k, b[ROWS];
k = 0;
printf("\n");
for (i = 0; i < ROWS; i++) {
total = 0;
for (j = 0; j < COLS; j++) {
total += arr[i][j];
}
if (j == COLS) {
b[k] = total;
k += 1;
}
}
for (k = 0; k < ROWS; k++) {
printf("the sum of the %dst row is %d\n", k + 1, b[k]);
}
int a, q, min_idx;
int n = sizeof(b) / sizeof(b[0]);
// One by one move boundary of unsorted subarray
for (q = 0; q < n - 1; q++) {
// Find the minimum element in unsorted array
min_idx = q;
for (a = q + 1; a < n; a++)
if (b[a] < b[min_idx])
min_idx = a;
// Swap the found minimum element
// with the first element
swap(&b[min_idx], &b[q]);
}
for (i = 0; i < n; i++)
printf("%d ", b[i]);
printf("\n");
//Now I want to find which row has the least sum and which has the max sum but the b[] array is already sorted.
}
This prints:
the sum of the 1st row is 6
the sum of the 2st row is 9
the sum of the 3st row is 5
the sum of the 4st row is 16
the sum of the 5st row is 376
5 6 9 16 376 //it got sorted
and it needs to print also this:
The row with the min sum is in the 3rd row
The row with the max sum us un the 5th row.
One solution would be to make b an array of a struct with the sum and row numbers. The swap() and sortfunction() functions would then be as follows (including some minor simplifications):
typedef struct
{
int sum;
int row;
} tRowSum;
//swap function below
void swap(tRowSum* xp, tRowSum* yp)
{
tRowSum temp = *xp;
*xp = *yp;
*yp = temp;
}
// sort function
void sortfunction(int arr[][COLS]) {
int i, j, total;
tRowSum b[ROWS];
printf("\n");
for (i = 0; i < ROWS; i++) {
total = 0;
for (j = 0; j < COLS; j++) {
total += arr[i][j];
}
b[i].sum = total;
b[i].row = i;
}
for (i = 0; i < ROWS; i++) {
printf("the sum of the %dst row is %d\n", i + 1, b[i].sum);
}
int a, q, min_idx;
// One by one move boundary of unsorted subarray
for (q = 0; q < ROWS - 1; q++) {
// Find the minimum element in unsorted array
min_idx = q;
for (a = q + 1; a < ROWS; a++)
if (b[a].sum < b[min_idx].sum)
min_idx = a;
// Swap the found minimum element
// with the first element
swap(&b[min_idx], &b[q]);
}
for (i = 0; i < ROWS; i++) {
printf("%d (%d)", b[i].sum, b[i].row);
printf("\n");
}
}
After sorting b with respect to the sum, the original row numbers are then available for each entry.

How to raise a matrix to a power with double pointers in C

I am trying to raise a matrix to a power, using pointers but there is a mistake in my code I can't find.
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
>
int **alloc(int r, int c) {
int **d;
d = (int **)malloc(r * sizeof(int *));
for (int i = 0; i < r; i++) {
d[i] = (int *)malloc(c * sizeof(int));
}
return d;
void input(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("[%d][%d]=", i, j);
scanf_s("%d", &A[i][j]);
}
}
}
void output(int **A, int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("%d ", A[i][j]);
}
printf("\n");
}
}
void power(int **A,int**D, int r, int c,int p) {
int i, j,k;
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
D[i][j] = A[i][j];
}
}
while (p) {
// this is the matrix multiplication, where I attempt to multiply my matrix A with itself, and store the result in D, which initially started as A's copy, and p is the power I'm raising it to.
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
for (k = 0; k < c; k++)
D[i][j] = D[i][j] + A[i][k] * D[k][j];
}
}
p--;
}
}
void main() {
int r, c;
int **A, **D;
printf("rows A: ");
scanf_s("%d", &r);
printf("columns A: ");
scanf_s("%d", &c);
A = alloc(r, c);
printf("\nValues of A:\n");
input(A, r, c);
printf("\nMatrIX A is:\n");
output(A, r, c);
D = alloc(r, c);
printf("input the value you want to raise your matrix to: ");
int p;
scanf_s("%d", &p);
power(A, D, r, c, p);
printf("\nMatrix raised to said power is:\n");
output(D, r, c);
_getch();
}
When I input the rows and columns as 2 each, and input all values in the matrix as 1 and raise it to the power of 3, my answer should be
4 4
4 4
instead of
72 72
232 232
What is wrong in my code? If I were to print the D matrix before the multiplication, it would print it correctly, as:
1 1
1 1
Your two-step allocation looks okay, except that you don't free the memory after you're done. Your problem is in how you multiply the matrix:
Raising a matrix to a power involves multiplying it to itself. You can only do that if the matrix is square. You can replace all occurrences of rows r and columns c with a single dimension n.
When you do the actual multiplication:
D[i][j] = D[i][j] + A[i][k] * D[k][j];
you assign to D and read from it at the same time. Subsequent calculations (of the same multiplication) will see a changed value of D[i][j]. You will need a temporary "scratch" matrix.
Your code multiplies once too many. Also, Raising a matrix to the power of zero should yield the identity matrix.
Here's how your power function could look like:
void power(int **A, int **D, int n, int p)
{
int i, j,k;
// assign identity matrix to result D
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
D[i][j] = (i == j);
}
}
// create a scratch matrix
int **tmp = alloc(n);
while (p-- > 0) {
// multiply [tmp] = [A] * [D]
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
tmp[i][j] = 0;
for (k = 0; k < n; k++)
tmp[i][j] += A[i][k] * D[k][j];
}
}
// copy [D] = [tmp]
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
D[i][j] = tmp[i][j];
}
}
}
// TODO: clean up the scratch matrix
}

How to multiply a 4x4 matrix with a 1x3 matrix in C?

If you already have a set 4x4 matrix.
Ex.
Matrix A = [1 2 3 4;
5 6 7 8;`
9 10 11 12;
13 14 15 16]
Matrix B = [1, 2, 3]
How would you convert Matrix A into C coding? Also what would there positions be in code? For position I mean: if I'm trying to multiply the first row into matrix B, can I do this?
A[1][0]*B[0]+A[1][1]*B[1]+A[1][2]*B[2]
Outline code:
main(){
int matrixA[4][4] = [{"1","2","3","4"};
{"5","6","7","8"};
{"9","10","11","12"};
{"13","14","15","16"}];
printf(matrix A);
return 0;
}
First of all you cannot multiply a 1×3 matrix with 4×4 matrix.
You should have matrices like m×n and n×p to get them multiplied (the result will be an m×p matrix).
Also for having a 4×4 matrix in C you should implement it like this:
int main()
{
int mat[4][4];
for(int i=0;i<=3;i++)
{
for(int j=0;j<=3;j++)
{
scanf("%d", &mat[i][j]);
}
}
return 0;
}
As far i can understand, you want to make a program to execute mathematical fractions related to matrices. Example in linear algebra. Matrix sizes are not checked, but you get the idea. In division you have to make the calculation of Array2^-1 to find it. Hope i helped. After you find it, multiply the result ,to Array1. In division however, things are more complicated. You need to approach your coding in different ways, depending to the array(matrix) dimensions you have. Exceptions must be included and need to read a bit of theory on how to divide those matrices. See https://en.wikipedia.org/wiki/Division_(mathematics) for more details.
#include <stdio.h>
#include <math.h>
int main(){
//counters
int i=0,j=0,k=0,sum=0;
//first array
int Array1[4][4] ={
{87,96,70,22},
{18,65,77,78},
{76,72,84,65},
{87,93,73,77}};
//second array
int Array2[4][4]={
{14,45,66,88},
{45,32,97,44},
{34,64,23,66},
{39,98,55,32}};
//result array.
int ResultArray[4][4];
// Add
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
ResultArray[i][j]= Array1[i][j]+Array2[i][j];
}
}
//result
printf("\tAdd Array1 and Array2\n");
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
printf(" %10d \t",ResultArray[i][j]);
}
printf("\n");
}
//subtract
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
ResultArray[i][j]= Array1[i][j]-Array2[i][j];
}
}
//result
printf("\tSubtract Array1 and Array2\n");
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
printf(" %10d \t",ResultArray[i][j]);
}
printf("\n");
}
//multiply
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
for (k = 0; k < 4; ++k) {
sum=sum+Array1[i][k]*Array2[k][j];
}
ResultArray[i][j]=sum;
sum=0;
}
}
//result
printf("\tMultiplication Array1 and Array2\n");
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
printf(" %10d \t",ResultArray[i][j]);
}
printf("\n");
}
return 0;
}
you can write like this:
int matrixA[4][4] = {
{ 1, 2, 3, 4},//matrixA[0][0] is 1
{ 5, 6, 7, 8},//matrixA[1][1] is 6
{ 9, 10, 11, 12},
{13, 14, 15, 16}
};
int matrixB[] = { 1, 2, 3};
for(int r = 0; r < 4; ++r){
for(int c = 0; c < 4; ++c){
printf("%3d", matrixA[r][c]);
}
printf("\n");
}
Let me help you a bit, but you in return help me understand the question. :)
Representation
Ok Matrices are represented using 2-d array.
Like
int a[][]= { {1,2,3,4}, {5,6,7,8},{9,10,11,12},{13,14,15,16}};
Matrix is ready. :)
If you want to create it on the fly..malloc() will be your friend.
Here I meant to say that you have to dynamically allocate the array.
For example:
int **a;
a= malloc(sizeof(int*)*m);
for(int i=0;i<m;i++)
a[i]=malloc(sizeof(int)*n);
Forming mxn matrix where m and n are got as input maybe.
How to multiply 2 matrices [ ofcourse compatible]?
Here in your case A[4x4] B[1x4] so p=4,m=1,q=4.
for (c = 0; c < m; c++) {
for (d = 0; d < q; d++) {
for (k = 0; k < p; k++) {
sum = sum + first[c][k]*second[k][d];
}
multiply[c][d] = sum;
sum = 0;
}
}

How to use second rank pointer rightly?

I have a 2D array called matrix, now I would like to add one to every element.
#include <stdio.h>
#include <stdlib.h>
int **add_one(int **matrix, int m, int n) {
int i, j;
int **new_mat;
new_mat = (int **) malloc(m * n *sizeof(int));
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
new_mat[i][j] = matrix[i][j] + 1;
}
}
//return the 2nd rank pointer
return new_mat;
}
int main() {
int matrix[3][2] = {1, 2, 3, 4, 5, 6};
int **new_mat;
int i, j;
new_mat = add_one(matrix, 3, 2);
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf("%d ", new_mat[i][j]);
}
printf("\n");
}
free(new_mat);
}
However, the compiler told me that
[Error] cannot convert 'int (*)[2]' to 'int**' for argument '1' to 'int** add_one(int**, int, int)'
It works a bit differently from what you thought
#include <stdio.h>
#include <stdlib.h>
// you can only pass what you have
int **add_one(int matrix[3][2], int m, int n)
{
int i, j;
int **new_mat;
// allocate m pointers (the rows)
new_mat = malloc(m * sizeof(*new_mat));
for (i = 0; i < m; i++) {
// allocate space for n ints
new_mat[i] = malloc(n * sizeof(int));
for (j = 0; j < n; j++) {
new_mat[i][j] = matrix[i][j] + 1;
}
}
//return the 2nd rank pointer
return new_mat;
}
int main()
{
// you forgot to encapsulate the rows, too
int matrix[3][2] = { {1, 2}, {3, 4}, {5, 6} };
int **new_mat;
int i, j;
new_mat = add_one(matrix, 3, 2);
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
printf(" %d ", new_mat[i][j]);
}
printf("\n");
}
free(new_mat);
}
If you want to pass the two-star matrix as a two-star matrix you need to build it like the new_mat in the function add_one.

Taking the transpose of a matrix in C with 1D arrays

I have a matrix that is represented by a one dimensional array,
example:
the matrix
0 1 2 3
4 5 6 7
8 9 10 11
the array
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
now give the dimensions of this matrix and the array I want to find the transpose, i.e.
0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11
I'm working in C and here is my code
#include <stdlib.h>
#include <stdio.h>
void transpose(int *array, int m, int n){
int new_array[12];
for (int i=0; i<m*n; i++) {
new_array[i] = ??;
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
void print_array(int array[], int size){
for (int i=0; i<size; i++) {
printf("%d\n",array[i]);
}
}
int main(){
int array[12];
for (int i=0; i<12; i++) {
array[i]=i;
}
print_array(array,12);
transpose(array,3,4);
print_array(array,12);
return 0;
}
I've tried a dozen times and failed. Is there a simple way to do this that I have missed?
Use couple of for loops to make the code easier to follow.
void transpose(int *array, int m, int n){
int new_array[12];
for (int i = 0; i < m; ++i )
{
for (int j = 0; j < n; ++j )
{
// Index in the original matrix.
int index1 = i*n+j;
// Index in the transpose matrix.
int index2 = j*m+i;
new_array[index2] = array[index1];
}
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
void transpose(int *array, int m, int n){
int new_array[12];
int k = 0;
for(int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
new_array[k++] = array[j*n + i];
}
}
for (int i=0; i<m*n; i++) {
array[i] = new_array[i];
}
}
Write the transpose in terms of a double loop over range [0..n) and [0..m) and calculate the indexes corresponding to the old position and the new position:
#include <stdio.h>
static void transpose(int *array, int m, int n)
{
int new_array[m * n];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
int old_idx = i * n + j;
int new_idx = j * m + i;
new_array[new_idx] = array[old_idx];
}
}
for (int i = 0; i < m * n; i++)
{
array[i] = new_array[i];
}
}
static void print_array(int array[], int size)
{
for (int i = 0; i < size; i++)
{
printf(" %d", array[i]);
}
putchar('\n');
}
int main(void)
{
int array[12];
for (int i = 0; i < 12; i++)
{
array[i] = i;
}
print_array(array, 12);
transpose(array, 3, 4);
print_array(array, 12);
return 0;
}
The functions have to be pre-declared or made static to compile with my default compilation options. The transpose() function shown will work with any shape (size) of matrix (whereas the original won't work if the product of the dimensions is more than 12). I flattened the output from the array printer, too (though I'd probably make it print matrix shaped output if it were for 'production' use). I do assume that you have C99, or C11 with VLA support.
$ ./trans
0 1 2 3 4 5 6 7 8 9 10 11
0 4 8 1 5 9 2 6 10 3 7 11
$
I have changed:
for (int i = 0 ; i < m*n ; i++) {
new_array[i] = ??;
}
to:
int ctr = 0;
for (int i = 0 ; i <= m*n ; i++) {
if (ctr > m*n)
ctr -= m*n - 1;
new_array[i] = array[ctr];
ctr += n;
}
The logic is quite simple. Each row is n integers long and so the number below a num in the 2-D matrix form would be n+num
You can rewrite your transpose function as like this:
static void transpose(int *array, int m, int n)
{
int *temp=malloc(m*n*sizeof(int)); //need to create a temporary array.
memcpy(temp,array,m*n*sizeof(int));
int i, j;
for (i = 0; i < m; ++i)
{
for (j = 0; j < n; ++j)
{
array[j*m+i]=temp[i*n+j];
}
}
free(temp);
}
You almost had it, I think this would do it...
void transpose(int *array, int m, int n){
int new_array[12];
int count;
count = 0;
for (int i=0; i < n; i++) {
for (int j=0; j < m; j += n) {
new_array[count++] = i + j;
}
}
for (int i=0; i < m * n; i++) {
array[i] = new_array[i];
}
}
This algorithm works for any number of rows an columns:
for (std::size_t i = 0; i < col; i++) {
for (std::size_t j = 0; j < row; j++) {
transpose[c++] = array[j * col + i];
}
}

Resources