2017-10-25 37 views
-2

のための動的メモリ割り当ては、現在、私は、行列の値を返すために、二つの行列、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 

R esultマトリックス:

716559 
194430 
323391 

私のコードは、私はサイズが動的に割り当てられていないので、これは知っている1000の大きさ以上の行列を除いて、テストケースのために適切な値を返しますが、私はわからないものを最高私のコードでこれを行うためのアプローチは次のようになります。私は、各行列にmalloc関数を使用する場合は、何らかの理由で、私は私のガウス・ジョーダンの減少を拡大行列を作成したり実行できるようにされていないことが表示されます

#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; 
} 

ました私の最終的な答えを台無しにしています。

+0

Ugh!あなたは機能について聞いたことがありませんか?あなたはそれらを使用する必要があります。 –

+0

とにかく、あなたは 'malloc()'でメモリを割り当てます。何が問題なの?何を試しましたか? –

+0

@JonathanLeffler私は、それぞれのマトリックスに対して、[i] =(double *)malloc(sizeof(double)* row)のforループを使用しようとしましたが、これは私のコードを壊し、より多くのセグメンテーションフォールトを引き起こしました –

答えて

1

多次元配列にメモリを割り当てるための最良のアプローチ(あなたがあなたのプログラムの中でマトリックスを使用していることから、2次元配列の例を取る):

int(*matrix)[col] = malloc (sizeof(int[row][col])); 

あなたはそれのための機能を書きたい場合:あなたは、多次元配列にメモリを動的に割り当てるこの方法に精通していない場合

void* allocMatrix (int row, int col) 
{ 
    return malloc (sizeof(int[row][col])); 
} 

は、次に(非常にうまくランディンによって説明)thisを読み取ります。あなたのプログラムで

、あなたはタイプdoubleのマトリックスを有するされているので、allocMatrix()になります -

void* allocMatrix (int row, int col) 
{ 
    return malloc (sizeof(double[row][col])); 
} 

main()に、あなたが動的に行列を作成するには、次の変更を加える必要がある -

double (*trainX)[col] = allocMatrix (row, col); 

他の行列に対しても同じ変更を行い、プログラム内の適切な場所に行列に動的に割り当てられたメモリをfree()にしてください。

知識目的のために、this多次元配列にメモリを割り当てる習慣は、それが最善ではないが一般的に従いました。

+0

私は、初期化によってキャストなしの整数からポインタを作成し、allocMatrixと以前の暗黙の宣言の型が競合していることを伝えています。trainXとtrainYをコメントアウトしてint(* trainX)を配置すると[col] = allocMatrix(row 、col);コメント付きの行列の下に列車の対応するものと一緒に –

+0

@JoeCurあなたのプログラムで 'trainX'を変更しようとしましたが、警告メッセージが表示されません。あなたのプログラム、 'trainX'はtyですpe 'double'ですが、あなたのコメントであなたは' int(* trainX)[col] ... 'を配置していると言いました。 'int'を' double'に変更してください。 –

+0

@JoeCur:これはうまくいくはずです。しかし、最小限のデータセットを持たないため、誰でもあなたのコードをテストすることは難しく、レイアウトは気になるところです。 –