Bagaimana cara kerja fungsi trigonometri?

102

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.

Jurassic_C
sumber
Apakah Anda bingung tentang apa itu fungsi trigonometri atau bagaimana penerapannya?
Kyle Cronin
15
Saya tahu apa itu. Saya tahu apa yang mereka lakukan. Saya tahu bagaimana menentukan mana yang saya butuhkan untuk tujuan apa. Saya dapat memberi tahu Anda semua tentang hubungan antara sudut dan jarak. Apa yang saya cari lebih sejalan dengan jawaban John D. Cook. Dan semua orang yang menyebutkan algoritme sebenarnya
Jurassic_C
Ini pertanyaan yang bagus. Misalnya, sinus, cosinus, dan garis singgung adalah fungsi transendental dan sulit dipecahkan ... Di sisi lain, keduanya dapat ditentukan dengan menggunakan ekspansi deret Taylor sederhana yang akan memberi Anda jawaban yang benar hingga tingkat akurasi yang terbatas yg dibutuhkan.
Alex

Jawaban:

144

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.

John D. Cook
sumber
4
Jawaban yang bagus - meskipun CORDIC tidak benar-benar membutuhkan pengurangan jarak (sebenarnya ini pada dasarnya adalah algoritma pengurangan jarak dalam dirinya sendiri); ini berfungsi dengan baik untuk sudut antara -pi / 2 dan + pi / 2, jadi Anda hanya perlu melakukan rotasi vektor 180 derajat untuk sudut di luar rentang itu.
Jason S
3
Implementasi yang menggunakan pendekatan polinomial mungkin sering menggunakan deret Taylor, tetapi biasanya harus menggunakan koefisien yang telah ditentukan dengan algoritma Remez. lolengine.net/blog/2011/12/21/better-function-approximations
Pascal Cuoq
1
Perhatikan bahwa tabel nilai yang digunakan oleh CORDIC harus sudah dihitung sebelumnya. Jadi, Taylor mungkin masih digunakan pada "waktu kompilasi".
Rhubbarb
2
Tampaknya jawaban ini bertentangan dengan jawaban yang diterima berperingkat tinggi untuk pertanyaan serupa ini: stackoverflow.com/questions/2284860/… . Jawaban ini mengatakan bahwa fungsi sin () sebagian besar diimplementasikan pada tingkat perangkat keras, sementara yang lain mengatakan di C.
Perry
48

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:

  1. bahwa kesalahan maksimum dari pendekatan deret Taylor pada rentang tertentu, jauh lebih besar daripada kesalahan maksimum dari pendekatan Chebyshev pada derajat yang sama. (Untuk kesalahan yang sama, Anda bisa lolos dengan satu istilah lebih sedikit dengan Chebyshev, yang berarti kinerja lebih cepat)
  2. Pengurangan jangkauan adalah kemenangan besar. Ini karena kontribusi polinomial orde tinggi menyusut ketika interval aproksimasi lebih kecil.
  3. Jika Anda tidak dapat menghindari pengurangan jangkauan, koefisien Anda perlu disimpan dengan lebih presisi.

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)

  • Taylor: max error sekitar 4.5E-3, f (x) = xx 3 /6 + x 5 /120
  • Chebyshev: kesalahan maks sekitar 7e-5, f (x) = 0.9996949x-0.1656700x 3 + 0.0075134x 5

Range = -pi / 2 sampai + pi / 2, derajat 7 (4 suku)

  • Taylor: max error sekitar 1.5 E-4, f (x) = xx 3 /6 + x 5 /120 x 7 /5040
  • Chebyshev: kesalahan maks sekitar 6e-7, f (x) = 0.99999660x-0.16664824x 3 + 0.00830629x 5 -0.00018363x 7

Range = -pi / 4 sampai + pi / 4, derajat 3 (2 suku)

  • Taylor: max error sekitar 2.5e-3, f (x) = xx 3 /6
  • Chebyshev: kesalahan maks sekitar 1.5e-4, f (x) = 0.999x-0.1603x 3

Range = -pi / 4 sampai + pi / 4, derajat 5 (3 suku)

  • Taylor: max error sekitar 3.5E-5, f (x) = xx 3 /6 + x 5
  • Chebyshev: kesalahan maks sekitar 6e-7, f (x) = 0.999995x-0.1666016x 3 + 0.0081215x 5

Range = -pi / 4 sampai + pi / 4, derajat 7 (4 suku)

  • Taylor: max error sekitar 3e-7, f (x) = xx 3 /6 + x 5 /120 x 7 /5040
  • Chebyshev: kesalahan maks sekitar 1.2e-9, f (x) = 0.999999986x-0.166666367x 3 + 0.008331584x 5 -0.000194621x 7
Jason S
sumber
2
Komentar ini salah. Ada waktu dan tempat untuk setiap perkiraan. Jika Anda tidak cukup mengetahui analisis untuk menentukan wilayah konvergensi untuk perkiraan deret APA PUN, Anda TIDAK boleh menggunakannya. Itu berlaku untuk seri Taylor, Chebyshev, Padé, dll. Seri Taylor seringkali Cukup Baik.
kquinn
4
: shrug: Saya tidak tahu tentang Anda tapi saya tidak pernah tertarik untuk mengevaluasi suatu fungsi di lingkungan kecil yang hanya sekitar satu titik. Bahkan kuadrat terkecil yang pas dalam suatu interval cukup mudah dilakukan. Siapa pun yang menggunakan seri Taylor melewatkan intinya.
Jason S
1
@ kquinn: wilayah konvergensi untuk pendekatan Chebyshev bukanlah konsep yang berguna karena interval penghitungannya merupakan masukan eksplisit untuk proses.
Jason S
2
Upvoting karena responden tahu Hart ada. : smile: Hart adalah referensi klasik di sini, meskipun sulit ditemukan ketika saya membeli salinannya (dicetak) 25 tahun yang lalu. Layak setiap sen. Pengurangan jangkauan sedapat mungkin, ditambah dengan pendekatan yang tepat, baik itu Pade, Chebychev, bahkan seri Taylor yang sesuai, adalah pendekatan yang baik. Pendekatan Pade atau Chebychev biasanya merupakan pilihan yang lebih baik daripada seri Taylor.
3
??? Apa bedanya? Deret Taylor ke derajat ke-17 untuk menghitung sin (x) dari -2pi hingga + 2pi mungkin bisa dikalahkan oleh Chebyshev dengan polinomial derajat ke-7 atau ke-9. Saya tidak akan kesulitan membuat pernyataan, "Jika Anda memiliki kendala waktu saat menebang pohon, sebaiknya Anda tidak menggunakan gergaji tangan. Gunakan gergaji mesin." Mungkin saya harus mengubah kata dari "seharusnya tidak" menjadi sesuatu seperti "Saya tidak akan merekomendasikan menggunakan seri Taylor". Tentu, Anda dapat menggunakan seri Taylor dalam beberapa kasus, tetapi akurasi dan kinerja Anda akan bermasalah. Yang saya maksud dengan kinerja adalah waktu eksekusi CPU.
Jason S
14

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.

Jon Galloway
sumber
6

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.

Parappa
sumber
1

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.

Joshua Howard
sumber
0

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.

Roger Wehage
sumber
-5

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).

jeffD
sumber