Как мне написать модульные тесты для обеспечения численной точности в научных вычислениях в C? - PullRequest
1 голос
/ 16 декабря 2009

В настоящее время я изучаю взаимодействие C и R (используя R .Call для скорости). Я использовал C только для тривиальных целочисленных вычислений и приложений для обработки текста, и мне никогда не приходилось беспокоиться о проблемах с плавающими переменными, недостаточным вычислением и т. Д. Какие тесты я могу написать для функций, чтобы обеспечить точность чисел?

Ответы [ 3 ]

3 голосов
/ 16 декабря 2009

Большой обзор возможных крайних случаев см. В этой статье Википедии .

Тогда для модульных тестов см. Подводные камни проверки вычислений с плавающей запятой .

2 голосов
/ 17 декабря 2009

Для правильного выполнения таких тестов вам придется выполнить анализ ошибок всех вычислений с плавающей запятой в вашем коде. Канонические примеры того, почему это важно, варьируются от простых вещей, таких как поиск корней квадратного уравнения до решения сумасшедших рекуррентных отношений (например, поиск «повторения Мюллера»).

Но выполнение этого анализа ошибок обычно нетривиально и отнимает много времени, а зачастую и невозможно. В таких случаях вторая лучшая ситуация будет иметь большой набор входных данных и правильные выходные значения, и использовать их в своих тестах. Но это в основном проблема курицы и яйца, потому что как вы находите правильные значения для чего-то, даже немного сложного, сохраняя, фактически вычисляя их на каком-то компьютере?

Итак, практические решения включают в себя:

  1. Интервальная арифметика , где вы используете структуры данных, чтобы дать вам оценку интервала, в котором могут лежать ваши вычисления с плавающей запятой. Если интервал результата слишком велик, вы знаете, что есть некоторые проблемы , Существует много реализаций для проведения такого анализа, подробности см. в этом списке . Для больших вычислений этот метод будет медленным, но вы можете попробовать запустить его для некоторой репрезентативной выборки, взятой из ваших реальных данных, чтобы получить представление.
  2. Если ваш компилятор поддерживает это, вы можете запустить один и тот же код с разными режимами округления с плавающей запятой. C99 стандартизировал это, и gcc поддерживает это, так что вам может повезти. Посмотрите на fesetround() и fegetround() например. Идея состоит в том, что если ваши вычисления с плавающей запятой стабильны и точны, различные режимы округления должны приводить к одинаковому результату. Если разные режимы округления приводят к слишком разным числам, вы знаете, что что-то не так. Этот метод, к сожалению, не может сказать вам , что не так, но это первый шаг. Кроме того, этот метод должен быть быстрым, за исключением того факта, что вы собираетесь выполнить свой код четыре раза для одного набора ввода.
0 голосов
/ 16 декабря 2009

Я думаю:

  1. Точность будет зависеть от аргументов - так что вы можете проверить некоторые значения, но позже обнаружите, что есть другие значения, в которых есть потеря точности.
  2. Вы можете проверить значения, которые отличаются чрезвычайно малыми приращениями, и посмотреть, поддерживает ли алгоритм точность.
  3. Используйте удваивается, а не плавает.
  4. Наконец, вы можете выполнить вычисления в два раза (увеличив аргументы на наименьшую дельту для второго запуска?), Выбрав наихудший вариант для каждой операции и посмотрите, какой диапазон ответов вы получите.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...