matrix multiplied by a vector in C - c

I have a matrix[2][3], a vector[3] and I am computing the result of this with the below code which works perfectly fine.
My approach: Initialize a product matrix of size [3][2] to zero, perform the computation as in the function matrix_x_vector and extract the last row to get the final output(vector).
What I expect: Instead of using a product matrix of size [3][2] and then extracting the vector from it, is there any direct way of multiplying a matrix by a vector and store it directly into a resultant vector.
#include <stdio.h>
int main()
{
// Define Variables
int n1 = 2, n2= 3;
int vector[3] = {2,1,2};
int matrix[2][3] = {
{1,-1,2},
{2,-3,1},
};
int Product_matrix[3][2] = {
{0},
{0},
{0}
};
// Define Functions
void matrix_x_vector(int n1,int n2, int vector[n2], int matrix[n1][n2], int Product[n1][n2]); // Performs the calculation
// Execute Functions
matrix_x_vector(n1, n2, vector, matrix, Product_matrix);
printf("\n");
return 0;
}
void matrix_x_vector(int n1,int n2, int vector[n2], int matrix[n1][n2], int Product[n1][n2])
{
int i, j; // i = row; j = column;
printf("\nProduct Matrix of [x]*[y]\n");
// Load up A[n][n]
for (i=0; i<n2; i++)
{
for (j=0; j<n1; j++)
{
Product[j][0] += matrix[j][i] * vector[i];
printf("%4i", Product[j][0]);
}
printf("\n");
}
printf("Vector: \n");
// Print Vector from Product[n][n]
for (i=0; i<n1; i++){
printf("%4i\n", Product[i][0]);
}
}
Product Matrix of [x]*[y]
2 4
1 1
5 3
Vector:
5
3

If I understood the question correctly, it is asked for a function which uses a vector instead of a matrix for the result type. This function can be formulated as follows.
void matrix_x_vector_new(int n1,
int n2,
int vector[3],
int matrix[2][3],
int result_vector[3])
{
int i, j; // i = row; j = column;
printf("\nProduct Matrix of [x]*[y]\n");
// Load up A[n][n]
for (i = 0; i<n2; i++)
{
for (j = 0; j<n1; j++)
{
result_vector[j] += matrix[j][i] * vector[i];
printf("%4i", result_vector[j]);
}
printf("\n");
}
printf("Vector: \n");
// Print Vector from Product[n][n]
for (i = 0; i<n1; i++)
{
printf("%4i\n", result_vector[i]);
}
}

Related

Segmentation Fault During Matrix Multiplication

