Làm thế nào để các hàm lượng giác hoạt động?


102

Vì vậy, trong môn toán trung học, và có thể là đại học, chúng ta được dạy cách sử dụng các hàm trig, chúng làm gì và chúng giải quyết những vấn đề gì. Nhưng chúng luôn được trình bày với tôi như một chiếc hộp đen. Nếu bạn cần sin hoặc Cosine của một thứ gì đó, bạn nhấn nút sin hoặc cos trên máy tính của mình và bạn đã sẵn sàng. Cái nào tốt.

Điều tôi tự hỏi là làm thế nào các hàm lượng giác thường được thực hiện.


Bạn có nhầm lẫn về các hàm trig là gì hoặc chúng được triển khai như thế nào?
Kyle Cronin

15
Tôi biết chúng là gì. Tôi biết họ làm gì. Tôi biết làm thế nào để xác định tôi cần cho mục đích gì. Tôi có thể cho bạn biết tất cả về mối quan hệ giữa góc và khoảng cách. Những gì tôi đang tìm kiếm là nhiều hơn từ câu trả lời của John D. Cook. Và những người khác đã đề cập đến các thuật toán thực tế
Jurassic_C

Đây là một câu hỏi hay. Ví dụ: sin, cosine và tiếp tuyến là các hàm siêu việt và chúng rất khó giải ... Mặt khác, chúng có thể được xác định bằng cách sử dụng khai triển chuỗi Taylor đơn giản sẽ cung cấp cho bạn câu trả lời chính xác với bất kỳ mức độ chính xác hữu hạn nào cần thiết.
Alex

Câu trả lời:


144

Đầu tiên, bạn phải thực hiện một số loại giảm phạm vi. Các hàm Trig là tuần hoàn, vì vậy bạn cần giảm các đối số xuống một khoảng tiêu chuẩn. Để bắt đầu, bạn có thể giảm các góc từ 0 đến 360 độ. Nhưng bằng cách sử dụng một vài đặc điểm nhận dạng, bạn nhận ra mình có thể kiếm được ít tiền hơn. Nếu bạn tính sin và cosin cho các góc từ 0 đến 45 độ, bạn có thể bắt đầu theo cách của mình để tính tất cả các hàm trig cho mọi góc.

Khi bạn đã giảm đối số của mình, hầu hết các chip sử dụng thuật toán CORDIC để tính toán các sin và cosin. Bạn có thể nghe mọi người nói rằng máy tính sử dụng dòng Taylor. Điều đó nghe có vẻ hợp lý, nhưng nó không phải sự thật. Các thuật toán CORDIC phù hợp hơn nhiều với việc triển khai phần cứng hiệu quả . ( Thư viện phần mềm có thể sử dụng chuỗi Taylor, chẳng hạn như trên phần cứng không hỗ trợ các hàm trig.) Có thể có một số xử lý bổ sung, sử dụng thuật toán CORDIC để nhận được câu trả lời khá tốt nhưng sau đó làm điều gì đó khác để cải thiện độ chính xác.

Có một số cải tiến ở trên. Ví dụ, đối với các góc rất nhỏ theta (tính bằng radian), sin (theta) = theta với tất cả độ chính xác bạn có, vì vậy, chỉ cần trả về theta sẽ hiệu quả hơn là sử dụng một số thuật toán khác. Vì vậy, trong thực tế có rất nhiều logic trường hợp đặc biệt để loại bỏ tất cả hiệu suất và độ chính xác có thể. Các chip có thị trường nhỏ hơn có thể không cần nỗ lực tối ưu hóa nhiều.


4
Câu trả lời tuyệt vời - mặc dù CORDIC không thực sự cần giảm phạm vi mỗi lần (trên thực tế, về cơ bản nó là một thuật toán giảm phạm vi theo đúng nghĩa của nó); nó hoạt động tốt đối với các góc từ -pi / 2 đến + pi / 2, vì vậy bạn chỉ cần thực hiện quay vectơ 180 độ cho các góc ngoài phạm vi đó.
Jason S

3
Các triển khai sử dụng phép gần đúng đa thức có thể thường sử dụng chuỗi Taylor, nhưng chúng thường nên sử dụng các hệ số đã được xác định bằng thuật toán Remez. lolengine.net/blog/2011/12/21/better- Chức năng
Pascal Cuoq

1
Lưu ý rằng bảng giá trị được CORDIC sử dụng phải được tính toán trước. Vì vậy, Taylor có thể vẫn được sử dụng tại "thời gian biên dịch".
Rhubbarb

