Algoritma untuk plot fungsi (adaptif?)

21

Saya mencari algoritma untuk menggambar 2d-grafik standar untuk fungsi yang mungkin atau mungkin tidak memiliki singularitas. Tujuannya adalah untuk menulis "Mini-CAS", jadi saya tidak memiliki pengetahuan apriori tentang jenis fungsi, pengguna ingin membuat grafik.

Masalah ini sudah sangat tua, jadi saya membayangkan harus ada beberapa algoritma standar dalam literatur. Untuk sekali ini saya tidak punya banyak keberhasilan menemukan referensi melalui Google.

Saya memang menemukan satu algoritma yang menarik, yaitu yang ini dari "YACAS - Book of algoritma" bernama "Adaptive function plotting".

Singkatnya:

  • Apakah ada algoritma standar?
  • Apakah ada rangkaian uji untuk fungsi yang sulit untuk diketahui yang diketahui?
  • Apa makalah menarik untuk dibaca?
soegaard
sumber
2
Mungkin pertanyaannya akan lebih dipahami dengan "fungsi memplot" daripada "menggambar grafik"? Saya salah mengartikan judul pada awalnya (teori grafik).
astrojuanlu
@ Juanlu001 Terima kasih atas sarannya. Saya mengubah judul.
soegaard
Ketika Anda mengatakan 2D, maksud Anda memplot fungsi satu variabel seperti , atau Anda juga tertarik pada fungsi dua variabel ( f ( x , y ) ) yang ditampilkan dalam 2D ​​dengan misalnya berbagai warna / nuansa yang mewakili nilai yang berbeda? f(x)f(x,y)
Szabolcs
Yah, maksud saya merencanakan fungsi satu variabel. Namun, saya juga ingin mendengar tentang algoritma untuk memilih poin mana yang akan dievaluasi dalam pengaturan dua variabel juga. Saya tidak begitu tertarik mendengar tentang warna dan bayangan.
soegaard
Untuk fungsi 2D, lihat pertanyaan dan jawaban saya di sini . Apa yang saya lakukan di sana sangat terbatas, dan tidak akan berfungsi dengan baik untuk fungsi sewenang-wenang. Juga, ada beberapa langkah penting yang hilang dari deskripsi yang tanpanya metode tidak akan bertemu dengan benar: Saya perlu memasukkan titik pengambilan sampel baru di tengah setiap tepi mesh yang akan hilang pada retriangulasi berikutnya. (lanjutan)
Szabolcs

Jawaban:

10

Saya telah menerapkan rutin pengambilan sampel adaptif Mathematica di GitHub (Ini adalah file C tunggal, naik ke pohon sumber untuk file header). Saya menemukan deskripsi rutin dalam buku besar tentang Mathematica sejak lama, dan saya telah menggunakan variasi pada implementasi ini untuk beberapa waktu sekarang. Ini pada dasarnya melakukan sampel linier kasar atas domain yang diminati, kemudian kembali untuk memperbaiki daerah dengan kelengkungan tinggi. Ada kemungkinan bahwa beberapa fitur yang sangat tajam terlewatkan, tetapi dalam praktiknya saya menemukan ini sangat langka. File ini juga berisi versi paralel.

Victor Liu
sumber
1
Buku apa itu? Apakah itu yang saya tautkan? Apakah Anda tahu apa yang sebenarnya berubah dalam implementasinya antara versi 5 dan 6?
Szabolcs
1
@Szabolcs: Tidak, saya yakin itu ada di bagian buku ini 4.1.3. Deskripsi ini menggunakan versi Mathematica yang sangat lama. Versi yang lebih baru (mungkin dimulai dari v6) mendeteksi asimtot vertikal dan menghapus garis vertikal palsu dari plot. Versi baru pasti melakukan banyak preprocessing simbolis canggih untuk mengatasi diskontinuitas, daerah yang tidak ditentukan, dan pemotongan cabang.
Victor Liu
Pra-pemrosesan simbolis yang Anda bicarakan disebut "deteksi pengecualian" dalam dokumentasi. Itu dapat dimatikan dengan Exclusions -> Noneatau dengan menyembunyikan struktur fungsi Anda dari Plotdengan mendefinisikannya sebagai f[x_?NumericQ] := .... Ini bukan yang saya maksud ketika saya bertanya tentang perubahan. Saya percaya ada beberapa perubahan pada algoritma, karena v5 dan v6 dijadikan sampel pada titik yang berbeda. Saat ini saya tidak dapat menguji pada v5 untuk membandingkan lagi.
Szabolcs
"Buku Panduan Grafik Mathematica" berisi diskusi yang sangat baik tentang masalah tersebut. Saya terutama suka bahwa pendeknya algoritma juga dijelaskan.
soegaard
Saya tidak lagi dapat menemukan file GitHub, apakah sudah pindah?
Andrei
12

