Нормализация двойных значений для исчисления вероятностей

Я хочу нормализовать вес в списке частиц. Эти веса принадлежат частицам-объектам. Я пытаюсь нормализовать их, разделив их на сумму весов. Все веса объявлены в двойных. Когда программа начинает деление в начале списка, значение является правильным, но вскоре после второго или третьего деления я получаю неправильные результаты... что приводит к тому, что сумма весов после операции не равна 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 ответа

Решение

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

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

в

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

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

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

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

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

в

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

Есть также ошибки округления, которые нужно учитывать.

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

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

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