2
Có vẻ như câu trả lời này mâu thuẫn với câu trả lời được chấp nhận được đánh giá cao cho câu hỏi tương tự này: stackoverflow.com/questions/2284860/… . Câu trả lời này nói rằng hàm sin () chủ yếu được triển khai ở cấp phần cứng, trong khi câu kia nói ở C.
Perry

48

chỉnh sửa: Jack Ganssle đã có một cuộc thảo luận đàng hoàng trong cuốn sách của mình về các hệ thống nhúng, "Sổ tay phần vững" .

FYI: Nếu bạn có các hạn chế về độ chính xác và hiệu suất, chuỗi Taylor không nên được sử dụng để ước lượng các hàm cho mục đích số. (Lưu chúng cho các khóa học Giải tích của bạn.) Chúng sử dụng tính phân tích của một hàm tại một điểm duy nhất , ví dụ thực tế là tất cả các đạo hàm của nó tồn tại tại điểm đó. Chúng không nhất thiết phải hội tụ trong khoảng thời gian quan tâm. Thường thì họ làm một công việc tệ hại là phân phối độ chính xác của hàm xấp xỉ để được "hoàn hảo" ngay gần điểm đánh giá; lỗi thường phóng to lên khi bạn rời khỏi nó. Và nếu bạn có một hàm với bất kỳ đạo hàm không liên tục nào (ví dụ: sóng vuông, sóng tam giác và tích phân của chúng), một chuỗi Taylor sẽ cho bạn câu trả lời sai.

Giải pháp "dễ" nhất, khi sử dụng đa thức có bậc lớn nhất N để tính gần đúng hàm f (x) đã cho trên một khoảng x0 <x <x1, là từ phép gần đúng Chebyshev ; xem Bí quyết số để có một cuộc thảo luận tốt. Lưu ý rằng Tj (x) và Tk (x) trong bài viết Wolfram mà tôi đã liên kết để sử dụng cos và nghịch đảo cosin, đây là các đa thức và trong thực tế, bạn sử dụng công thức truy hồi để lấy các hệ số. Một lần nữa, hãy xem Bí quyết số.

sửa: Wikipedia có một bài viết khá tốt về lý thuyết xấp xỉ . Một trong những nguồn mà họ trích dẫn (Hart, "Phương pháp xấp xỉ máy tính") đã hết bản in (& các bản sao đã qua sử dụng có xu hướng đắt tiền) nhưng đi sâu vào chi tiết về những thứ như thế này. (Jack Ganssle đề cập đến vấn đề này trong số 39 của bản tin The Embedded Muse .)

chỉnh sửa 2: Đây là một số chỉ số lỗi hữu hình (xem bên dưới) cho Taylor so với Chebyshev cho sin (x). Một số điểm quan trọng cần lưu ý:

  1. rằng sai số lớn nhất của một xấp xỉ chuỗi Taylor trong một phạm vi nhất định, lớn hơn nhiều so với sai số lớn nhất của một xấp xỉ Chebyshev có cùng mức độ. (Đối với cùng một lỗi, bạn có thể loại bỏ một số thuật ngữ ít hơn với Chebyshev, có nghĩa là hiệu suất nhanh hơn)
  2. Giảm phạm vi là một chiến thắng lớn. Điều này là do sự đóng góp của các đa thức bậc cao sẽ giảm xuống khi khoảng thời gian xấp xỉ nhỏ hơn.
  3. Nếu bạn không thể giảm phạm vi, các hệ số của bạn cần được lưu trữ với độ chính xác cao hơn.

Đừng hiểu sai ý tôi: Dòng Taylor sẽ hoạt động đúng với sin / cosine (với độ chính xác hợp lý cho phạm vi -pi / 2 đến + pi / 2; về mặt kỹ thuật, với đủ điều kiện, bạn có thể đạt được bất kỳ độ chính xác mong muốn nào cho tất cả các đầu vào thực, nhưng hãy thử tính cos (100) bằng chuỗi Taylor và bạn không thể làm được điều đó trừ khi bạn sử dụng số học có độ chính xác tùy ý). Nếu tôi bị mắc kẹt trên một hòn đảo hoang với một chiếc máy tính phi khoa học, và tôi cần tính sin và cosine, có lẽ tôi sẽ sử dụng chuỗi Taylor vì các hệ số rất dễ nhớ. Nhưng các ứng dụng trong thế giới thực để phải viết các hàm sin () hoặc cos () của riêng bạn là đủ hiếm để bạn nên sử dụng cách triển khai hiệu quả để đạt được độ chính xác mong muốn - điều mà chuỗi Taylor không như vậy .

