C、使用动态内存分配的矩阵转置乘法
C, matrix transposed multiplication using dynamic memory allocation
我正在尝试转置和乘以一些矩阵,基本上
我得到 2 个矩阵,matrixA
和 matrixB
要执行的操作是 trace(transpose(matrixA)*matrixB)
.
我设法让它适用于 nxn
矩阵,但我无法让它适用于 mxn
where (n>m
or m>n
).
我在网上寻找解决方案,但我无法将他们的解决方案应用到我的解决方案中。
我删除了几乎所有代码以简化阅读,如果您更喜欢整个代码I linked it here.
如果您确实想要 运行 整个代码,请使用以下命令重现问题:
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
上面的命令应该 return Sum 56
但我得到的是 Sum 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);
您用于计算转置、乘法和迹的数组索引似乎不正确。我已在以下程序中更正它们:
#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
我正在尝试转置和乘以一些矩阵,基本上
我得到 2 个矩阵,matrixA
和 matrixB
要执行的操作是 trace(transpose(matrixA)*matrixB)
.
我设法让它适用于 nxn
矩阵,但我无法让它适用于 mxn
where (n>m
or m>n
).
我在网上寻找解决方案,但我无法将他们的解决方案应用到我的解决方案中。
我删除了几乎所有代码以简化阅读,如果您更喜欢整个代码I linked it here.
如果您确实想要 运行 整个代码,请使用以下命令重现问题:
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
上面的命令应该 return Sum 56
但我得到的是 Sum 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);
您用于计算转置、乘法和迹的数组索引似乎不正确。我已在以下程序中更正它们:
#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