Подтвердить что ты не робот

Лучшая практика для сравнения поплавка в Matlab

Очевидно, сравнение с плавающей запятой всегда сложно. В моем (научном) коде я много проверяю утверждения, поэтому очень часто мне приходится проверять равенство сумм одному и тому подобное.

Есть ли быстрый и простой/лучший способ выполнения этих проверок?

Самым простым способом, который я могу придумать, является создание пользовательской функции для сравнения с плавающей запятой с фиксированным допуском, но мне это кажется довольно уродливым. Я бы предпочел встроенное решение, или, по крайней мере, то, что предельно ясно и понятно для понимания.

4b9b3361

Ответ 1

Я думаю, что это, скорее всего, будет функцией, которую вы пишете сами. Я использую три вещи довольно постоянно для выполнения вычислительных векторных тестов, так сказать:

Максимальная абсолютная ошибка

return max(abs(result(:) - expected(:))) < tolerance

Это вычисляет максимальную абсолютную погрешность по точкам и сообщает вам, что это меньше, чем некоторый допуск.

Максимальное количество ошибок при превышении ошибки

return sum( (abs(result(:) - expected(:))) < tolerance )

Это возвращает количество точек, выходящих за пределы допустимого диапазона. Это также легко изменить, чтобы вернуть процент.

Ошибка квадратного квадратного квадрата

return norm(result(:) - expected(:)) < rmsTolerance

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

Ответ 2

Любой фиксированный перенос будет терпеть неудачу, если вы поместите очень большие или очень маленькие числа, самым простым решением является использование eps для получения двойной точности:

abs(A-B)<eps(A)*4

4 - это абсолютно произвольное число, которое в большинстве случаев является достаточным.

Ответ 3

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

Например, как вы, вероятно, знаете, это даст False (то есть 0) в результате:

>> 0.1 + 0.1 + 0.1 == 0.3

ans =

     0

Но с eps вы можете сделать следующее, и результат будет таким, как ожидалось:

>> (0.1+0.1+0.1) - 0.3  < eps     

ans =

     1

Ответ 4

У меня был хороший опыт работы с xUnit, unit test для Matlab. После его установки вы можете использовать:

  • assertVectorsAlmostEqual(a,b) (проверяет нормальную близость между векторами, настраиваемый абсолютный/относительный допуск и нормальные значения по умолчанию)
  • assertElementsAlmostEqual(a,b) (такая же проверка, но по-разному на каждой отдельной записи - так что [1 1e-12] и [1 -1e-9] будут сравниваться с прежним, но не с последним).

Они хорошо протестированы, понятны и понятны для чтения. Названия функций довольно длинные, но с любым достойным редактором (или с Matlab) вы можете записать их как assertV<tab>.

Ответ 5

Для тех, кто понимает как MATLAB, так и Python (NumPy), было бы полезно проверить код следующих функций Python, которые выполняют задание:

numpy.allclose(a, b, rtol=1e-05, atol=1e-08)
numpy.isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)