Phạm vi = -pi / 2 đến + pi / 2, bậc 5 (3 số hạng)

  • Taylor: lỗi tối đa khoảng 4.5e-3, f (x) = xx 3 /6 + x 5 /120
  • Chebyshev: lỗi tối đa khoảng 7e-5, f (x) = 0,9996949x-0,1656700x 3 + 0,0075134x 5

Phạm vi = -pi / 2 đến + pi / 2, độ 7 (4 số hạng)

  • Taylor: lỗi tối đa khoảng 1.5E-4, f (x) = xx 3 /6 + x 5 /120 x 7 /5040
  • Chebyshev: lỗi tối đa khoảng 6e-7, f (x) = 0,99999660x-0,16664824x 3 + 0,00830629x 5 -0,00018363x 7

Phạm vi = -pi / 4 đến + pi / 4, bậc 3 (2 số hạng)

  • Taylor: lỗi tối đa khoảng 2.5e-3, f (x) = xx 3 /6
  • Chebyshev: lỗi tối đa khoảng 1,5e-4, f (x) = 0,999x-0,1603x 3

Phạm vi = -pi / 4 đến + pi / 4, độ 5 (3 số hạng)

  • Taylor: lỗi tối đa khoảng 3,5e-5, f (x) = xx 3/6 + x 5
  • Chebyshev: lỗi tối đa khoảng 6e-7, f (x) = 0,999995x-0,1666016x 3 + 0,0081215x 5

Phạm vi = -pi / 4 đến + pi / 4, độ 7 (4 số hạng)

  • Taylor: lỗi tối đa xung quanh 3e-7, f (x) = xx 3 /6 + x 5 /120 x 7 /5040
  • Chebyshev: lỗi tối đa xung quanh 1,2e-9, f (x) = 0,999999986x-0,166666367x 3 + 0,008331584x 5 -0,000194621x 7

2
Nhận xét này là sai. Có một thời gian và một địa điểm cho mọi ước tính. Nếu bạn không biết phân tích đủ để xác định vùng hội tụ cho BẤT KỲ chuỗi xấp xỉ nào, bạn KHÔNG nên sử dụng nó. Điều đó đúng với loạt phim Taylor, Chebyshev, Padé, v.v. Chuỗi Taylor thường là Đủ Tốt.
kquinn

4
: shrug: Tôi không biết về bạn nhưng tôi chưa bao giờ quan tâm đến việc đánh giá một chức năng trong một khu phố nhỏ xung quanh chỉ một điểm. Ngay cả một hình vuông nhỏ nhất nhanh chóng vừa với một khoảng thời gian cũng khá dễ thực hiện. Bất cứ ai đang sử dụng chuỗi Taylor chỉ thiếu điểm.
Jason S

1
@kquinn: vùng hội tụ cho các phép xấp xỉ Chebyshev không phải là một khái niệm hữu ích vì khoảng thời gian mà chúng được tính là một đầu vào rõ ràng cho quá trình.
Jason S

2
Ủng hộ vì người trả lời biết Hart tồn tại. : smile: Hart là tài liệu tham khảo kinh điển ở đây, ngay cả khi nó rất khó tìm khi tôi mua một bản in (bản in) cách đây 25 năm. Đáng từng đồng từng cắc. Giảm phạm vi bất cứ khi nào có thể, cùng với một giá trị xấp xỉ thích hợp, có thể là chuỗi Pade, Chebychev, thậm chí cả chuỗi Taylor nếu thích hợp, là một cách tiếp cận tốt. Mặc dù vậy, các đại lượng xấp xỉ Pade hoặc Chebychev thường là lựa chọn tốt hơn so với chuỗi Taylor.

3
??? Làm thế nào là bất kỳ khác nhau? Chuỗi Taylor ra đến bậc 17 để tính sin (x) từ -2pi đến + 2pi có thể bị Chebyshev đánh bại với đa thức bậc 7 hoặc 9. Tôi sẽ không gặp vấn đề gì khi đưa ra tuyên bố, "Nếu bạn bị hạn chế về thời gian khi chặt cây, bạn không nên sử dụng cưa tay. Hãy sử dụng cưa máy." Có lẽ tôi nên đặt lại từ "shouldn’t" thành một thứ gì đó như "Tôi không khuyên bạn nên sử dụng chuỗi Taylor". Chắc chắn, bạn có thể sử dụng chuỗi Taylor trong một số trường hợp, nhưng độ chính xác và hiệu suất của bạn sẽ có vấn đề. Theo hiệu suất, ý tôi là thời gian thực thi của CPU.
Jason S

