Implementasi ganda presisi yang cepat dan akurat untuk fungsi gamma tidak lengkap


10

Apa cara canggih menerapkan fungsi khusus presisi ganda? Saya membutuhkan integral berikut: untuk dan , yang dapat ditulis dalam bentuk fungsi gamma bawah yang tidak lengkap. Inilah implementasi Fortran dan C saya: m=0,1,2,. . . t>0

Fm(t)=01kamu2me-tkamu2dkamu=γ(m+12,t)2tm+12
m=0,1,2,...t>0

https://gist.github.com/3764427

yang menggunakan ekspansi seri, meringkas istilah sampai akurasi yang diberikan, dan kemudian menggunakan hubungan rekursi untuk secara efisien mendapatkan nilai untuk lebih rendah . Saya mengujinya dengan baik dan saya mendapatkan akurasi 1e-15 untuk semua nilai parameter yang saya butuhkan, lihat komentar versi Fortran untuk detailnya.m

Apakah ada cara yang lebih baik untuk mengimplementasikannya? Berikut ini adalah implementasi fungsi gamma di gfortran:

https://github.com/mirrors/gcc/blob/master/libgfortran/intrinsics/c99_functions.c#L1781

itu menggunakan perkiraan fungsi rasional alih-alih menyimpulkan beberapa seri tak terbatas yang saya lakukan. Saya pikir itu pendekatan yang lebih baik, karena seseorang harus mendapatkan akurasi yang seragam. Apakah ada beberapa cara kanonik untuk mendekati hal-hal ini, atau apakah kita harus mencari algoritma khusus untuk setiap fungsi khusus?

Pembaruan 1 :

Berdasarkan komentar, berikut adalah implementasinya menggunakan SLATEC:

https://gist.github.com/3767621

itu mereproduksi nilai dari fungsi saya sendiri, kira-kira pada tingkat akurasi 1e-15. Namun, saya melihat masalah bahwa untuk t = 1e-6 dan m = 50, istilah sama dengan 1e-303 dan untuk "m" yang lebih tinggi, ia mulai memberikan jawaban yang salah. Fungsi saya tidak memiliki masalah ini, karena saya menggunakan hubungan ekspansi / perulangan rangkaian langsung untuk . Berikut ini contoh nilai yang benar: Fmtm+12Fm

F100(1e-6)=4.97511945200351715E-003 ,

tapi saya tidak bisa mendapatkan ini menggunakan SLATEC karena penyebutnya meledak. Seperti yang Anda lihat, nilai sebenarnya dari bagus dan kecil.Fm

Pembaruan 2 :

Untuk menghindari masalah di atas, seseorang dapat menggunakan fungsi dgamit( fungsi Gamma Tricomi yang tidak lengkap), maka F(m, t) = dgamit(m+0.5_dp, t) * gamma(m+0.5_dp) / 2, jadi tidak ada masalah dengan lagi, tapi sayangnya pukulan untuk . Namun ini mungkin cukup tinggi untuk tujuan saya.m 172 mtgamma(m+0.5_dp)m172m


2
Mengapa kode fungsi Anda sendiri? GSL, cephes, dan SLATEC semuanya mengimplementasikannya.
Geoff Oxberry

Saya telah memperbarui pertanyaan mengapa saya tidak menggunakan SLATEC.
Ondřej Čertík

@ OndřejČertík Anda telah menemukan bug! Terbalik pertanyaan Anda!
Ali

Ali --- ini bukan bug di SLATEC, tetapi pada kenyataannya, bahwa saya benar-benar perlu membagi dengan untuk mendapatkan nilai untuk . Jadi metode numerik yang bekerja untuk mungkin tidak berfungsi dengan baik untuk . γ(z,x)tm+12Fm(t)γ(z,x)Fm(t)
Ondřej Čertík

@ OndřejČertík OK, maaf, kesalahan saya, saya tidak memeriksa kode Anda sebelum berkomentar.
Ali

Jawaban:


9

Integral yang dimaksud juga dikenal sebagai fungsi Boys, setelah ahli kimia Inggris Samuel Francis Boys yang memperkenalkan penggunaannya pada awal 1950-an. Beberapa tahun yang lalu, saya perlu menghitung fungsi ini dalam presisi ganda, secepat mungkin tetapi akurat. Saya berhasil mencapai kesalahan relatif pada urutan di seluruh domain input.1015

