Ketika seseorang ingin menghitung turunan numerik, metode yang disajikan oleh Bengt Fornberg di sini (dan dilaporkan di sini ) sangat mudah (baik tepat dan mudah diimplementasikan). Sebagai kertas asli tanggal dari 1988, saya ingin tahu apakah ada alternatif yang lebih baik hari ini (sebagai (atau hampir sama) sederhana dan lebih tepat)?
finite-difference
precision
Vincent
sumber
sumber
Jawaban:
Gambaran
Pertanyaan bagus. Ada sebuah makalah yang berjudul "Meningkatkan akurasi metode diferensiasi matriks untuk titik kolokasi sewenang-wenang" oleh R. Baltensperger. Ini bukan masalah besar menurut saya, tetapi ada benarnya (yang sudah diketahui sebelum penampilan pada tahun 2000): ini menekankan pentingnya representasi akurat dari fakta bahwa turunan dari fungsi konstanf( x ) = 1 harus menjadi nol (ini berlaku persis dalam arti matematika, tetapi tidak harus dalam representasi numerik).
Sangat mudah untuk melihat bahwa ini membutuhkan jumlah baris dari matriks turunan ke-nD( n ) menjadi nol. Hal ini umum untuk menegakkan kendala ini dengan menyesuaikan entri diagonal, yaitu dengan menetapkan D( n )j j: = - Âi = 1i ≠ jNDsaya j.(1) Jelas bahwa fitur ini tidak berlaku ketika bekerja pada komputer karena kesalahan pembulatan dalam perhitungan floating point. Apa yang lebih mengejutkan adalah bahwa kesalahan ini bahkan lebih parah ketika menggunakan rumus analitik untuk matriks turunan (yang tersedia untuk banyak titik kolokasi klasik, misalnya Gauss-Lobatto).
Sekarang, makalah (dan referensi di dalamnya) menyatakan bahwa kesalahan turunan adalah dalam urutan penyimpangan dari jumlah baris dari nol. Karena itu tujuannya adalah untuk membuat angka-angka ini sekecil mungkin.
Tes numerik
Poin baiknya adalah prosedur Fornberg tampaknya cukup bagus dalam hal ini. Pada gambar di bawah ini saya telah membandingkan perilaku yang tepat, yaitu analitik, matriks turunan pertama dan yang diturunkan oleh algoritma Fornberg, untuk jumlah titik kolokasi Chebyshev-Lobatto yang bervariasi.
Sekali lagi, meyakini pernyataan dalam makalah yang dikutip, ini menyiratkan bahwa algoritma Fornberg akan menghasilkan hasil yang lebih akurat untuk turunannya.
Untuk membuktikannya, saya akan menggunakan fungsi yang sama seperti di kertas,f( x ) = 11 + x2.(2) En= maksi ∈ { 0 , … , n }∣∣∣f′( xsaya) - ∑j = 1nDsaya jf( xj) ∣∣∣.(3) D~j j= Dj j- ( ∑i = 1nDj i) ,untuk semua j .(4)
Kesimpulan
Kesimpulannya, metode Fornberg tampaknya cukup akurat, dalam kasus bahkan sekitar 3 urutan besarnya lebih akurat daripada hasil dari rumus analitik. Ini harus cukup akurat untuk sebagian besar aplikasi. Selain itu, ini luar biasa karena Fornberg tampaknya tidak secara eksplisit memasukkan fakta ini dalam metodenya (setidaknya tidak disebutkan dalam dua makalah Fornberg).N= 512
Urutan besar lainnya dapat diperoleh untuk contoh ini melalui penyertaan langsung Persamaan (4). Karena ini adalah pendekatan yang cukup sederhana dan hanya diterapkan sekali untuk setiap turunan, saya tidak melihat alasan untuk tidak menggunakannya.
Metode dari makalah Baltensperger - yang menggunakan pendekatan yang lebih canggih untuk mengevaluasi jumlah dalam Persamaan (1) untuk mengurangi kesalahan pembulatan - menghasilkan sekitar urutan yang sama besarnya untuk kesalahan. Jadi, setidaknya untuk contoh ini, kira-kira setara dengan metode "Adjusted Fornberg" di atas.
sumber
Dengan asumsi Anda mencoba untuk membedakan implementasi numerik dari fungsi kontinu, ada sejumlah besar metode:
1) Diferensiasi otomatis. Metode yang paling akurat dan umum. Nyeri untuk kode, membutuhkan operator kelebihan dan pencarian tergantung argumen. Memberi beban pada pengguna untuk memahami konsep-konsep ini. Juga berjuang dengan singularitas yang dapat dilepas, seperti membedakan sinc pada .x = 0
2) Transformasi Chebyshev. Proyeksikan fungsi Anda ke rentang polinomial Chebyshev dan bedakan perulangan tiga istilah. Sangat cepat, sangat akurat. Tetapi mengharuskan Anda memiliki domain minat yang didukung secara kompak; di luar domain yang dipilih , perulangan istilah tiga tidak stabil.[ a , b ]
3) Perbedaan terbatas. Underrated dalam 1D; lihat Tip dan Trik Nick Higham dalam Komputasi Numerik . Idenya adalah bahwa jika Anda menyeimbangkan kesalahan pemotongan dan kesalahan roundoff maka Anda tidak perlu memilih stepsize; itu dapat dipilih secara otomatis. Dalam Boost, ide ini digunakan untuk memulihkan (secara default) 6/7 digit yang benar untuk tipe tersebut. (Higham hanya menunjukkan ide untuk case yang lebih sederhana dari 1/2 digit yang benar, tetapi idenya mudah diperpanjang.) Koefisiennya berasal dari tabel Fornberg yang sama, tetapi ukuran langkah dipilih dengan asumsi bahwa fungsi tersebut dapat dievaluasi menjadi 1ULP ketepatan. Kerugiannya adalah itu membutuhkan 2 evaluasi fungsi untuk memulihkan setengah digit dari tipe, 4 untuk memulihkan 3/4 digit, begitu seterusnya. Dalam 1D, bukan transaksi yang buruk. Dalam dimensi yang lebih tinggi, ini adalah bencana besar.
4) Langkah turunan kompleks. Gunakan . Ambil untuk menjadi unit roundoff dan ini akan pulih hampir setiap bit dengan benar. Namun, itu agak curang, karena umumnya lebih sulit untuk mengimplementasikan suatu fungsi dalam bidang kompleks daripada memberikan kode turunan nyata. Masih ide yang keren dan bermanfaat dalam kondisi tertentu.f′( x ) ≈ I ( f( x + i h ) ) h
sumber
Saya tidak mengetahui ada yang memperbaiki algoritma Fornberg (lihat juga makalahnya yang sedikit lebih baru ). Sebagai tambahan, bagi saya tampaknya melihat algoritme sebagai cara untuk menghitung turunan numerik tidak benar. Semua yang dia lakukan adalah mendapatkan algoritma yang efisien untuk menghitung bobot untuk metode beda hingga. Keuntungan dari metodenya adalah memberi Anda bobot untuk semua turunan hingga turunan yang diinginkan dalam sekali jalan.
sumber
Skema yang lebih sederhana
Selain jawaban saya yang lain yang lebih lanjut tentang perluasan metode Fornberg, saya akan membahas di sini pertanyaan untuk alternatif yang lebih sederhana.
Untuk ini saya membuat sketsa skema alternatif yang menghasilkan koefisien turunan interpolasi Lagrangian lebih langsung. Implementasinya hanya membutuhkan beberapa baris kode, berfungsi untuk grid sewenang-wenang, dan menurut eksperimen pertama saya, seakurat Fornberg.
Dasar implementasi adalah turunan langkah imajiner mana adalah variabel dalam urutan ketepatan mesin. Derivatif-langkah imajiner diketahui secara stabil menghasilkan nilai-nilai turunan dan tidak mengalami ketidakstabilan numerik dari implementasi beda hingga dengan .f′( x ) = 1 hAku ( f( x + i h ) ), h h → 0
Bahan kedua adalah polinomial interpolasi Lagrange pada grid dievaluasi dengan salah satu bentuk barycentric, misalnya mana Untuk menggunakan turunan langkah-kompleks, kita harus memastikan formula ini juga berfungsi untuk kompleks argumen . Selain itu, untuk fungsi yang diberikan f (x) dan vektor koefisien , kami menunjukkan polinomial interpolasi melalui olehL.saya( x ) { x1, ... , xN} L.saya( z) = ⎧ ⎩⎨⎪⎪1 μsayaz- xk∑kμkz- xkjika z= xsayajika tidak. μsaya= 1∏k ≠ i( xsaya- xk) z fsaya= f( xsaya) ( x1, fsaya) P( x ; f) = ∑i = 1NfsayaL.saya( x ).
Algoritma
Algoritma ini dibuat sketsa sebagai berikut. Ini memiliki input dan output parameter yang sama dengan Fornberg, tetapi jauh lebih pintar.
Memasukkan:
Inisialisasi
Algoritma
Sementara :o < o r d
Hitung oleh langkah turunan kompleks untuk semua dan . Di sini, menunjukkan baris -th .D( O + 1 )saya k= CSD ( P( xk; D( o )saya) ) CSD saya k
D( o )saya saya D( o )
Set o = o + 1;
Putuskan apa yang akan Output :
Vektor dari koefisien Perbedaan Hingga pada titik , di mana . Inilah yang dilakukan Fornberg.d( o r d) z dsaya= P(z; D( o r d)saya)
Fungsi interpolasi ke turunan dari pesanan . Untuk ini, Anda harus memasukkan fungsi resp. nilai fungsi di ke algoritma.hal( o r d)( x ) = ∑Ni = 1f( xsaya) P( x ; D( o r d)saya) f( o r d)( x ) o r d fsaya xsaya
Sebuah fungsi-meta yang mengembalikan fungsi interpolasi varian 2., tetapi untuk fungsi sewenang-wenang yang akan diinterpolasi pada titik-titik grid.diff ( int o r d, fungsi g) g
Secara pribadi, saya suka varian 3. yang paling.
Analisis algoritma
Seperti Fornberg, algoritma ini adalah . Saya akan memposting hasil yang lebih empiris mengenai akurasi, stabilitas, dll. Jika saya menemukan waktu.O (ord⋅ N2)
sumber
Untuk meningkatkan ketepatan diferensiasi numerik, lakukan hal berikut:
1) Pilih metode "standar" presisi tinggi favorit Anda berdasarkan beberapa ukuran langkah h .
2) Hitung nilai derivatif dengan metode yang dipilih dalam 1) berkali-kali dengan ukuran langkah yang berbeda tetapi masuk akal h . Setiap kali Anda dapat memilih h sebagai angka acak dari interval (0,5 * H / 10, 1,5 * H / 10) di mana H adalah ukuran langkah yang tepat untuk metode yang Anda gunakan.
3) Rata-rata hasilnya.
Hasil Anda mungkin mendapatkan 2-3 urutan besarnya dalam kesalahan kesalahan mutlak. hasil tidak rata-rata.
https://arxiv.org/abs/1706.10219
sumber