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?
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.