'How can I perform Matrix Multiplication without restricting the dimensions of the matrices read from a text file in C programming
I want to multiply matrices but without restricting the dimensions of the matrix A and B that are actually read from different textfiles MatAsmall.txt MatBsmall.txt MatAlarge.txt MatBlarge.txt. There are small matrices and even huge matrices in different text files. I want to create 1 program to read a file of any dimension and then store the dimensions in a variable which will help further with the matrix multiplication,multithreading and dynamic memory allocation. All of the matrices used are 2d. How can I do that?
Solution 1:[1]
Provided that your files look something like:
5 5
-9 8 -8 -3 10
8 -10 10 -8 -4
-2 -8 8 10 8
4 3 5 -7 -7
-5 4 -3 7 3
where 5 and 5 are the dimensions of later defined matrix, you could use such function to read them:
struct matrix_t {
int **ptr;
int width;
int height;
};
struct matrix_t* matrix_create_struct(int width, int height) {
struct matrix_t *matrix = (struct matrix_t *) malloc(sizeof(struct matrix_t));
matrix->ptr = (int **) malloc(height * sizeof(int *));
for (int i = 0; i < height; i++) {
*(matrix->ptr + i) = (int *) malloc(width * sizeof(int));
}
matrix->width = width;
matrix->height = height;
return matrix;
}
struct matrix_t *matrix_load_from_file(const char *filename) {
FILE* fptr = fopen(filename, "rt");
int width, height;
fscanf(fptr, "%d", &width);
fscanf(fptr, "%d", &height);
struct matrix_t *matrix = matrix_create_struct(width, height);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
fscanf(fptr, "%d", (*(matrix->ptr + i) + j));
}
}
fclose(fptr);
return matrix;
}
Here I am using dynamic allocation, since, as you said, we don't know what the dimensions of matrix will be.
And such in order to multiply them:
struct matrix_t* matrix_multiply(const struct matrix_t *m1, const struct matrix_t *m2) {
if (m1->width != m2->height)
return NULL;
struct matrix_t *new_matrix = matrix_create_struct(m2->width, m1->height);
for (int i = 0; i < m1->height; i++) {
for (int j = 0; j < m2->width; j++) {
int res = 0;
for (int k = 0, l = 0; k < m1->width && l < m2->height; k++, l++)
res += *(*(m1->ptr + i) + k) * *(*(m2->ptr + l) + j);
*(*(new_matrix->ptr + i) + j) = res;
}
}
return new_matrix;
}
Here I am using math I looked up here: https://www.mathsisfun.com/algebra/matrix-multiplying.html. I am returning NULL if the following isn't true:
The number of columns of the 1st matrix must equal the number of rows of the 2nd matrix.
Please, note how optimistic I am... Each and every fopen and malloc should be checked if it didn't return NULL, also be careful with fscanfs if you don't have trust for files creators.
I used such code to test my code:
void display_matrix(const struct matrix_t * matrix) {
for (int i = 0; i < matrix->height; i++) {
for (int j = 0; j < matrix->width; j++) {
printf("%d ", *(*(matrix->ptr + i) + j));
}
printf("\n");
}
}
int main() {
struct matrix_t * m1 = matrix_load_from_file("test.txt");
struct matrix_t * m2 = matrix_load_from_file("test.txt");
struct matrix_t * m3 = matrix_multiply(m1, m2);
display_matrix(m3);
return 0;
}
and checked the results here: https://matrixcalc.org/. Everything seems to be working fine, but feel free to ask in case of questions or doubts.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
