2011-12-15 8 views
0

私は粒子のリストの加重を正規化したいと思います。これらの重みはパーティクルオブジェクトに属します。私はそれらを体重の合計で割って正規化しようとします。すべてのウェイトは倍精度で宣言されます。プログラムがリストの先頭で分割を開始するとき、値は正しいですが、2番目または3番目の除算の直後に、私は間違った結果を得ます。これは、演算後の重みの合計が1ではない結果をもたらします。すべきだ。誰もこの問題で私を助けることができますか?多分スレッドと関係がありますか? Thxは事前に..確率計算のための二重値の正規化

// normalizing weights 
double weightsum = 0; 
double check = 0; 
List<ParticleRobot> temporalparticleSet = new List<ParticleRobot>(); 

for (int i = 0; i < particleSet.Count; i++) 
{ 
    weightsum = weightsum + this.particleSet[i].Weight; 
} 

Program.Weightsum = weightsum; 

Console.WriteLine("Sum of unnormalized particleweights is " + weightsum); 

foreach (ParticleRobot p in this.particleSet) 
{ 
    Program.Weight = p.Weight; 
    p.Weight = Program.Weight/Program.Weightsum; 
    Console.WriteLine("Updated Particleweight is now : " + p.Weight); 
} 

// checking that they sum up to 1 
for (int i = 0; i < particleSet.Count; i++) 
{ 
    check = check + this.particleSet[i].Weight; 
} 

Console.WriteLine("Check: Sum of particles-weights is = " + check); 
+0

なぜあなたの地元の人を保存するためにプログラムタイプが必要ですか? Program.Weight = p.Weightは、並列処理が導入されたときに痛みの世界につながる可能性があります。 – Polity

答えて

0

まず、時間的パーティクルセットとは何ですか?実際にthis.particleSetの代わりにそれをループすることを意味しますか?それ以外には、コードに関する問題は一切ありません。私が変更になります。

Program.Weight = p.Weight; 
p.Weight = Program.Weight/Program.Weightsum; 

またp.Weightがダブルで

p.Weight = p.Weight/Program.Weight; 

に?丸めの問題があるかもしれません。ブレークポイントを使用して試してみましたか?

+0

はい、普通の地元の人が宣言しましたが、おそらく問題に関連していると思っていました。 –

0

私はProgram.Weightが割り当てられた値を変更するか、同じデータ型ではないことに懸念します。

 Program.Weight = p.Weight; 
     p.Weight = Program.Weight/Program.Weightsum; 

 p.Weight = p.Weight/Program.Weightsum; 

にも考慮すべき丸め誤差れあり:

私は、次の行を変更しようとするだろう。

0

多数の数値が累積すると精度が低下する可能性があります。

  1. 和、重みの昇順最軽量 から始めて、最も重いに進んで重み:ここに助けることができる2つの技術があります。数値が負数である場合、大きさの順に合計します。
  2. Kahan summation algorithmを使用して重みを累積します。配列を最初にソートする必要がないので、(1)より簡単です。
  3. 合計の最小重みに対する比率が10^16のように大きい場合は、上記の両方を使用します。