Mengetahui bagaimana CAS lainnya melakukan ini dapat membantu Anda.

f(x)(x(t),y(t))f(x)

  1. Mulailah dengan kisi-kisi titik spasi secara teratur pada domain yang merencanakan. (Dalam Mathematica, ada parameter untuk mengontrol berapa yang harus diambil, yang disebut PlotPoints.)

  2. (x1,f(x1)),(x2,f(x2)),(x3,f(x3))x1+x22x2+x32

  3. Jika kami belum mencapai batas iterasi (ditetapkan oleh MaxRecursiondi Mathematica), ulangi dari langkah 2.

Beberapa dari ini dibahas dalam buku Mathematica in Action oleh Stan Wagon, yang dapat Anda lihat di sini di Google Books .

Saya menerapkan algoritma ini sebelumnya untuk memiliki kontrol yang lebih baik atas berapa kali fungsi perhitungan saya yang mahal dievaluasi. Berikut kode Mathematica untuk langkah 2:

nd[{points_, values_}] :=
Transpose@{(Drop[points, 1] + Drop[points, -1])/2,
Differences[values]/Differences[points]}

subdivide1d[result_, resolution_, maxAngle_: 10] :=
  Module[
    {deriv, angle, dangle, pos, nf},
    deriv = nd[result\[Transpose]];
    angle = ArcTan[#2] & @@@ deriv;
    dangle = Differences[angle];
    pos = Flatten@Position[dangle, d_ /; Abs[d] > maxAngle/180 Pi];
    pos = Union[pos, pos + 1];
    nf = Nearest[result[[All, 1]]];
    Select[deriv[[pos, 1]], Abs[# - First@nf[#]] > resolution &]
  ]
Szabolcs
sumber
7

Halaman web MathWorld pada Function Graphs berisi referensi ke beberapa makalah yang tampaknya relevan pada plot fungsi adaptif. Mengutip halaman:

Rutinitas yang baik untuk memplot grafik menggunakan algoritma adaptif yang memplot lebih banyak titik di daerah di mana fungsi berubah paling cepat (Wagon 1991, Math Works 1992, Heck 1993, Wickham-Jones 1994). Tupper (1996) telah mengembangkan suatu algoritma [...]

Di sisi lain, di Google saya menemukan kertas

www.cs.uic.edu/~wilkinson/Publications/plotfunc.pdf

yang menjelaskan cara memilih domain dengan benar dan hal-hal lain. Semoga bermanfaat bagi Anda.

astrojuanlu
sumber
1

Saya menemukan topik ini dan berpikir saya harus berbagi halaman masalah pengembang untuk menambahkan ini ke perpustakaan Julia Plots.jl. Kami mencoba banyak teknik untuk melihat apa yang akan memberikan hasil yang baik, mulai dari catatan tentang implementasi Mathematica. Menambahkan beberapa pemangkasan, gangguan kecil untuk tidak memulai tepat pada titik akhir interval, batas rekursi, dan penaksir kesalahan jala ganda semua diperlukan untuk "melakukannya dengan benar". Utas juga mengarahkan Anda ke kode sumber terbuka untuk implementasi. Jadi memang butuh sedikit penyesuaian, tetapi menambahkan fitur-fitur itu membuatnya cukup kuat (menurut tes, seperti yang ditunjukkan pada utas).

Chris Rackauckas
sumber