Saya punya pertanyaan sederhana yang benar-benar sulit bagi Google (di samping kanonik Apa Yang Harus Diketahui Setiap Ilmuwan Komputer tentang kertas Aritmatika Titik Apung ).
Kapan seharusnya fungsi seperti log1p
atau expm1
digunakan, bukan log
dan exp
? Kapan mereka tidak digunakan? Bagaimana perbedaan implementasi dari fungsi-fungsi tersebut berbeda dalam hal penggunaannya?
floating-point
Tim
sumber
sumber
log1p
Anda maksud (terutama bagaimana penerapannya, jadi kami tidak perlu menebak).Jawaban:
Kita semua tahu bahwaexp(x)=∑n=0∞xnn!=1+x+12x2+…
menyiratkan bahwa untuk|x|≪1 , kami memilikiexp(x)≈1+x . Ini berarti bahwa jika kita harus mengevaluasi dalam floating pointexp(x)−1 , untuk|x|≪1 pembatalan katastropik dapat terjadi.
Ini dapat dengan mudah ditunjukkan dengan python:
Nilai yang tepat adalahexp(10−8)−1exp(10−22)−1=0.000000010000000050000000166666667083333334166666668…=0.000000000000000000000100000000000000000000005000000…
Secara umum implementasi "akurat" dari
exp
danexpm1
harus benar tidak lebih dari 1ULP (yaitu satu unit tempat terakhir). Namun, karena mencapai akurasi ini menghasilkan kode "lambat", terkadang implementasi yang cepat dan kurang akurat tersedia. Misalnya dalam CUDA yang kita milikiexpf
danexpm1f
, di manaf
singkatan dari fast. Menurut panduan pemrograman CUDA C, aplikasi. D yangexpf
memiliki kesalahan dari 2ULP.Jika Anda tidak peduli tentang kesalahan dalam urutan beberapa ULPS, biasanya implementasi yang berbeda dari fungsi eksponensial adalah setara, tetapi berhati-hatilah bahwa bug mungkin disembunyikan di suatu tempat ... (Ingat bug Pentium FDIV ?)
Jadi cukup jelas bahwaexp(x)−1 untuk x kecil . Menggunakannya untuk x umum tidak berbahaya, karena
expm1
harus digunakan untuk menghitungexpm1
diharapkan akurat pada kisaran lengkapnya:(Dalam contoh di atas1 jauh di bawah 1ULP exp(200) , jadi ketiga ekspresi mengembalikan angka floating point yang persis sama.)
Diskusi serupa berlaku untuk fungsi terbaliklog(1+x)≈x untuk |x|≪1 .
log
danlog1p
karenasumber
expm1(x)
bukanexp(x)-1
. Tentu sajaexp(x) == exp(x) - 1
tidak berlaku secara umum.expm1(x)
exp(x) - 1
Untuk memperluas perbedaan antara
log
danlog1p
mungkin membantu untuk mengingat grafik jika logaritma:log
log1p
log
log1p
sumber