Как сравнить две реализации библиотеки Math? - PullRequest
0 голосов
/ 07 января 2020

Как вы знаете, C стандартная библиотека определяет несколько вызовов стандартных функций, которые должны быть реализованы любой совместимой реализацией, например, Newlib, MUSL, GLIB C ...

Если я нацеливаюсь Linux например, я должен выбрать между glib c и MUSL, и для меня критерием является точность математической библиотеки libm. Как я могу сравнить две возможные реализации, скажем, например sin() или cos()?

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

1 Ответ

1 голос
/ 10 января 2020

Некоторые мысли:

  • Вы можете использовать библиотеку GNU Multiple Precision c (GnuMP для получения хороших эталонных результатов.
  • Возможно провести исчерпывающее тестирование большинства, если не всех подпрограмм с одинарной точностью (один аргумент IEEE-754) (для некоторых подпрограмм macOS trigonometri c, таких как sinf, мы полностью протестировали одну реализацию, убедившись, что он вернул точно округленные результаты, означающие, что результатом было математическое значение [если представимо] или одно из двух смежных значений [если нет]. Затем при изменении реализаций мы сравнивали одно с другим. Результат новой реализации был идентичен результату старой реализации, который он прошел. В противном случае для его тестирования использовался GnuMP. Поскольку новые реализации в основном совпадали со старыми реализациями, это привело к нескольким вызовам GnuMP, поэтому мы смогли полностью протестировать Новая рутинная реализация примерно через три минуты, если я правильно помню. )
  • Невозможно исчерпывающе протестировать процедуры с несколькими аргументами или двойной точности.
  • При сравнении реализаций вы должны выбрать метрику c или несколько метрик. Библиотека с хорошей ошибкой в ​​худшем случае хороша для доказательств; его граница может быть подтверждена для любого аргумента, и это может быть использовано для получения дальнейших границ в последующих вычислениях. Но библиотека с хорошей средней ошибкой может иметь тенденцию давать лучшие результаты, скажем, для физических симуляций, которые используют большие массивы данных. Для некоторых приложений могут быть релевантными только ошибки в «нормальной» области (углы от -2π до + 2π), поэтому ошибки в уменьшении больших аргументов (примерно до 10 308 ) могут быть несущественными, поскольку аргументы никогда не используются.
  • Есть некоторые общие точки, в которых следует проверять различные подпрограммы. Например, для тригонометрии c подпрограммы, тест на различных фракциях π. Помимо того, что математически интересно, они, как правило, реализуются в тех случаях, когда реализации переключаются между приближениями внутри. Также тестируйте большие числа, которые представимы, но оказываются очень близкими к кратным числам простых дробей π. Это худшие случаи для сокращения аргументов и могут привести к огромным относительным ошибкам, если не все сделано правильно. Они требуют теории чисел, чтобы найти. Тестирование с использованием любого метода «точечного выстрела» или даже упорядоченных подходов, в которых не рассматривается эта проблема сокращения, не сможет найти эти проблемные аргументы, поэтому было бы легко сообщить о точности подпрограммы с огромными ошибками.
  • С другой стороны, есть важные моменты для тестирования, которые невозможно узнать без внутренних знаний о реализации. Например, при разработке синусоидальной процедуры я использовал бы алгоритм Ремеза, чтобы найти минимаксный многочлен, стремясь к тому, чтобы он был хорошим, скажем, от –π / 2 до + π / 2 (довольно большой для такого рода вещей, но только для примера). Затем я посмотрел бы на арифметику c и ошибки округления, которые могут возникнуть при уменьшении аргумента. Иногда они дают результат немного за пределами этого интервала. Так что я бы go вернулся к минимаксному полиномиальному поколению и pu sh для немного большего интервала. И я также буду искать улучшения в сокращении аргументов. В конце концов, я получу сокращение, гарантирующее получение результатов в течение определенного интервала, и многочлен, о котором известно, что он хорошо работает с определенной точностью в этом интервале. Чтобы проверить мою процедуру, вам нужно знать конечные точки этого интервала, и вы должны быть в состоянии найти некоторые аргументы, для которых сокращение аргументов дает точки вблизи этих конечных точек, что означает, что вы должны иметь некоторое представление о том, как мое сокращение аргументов реализован - сколько битов он использует, и тому подобное. Как и упомянутые выше неприятные аргументы, эти точки не могут быть найдены с помощью метода точечной стрельбы. Но в отличие от вышеупомянутых, их нельзя найти из чистой математики; Вам нужна информация о реализации. Это делает практически невозможным узнать, что вы сравнили худшие потенциальные аргументы для реализаций.
...