Secara umum menguntungkan untuk menggunakan pendekatan yang berbeda untuk argumen kecil dan besar, di mana peralihan optimal antara "besar" dan "kecil" paling baik ditentukan secara eksperimental, dan secara umum merupakan fungsi dari . Untuk kode saya, saya mendefinisikan argumen "kecil" sebagai kondisi yang memuaskan a m + 1 1m .am+112

Untuk argumen besar, saya menghitung

Fm(a)=12γ(m+12,a)×p×p,  p=a12(m+12)

Urutan operasi ini menghindari underflow dini. Karena kita hanya memerlukan fungsi gamma rendah tidak lengkap dari pesanan setengah bilangan bulat di sini daripada fungsi gamma lengkap tidak lengkap yang lebih rendah, menguntungkan dari perspektif kinerja untuk menghitung

γ(m+12,a)=Γ(m+12)Γ(m+12,a)

menggunakan nilai tabulasi dan komputasiΓ(m+1Γ(m+12)sesuai dengan jawaban ini, sambil dengan hati-hati menghindari masalah pembatalan kurang melalui penggunaan operasi penambahan-penggandaan yang digabungkan. Sebuah optimasi lebih lanjut potensial adalah untuk mengamati bahwa untuk cukup besaryang,γ(m+1Γ(m+12,a)ake dalam presisi floating-point yang diberikan.γ(m+12,a)=Γ(m+12)

Untuk argumen kecil, saya mulai dengan ekspansi seri untuk fungsi gamma rendah lengkap dari

A. Erdelyi, W. Magnus, F. Oberhettinger, dan FG Tricomi, "Fungsi Transendental Tinggi, Vol. 2". New York, NY: McGraw-Hill 1953

dan dimodifikasi untuk menghitung Boys fungsi sebagai berikut (truncating seri ketika istilah ini cukup kecil untuk presisi yang diberikan):Fm(a)

Fm(a)=121m+12exp(a)(1+n=1an(1+m+12)× ... ×(n+m+12))

m=0,1,2,3F0(a)=π4aerf(a)erfERFerferff

m=1,2,3Sebuah<212Fm(Sebuah)=12Sebuah((2m-1)Fm-1(Sebuah)-exp(-Sebuah))

SebuahmmFm1=12m1(2a Fm(a)+exp(a))


Terima kasih @njuffa untuk jawaban yang bagus. Jika Anda membuat kode untuk sumber terbuka ini, saya pikir itu akan sangat berguna bagi banyak orang.
Ondřej Čertík

1
Saat ini, implementasi algoritma CUDA yang dijelaskan tersedia untuk diunduh gratis dari situs web pengembang NVIDIA (memerlukan pendaftaran gratis sebagai pengembang CUDA, persetujuan biasanya dalam satu hari kerja). Kode ini berada di bawah lisensi BSD, yang harus kompatibel dengan hampir semua jenis proyek.
njuffa


4

Saya akan melihat buku Abramowicz & Stegun, atau revisi yang lebih baru yang diterbitkan NIST beberapa tahun yang lalu dan itu tersedia secara online, saya percaya. Mereka juga membahas cara-cara untuk mengimplementasikan berbagai hal dengan cara yang stabil.


Saya menggunakan ini: dlmf.nist.gov/8 , ketika mengimplementasikannya, tapi itu mungkin sumber daya lain. Bab 5 dalam Numerical Recipes juga memiliki info menarik, tetapi hanya berlaku untuk fungsi satu variabel.
Ondřej Čertík

Saya tidak berpikir Anda akan menemukan sesuatu yang jauh lebih baru daripada referensi tahun 2001 mereka; SLATEC akan lebih tua dari itu.
Geoff Oxberry

1

Tampaknya tidak canggih, tetapi SLATEC di Netlib menawarkan "1.400 tujuan umum matematika dan statistik." Gamma tidak lengkap tersedia di bawah fungsi khusus di sini .

Menerapkan fungsi-fungsi seperti itu memakan waktu dan rawan kesalahan jadi saya tidak akan melakukannya sendiri kecuali benar-benar diperlukan. SLATEC telah ada selama beberapa waktu sekarang dan banyak digunakan, setidaknya berdasarkan jumlah unduhan , jadi saya berharap implementasinya akan matang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.