삼각 함수는 어떻게 작동합니까?


102

그래서 고등학교 수학, 그리고 아마도 대학에서 삼각 함수를 사용하는 방법, 그들이하는 일, 그들이 해결하는 문제의 종류를 배웁니다. 그러나 그들은 항상 나에게 블랙 박스로 제시되었습니다. 사인 또는 코사인이 필요한 경우 계산기의 sin 또는 cos 버튼을 누르면 설정이 완료됩니다. 괜찮습니다.

내가 궁금한 것은 삼각 함수가 일반적으로 어떻게 구현되는지입니다.


trig 함수가 무엇인지 또는 구현 방법에 대해 혼란 스럽습니까?
Kyle Cronin

15
나는 그들이 무엇인지 압니다. 나는 그들이 무엇을하는지 압니다. 어떤 용도로 필요한지 결정하는 방법을 알고 있습니다. 각도와 거리의 관계에 대해 모두 말할 수 있습니다. 내가 찾고 있던 것은 John D. Cook의 대답에 더 가깝습니다. 그리고 실제 알고리즘을 언급 한 모든 사람들
Jurassic_C

이것은 좋은 질문입니다. 예를 들어, 사인, 코사인 및 탄젠트는 초월 함수이며 해결하기 어렵습니다 ... 반면에, 유한 한 정확도까지 정확한 답을 제공하는 간단한 Taylor 급수 확장을 사용하여 정의 할 수 있습니다. 필수입니다.
Alex

답변:


144

먼저, 일종의 범위 축소를 ​​수행해야합니다. 삼각 함수는 주기적이므로 인수를 표준 간격으로 줄여야합니다. 우선 각도를 0도에서 360도 사이로 줄일 수 있습니다. 그러나 몇 가지 신원을 사용하면 더 적은 것으로 얻을 수 있다는 것을 알게됩니다. 0도에서 45도 사이의 각도에 대해 사인과 코사인을 계산하는 경우 모든 각도에 대한 모든 삼각 함수를 계산하는 방법을 부트 스트랩 할 수 있습니다.

인수를 줄이면 대부분의 칩은 CORDIC 알고리즘을 사용하여 사인과 코사인을 계산합니다. 사람들이 컴퓨터가 Taylor 시리즈를 사용한다고 말하는 것을들을 수 있습니다. 합리적으로 들리지만 사실이 아닙니다. CORDIC 알고리즘은 효율적인 하드웨어 구현에 훨씬 더 적합합니다 . ( 소프트웨어 라이브러리는 삼각 함수를 지원하지 않는 하드웨어에서 Taylor 시리즈를 사용할 수 있습니다.) CORDIC 알고리즘을 사용하여 상당히 좋은 답변을 얻었지만 정확도를 높이기 위해 다른 작업을 수행하는 몇 가지 추가 처리가있을 수 있습니다.

위의 몇 가지 개선 사항이 있습니다. 예를 들어, 아주 작은 각도 theta (라디안 단위)의 경우 sin (theta) = theta를 모든 정밀도에 적용하므로 다른 알고리즘을 사용하는 것보다 단순히 theta를 반환하는 것이 더 효율적입니다. 따라서 실제로는 가능한 모든 성능과 정확성을 끌어 내기위한 많은 특수한 경우 논리가 있습니다. 시장 규모가 작은 칩은 최적화 작업이 많지 않을 수 있습니다.


4
훌륭한 대답-CORDIC은 실제로 범위 축소가 필요하지 않지만 (사실 본질적으로 자체적으로 범위 축소 알고리즘입니다.) -pi / 2와 + pi / 2 사이의 각도에서 잘 작동하므로 해당 범위를 벗어난 각도에 대해 180도 벡터 회전을 수행해야합니다.
Jason S

3
다항식 근사를 사용하여 구현 할 수 종종 테일러 시리즈를 사용하지만, 그들은 일반적으로 해야 Remez 알고리즘으로 결정된 계수를 사용한다. lolengine.net/blog/2011/12/21/better-function-approximations
Pascal Cuoq 2013

1
CORDIC에서 사용하는 값 ​​테이블은 미리 계산되어야합니다. 따라서 Taylor는 "컴파일 타임"에 여전히 사용될 수 있습니다.
루 바브