14

Tôi tin rằng chúng được tính toán bằng cách sử dụng Taylor Series hoặc CORDIC . Một số ứng dụng sử dụng nhiều hàm trig (trò chơi, đồ họa) sẽ tạo bảng trig khi chúng khởi động để chúng có thể chỉ tra cứu các giá trị thay vì tính toán lại chúng nhiều lần.


6

Xem bài viết trên Wikipedia về các hàm trig. Một nơi tốt để tìm hiểu về cách thực sự triển khai chúng trong mã là Công thức số .

Tôi không phải là một nhà toán học, nhưng sự hiểu biết của tôi về nguồn gốc của sin, cos và tan là chúng, theo một nghĩa nào đó, được quan sát thấy khi bạn làm việc với các tam giác vuông. Nếu bạn đo độ dài các cạnh của một loạt các tam giác vuông góc khác nhau và vẽ các điểm trên đồ thị, bạn có thể nhận được sin, cos và tan từ đó. Như Harper Shelby đã chỉ ra, các hàm được định nghĩa đơn giản là thuộc tính của tam giác vuông.

Một sự hiểu biết tinh vi hơn đạt được bằng cách hiểu những tỷ lệ này liên quan như thế nào đến hình học của đường tròn, dẫn đến radian và tất cả những điều tốt đẹp đó. Tất cả đều có trong mục nhập Wikipedia.


1

Thông thường nhất đối với máy tính, biểu diễn chuỗi lũy thừa được sử dụng để tính toán sin và cosin và chúng được sử dụng cho các hàm trig khác. Việc mở rộng chuỗi này ra khoảng 8 số hạng sẽ tính toán các giá trị cần thiết với độ chính xác gần bằng epsilon của máy (số dấu phẩy động khác 0 nhỏ nhất có thể được giữ).

Phương pháp CORDIC nhanh hơn vì nó được thực hiện trên phần cứng, nhưng nó chủ yếu được sử dụng cho các hệ thống nhúng chứ không phải máy tính tiêu chuẩn.


0

Tôi muốn mở rộng câu trả lời được cung cấp bởi @Jason S. Sử dụng phương pháp chia nhỏ miền tương tự như phương pháp được mô tả bởi @Jason S và sử dụng xấp xỉ chuỗi Maclaurin, tốc độ trung bình (2-3) X so với tan (), sin () Các hàm, cos (), atan (), asin () và acos () được tích hợp trong trình biên dịch gcc với tối ưu hóa -O3 đã đạt được. Các hàm xấp xỉ dòng Maclaurin tốt nhất được mô tả bên dưới đạt được độ chính xác gấp đôi.

Đối với các hàm tan (), sin () và cos () và để đơn giản, miền chồng chéo từ 0 đến 2pi + pi / 80 được chia thành 81 khoảng bằng nhau với "điểm neo" tại pi / 80, 3pi / 80, ..., 161pi / 80. Sau đó tan (), sin () và cos () của 81 điểm neo này được đánh giá và lưu trữ. Với sự trợ giúp của nhận dạng trig, một hàm chuỗi Maclaurin duy nhất đã được phát triển cho mỗi hàm trig. Bất kỳ góc nào giữa ± vô cực đều có thể được đưa vào các hàm xấp xỉ trig vì trước tiên các hàm dịch góc đầu vào sang miền 0 đến 2pi. Chi phí dịch thuật này được bao gồm trong chi phí ước tính.

Các phương pháp tương tự đã được phát triển cho các hàm atan (), asin () và acos (), trong đó miền chồng chéo -1.0 đến 1.1 được chia thành 21 khoảng bằng nhau với các điểm neo ở -19/20, -17/20, .. ., 19/20, 21/20. Sau đó, chỉ atan () trong số 21 điểm neo này được lưu trữ. Một lần nữa, với sự trợ giúp của các nhận dạng trig nghịch đảo, một hàm chuỗi Maclaurin duy nhất đã được phát triển cho hàm atan (). Kết quả của hàm atan () sau đó được sử dụng để tính gần đúng asin () và acos ().

Vì tất cả các hàm xấp xỉ trig nghịch đảo đều dựa trên hàm xấp xỉ atan (), mọi giá trị đầu vào đối số có độ chính xác kép đều được phép. Tuy nhiên, đầu vào đối số cho các hàm xấp xỉ asin () và acos () bị cắt ngắn thành miền ± 1 vì bất kỳ giá trị nào bên ngoài nó đều vô nghĩa.

