Jadi dalam matematika sekolah menengah, dan mungkin perguruan tinggi, kita diajari cara menggunakan fungsi trigonometri, apa fungsinya, dan jenis masalah apa yang mereka pecahkan. Tapi mereka selalu disajikan kepada saya sebagai kotak hitam. Jika Anda membutuhkan Sine atau Cosine dari sesuatu, Anda menekan tombol sin atau cos pada kalkulator Anda dan Anda sudah siap. Itu bagus.
Yang saya ingin tahu adalah bagaimana fungsi trigonometri biasanya diimplementasikan.
algorithm
math
trigonometry
Jurassic_C
sumber
sumber
Jawaban:
Pertama, Anda harus melakukan semacam pengurangan jarak. Fungsi pemicu bersifat periodik, jadi Anda perlu mengurangi argumen ke interval standar. Sebagai permulaan, Anda bisa mengurangi sudut antara 0 dan 360 derajat. Tetapi dengan menggunakan beberapa identitas, Anda menyadari bahwa Anda dapat bertahan dengan lebih sedikit. Jika Anda menghitung sinus dan cosinus untuk sudut antara 0 dan 45 derajat, Anda dapat melakukan bootstrap untuk menghitung semua fungsi trigonometri untuk semua sudut.
Setelah Anda mengurangi argumen Anda, kebanyakan chip menggunakan algoritma CORDIC untuk menghitung sinus dan cosinus. Anda mungkin mendengar orang mengatakan bahwa komputer menggunakan seri Taylor. Kedengarannya masuk akal, tapi itu tidak benar. Algoritme CORDIC jauh lebih cocok untuk implementasi perangkat keras yang efisien . ( Pustaka perangkat lunak dapat menggunakan seri Taylor, katakanlah pada perangkat keras yang tidak mendukung fungsi trigonometri.) Mungkin ada beberapa pemrosesan tambahan, menggunakan algoritme CORDIC untuk mendapatkan jawaban yang cukup baik tetapi kemudian melakukan sesuatu yang lain untuk meningkatkan akurasi.
Ada beberapa penyempurnaan di atas. Misalnya, untuk sudut yang sangat kecil theta (dalam radian), sin (theta) = theta ke semua presisi yang Anda miliki, jadi lebih efisien jika mengembalikan theta daripada menggunakan algoritme lain. Jadi dalam praktiknya ada banyak logika kasus khusus untuk memeras semua kinerja dan keakuratan yang mungkin. Chips dengan pasar yang lebih kecil mungkin tidak melakukan banyak upaya pengoptimalan.
sumber
sunting: Jack Ganssle memiliki diskusi yang layak dalam bukunya tentang sistem tertanam, "Buku Pegangan Firmware" .
FYI: Jika Anda memiliki batasan akurasi dan kinerja, deret Taylor sebaiknya tidak digunakan untuk memperkirakan fungsi untuk tujuan numerik. (Simpan untuk kursus Kalkulus Anda.) Mereka menggunakan analitik suatu fungsi pada satu titik , misalnya fakta bahwa semua turunannya ada pada titik tersebut. Mereka tidak selalu menyatu dalam interval minat. Seringkali mereka melakukan pekerjaan yang buruk dalam mendistribusikan akurasi perkiraan fungsi agar menjadi "sempurna" tepat di dekat titik evaluasi; kesalahan biasanya membesar ke atas saat Anda menjauh darinya. Dan jika Anda memiliki fungsi dengan turunan tidak kontinu (misalnya gelombang persegi, gelombang segitiga, dan integralnya), deret Taylor akan memberikan jawaban yang salah.
Solusi "mudah" terbaik, saat menggunakan polinomial dengan derajat maksimum N untuk mendekati fungsi tertentu f (x) selama interval x0 <x <x1, adalah dari pendekatan Chebyshev ; lihat Resep Numerik untuk diskusi yang baik. Perhatikan bahwa Tj (x) dan Tk (x) dalam artikel Wolfram I yang ditautkan menggunakan cos dan invers cosinus, ini adalah polinomial dan dalam praktiknya Anda menggunakan rumus pengulangan untuk mendapatkan koefisien. Sekali lagi, lihat Resep Numerik.
sunting: Wikipedia memiliki artikel semi-layak tentang teori pendekatan . Salah satu sumber yang mereka kutip (Hart, "Computer Approximations") sudah tidak dicetak lagi (& salinan bekas cenderung mahal) tetapi membahas banyak detail tentang hal-hal seperti ini. (Jack Ganssle menyebutkan ini dalam edisi 39 buletinnya The Embedded Muse .)
sunting 2: Berikut ini beberapa metrik kesalahan yang nyata (lihat di bawah) untuk Taylor vs. Chebyshev untuk sin (x). Beberapa poin penting yang perlu diperhatikan:
Jangan salah paham: Seri Taylor akan bekerja dengan baik untuk sinus / cosinus (dengan presisi yang wajar untuk kisaran -pi / 2 hingga + pi / 2; secara teknis, dengan persyaratan yang cukup, Anda dapat mencapai presisi yang diinginkan untuk semua input nyata, tetapi cobalah untuk menghitung cos (100) menggunakan deret Taylor dan Anda tidak dapat melakukannya kecuali jika Anda menggunakan aritmatika presisi-arbitrer). Jika saya terjebak di pulau terpencil dengan kalkulator nonscientific, dan saya perlu menghitung sinus dan cosinus, saya mungkin akan menggunakan deret Taylor karena koefisiennya mudah diingat. Tapi aplikasi dunia nyata untuk harus menulis dosa Anda sendiri () atau cos () fungsi cukup langka bahwa Anda akan terbaik dari menggunakan implementasi yang efisien untuk mencapai akurasi yang diinginkan - yang seri Taylor adalah tidak .
Range = -pi / 2 sampai + pi / 2, derajat 5 (3 suku)
Range = -pi / 2 sampai + pi / 2, derajat 7 (4 suku)
Range = -pi / 4 sampai + pi / 4, derajat 3 (2 suku)
Range = -pi / 4 sampai + pi / 4, derajat 5 (3 suku)
Range = -pi / 4 sampai + pi / 4, derajat 7 (4 suku)
sumber
Saya yakin mereka dihitung menggunakan Taylor Series atau CORDIC . Beberapa aplikasi yang banyak menggunakan fungsi trigonometri (permainan, grafik) membuat tabel trigonometri ketika mereka mulai sehingga mereka hanya dapat mencari nilai daripada menghitungnya berulang-ulang.
sumber
Lihat artikel Wikipedia tentang fungsi trigonometri. Tempat yang baik untuk mempelajari tentang penerapannya dalam kode adalah Resep Numerik .
Saya bukan ahli matematika, tetapi pemahaman saya tentang dari mana sin, cos, dan tan "berasal" adalah bahwa mereka, dalam arti tertentu, diamati saat Anda mengerjakan segitiga siku-siku. Jika Anda mengukur panjang sisi dari sekelompok segitiga siku-siku yang berbeda dan memplot titik-titik pada grafik, Anda bisa mendapatkan sin, cos, dan tan dari itu. Seperti yang ditunjukkan oleh Harper Shelby, fungsi secara sederhana didefinisikan sebagai properti segitiga sudut siku-siku.
Pemahaman yang lebih canggih dicapai dengan memahami bagaimana rasio ini berhubungan dengan geometri lingkaran, yang mengarah ke radian dan semua kebaikan itu. Semuanya ada di entri Wikipedia.
sumber
Paling umum untuk komputer, representasi deret pangkat digunakan untuk menghitung sinus dan cosinus dan ini digunakan untuk fungsi trigonometri lainnya. Memperluas seri ini menjadi sekitar 8 istilah menghitung nilai yang diperlukan untuk akurasi yang mendekati mesin epsilon (angka floating point bukan nol terkecil yang dapat ditahan).
Metode CORDIC lebih cepat karena diterapkan pada perangkat keras, tetapi metode ini terutama digunakan untuk sistem tertanam dan bukan komputer standar.
sumber
Saya ingin memperluas jawaban yang diberikan oleh @Jason S. Menggunakan metode subdivisi domain yang mirip dengan yang dijelaskan oleh @Jason S dan menggunakan pendekatan seri Maclaurin, kecepatan rata-rata (2-3) X di atas tan (), sin () , cos (), atan (), asin (), dan acos () fungsi yang dibangun ke dalam kompiler gcc dengan -O3 optimasi tercapai. Fungsi pendekatan seri Maclaurin terbaik yang dijelaskan di bawah ini mencapai akurasi presisi ganda.
Untuk fungsi tan (), sin (), dan cos (), dan untuk kesederhanaan, domain 0 hingga 2pi + pi / 80 yang tumpang tindih dibagi menjadi 81 interval yang sama dengan "titik jangkar" pada pi / 80, 3pi / 80, ..., 161pi / 80. Kemudian tan (), sin (), dan cos () dari 81 titik jangkar ini dievaluasi dan disimpan. Dengan bantuan identitas trigonometri, satu fungsi deret Maclaurin dikembangkan untuk setiap fungsi trigonometri. Setiap sudut antara ± tak terhingga dapat dikirimkan ke fungsi perkiraan trigonometri karena fungsi pertama menerjemahkan sudut masukan ke domain 0 hingga 2pi. Overhead terjemahan ini termasuk dalam overhead aproksimasi.
Metode serupa dikembangkan untuk fungsi atan (), asin (), dan acos (), di mana domain -1.0 hingga 1.1 yang tumpang tindih dibagi menjadi 21 interval yang sama dengan titik jangkar pada -19/20, -17/20, .. ., 19/20, 21/20. Kemudian hanya atan () dari 21 titik jangkar ini yang disimpan. Sekali lagi, dengan bantuan identitas trigonometri terbalik, satu fungsi deret Maclaurin dikembangkan untuk fungsi atan (). Hasil dari fungsi atan () kemudian digunakan untuk mendekati asin () dan acos ().
Karena semua fungsi pendekatan trigonometri terbalik didasarkan pada fungsi perkiraan atan (), nilai masukan argumen presisi ganda apa pun diperbolehkan. Namun masukan argumen ke fungsi pendekatan asin () dan acos () dipotong ke domain ± 1 karena nilai apa pun di luarnya tidak berarti.
Untuk menguji fungsi yang mendekati, satu miliar evaluasi fungsi acak dipaksa untuk dievaluasi (yaitu, compiler pengoptimalan -O3 tidak diizinkan untuk melewati evaluasi sesuatu karena beberapa hasil yang dihitung tidak akan digunakan.) Untuk menghilangkan bias dalam mengevaluasi satu miliar bilangan acak dan memproses hasilnya, biaya menjalankan tanpa mengevaluasi fungsi trigonometri atau inversi dilakukan terlebih dahulu. Bias ini kemudian dikurangkan dari setiap pengujian untuk mendapatkan perkiraan waktu evaluasi fungsi yang lebih representatif.
Tabel 2. Waktu yang dihabiskan dalam hitungan detik untuk menjalankan fungsi atau fungsi yang ditunjukkan satu miliar kali. Estimasi diperoleh dengan mengurangi biaya waktu untuk mengevaluasi satu miliar bilangan acak yang ditunjukkan pada baris pertama Tabel 1 dari baris yang tersisa pada Tabel 1.
Waktu yang dihabiskan di tan (): 18.0515 18.2545
Waktu yang dihabiskan di TAN3 (): 5.93853 6.02349
Waktu yang dihabiskan di TAN4 (): 6.72216 6.99134
Waktu yang dihabiskan dalam sin () dan cos (): 19.4052 19.4311
Waktu yang dihabiskan di SINCOS3 (): 7.85564 7.92844
Waktu yang dihabiskan di SINCOS4 (): 9.36672 9.57946
Waktu yang dihabiskan di atan (): 15.7160 15.6599
Waktu yang dihabiskan di ATAN1 (): 6.47800 6.55230
Waktu yang dihabiskan di ATAN2 (): 7.26730 7.24885
Waktu yang dihabiskan di ATAN3 (): 8.15299 8.21284
Waktu yang dihabiskan di asin () dan acos (): 36.8833 36.9496
Waktu yang dihabiskan di ASINCOS1 (): 10.1655 9.78479
Waktu yang dihabiskan di ASINCOS2 (): 10.6236 10.6000
Waktu yang dihabiskan di ASINCOS3 (): 12.8430 12.0707
(Demi menghemat ruang, Tabel 1 tidak diperlihatkan.) Tabel 2 menunjukkan hasil dari dua proses terpisah dari satu miliar evaluasi dari setiap fungsi perkiraan. Kolom pertama adalah proses pertama dan kolom kedua adalah proses kedua. Angka '1', '2', '3' atau '4' pada nama fungsi menunjukkan jumlah istilah yang digunakan dalam fungsi deret Maclaurin untuk mengevaluasi perkiraan trigonometri atau inversi trigonometri tertentu. SINCOS # () berarti bahwa sin dan cos dievaluasi pada waktu yang sama. Demikian juga, ASINCOS # () berarti asin dan acos dievaluasi pada waktu yang sama. Ada sedikit biaya tambahan dalam mengevaluasi kedua kuantitas secara bersamaan.
Hasilnya menunjukkan bahwa peningkatan jumlah persyaratan sedikit meningkatkan waktu eksekusi seperti yang diharapkan. Bahkan jumlah suku terkecil memberikan akurasi sekitar 12-14 digit di mana-mana kecuali untuk perkiraan tan () di dekat dimana nilainya mendekati ± tak terhingga. Orang akan berharap bahkan fungsi tan () memiliki masalah di sana.
Hasil serupa diperoleh pada laptop MacBook Pro kelas atas di Unix dan pada komputer desktop kelas atas di Linux.
sumber
Jika Anda meminta penjelasan yang lebih fisik tentang sin, cos, dan tan, pertimbangkan bagaimana hubungannya dengan segitiga siku-siku. Nilai numerik sebenarnya dari cos (lambda) dapat ditemukan dengan membentuk segitiga siku-siku dengan salah satu sudutnya adalah lambda dan membagi panjang sisi segitiga yang berdekatan dengan lambda dengan panjang hipotenusa. Demikian pula untuk sin, gunakan sisi yang berlawanan dibagi dengan sisi miring. Untuk garis singgung gunakan sisi yang berlawanan dibagi dengan sisi yang berdekatan. Memonik klasik untuk mengingat ini adalah SOHCAHTOA (diucapkan socatoa).
sumber