2
이 답변은 stackoverflow.com/questions/2284860/… 과 같은 유사한 질문에 대한 높은 등급의 수락 된 답변과 모순되는 것 같습니다 . 이 답변은 sin () 함수가 대부분 하드웨어 수준에서 구현되고 다른 함수는 C로 구현되어 있다고 말합니다.
Perry

48

편집 : Jack Ganssle은 임베디드 시스템에 대한 저서 "The Firmware Handbook" 에서 적절한 토론을했습니다 .

참고 : 정확도와 성능 제약이있는 경우 Taylor 시리즈를 사용하여 수치 목적으로 함수를 근사 하면 안됩니다 . (미적분 과정을 위해 저장하십시오.) 그들은 단일 지점에서 함수 의 분석 을 사용 합니다 . 예를 들어 모든 파생물이 해당 지점에 존재한다는 사실. 관심 구간에서 반드시 수렴하는 것은 아닙니다. 종종 그들은 평가 지점 근처에서 "완벽"하기 위해 함수 근사값의 정확도를 분배하는 형편없는 일을합니다. 오류는 일반적으로 벗어나면 위로 확대됩니다. 그리고 비 연속적 미분 (예 : 구형파, 삼각파 및 적분)이있는 함수가있는 경우 Taylor 시리즈는 잘못된 답을 제공합니다.

최대 차수 N의 다항식을 사용하여 구간 x0 <x <x1 동안 주어진 함수 f (x)를 근사화 할 때 가장 좋은 "쉬운"솔루션은 Chebyshev 근사치입니다 . 좋은 토론은 수치 레시피를 참조하십시오. 내가 링크 한 Wolfram 기사의 Tj (x)와 Tk (x)는 cos와 inverse cosine을 사용했으며, 이들은 다항식이며 실제로는 계수를 얻기 위해 반복 공식을 사용합니다. 다시, 수치 레시피를 참조하십시오.

편집하다 : Wikipedia에는 근사 이론 에 대한 반쯤 괜찮은 기사가 있습니다 . 그들이 인용하는 출처 중 하나 (Hart, "Computer Approximations")는 절판 (& 중고 사본은 비싸다)이지만 이와 같은 항목에 대해 자세히 설명합니다. (Jack Ganssle은 자신의 뉴스 레터 The Embedded Muse 39 호에서이를 언급합니다 .)

편집 2 : 다음은 sin (x)에 대한 Taylor 대 Chebyshev에 대한 유형의 오류 메트릭 (아래 참조)입니다. 참고해야 할 몇 가지 중요한 사항 :

  1. 주어진 범위에 대한 Taylor 급수 근사치의 최대 오차는 같은 정도의 Chebyshev 근사치의 최대 오차보다 훨씬 큽니다. (거의 동일한 오류에 대해 Chebyshev를 사용하면 항을 하나 줄이면 성능이 더 빨라집니다.)
  2. 범위 축소는 큰 승리입니다. 근사 구간이 더 작을 때 고차 다항식의 기여도가 줄어들 기 때문입니다.
  3. 범위 축소로 벗어날 수 없다면 계수를 더 정확하게 저장해야합니다.