Để kiểm tra các hàm gần đúng, một tỷ đánh giá hàm ngẫu nhiên buộc phải được đánh giá (nghĩa là, trình biên dịch tối ưu hóa -O3 không được phép bỏ qua đánh giá thứ gì đó vì một số kết quả tính toán sẽ không được sử dụng.) Để loại bỏ sai lệch khi đánh giá một tỷ số ngẫu nhiên và xử lý kết quả, chi phí của một lần chạy mà không đánh giá bất kỳ hàm trig hoặc nghịch đảo nào được thực hiện trước. Độ chệch này sau đó được trừ đi trong mỗi phép thử để thu được giá trị xấp xỉ đại diện hơn cho thời gian đánh giá hàm thực tế.

Bảng 2. Thời gian tính bằng giây để thực hiện chức năng được chỉ định hoặc các chức năng một tỷ lần. Các ước tính thu được bằng cách trừ đi chi phí thời gian để đánh giá một tỷ số ngẫu nhiên được hiển thị trong hàng đầu tiên của Bảng 1 với các hàng còn lại trong Bảng 1.

Thời gian ở tan (): 18.0515 18.2545

Thời gian ở TAN3 (): 5.93853 6.02349

Thời gian ở TAN4 (): 6.72216 6.99134

Thời gian dành cho sin () và cos (): 19.4052 19.4311

Thời gian dành cho SINCOS3 (): 7.85564 7.92844

Thời gian dành cho SINCOS4 (): 9.36672 9.57946

Thời gian sử dụng atan (): 15,7160 15,6599

Thời gian sử dụng ATAN1 (): 6.47800 6.55230

Thời gian sử dụng ATAN2 (): 7.26730 7.24885

Thời gian sử dụng ATAN3 (): 8.15299 8.21284

Thời gian sử dụng asin () và acos (): 36,8833 36,9496

Thời gian dành cho ASINCOS1 (): 10.1655 9.78479

Thời gian dành cho ASINCOS2 (): 10.6236 10.6000

Thời gian dành cho ASINCOS3 (): 12.8430 12.0707

(Vì lợi ích của việc tiết kiệm không gian, Bảng 1 không được hiển thị.) Bảng 2 cho thấy kết quả của hai lần chạy riêng biệt của một tỷ đánh giá của mỗi hàm gần đúng. Cột đầu tiên là lần chạy đầu tiên và cột thứ hai là lần chạy thứ hai. Các số '1', '2', '3' hoặc '4' trong tên hàm cho biết số thuật ngữ được sử dụng trong hàm chuỗi Maclaurin để đánh giá xấp xỉ trig cụ thể hoặc nghịch đảo. SINCOS # () có nghĩa là cả sin và cos đều được đánh giá cùng một lúc. Tương tự như vậy, ASINCOS # () có nghĩa là cả asin và acos đều được đánh giá cùng một lúc. Có rất ít chi phí bổ sung trong việc đánh giá cả hai đại lượng cùng một lúc.

Kết quả cho thấy rằng việc tăng số lượng điều khoản sẽ làm tăng nhẹ thời gian thực hiện như mong đợi. Ngay cả số thuật ngữ nhỏ nhất cũng cho độ chính xác khoảng 12-14 chữ số ở mọi nơi ngoại trừ xấp xỉ tan () gần nơi giá trị của nó tiến tới ± vô cùng. Người ta có thể mong đợi ngay cả hàm tan () cũng có vấn đề ở đó.

Kết quả tương tự cũng thu được trên máy tính xách tay MacBook Pro cao cấp trong Unix và trên máy tính để bàn cao cấp chạy Linux.


-5

Nếu bạn yêu cầu một lời giải thích vật lý hơn về sin, cos và tan, hãy xem xét chúng liên quan như thế nào với các tam giác vuông. Giá trị số thực của cos (lambda) có thể được tìm thấy bằng cách tạo thành một tam giác vuông với một trong các góc là lambda và chia độ dài của cạnh tam giác với lambda cho độ dài của cạnh huyền. Tương tự như vậy đối với sin sử dụng cạnh đối diện chia cho cạnh huyền. Đối với tiếp tuyến, sử dụng cạnh đối diện chia cho cạnh liền kề. Bản ghi nhớ cổ điển để ghi nhớ điều này là SOHCAHTOA (phát âm là socatoa).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.