Может ли кто-нибудь рекомендовать любые библиотеки/подпрограммы/пакеты C++, содержащие стратегии для поддержания стабильности различных операций с плавающей запятой?C++: стратегии стабильности арифметики с плавающей запятой
Пример: предположим, что вы хотите суммировать вектор/массив из миллиона long double
в единичном интервале (0,1) и чтобы каждое число было примерно того же порядка величины. Наивное суммирование for (int i=0;i<1000000;++i) sum += array[i];
ненадежно - для достаточно больших i
, sum
будет иметь значительно больший порядок, чем array[i]
, и поэтому sum += array[i]
будет эквивалентно sum += 0.00
. (Примечание: решение этого примера представляет собой двоичную стратегию суммирования.)
Имею дело с суммами и произведениями тысяч/миллионов наименьших вероятностей. Я использую библиотеку произвольной точности MPFRC++
с существенным значением 2048 бит, но те же проблемы все еще применяются.
Я в основном озабочен:
- стратегий для точного суммирования много чисел (например, выше примера).
- Когда умножение и деление потенциально нестабильны? (Если я хочу, чтобы нормализовать большой массив чисел, что должно моя постоянная нормировки быть? Наименьшее значение? Крупнейшее? Медиана?)
«Нормализовать», я имею в виду: На шаге X у меня есть набор миниатюрных, но ненулевых вероятности. На шаге X + 1 я умножу эти числа на еще более мелкие вероятности. Согласно деталям моей математической модели, я могу умножить числа на шаге X на любую константу (т.е. нормализовать) до перехода на шаг X + 1. Это имеет практическое преимущество, помогая избежать недоиспользования. – cmo
@CycoMatto: тогда вы должны умножаться на мощность два раза в секунду. Единственный способ избежать переполнения/переполнения - гарантировать, что отношение между самым большим и наименьшим числами представляется с плавающими точками (если нет, вы ничего не можете сделать). – ybungalobill
Альтернативно хранить свои логарифмы и использовать суммирование. Однако не могу сказать об устойчивости этого подхода. – ybungalobill