[英]Dynamic Memory Allocation for Matrix Multiplication
目前我正在编写一个代码,该代码使用两个矩阵 X 和 Y 计算以下方程,以返回矩阵 W 的值。
W = (XT * X)^-1 * XT * Y
输入矩阵训练:
4
10
3.000000,1.000000,1180.000000,1955.000000,221900.000000
3.000000,2.250000,2570.000000,1951.000000,538000.000000
2.000000,1.000000,770.000000,1933.000000,180000.000000
4.000000,3.000000,1960.000000,1965.000000,604000.000000
3.000000,2.000000,1680.000000,1987.000000,510000.000000
4.000000,4.500000,5420.000000,2001.000000,1230000.000000
3.000000,2.250000,1715.000000,1995.000000,257500.000000
3.000000,1.500000,1060.000000,1963.000000,291850.000000
3.000000,1.000000,1780.000000,1960.000000,229500.000000
3.000000,2.500000,1890.000000,2003.000000,323000.000000
输入矩阵测试:
3
3.000000,2.500000,3560.000000,1965.000000
2.000000,1.000000,1160.000000,1942.000000
3.000000,1.000000,1430.000000,1927.000000
结果矩阵:
716559
194430
323391
我的代码返回测试用例的正确值,但超过 1000 的矩阵除外。我知道这是因为大小不是动态分配的,但我不确定在我的代码中执行此操作的最佳方法是什么:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]){
if(argc < 3){
printf("error.");
return 0;
}
FILE *fptrain = fopen(argv[1], "r");
if(fptrain == NULL)
{
printf("error.");
return 0;
}
int row, col, i, j;
fscanf(fptrain, "%d", &col);
col = col+1;
fscanf(fptrain, "%d", &row);
char ch;
//creates the original X and Y matrix
double trainX[row][col];
double trainY[row][1];
for(i=0; i<row; i++)
{
trainX[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptrain, "%lf%c", &trainX[i][j], &ch);
}
fscanf(fptrain, "%lf%c", &trainY[i][0], &ch);
}
//creates the X transposed matrix
double trainXtrans[col][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXtrans[j][i] = trainX[i][j];
}
}
//multiplies X and X transposed
double trainXtemp[row][row];
int s;
double num=0;
for(i=0; i<col; i++)
{
for(j=0; j<col; j++)
{
for(s=0; s<row; s++)
{
num = num + trainX[s][j]*trainXtrans[i][s];
}
trainXtemp[i][j] = num;
num = 0;
}
}
//finds the identity matrix of X times X transposed
double trainXinden[col][col*2];
for(i=0; i<col; i++)
{
for(j=0; j<col; j++)
{
trainXinden[i][j] = trainXtemp[i][j];
}
for(j=col; j<col*2; j++)
{
if(j==i+col)
{
trainXinden[i][j] = 1.000000;
}
else{
trainXinden[i][j] = 0.000000;
}
}
}
//finds the inverse of X times X transposed through Gauss Jordan Elimination
int k;
double divscalar;
for(i=0; i<col; i++)
{
divscalar = trainXinden[i][i];
for(j=0; j<col*2; j++)
{
if(trainXinden[i][j] != 0)
{
trainXinden[i][j] = trainXinden[i][j]/divscalar;
}
}
for(k=0; k<col; k++)
{
if(i!=k)
{
double subscalar = trainXinden[k][i];
for(j=0; j<col*2; j++)
{
trainXinden[k][j] = trainXinden[k][j] - subscalar*trainXinden[i][j];
}
}
}
}
double trainXinverse[row][row];
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
trainXinverse[i][j] = trainXinden[i][j+col];
}
}
double trainXinvXt[col][row];
for(i=0; i<col; i++)
{
for(j=0; j<row; j++)
{
for(s=0; s<col; s++)
{
num = num + trainXinverse[i][s]*trainXtrans[s][j];
}
trainXinvXt[i][j] = num;
num = 0;
}
}
//multiples (trainXinvXt) by Y
double weight[row][1];
for(i=0; i<col; i++)
{
for(s=0; s<row; s++)
{
weight[i][0] += trainXinvXt[i][s]*trainY[s][0];
}
}
FILE *fptest = fopen(argv[2], "r");
if(fptest == NULL)
{
printf("error.");
return 0;
}
int testrows;
fscanf(fptest, "%d", &testrows);
//creates the test file matrix
double testM[testrows][col];
for(i=0; i<testrows; i++)
{
testM[i][0] = 1.000000;
for(j=1; j<col; j++)
{
fscanf(fptest, "%lf%c", &testM[i][j], &ch);
}
}
double prices[testrows][1];
for(i=0; i<testrows; i++)
{
for(s=0; s<col; s++)
{
num = num + testM[i][s]*weight[s][0];
}
prices[i][0] = num;
num = 0;
}
for(i=0; i<testrows; i++)
{
printf("%0.0lf", prices[i][0]);
printf("\n");
}
return 0;
}
当我在每个矩阵上使用 malloc 时,出于某种原因,它似乎不允许我创建增强矩阵或执行我的 gauss-jordan 约简,这破坏了我的最终答案。
将内存分配给多维数组的最佳方法(以二维数组为例,因为您在程序中使用矩阵):
int(*matrix)[col] = malloc (sizeof(int[row][col]));
如果你想为它写一个函数,那么:
void* allocMatrix (int row, int col)
{
return malloc (sizeof(int[row][col]));
}
如果您不熟悉这种将内存动态分配给多维数组的方法,请阅读本文(Lundin 很好地解释了这一点)。
在您的程序中,您使用的是double
类型的矩阵,因此allocMatrix()
将是 -
void* allocMatrix (int row, int col)
{
return malloc (sizeof(double[row][col]));
}
在main()
,您需要进行以下更改以动态创建矩阵 -
double (*trainX)[col] = allocMatrix (row, col);
也对其他矩阵进行相同的更改,并确保将动态分配的内存free()
到程序中适当位置的矩阵。
只是出于知识目的,这种将内存分配给多维数组的做法已被普遍遵循,尽管它不是最好的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.