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?
CodePudding user response:
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");
}
CodePudding user response:
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.