简体   繁体   中英

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?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM