2012-02-27 15 views
1

以下のコードは、共分散行列を使用して相関行列を計算しています。私はこれをより良く書くにはどうすればいいですか?問題は、コードのこのセクションは、その寸法は約100×100相関行列の計算を最適化する

// Copy upper triangle of covariance matrix to correlation matrix 
for(i = 0; i < rows; i++){ 
    for(j = i; j < rows; j++){ 
    corrmatrix.array[i * rows + j] = covmatrix.array[i * rows + j]; 
    } 
} 

// Calculate upper triangle of corr matrix 
for(i = 0; i < rows; i++){ 

    root = sqrt(covmatrix.array[(i * rows) + i]);  

    for(j = 0; j <= i; j++){ // Move down 
    corrmatrix.array[ j * rows + i ] /= root; 
    } 

    k = i * rows; 

    for(j = i; j < rows; j++){ // Move across 
    corrmatrix.array[ k + j ] /= root; 
    } 

} 

// Copy upper triangle to lower triangle 
for(i = 0; i < rows; i++){ 
    k = i * rows; 
    for(j = i; j < rows; j++){ 
    corrmatrix.array[ (j * rows) + i ] = corrmatrix.array[ k + j ]; 
    } 
} 

ある行列に倍の1000を実行しますです、私は、行と列が等しいなどであることをチェックしてきたので、私はちょうどどこでも行を使用しています。私は速度を大幅に向上させたい。

PS:

  1. 行列が行優先に格納されている、私は今のパックされたストレージを使用していない
  2. 密な形式。

は私に飛び出し最初の事はあなたの内側のループ内で同じ数で割り算をやっているということであるあなた

答えて

1

ありがとうございます。

しないでください。分裂が遅いです。あなたの代わりに何をすべき

ではなく、繰り返し、それで割るのrootの逆数を掛けることです:

inv_root = 1./sqrt(covmatrix.array[(i * rows) + i]); 

for(j = 0; j <= i; j++){ // Move down 
    corrmatrix.array[ j * rows + i ] *= inv_root; 
} 

k = i * rows; 

for(j = i; j < rows; j++){ // Move across 
    corrmatrix.array[ k + j ] *= inv_root; 
} 

この最適化は、コンパイラに明らかに思えるかもしれないが、この最適化を行うことを許可されない場合があります浮動小数点の厳密さのために。 -ffast-math(GCC内)などの浮動小数点設定を緩和することができます。

+0

ありがとう、私はその変更を追加します。私はそれ以上の最適化ができますか? – mod0

+0

これは簡単ではありません。コンパイラによっては、それをベクトル化することもできます。それ以外のコードは、おそらくあなたが行う膨大なメモリアクセス数によって制限されるでしょう。これを修正する唯一の方法は、アルゴリズムを再構成することです。これは容易ではないかもしれません。 – Mysticial

+0

ありがとうございました。 – mod0

関連する問題