Saya sering berakhir dalam situasi di mana perlu untuk memeriksa apakah perbedaan yang diperoleh di atas presisi mesin. Sepertinya untuk tujuan ini R memiliki variabel berguna: .Machine$double.eps
. Namun ketika saya beralih ke kode sumber R untuk panduan tentang menggunakan nilai ini saya melihat beberapa pola yang berbeda.
Contohnya
Berikut beberapa contoh dari stats
perpustakaan:
t.test.R
if(stderr < 10 *.Machine$double.eps * abs(mx))
chisq.test.R
if(abs(sum(p)-1) > sqrt(.Machine$double.eps))
mengintegrasikan
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]))
dll.
Pertanyaan
- Bagaimana seseorang dapat memahami alasan di balik semua berbeda
10 *
,100 *
,50 *
dansqrt()
pengubah? - Apakah ada pedoman tentang cara
.Machine$double.eps
menyesuaikan perbedaan karena masalah presisi?
r
floating-point
rounding
precision
Karolis Koncevičius
sumber
sumber
double.eps
. Jika Anda melakukan beberapa operasi pada nomor floating point, maka toleransi kesalahan Anda juga harus menyesuaikan. Inilah mengapa all.equal memberi Andatolerance
argumen.Jawaban:
Presisi mesin
double
tergantung pada nilai saat ini..Machine$double.eps
memberikan presisi saat nilainya 1. Anda dapat menggunakan fungsi CnextAfter
untuk mendapatkan presisi mesin untuk nilai lainnya.Menambahkan nilai
a
ke nilaib
tidak akan berubahb
ketikaa
adalah<=
setengah dari itu mesin presisi. Memeriksa apakah perbedaannya lebih kecil daripada presisi mesin dilakukan<
. Pengubah mungkin mempertimbangkan kasus-kasus tertentu seberapa sering penambahan tidak menunjukkan perubahan.Dalam R , presisi mesin dapat diperkirakan dengan:
Setiap
double
nilai mewakili rentang. Untuk tambahan sederhana, kisaran hasil tergantung pada pengubahan setiap musim dan juga jumlah dari jumlah mereka.Untuk precisi yang lebih tinggi
Rmpfr
bisa digunakan.Dalam hal ini dapat dikonversi ke integer
gmp
dapat digunakan (apa yang ada di Rmpfr).sumber
Definisi machine.eps: ini adalah nilai terendah
eps
yang1+eps
bukan1
Sebagai aturan praktis (dengan asumsi representasi floating point dengan basis 2):
Ini
eps
membuat perbedaan untuk rentang 1 .. 2,untuk rentang 2 .. 4 presisinya
2*eps
dan seterusnya.
Sayangnya, tidak ada aturan praktis yang baik di sini. Ini sepenuhnya ditentukan oleh kebutuhan program Anda.
Di R kita memiliki semua. Sama dengan cara bawaan untuk menguji perkiraan persamaan. Jadi Anda bisa menggunakan mungkin sesuatu seperti
(x<y) | all.equal(x,y
)Google mock memiliki sejumlah pencocokan floating point untuk perbandingan presisi ganda, termasuk
DoubleEq
danDoubleNear
. Anda dapat menggunakannya dalam pencocokan array seperti ini:Memperbarui:
Numerical Recipes memberikan derivasi untuk menunjukkan bahwa dengan menggunakan selisih selisih satu sisi,
sqrt
adalah pilihan langkah-ukuran yang baik untuk perkiraan perbedaan turunan yang terbatas.Situs artikel Wikipedia, Numerical Recipes, edisi ke-3, Bagian 5.7, yang merupakan halaman 229-230 (sejumlah terbatas tampilan halaman tersedia di http://www.nrbook.com/empanel/ ).
Aritmatika titik apung IEEE ini adalah batasan aritmatika komputer yang terkenal dan dibahas di beberapa tempat:
.
dplyr::near()
adalah pilihan lain untuk menguji apakah dua vektor angka floating point sama.Fungsi ini memiliki parameter toleransi bawaan:
tol = .Machine$double.eps^0.5
yang dapat disesuaikan. Parameter default sama dengan default untukall.equal()
.sumber
all.equal()
memiliki asumsi sendiri sebagai toleransi standarsqrt(double.eps)
- mengapa standar? Apakah ini aturan praktis yang baik untuk digunakansqrt()
?stats::
sumber R , dan 2) apa pedomannya; jawabannya cukup tipis. Satu-satunya kalimat yang berlaku tampaknya adalah referensi dari "Numerical Recipes" tentang sqrt () sebagai standar yang baik, yang benar-benar tepat, saya rasa. Atau mungkin saya kehilangan sesuatu di sini.