Ich lande oft in Situationen, in denen überprüft werden muss, ob der ermittelte Unterschied über der Maschinengenauigkeit liegt. Scheint für diesen Zweck R hat eine handliche Variable:.Machine$double.eps
. Wenn ich mich jedoch an den R-Quellcode wende, um Richtlinien zur Verwendung dieses Werts zu erhalten, werden mehrere unterschiedliche Muster angezeigt.
Beispiele
Hier einige Beispiele aus stats
Bibliothek:
t.test.R
if(stderr < 10 *.Machine$double.eps * abs(mx))
chisq.test.R
if(abs(sum(p)-1) > sqrt(.Machine$double.eps))
integrieren.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]))
usw.
Fragen
- Wie kann man die Gründe für all diese verschiedenen verstehen
10 *
,100 *
,50 *
undsqrt()
Modifikatoren? - Gibt es Richtlinien
.Machine$double.eps
zur Anpassung von Unterschieden aufgrund von Präzisionsproblemen?
r
floating-point
rounding
precision
Karolis Koncevičius
quelle
quelle
double.eps
. Wenn Sie mehrere Operationen mit einer Gleitkommazahl ausführen, sollte sich auch Ihre Fehlertoleranz anpassen. Deshalb gibt Ihnen all.equal eintolerance
Argument.Antworten:
Die Maschinengenauigkeit für
double
hängt von ihrem aktuellen Wert ab..Machine$double.eps
Gibt die Genauigkeit an, wenn die Werte 1 sind. Mit der C-Funktion könnennextAfter
Sie die Maschinengenauigkeit für andere Werte ermitteln.Das Hinzufügen von Wert
a
zu Wertb
ändert sich nicht,b
wenna
die<=
Hälfte der Maschinengenauigkeit erreicht ist. Es wird geprüft, ob der Unterschied geringer ist als die Maschinengenauigkeit<
. Die Modifikatoren können typische Fälle berücksichtigen, in denen eine Addition keine Änderung zeigte.In R kann die Maschinengenauigkeit geschätzt werden mit:
Jeder
double
Wert repräsentiert einen Bereich. Für eine einfache Addition hängt der Bereich des Ergebnisses von der Neuausrichtung jedes Summanden und auch vom Bereich ihrer Summe ab.Für eine höhere Präzision
Rmpfr
könnte verwendet werden.Falls es in eine Ganzzahl konvertiert werden
gmp
könnte, könnte es verwendet werden (was in Rmpfr ist).quelle
Definition einer machine.eps: Dies ist der niedrigste Wert, für den dies nicht der Fall ist
eps
1+eps
1
Als Faustregel (unter der Annahme einer Gleitkommadarstellung mit Basis 2):
Dies
eps
macht den Unterschied für den Bereich 1 .. 2,für den Bereich 2 .. 4 ist die Genauigkeit
2*eps
und so weiter.
Leider gibt es hier keine gute Faustregel. Es wird ganz von den Bedürfnissen Ihres Programms bestimmt.
In R haben wir all.equal als eingebauten Weg, um die ungefähre Gleichheit zu testen. Also könntest du vielleicht so etwas gebrauchen
(x<y) | all.equal(x,y
)Google Mock verfügt über eine Reihe von Gleitkomma-Matchern für Vergleiche mit doppelter Genauigkeit, einschließlich
DoubleEq
undDoubleNear
. Sie können sie in einem Array-Matcher wie folgt verwenden:Aktualisieren:
Numerische Rezepte liefern eine Ableitung, um zu demonstrieren, dass unter Verwendung eines einseitigen Differenzquotienten
sqrt
eine gute Wahl der Schrittgröße für endliche Differenznäherungen von Derivaten ist.Die Wikipedia-Artikelseite Numerical Recipes, 3. Auflage, Abschnitt 5.7, Seiten 229-230 (eine begrenzte Anzahl von Seitenaufrufen ist unter http://www.nrbook.com/empanel/ verfügbar ).
Diese IEEE-Gleitkomma-Arithmetik ist eine bekannte Einschränkung der Computer-Arithmetik und wird an mehreren Stellen diskutiert:
.
dplyr::near()
ist eine weitere Option zum Testen, ob zwei Vektoren von Gleitkommazahlen gleich sind.Die Funktion verfügt über einen eingebauten Toleranzparameter
tol = .Machine$double.eps^0.5
, der angepasst werden kann. Der Standardparameter ist der gleiche wie der Standardparameter fürall.equal()
.quelle
all.equal()
auch seine eigene Annahme als Standardtoleranz gibt essqrt(double.eps)
- warum ist es der Standard? Ist es eine gute Faustregelsqrt()
?stats::
Quelle versteht und 2) was sind die Richtlinien; Die Antwort ist ziemlich dünn. Der einzig zutreffende Satz scheint der Verweis aus "Numerical Recipes" zu sein, wonach sqrt () ein guter Standard ist, was meiner Meinung nach wirklich zutreffend ist. Oder vielleicht fehlt mir hier etwas.