2011-06-30 16 views
0

ベクトル(サイズnmask + 3の)を作成して0に初期化し、要素の1つに初期値を割り当てます。次に、ベクトルの最初のnmask要素を通過するforループを作成し、ベクトル内の平均26個の他の要素(ベクトルアドレスを含む4D int配列voxtで定義)を各要素に割り当てます。入れ子のforループでC++ベクトルが更新されない

私の問題は、ネストされたループ(最初のcout)内のベクトル(phi)の非ゼロ要素の値をチェックすると、値が正常であり、期待していることです。しかし、ループがすべてのnmask要素(for (int i= 0; i<nmask; i++)終了)を通過すると、phiの非ゼロ要素を再度チェックし、最後の非ゼロ要素(および要素tvoxを手動で除いてすべて0にリセットされます) 1に設定)。

phiはすべてのループの外側で初期化されているので、値のリセットは行われず、ネストされたループ内の更新された要素はループの終了時に更新されたままになるはずです。何が起こっているか、どのようにこれを修正するための任意のアイデア?コードは以下のとおりです。私は、私が得ているアウトプットの感覚でコメントしようとしました。前もって感謝します。

vector<double> phi(nmask+3, 0); //vector with nmask+3 elements all set to 0 (nmask = 13622) 
    phi[tvox]= 1; //tvox is predefined address (7666) 

    for (int n= 0; n<1; n++) 
    { 
     vector<double> tempPhi(phi); //copy phi to tempPhi 

     for (int i= 0; i<nmask; i++) 
     { 
      for (int a= -1; a<=1; a++) 
      { 
       for (int b= -1; b<=1; b++) 
       { 
        for (int c= -1; c<=1; c++) 
        { 
         if (!(a==0 && b==0 && c==0)) 
         { 
          //oneD26 is just (double) 1/26 
          phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]]; 
          if (phi[i]!=0) 
          { 
           //this gives expected results: 27 nonzero elements (including tvox) 
           cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl; 
          } 
         } 
        } 
       } 
      } 
     } 

     phi[svox]= 0; //svox = 7681 
     phi[tvox]= 1; 

     for (int q= 0; q<nmask; q++) 
     { 
      //this gives only 2 nonzero values: phi[tvox] and phi[9642], which was the last nonzero value from 1st cout 
      if (phi[q]!=0) 
       cout << q << " " << phi[q] << endl; 
     } 

    } 
+2

....すごく面白いクリスマスツリーです。 – sehe

+1

muximam cyclomatic complexity。 – slaphappy

+3

それを忘れて、深く入れ子になっていないようにコードを書き換えてください。 –

答えて

1

あなたには、いくつかのトレースを行うと、ちょうどあなたが頻繁にゼロと非ゼロ要素を上書きしていることがわかります更新する前phi[i]を確認してください。

注:私はあなたのコードが何をしているのか分かりませんが、これは純粋なSherlock Holmesの推論です..もしループの後で2つの非ゼロ要素しか見つからなければ、唯一の論理的な結果は、ループではゼロに更新します。

+0

ええ、ありがとう – Marvin

2

何が起きているのか分かりにくいですが、最も簡単な説明は、phi [i]が0以外の値に設定され、coutに表示された後、後の繰り返しの1つで、ループ。

+0

ええ、私はようやくそれを参照してください。ありがとうございました – Marvin

1
phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]]; 

a、b、およびcを使用してネストされたforループは、同じ値iの9回の繰り返しに対して使用されます。毎回新しい値にphi [i]を上書きするので、最後の反復の値を保持します。ここで、aとcはすべて1です。最後の反復でゼロ値が生成された場合、phi [i]はロットゼロのおそらく、あなたはphi [i] = ...の代わりにphi [i] + = ...のようなことをするつもりでしたか?

+0

はい、ありがとうございます! – Marvin

0

私はもちろん

const boost::irange domain(-1,2); 
for (int i: boost::irange(0, nmask)) for (int a: domain) for (int b: domain) for (int c: domain) 
{ 
    if (a==0 && b==0 && c==0) 
     continue; 
    //oneD26 is just (double) 1/26 
    phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]]; 
    if (phi[i]!=0) 
    { 
     //this gives expected results: 27 nonzero elements (including tvox) 
     cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl; 
    } 
} 

ようなもので、ループの肉を交換することをお勧めします、簡潔にするために私はboost/range.hppとC++ 0xのコンパイラの両方を想定しています。しかし、些細なマクロでも同じことを達成することができます。それは書かれていない/適切なcombinationsアルゴリズム(なぜそれが標準ではありません、とにかく)を使用しています。

+0

これは、私の醜いコードよりもかなり良く見えます、ありがとう – Marvin

関連する問題