Я часто оказываюсь в ситуациях, когда необходимо проверить, превышает ли полученная разница точность станка. Похоже , что для этой цели R имеет удобную переменную: .Machine$double.eps
. Однако, когда я обращаюсь к исходному коду R за рекомендациями по использованию этого значения, я вижу несколько разных шаблонов.
Примеры
Вот несколько примеров из stats
библиотеки:
t.test.R
if(stderr < 10 *.Machine$double.eps * abs(mx))
chisq.test.R
if(abs(sum(p)-1) > sqrt(.Machine$double.eps))
integrate.R
rel.tol < max(50*.Machine$double.eps, 0.5e-28)
lm.influence.R
e[abs(e) < 100 * .Machine$double.eps * median(abs(e))] <- 0
princomp.R
if (any(ev[neg] < - 9 * .Machine$double.eps * ev[1L]))
и т.п.
Вопросов
- Как можно понять рассуждение за все эти разные
10 *
,100 *
,50 *
иsqrt()
модификаторы? - Существуют ли рекомендации по использованию
.Machine$double.eps
для корректировки различий из-за проблем с точностью?
r
floating-point
rounding
precision
Каролис Концевичюс
источник
источник
double.eps
. Если вы выполняете несколько операций над числом с плавающей запятой, то и ваша погрешность должна быть скорректирована. Вот почему all.equal дает вамtolerance
аргумент.Ответы:
Точность станка
double
зависит от его текущего значения..Machine$double.eps
дает точность, когда значения равны 1. Вы можете использовать функцию C,nextAfter
чтобы получить точность станка для других значений.Прибавление значения
a
к значениюb
не изменится,b
если оноa
будет<=
вдвое меньше точности станка. Проверка, является ли разница меньше точности станка, сделана с<
. Модификаторы могут учитывать типичные случаи, когда часто дополнение не показывало изменения.В R точность станка можно оценить с помощью:
Каждое
double
значение представляет диапазон. Для простого сложения диапазон результата зависит от диапазона каждого слагаемого, а также диапазона их суммы.Для более высокой точности
Rmpfr
можно использовать.В случае, если это может быть преобразовано в целое число
gmp
может быть использовано (что находится в Rmpfr).источник
Определение machine.eps: это самое низкое значение,
eps
для которого1+eps
нет1
Как правило (предполагая представление с плавающей запятой с основанием 2):
это
eps
составляет разницу для диапазона 1 .. 2,для диапазона 2 .. 4 точность
2*eps
и т. Д.
К сожалению, здесь нет хорошего эмпирического правила. Это полностью определяется потребностями вашей программы.
В R мы имеем all.equal как встроенный способ проверки приближенного равенства. Таким образом, вы могли бы использовать что-то вроде
(x<y) | all.equal(x,y
)В Google mock есть несколько средств сравнения с плавающей запятой для сравнений с двойной точностью, включая
DoubleEq
иDoubleNear
. Вы можете использовать их в сопоставлении массива следующим образом:Обновить:
Численные рецепты обеспечивают вывод, чтобы продемонстрировать, что использование одностороннего разностного коэффициента
sqrt
является хорошим выбором размера шага для конечно-разностных аппроксимаций производных.Сайт статьи Википедии «Числовые рецепты», 3-е издание, раздел 5.7, страницы 229-230 (ограниченное количество просмотров страниц доступно по адресу http://www.nrbook.com/empanel/ ).
Эта арифметика с плавающей точкой IEEE является хорошо известным ограничением компьютерной арифметики и обсуждается в нескольких местах:
,
dplyr::near()
еще один вариант проверки, если два вектора чисел с плавающей точкой равны.Функция имеет встроенный параметр допуска:
tol = .Machine$double.eps^0.5
его можно настроить. Параметр по умолчанию совпадает с параметром по умолчанию дляall.equal()
.источник
all.equal()
есть свое собственное допущение как допуск по умолчаниюsqrt(double.eps)
- почему это по умолчанию? Это хорошее правило для использованияsqrt()
?stats::
источнике R , и 2) каковы рекомендации; ответ довольно тонкий. Кажется, единственное применимое предложение - это ссылка из «Числовых рецептов» о том, что sqrt () является хорошим значением по умолчанию, что, на мой взгляд, действительно соответствует действительности. Или, может быть, я что-то здесь упускаю.