C, матричное транспонированное умножение с использованием динамического выделения памяти - PullRequest
0 голосов
/ 12 мая 2018

Я пытаюсь транспонировать и умножать некоторые матрицы, в основном Я получаю 2 матрицы matrixA и matrixB, которые нужно выполнить: trace(transpose(matrixA)*matrixB).

Мне удалось заставить это работать для nxn матриц, но я не могу заставить его работать с mxn где (n>m или m>n).

Я искал в Интернете решения, но не могу внедрить их решение в мое.

Я удалил почти весь код, чтобы упростить чтение, если вы предпочитаете весь код Я связал его здесь.

Если вы хотите запустить весь код, чтобы воссоздать проблему, используйте следующие команды:

zeroes matrixA 2 3
zeroes matrixB 2 3
set matrixA
1 2 3 4 5 6
set matrixB
6 5 4 3 2 1
frob matrixA matrixB

Приведенные выше команды должны возвращать сумму 56, но вместо этого я получаю сумму 18

int* matrixATransposed = (int*) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
for (int i = 0; i < matrixARowLenght; i++)
{
    for (int j = 0; j < matrixAColLenght; j++)
    {
        *(matrixATransposed + i * matrixAColLenght + j) = *(matrixA + j * matrixAColLenght + i);
    }
}
// Multiply
int* mulRes = (int*)malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
for (int i = 0; i < matrixAColLenght; i++) {
    for (int j = 0; j < matrixBColLenght; j++) {
        *(mulRes + i * matrixARowLenght + j) = 0;
        for (int k = 0; k < matrixARowLenght; k++)
            *(mulRes + i * matrixAColLenght + j) += *(matrixATransposed + i * matrixAColLenght + k) * *(matrixB + k * matrixBColLenght + j);
    }
}
// Sum the trace
int trace = 0;
for (int i = 0; i < matrixARowLenght; i++) {
    for (int j = 0; j < matrixAColLenght; j++) {
        if (i == j) {
            trace += *(mulRes + i * matrixAColLenght + j);
        }
    }
}
printf_s("Sum: %d\n", trace);

1 Ответ

0 голосов
/ 12 мая 2018

Ваши индексы массива для вычисления транспонирования, умножения и трассировки кажутся неверными. Я исправил их в следующей программе:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int matrixARowLenght = 2;
    int matrixAColLenght = 3;
    int matrixA[] = {1,2,3,4,5,6};

    int matrixBRowLenght = 2;
    int matrixBColLenght = 3; 
    int matrixB[] = {6,5,4,3,2,1};

    // Transpose
    int* matrixATransposed = (int *) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
    for (int i = 0; i < matrixAColLenght; i++) {
        for (int j = 0; j < matrixARowLenght; j++) {
            *(matrixATransposed + i * matrixARowLenght + j) = *(matrixA + j * matrixAColLenght + i);
        }
    }

    // Multiply
    int *mulRes = (int *) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
    for (int i = 0; i < matrixAColLenght; ++i) {
        for (int j = 0; j < matrixAColLenght; ++j) {
            *(mulRes + (i * matrixAColLenght) + j) = 0;
            for (int k = 0; k < matrixARowLenght; ++k) {
                *(mulRes + (i * matrixAColLenght) + j) += *(matrixATransposed + (i * matrixARowLenght) + k) * *(matrixB + (k * matrixAColLenght) + j);
            } 
        }
    }
    free(matrixATransposed);

    // Sum the trace
    int trace = 0;
    for (int i = 0; i < matrixAColLenght; i++) {
        for (int j = 0; j < matrixAColLenght; j++) {
            if (i == j) {
                trace += *(mulRes + i * matrixAColLenght + j);
            }
        }
    }
    printf("Sum: %d\n", trace);
    free(mulRes);

    return 0;
}

Приведенная выше программа выведет ожидаемое значение:

Sum: 56


** ОБНОВЛЕНИЕ **
Как указывает MFisherKDX, приведенный выше код не будет работать, если матрица результата не является квадратной матрицей. Следующий код исправляет эту проблему:
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int matrixARowLenght = 2;
    int matrixAColLenght = 3;
    int matrixA[] = {1,2,3,4,5,6};

    int matrixBRowLenght = 2;
    int matrixBColLenght = 4; 
    int matrixB[] = {8,7,6,5,4,3,2,1};

    // Transpose
    int* matrixATransposed = (int *) malloc(matrixARowLenght * matrixAColLenght * sizeof(int));
    for (int i = 0; i < matrixAColLenght; i++) {
        for (int j = 0; j < matrixARowLenght; j++) {
            *(matrixATransposed + i * matrixARowLenght + j) = *(matrixA + j * matrixAColLenght + i);
        }
    }

    // Multiply
    int *mulRes = (int *) malloc(matrixAColLenght * matrixBColLenght * sizeof(int));
    for (int i = 0; i < matrixAColLenght; ++i) {
        for (int j = 0; j < matrixBColLenght; ++j) {
            *(mulRes + (i * matrixBColLenght) + j) = 0;
            for (int k = 0; k < matrixARowLenght; ++k) {
                *(mulRes + (i * matrixBColLenght) + j) += *(matrixATransposed + (i * matrixARowLenght) + k) * *(matrixB + (k * matrixBColLenght) + j);
            } 
        }
    }
    free(matrixATransposed);

    // Sum the trace
    int trace = 0;
    for (int i = 0; i < matrixAColLenght; i++) {
        for (int j = 0; j < matrixBColLenght; j++) {
            if (i == j) {
                trace += *(mulRes + i * matrixBColLenght + j);
            }
        }
    }
    printf("Sum: %d\n", trace);
    free(mulRes);

    return 0;
}

Этот код выведет следующее, как и ожидалось:

Sum: 83
...