오해하지 마세요 : Taylor 시리즈는 사인 / 코사인에 대해 제대로 작동합니다 (-pi / 2에서 + pi / 2 범위에 대해 합리적인 정밀도로; 기술적으로 충분한 용어를 사용하면 모든 실제 입력에 대해 원하는 정밀도에 도달 할 수 있습니다. 그러나 Taylor 시리즈를 사용하여 cos (100)를 계산하려고 시도하고 임의 정밀도 산술을 사용하지 않는 한 수행 할 수 없습니다. 비과학적인 계산기로 무인도에 갇혀서 사인과 코사인을 계산해야했다면 계수가 기억하기 쉽기 때문에 아마도 Taylor 시리즈를 사용할 것입니다. 그러나 자신의 sin () 또는 cos () 함수를 작성해야하는 실제 응용 프로그램은 원하는 정확도에 도달하기 위해 효율적인 구현을 사용하는 것이 가장 좋을만큼 드물며 Taylor 시리즈는 그렇지 않습니다 .

범위 = -pi / 2 ~ + pi / 2, 차수 5 (3 항)

  • 테일러 : 4.5e-3, F (X) = XX 주위 최대 오류 3 / 6 + X 5 / 120
  • 체비 쇼프 : 7e-5 주변의 최대 오차, f (x) = 0.9996949x-0.1656700x 3 + 0.0075134x 5

범위 = -pi / 2 ~ + pi / 2, 차수 7 (4 항)

  • 테일러 : 1.5E-4, F (X) = XX 주위 최대 오류 3 / 6 + X 5 / 120 X 7 / 5040
  • 체비 쇼프 : 6e-7 주변의 최대 오차, f (x) = 0.99999660x-0.16664824x 3 + 0.00830629x 5 -0.00018363x 7

범위 = -pi / 4 ~ + pi / 4, 차수 3 (2 항)

  • 테일러 : 2.5E-3, F (X) 주위의 최대 오차 XX = 3 / 6
  • 체비 쇼프 : 1.5e-4 주변의 최대 오차, f (x) = 0.999x-0.1603x 3

범위 = -pi / 4 ~ + pi / 4, 차수 5 (3 항)

  • 테일러 : 3.5e-5 주변의 최대 오차, f (x) = xx 3 / 6 + x 5
  • 체비 쇼프 : 6e-7 주변의 최대 오차, f (x) = 0.999995x-0.1666016x 3 + 0.0081215x 5

범위 = -pi / 4 ~ + pi / 4, 차수 7 (4 항)

  • 테일러 : 3E-7, F (X) = XX 주위 최대 오류 3 / 6 + X 5 / 120 X 7 / 5040
  • 체비 쇼프 : 1.2e-9 주변의 최대 오차, f (x) = 0.999999986x-0.166666367x 3 + 0.008331584x 5 -0.000194621x 7

2
이 의견은 잘못되었습니다. 모든 근사치에는 시간과 장소가 있습니다. 모든 계열 근사에 대한 수렴 영역을 결정하는 데 충분한 분석을 알지 못하는 경우이를 사용해서는 안됩니다. Taylor, Chebyshev, Padé 등 시리즈에 해당됩니다. Taylor 시리즈는 종종 Good Enough입니다.
kquinn

4
: shrug : 나는 당신에 대해 모르지만 단지 한 지점 주위의 작은 동네에서 함수를 평가하는 데 관심이 없었습니다. 간격에 대한 빠른 최소 제곱 법조차도 매우 쉽습니다. Taylor 시리즈를 사용하는 사람은 누구나 요점을 놓치고 있습니다.
Jason S

1
@kquinn : 체비 쇼프 근사에 대한 수렴 영역은 계산되는 간격이 프로세스에 대한 명시적인 입력이기 때문에 유용한 개념이 아닙니다.
Jason S

2
응답자가 하트가 존재한다는 것을 알았 기 때문에 찬성했습니다. : 미소 : 하트는 여기에서 고전적인 참고 자료입니다. 25 년 전에 책을 샀을 때 찾기 어려웠 지만요. 모든 페니의 가치가 있습니다. 가능한 경우 범위 축소는 적절한 근사치와 결합되어 Pade, Chebychev, 심지어 Taylor 시리즈까지도 적절한 접근 방식입니다. Pade 또는 Chebychev 근사치는 일반적으로 Taylor 시리즈보다 더 나은 선택입니다.

3
??? 그게 어떻게 다릅니 까? -2pi에서 + 2pi까지 sin (x)를 계산하기위한 17 차 테일러 급수는 아마도 7 차 또는 9 차 다항식을 사용하는 Chebyshev에 의해 이길 수 있습니다. 나는 "나무를 베는 데 시간이 부족하다면 손톱을 사용하지 말아야한다. 전기 톱을 사용하라"는 말을하는 데 아무런 문제가 없을 것입니다. 아마도 "안된다"에서 "테일러 시리즈 사용을 권장하지 않을 것"과 같은 단어로 바꿔야 할 것입니다. 물론, 어떤 경우에는 Taylor 시리즈를 사용할 수 있지만 정확도와 성능이 문제가 될 것입니다. 성능이란 CPU 실행 시간을 의미합니다.
Jason S

14

나는 그들이 Taylor Series 또는 CORDIC을 사용하여 계산되었다고 믿습니다 . 삼각 함수 (게임, 그래픽)를 많이 사용하는 일부 응용 프로그램은 시작할 때 삼각 함수 테이블을 구성하므로 값을 반복해서 다시 계산하지 않고 조회 할 수 있습니다.


6

삼각 함수에 대한 Wikipedia 기사 를 확인하십시오 . 실제로 코드로 구현하는 방법을 배우기에 좋은 곳은 Numerical Recipes입니다. 입니다.

저는 수학자는 아니지만 sin, cos 및 tan이 "어디에서 왔는지"에 대한 이해는 어떤 의미에서 직각 삼각형으로 작업 할 때 관찰된다는 것입니다. 다른 직각 삼각형의 변의 길이를 측정하고 그래프에 점을 플로팅하면 그로부터 sin, cos 및 tan을 얻을 수 있습니다. Harper Shelby가 지적했듯이 함수는 단순히 직각 삼각형의 속성으로 정의됩니다.

이러한 비율이 원의 기하학과 어떤 관련이 있는지 이해함으로써보다 정교한 이해가 이루어지며, 이는 라디안과 그 모든 장점으로 이어집니다. Wikipedia 항목에 모두 있습니다.


1

가장 일반적으로 컴퓨터에서 멱급수 표현은 사인과 코사인을 계산하는 데 사용되며 다른 삼각 함수에 사용됩니다. 이 시리즈를 약 8 개 항으로 확장하면 기계 엡실론 (유지할 수있는 가장 작은 0이 아닌 부동 소수점 수)에 가까운 정확도에 필요한 값이 계산됩니다.

CORDIC 방법은 하드웨어에서 구현되기 때문에 더 빠르지 만 주로 표준 컴퓨터가 아닌 임베디드 시스템에 사용됩니다.


0

@Jason S가 제공 한 답변을 확장하고 싶습니다. @Jason S가 설명한 것과 유사한 도메인 세분화 방법을 사용하고 Maclaurin 시리즈 근사를 사용하여 tan (), sin ()에 대한 평균 (2-3) X 속도 향상 , cos (), atan (), asin () 및 acos () 함수가 -O3 최적화를 통해 gcc 컴파일러에 내장되었습니다. 아래에 설명 된 최고의 Maclaurin 계열 근사 함수는 배정 밀도 정확도를 달성했습니다.

tan (), sin () 및 cos () 함수의 경우 단순화를 위해 0에서 2pi + pi / 80까지 겹치는 도메인은 pi / 80, 3pi / 80에서 "앵커 포인트"를 사용하여 81 개의 동일한 간격으로 나뉩니다. ..., 161pi / 80. 그런 다음이 81 개의 앵커 포인트 중 tan (), sin () 및 cos ()를 평가하고 저장했습니다. 삼각 ID의 도움으로 각 삼각 함수에 대해 단일 Maclaurin 시리즈 함수가 개발되었습니다. ± infinity 사이의 각도는 함수가 먼저 입력 각도를 0 ~ 2pi 도메인으로 변환하기 때문에 삼각 근사 함수에 제출 될 수 있습니다. 이 번역 오버 헤드는 근사 오버 헤드에 포함됩니다.

atan (), asin () 및 acos () 함수에 대해 유사한 메서드가 개발되었습니다. 여기서 -1.0에서 1.1까지의 겹치는 도메인은 -19/20, -17/20, .. ., 19/20, 21/20. 그런 다음이 21 개의 앵커 포인트 중 atan () 만 저장되었습니다. 다시 말하지만, 역 삼각 ID의 도움으로 atan () 함수에 대해 단일 Maclaurin 시리즈 함수가 개발되었습니다. 그런 다음 atan () 함수의 결과를 사용하여 asin () 및 acos ()를 근사했습니다.

모든 역 삼각 근사 함수는 atan () 근사 함수를 기반으로하므로 모든 배정 밀도 인수 입력 값이 허용됩니다. 그러나 asin () 및 acos () 근사 함수에 입력 된 인수는 ± 1 도메인으로 잘립니다. 외부의 값은 의미가 없기 때문입니다.

근사 함수를 테스트하기 위해 10 억 번의 임의 함수 평가가 강제로 평가되었습니다 (즉, -O3 최적화 컴파일러는 일부 계산 된 결과가 사용되지 않기 때문에 평가를 우회 할 수 없습니다.) 10 억 평가의 편향을 제거하기 위해 난수를 처리하고 결과를 처리하면 삼각 함수 또는 역 삼각 함수를 평가하지 않고 실행 비용이 먼저 수행되었습니다. 그런 다음이 편향을 각 테스트에서 빼서 실제 함수 평가 시간의보다 대표적인 근사치를 얻었습니다.

표 2. 표시된 기능을 10 억 번 실행하는 데 소요 된 시간 (초). 추정치는 표 1의 나머지 행에서 표 1의 첫 번째 행에 표시된 10 억 개의 난수를 평가하는 데 드는 시간 비용을 뺀 값입니다.

tan ()에서 보낸 시간 : 18.0515 18.2545

TAN3 ()에서 보낸 시간 : 5.93853 6.02349

TAN4 ()에서 보낸 시간 : 6.72216 6.99134

sin () 및 cos ()에서 보낸 시간 : 19.4052 19.4311

SINCOS3 ()에서 보낸 시간 : 7.85564 7.92844

SINCOS4 ()에서 보낸 시간 : 9.36672 9.57946

atan ()에서 보낸 시간 : 15.7160 15.6599

ATAN1 ()에서 보낸 시간 : 6.47800 6.55230

ATAN2 ()에서 보낸 시간 : 7.26730 7.24885

ATAN3 ()에서 보낸 시간 : 8.15299 8.21284

asin () 및 acos ()에 소요 된 시간 : 36.8833 36.9496

ASINCOS1 ()에서 보낸 시간 : 10.1655 9.78479

ASINCOS2 ()에서 보낸 시간 : 10.6236 10.6000

ASINCOS3 ()에서 보낸 시간 : 12.8430 12.0707

(공간 절약을 위해 표 1은 표시하지 않았습니다.) 표 2는 각 근사 함수에 대해 10 억 번의 평가를 두 번의 개별 실행 결과를 보여줍니다. 첫 번째 열은 첫 번째 실행이고 두 번째 열은 두 번째 실행입니다. 함수 이름의 숫자 '1', '2', '3'또는 '4'는 특정 삼각 또는 역 삼각 근사를 평가하기 위해 Maclaurin 급수 함수에서 사용되는 용어의 수를 나타냅니다. SINCOS # ()는 sin과 cos가 동시에 평가되었음을 의미합니다. 마찬가지로 ASINCOS # ()는 asin과 acos가 동시에 평가되었음을 의미합니다. 두 수량을 동시에 평가하는 데 추가 오버 헤드가 거의 없습니다.

결과에 따르면 용어 수를 늘리면 예상대로 실행 시간이 약간 늘어납니다. 가장 적은 수의 용어조차도 값이 ± 무한대에 가까운 tan () 근사값을 제외하고는 모든 곳에서 약 12-14 자리 정확도를 제공했습니다. tan () 함수에도 문제가있을 것으로 예상 할 수 있습니다.

비슷한 결과가 Unix의 고급 MacBook Pro 노트북과 Linux의 고급 데스크톱 컴퓨터에서 얻어졌습니다.


-5

sin, cos 및 tan에 대한 더 물리적 인 설명을 요청하는 경우 직각 삼각형과 어떤 관련이 있는지 고려하십시오. cos (lambda)의 실제 숫자 값은 각도 중 하나가 람다 인 직각 삼각형을 형성하고 람다에 인접한 삼각형 변의 길이를 빗변의 길이로 나누어 구할 수 있습니다. 마찬가지로 죄의 경우 반대편을 빗변으로 나눈 값을 사용하십시오. 접선의 경우 반대쪽을 인접한면으로 나눈 값을 사용합니다. 이것을 기억하는 고전적인 메모 닉은 SOHCAHTOA (socatoa로 발음)입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.