2011-12-15 55 views
0

我想正常化粒子列表中的权重。这些权重属于粒子对象。我试图通过将它们除以权重的总和来使它们正常化。所有的重量都在双打中声明。当程序在列表开始时开始分割时,该值是正确的,但在第二次或第三次分割后不久,我得到了错误的结果..其结果是操作后的权重之和不是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 2011-12-15 02:32:58

回答

0

首先,什么是temporalparticleSet?你真的想要循环而不是this.particleSet吗?除此之外,我根本没有看到任何代码问题。我想修改:

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

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

而且是p.Weight双?可能是一些舍入问题。你有没有尝试过使用断点并逐步完成它?

+0

是的,我有正常的本地声明,但我认为可能与问题有关,这就是为什么我在Program类中做了一些静态变量。 – 2011-12-15 02:46:30

0

我会担心Program.Weight修改它被分配的值或者不是相同的数据类型。

我会尝试改变下列行:

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

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

还有一些舍入误差考虑。

0

积累大量的数字可能会失去精度。这里有两个技巧可以帮助:

  1. 总和增加重量的顺序,首先是 最轻和程序,以最重的权重。如果数字可以是负数,则按照数量级递增的顺序进行求和。使用Kahan summation algorithm来累加权重。这比(1)更容易,因为不需要先对数组进行排序。
  2. 使用上述两者,如果总和与最小权重的比例很大,如10^16。