Нормализация двойных значений для исчисления вероятностей - PullRequest
0 голосов
/ 15 декабря 2011

Я хочу нормализовать вес в списке частиц.Эти веса принадлежат частицам-объектам.Я пытаюсь нормализовать их, разделив их на сумму весов.Все веса объявлены в двойных.Когда программа начинает деление в начале списка, значение является правильным, но вскоре после второго или третьего деления я получаю неправильные результаты ... что приводит к тому, что сумма весов после операции не равна 1, чтодолжно быть.Может кто-нибудь помочь мне с этой проблемой?Может быть, что-то делать с потоками?Спасибо заранее ..

// 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);

Ответы [ 4 ]

0 голосов
/ 17 декабря 2011

Накопление большого набора чисел может потерять точность. Вот две техники, которые могут помочь:

  1. Суммируйте веса в порядке возрастания веса, начиная с самый легкий и переходящий к самому тяжелому. Если числа могут быть отрицательными, сумма в порядке возрастания величины.
  2. Используйте алгоритм суммирования Кахана для накопления весов. Это проще, чем (1), потому что нет необходимости сначала сортировать массив.
  3. Используйте оба вышеперечисленных, если отношение суммы к наименьшему весу огромно, например 10 ^ 16.
0 голосов
/ 15 декабря 2011

Прежде всего, что такое temporalparticleSet?Вы действительно хотите проходить через это вместо this.particleSet?Кроме этого я не вижу никаких проблем с кодом вообще.Я бы изменил:

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

на

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

Также р.Вайт двойной?Может быть какая-то проблема округления.Вы пытались использовать точку останова и проходить через нее?

0 голосов
/ 15 декабря 2011

Меня беспокоит, что Program.Weight изменяет присвоенное ему значение или не совпадает с типом данных.

Я бы попробовал изменить следующие строки:

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

до

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

Существуют также ошибки округления.

0 голосов
/ 15 декабря 2011

Вероятно, не проблема с многопоточностью. Читайте математику с плавающей запятой в любой книге по численному анализу. Проверьте http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html. Ошибки округления, проблемы точности, проблемы отмены - все это может помочь.

...