I am new to C coding, and am trying to implement standard matrix multiplication. My code works fine for square matrices, but refuses to accept a column vector. Here is my attempt at the code. Any help would be much appreciated.
//---------------------------------------IMPORTING NECESSARY C PACKAGES AND DEFINING EXECUTION CONSTANTS-------------------------------------------//
#include <stdio.h> // Standard input output library
#include <math.h> // Mathematical function library
#include <stdlib.h> // General purpose standard library
#define true 1
#define false 0
typedef long double numeric; // Using the long double datatype to avoid overflows during computations
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------FUNCTION DECLERATION-------------------------------------------------------------//
numeric **create_matrix(int x, int y); // To dynamically allocate memory and create a matrix
void input_matrix(numeric **matrix, int m, int n); // To accept a matrix
void print_matrix(numeric **l, int x, int y); // To print a matrix
numeric **standard_matrix_multiplication(int m, int n, int l); // To multiply two matrices
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------DRIVER CODE--------------------------------------------------------------------//
int main(int argc, char *argv[]) {
int m, n, l; int choice;
printf("Enter the matrix operation to be performed using the corresponding index number.\n");
printf("\n");
printf("1.\tMatrix Multiplication");
printf("\n");
scanf("%d", &choice);
switch(choice) {
case 1 :
printf("Enter the number of rows in the first matrix\n");
scanf("%d", &m);
printf("Enter the number of columns in the first matrix\n");
scanf("%d", &n);
printf("Enter the number of columns in the second matrix\n");
scanf("%d", &l);
printf("Enter both matrices.\n");
numeric **matrix_x;
matrix_x = create_matrix(m, l);
matrix_x = standard_matrix_multiplication(m, n, l);
print_matrix(matrix_x, m, l);
break;
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------MATRIX MULTIPLICATION IMPLEMENTATIONS--------------------------------------------------//
numeric **standard_matrix_multiplication(int m, int n, int l) {
numeric **matrix_a; numeric **matrix_b; numeric **matrix_k;
matrix_a = create_matrix(m, n);
matrix_b = create_matrix(n, l);
matrix_k = create_matrix(m, l);
input_matrix(matrix_a, m, n);
print_matrix(matrix_a, m, n);
input_matrix(matrix_b, n, l);
for(int i = 0; i < m; i++) {
for (int j = 0; j < n; j ++) {
for (int k = 0; k < l; k++) {
matrix_k[i][j] += matrix_a[i][k] * matrix_b[k][j];
}
}
}
return matrix_k;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------HELPER FUNCTIONS------------------------------------------------------------------//
numeric **create_matrix(int x, int y) {
numeric **matrix = (numeric**)malloc(x * sizeof(numeric*)); // Dynamically creating an array of pointers
for (int i = 0; i < y; i++) {
matrix[i] = (numeric*)malloc(y * sizeof(numeric)); // Dynamically allocating memory for each columns of the matrix
}
return matrix;
}
void input_matrix(numeric **matrix, int m, int n) {
printf("Enter the elements of the matrix, row wise.\n"); // Instructing the user on matrix entry
printf("For example, to enter the matrix\n");
printf("\t\t1\t2\n");
printf("\t\t3\t4\n");
printf("enter 1, 2, 3, and 4 in that order.\n");
for (int i = 0; i < m; i++) { // Iterating through the rows and columns of the matrix
for (int j = 0; j < n; j++) {
scanf("%Lf", &matrix[i][j]); // Accepting each element
}
}
}
void print_matrix(numeric **l, int x, int y) { // To print a matrix
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
printf("%0.10Lf\t", l[i][j]); // Printing numeric type values
}
printf("\n");
}
printf("\n");
}
As of now, I have only written one switch case, and that is for matrix multiplication. So I chose 1. I gave 2, 1, 2 as my inputs for the number of rows in the first matrix, number of columns in the first matrix, and number of columns in the second matrix respectively. I have given a print statement in line 52, and it isn't executing it for the above input, giving a segmentation fault instead. Could someone please help me out?
Yes there are some issues with your code that gives segfault error during runtime.
The Matrix multiplication logic part of the code needs to be corrected as follows
for(int i = 0; i < m; i++) {
for (int j = 0; j < l; j ++) {
for (int k = 0; k < n; k++) {
matrix_k[i][j] += matrix_a[i][k] * matrix_b[k][j];
because k should iterate till the no of columns in 1st matrix which is n but not till l.
And there is a slight correction needed in create_matrix function.
You use y (i.e. no of columns in the matrix) in your for instead of x (no of rows in matrix).
If x < y, you end up outside of the memory you allocated.
If x > y, you end up with uninitialized pointers.
So change it as follows
for (int i = 0; i < x; i++) {
matrix[i] = (numeric*)malloc(y * sizeof(numeric));
After these corrections try executing the code, you should get the expected results without any segfault errors
Here is the complete working code
#include <stdio.h> // Standard input output library
#include <math.h> // Mathematical function library
#include <stdlib.h> // General purpose standard library
#define true 1
#define false 0
typedef long double numeric; // Using the long double datatype to avoid overflows during computations
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------FUNCTION DECLERATION-------------------------------------------------------------//
numeric **create_matrix(int x, int y); // To dynamically allocate memory and create a matrix
void input_matrix(numeric **matrix, int m, int n); // To accept a matrix
void print_matrix(numeric **l, int x, int y); // To print a matrix
numeric **standard_matrix_multiplication(int m, int n, int l); // To multiply two matrices
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------DRIVER CODE--------------------------------------------------------------------//
int main(int argc, char *argv[]) {
int m, n, l; int choice;
printf("Enter the matrix operation to be performed using the corresponding index number.\n");
printf("\n");
printf("1.\tMatrix Multiplication");
printf("\n");
scanf("%d", &choice);
switch(choice) {
case 1 :
printf("Enter the number of rows in the first matrix\n");
scanf("%d", &m);
printf("Enter the number of columns in the first matrix\n");
scanf("%d", &n);
printf("Enter the number of columns in the second matrix\n");
scanf("%d", &l);
printf("Enter both matrices.\n");
numeric **matrix_x;
matrix_x = create_matrix(m, l);
matrix_x = standard_matrix_multiplication(m, n, l);
print_matrix(matrix_x, m, l);
break;
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------MATRIX MULTIPLICATION IMPLEMENTATIONS--------------------------------------------------//
numeric **standard_matrix_multiplication(int m, int n, int l) {
numeric **matrix_a; numeric **matrix_b; numeric **matrix_k;
matrix_a = create_matrix(m, n);
matrix_b = create_matrix(n, l);
matrix_k = create_matrix(m, l);
input_matrix(matrix_a, m, n);
print_matrix(matrix_a, m, n);
input_matrix(matrix_b, n, l);
//print_matrix(matrix_b, n, l);
for(int i = 0; i < m; i++) {
for (int j = 0; j < l; j ++) {
for (int k = 0; k < n; k++) {
matrix_k[i][j] += matrix_a[i][k] * matrix_b[k][j];
}
}
}
return matrix_k;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------HELPER FUNCTIONS------------------------------------------------------------------//
numeric **create_matrix(int x, int y) {
numeric **matrix = (numeric**)malloc(x * sizeof(numeric*)); // Dynamically creating an array of pointers
for (int i = 0; i < x; i++) {
matrix[i] = (numeric*)malloc(y * sizeof(numeric)); // Dynamically allocating memory for each columns of the matrix
}
return matrix;
}
void input_matrix(numeric **matrix, int m, int n) {
printf("Enter the elements of the matrix, row wise.\n"); // Instructing the user on matrix entry
printf("For example, to enter the matrix\n");
printf("\t\t1\t2\n");
printf("\t\t3\t4\n");
printf("enter 1, 2, 3, and 4 in that order.\n");
for (int i = 0; i < m; i++) { // Iterating through the rows and columns of the matrix
for (int j = 0; j < n; j++) {
scanf("%Lf", &matrix[i][j]); // Accepting each element
}
}
}
void print_matrix(numeric **l, int x, int y) { // To print a matrix
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
printf("%0.10Lf\t", l[i][j]); // Printing numeric type values
}
printf("\n");
}
printf("\n");
}
You are not allocating enough memory for matrix_k. You are allocating memory for m rows and l columns, but you are trying to access m rows and n columns. You need to allocate memory for m rows and n columns. You can do this by changing the line
matrix_k = create_matrix(m, l);
to
matrix_k = create_matrix(m, n);
This is the same problem you had in your other question.

Got stuck in a customizable dimensional matrix operation program

`
//MATRIX INPUT
#include<stdio.h>
int main(void)
{
//declaring variables
size_t row=0;
size_t column=0;
int limit=0;
int en=0;
int mat[row][column];
//starting
printf("ENTRE THE NUMBER OF R
EPETITIONS OF MATRIX
INPUT:");
scanf("%d",&limit);
//starting loop
for(int i=0;i<=(limit-1);++i)
{
printf("\nINITIALIZED THE
MATRIX-%d...\n",i+1);
printf("\nENTER ROW
NUMBER FOR MATRIX:\n");
scanf("%d",&row);
printf("\nENTER COLUMN
NUMBER FOR MATRIX:\n");
scanf("%d",&column);
//entering the entries..
for(int j=0; j<row ;++j)
{
for(int k=0;
k<column;++k)
{
printf("ENTRY (%d,%d):",(j+1),(k+1));
scanf("%d",&mat[k][j]);
}
}
}
//starting the console output
of matrix
int v=0;
printf("Which matrix do you
want to see?\n");
scanf("%d",&v);
for(v=0; v<=limit; ++v)
{
for(int l=0; l<row; ++l)
{
for( int m=0; m<column;
++m)
{
printf("%2d", mat[m][l]);
}
}
}
return 0;
}`
I have written a program in C where the user can firstly define the number of matrices. Then, the dimension of individual matrix is defined. I have successfully proceeded to individual matrix input. But I am stuck in writing the operational codes like multiplying and adding matrices as well as to write code for showing output in matrix style.
How to fix this?
incomplete source code
Console of output
I couldn't get the part why you created an empty static array, and then changed its boundaries at least tried to change. However, I believe dynamic array allocation would serve your purpose better than static one. I implemented a 3D array that has the first index as matrices, the second index as rows of the current matrix, and the third index as columns of the current matrix. Also, fixed the display method, you have been using. However, there can be different-sized matrices for each matrix you have. Therefore, I implemented another list to keep track of the rows and columns. Lastly, I put two links at the top of the code that you can implement addition and multiplication operations by yourself. You can see the code from here:
//MATRIX INPUT
#include<stdio.h>
#include<stdlib.h>
//Add two matrices
//https://www.programmingsimplified.com/c-program-add-matrices
//Multiplying two matrices
//https://www.programiz.com/c-programming/examples/matrix-multiplication
void display_matrix(int** , int , int );
void fillWithNum(int**,int,int,int);
int main(void)
{
//declaring variables
size_t row=0;
size_t column=0;
int limit=0;
int en=0;
int ***mat;
//starting
printf("ENTRE THE NUMBER OF REPETITIONS OF MATRIX INPUT:");
scanf("%d",&limit);
mat = (int***)malloc(sizeof(int**) * limit);
//Two keep track of the rows and columns
//First index of the second dimension will be rows, and
//second index will be columns of matrices at the mat variable.
int **indexingList;
indexingList = (int**)malloc(sizeof(int*) * limit);
for(int i=0;i<limit;++i) {
indexingList = (int*) malloc(sizeof(int) * 2);
}
//starting loop
for(int i=0;i<limit;i++)
{
printf("\nINITIALIZED THE MATRIX-%d...\n",i+1);
printf("\nENTER ROW NUMBER FOR MATRIX:\n");
scanf("%d",&row);
printf("\nENTER COLUMN NUMBER FOR MATRIX:\n");
scanf("%d",&column);
mat[i] = (int**) malloc(row * sizeof(int*));
for (int j = 0;j < row;j++) {
mat[i][j] = (int*)malloc(column * sizeof(int));
}
//entering the entries..
for(int j=0;j < row;j++)
{
for(int k=0;k < column;k++)
{
printf("ENTRY (%d,%d):",(j+1),(k+1));
scanf("%d",&mat[i][j][k]);
}
}
indexingList[i][0] = row;
indexingList[i][1] = column;
}
//starting the console output of matrix
int v=1;
printf("Which matrix do you want to see?\n");
scanf("%d",&v);
//v-1 because if user want to display first matrix it should be 0, so user will enter 1
//therefore, 1-1 will give us 0 to display 0 index matrix
display_matrix(mat[v-1], indexingList[v-1][0], indexingList[v-1][1]);
//Problem at freeing memory for some purpose crash at here.
//I couldn't figure it out as well.
for(int i = 0;i < limit;i++) {
for(int j = 0;j < indexingList[i][0];j++) {
free(mat[i][j]);
}
free(mat[i]);
}
free(mat);
for(int i = 0;i < limit;i++) {
free(indexingList[i]);
}
free(indexingList);
return 0;
}
void display_matrix(int** matrix, int r, int c) {
for(int i = 0 ;i < r;i++){
for(int j = 0;j < c;j++) {
printf("%d\t",matrix[i][j]);
}
printf("\n");
}
}
//Test purpose
void fillWithNum(int** arr,int r, int c, int num) {
for (int i = 0;i<r;i++) {
for(int j = 0;j<c;j++) {
arr[i][j] = num;
}
}
}
However, this code also crashes at the end of the memory-freeing part. I couldn't figure out why, but if someone finds it out as well, I would appreciate it.

2D Array elements changing after they are set

The program below is meant to print a square grid of integers based on the dimension which is inputted by the user (as part of the harvard cs50 course on edx).
The array is being initialized correctly, but when it comes to printing it out, the last column always prints incorrectly. I tried debugging by putting 2 printf statements in the innermost for loop of the init() function.
It seems that after the outermost loop runs once, the entry in the last column gets decremented by one, although it was correct just before this.
Why is this happening? Shouldn't it print correctly?
#include <stdio.h>
main()
{
void init(int dim, int arr[dim-1][dim-1]);
int dim;
printf("Enter board dimension(max 10): ");
scanf("%d", &dim);
int arr[dim-1][dim-1];
init(dim, arr);
int i,j;
for(i=0;i<dim;i++)
{
for(j=0;j<dim;j++)
{
printf("%2d ",arr[i][j]);
}
printf("\n");
}
}
void init(int dim, int arr[dim-1][dim-1])
{
int i,j,p;
for(i=0;i<dim;i++)
{
for(j=0;j<dim;j++)
{
arr[i][j] = (dim*dim-1)-i*dim-j;
}
for(p=0;p<dim;p++)
{
printf("%d ", arr[i][p]);
if(i>=1)
printf("%d ", arr[i-1][p]);
}
}
printf("\n");
if(dim%2==0)
{
arr[dim-1][dim-3] = 1;
arr[dim-1][dim-2] = 2;
}
}
EDIT: it should compile now
You define your array with a[dim - 1][dim - 1], which is one short of the desired dimension. If the user enters "4", you create a 3×3 array.
Your array is two-dimensional and of variable length. Therefore, you must pass the dimension alongside the array in functions, at least for the last dimension. You do this correctly, but the code in ´initbehaves as if the array werea[dim][dim], when it's actuallya[dim - 1][dim - 1]`.
Define the array with the actual dimension, dim and access the elements with indices 0 through dim - 1. This is usually done in a loop like this:
for (int i = 0; i < dim; i++) ...
Seeing >= or dim - 1 something similar should make you wary.
Your program now looks like this:
#include <stdio.h>
void init(int dim, int arr[dim-1][dim-1]);
void print(int dim, int arr[dim-1][dim-1]);
int main(void)
{
int dim;
printf("Enter board dimension: ");
scanf("%d", &dim);
int arr[dim][dim];
init(dim, arr);
print(dim, arr);
return 0;
}
void print(int dim, int arr[dim][dim])
{
int i,j;
for(i = 0; i < dim; i++) {
for(j = 0; j < dim; j++) {
printf("%2d ", arr[i][j]);
}
printf("\n");
}
}
void init(int dim, int arr[dim][dim])
{
int i, j;
for(i = 0; i < dim; i++) {
for(j = 0; j < dim; j++) {
int ii = dim - 1 - i;
int jj = dim - 1 - j;
arr[i][j] = ii*dim + jj;
}
}
}

Cannot loop over all the matrix elements

I am trying to create a data structure to store a matrix and write a routine to generate a square matrix of random numbers.
Here is my code. I am strangely getting only 2 float numbers as output. I am doing all this to implement strassen matrix multiplication, which is why I added rs, re, cs, ce to struct.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _matrix {
int rs;
int re;
int cs;
int ce;
float a[100][100];
}matrix;
void display(matrix m)
{
int i, j;
for (i=m.rs ; i<=m.re ; i++) {
for (j=m.cs ; j<=m.ce ; j++)
printf("%f", m.a[i][j]);
printf("\n");
}
printf("\n");
return;
}
matrix random_matrix(int n)
{
matrix random;
random.cs = random.rs = 0;
random.rs = random.re = n -1;
int i, j;
for(i=0; i < n; i++){
for(j = 0; j < n; j++)
random.a[i][j] = rand();
}
return random;
}
int main(void)
{
matrix m1 = random_matrix(3);
matrix m2 = random_matrix(3);
display(m1);
display(m2);
return 0;
}
I think, to fit the logic, in your code, in random_matrix() function,
random.rs = random.re = n -1;
should be
random.ce = random.re = n -1;
Otherwise, in display(), for (i=m.rs ; i<=m.re ; i++) does not make sense.
That said, to see the random number generator, you can call srand(time(NULL)); in main(), before the call to the matrix generation functions.

Creating a matrix in a structure

I am trying to create a structure that will have two integer values, an array, and two 2-D matrices using my code below. I can initialize the structure with the integers and array just fine, and my 'Gen' function will create the random values I want for the array.
However, when I try adding in the matrix components, I run into a problem. My compiler gives me a warning: "initialization from incompatible pointer type". If I understand what I have read so far, this is because the structure needs to be pointed to an array of pointers that represent each row in the matrix. I don't know the syntax for that.
A quick note: the other topics I've seen that are related to this issue all initialize the structure in a function other than the main() function, so I haven't found those solutions helpful.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <string.h>
// Define structure
typedef struct {
int row;
int col;
int *arr;
int **mat1;
int **mat2;
}container;
// Function headers
void Gen(container Thing);
int main() {
int row = 5;
int col = 6;
int A[row];
int M1[row][col];
int M2[row][col+1];
// Initialize structure
container Object = {row, col, A, M1, M2};
// Run "Gen" function
Gen(Object);
int i, j; // Index variables
// Display the array
for(i = 0; i < row; i++)
{
printf("%i ", Object.arr[i]);
}
printf("\n\n");
// Display the numbers from the matrices
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat1[j][i]);
}
printf("\n");
}
printf("\n");
for(j = 0; j < Object.row; j++)
{
for(i = 0; i < Object.col; i++)
{
printf("%i ", Object.mat2[j][i]);
}
printf("\n");
}
return (EXIT_SUCCESS);
}
// Function to generate random values in the array & matrices
void Gen(container Thing)
{
int i, j;
srand(time(NULL));
// Generate random values for the array
for(i = 0; i < Thing.row; i++)
{
Thing.arr[i] = rand() % 5;
}
// Generate random values for the matrix
for(j = 0; j < Thing.row; j++)
{
for(i = 0; i < Thing.col; i++)
{
Thing.mat1[j][i] = rand() % 5;
Thing.mat2[j][i] = rand() % 5;
}
}
} // End of "Gen" function
container Object = {row, col, A, M1, M2};
is wrong since the type of M1 is int[row][col], which can decay to int (*)[col] but not to int**. You have the same problem with M2.
You'll need to rethink your strategy for generating a container.
For example:
int main() {
int row = 5;
int col = 6;
int A[row];
int* M1[row];
int* M2[row];
for ( int i = 0; i < row; ++i )
{
M1[i] = malloc(sizeof(M1[i][0])*col);
M2[i] = malloc(sizeof(M1[i][0])*(col+1));
}
// Initialize structure
container Object = {row, col, A, M1, M2};
...
for ( int i = 0; i < row; ++i )
{
free(M1[i]);
free(M2[i]);
}
return (EXIT_SUCCESS);
}

Resources