三角関数の値の求め方(マクローリン展開)

math

はじめに

三角関数、特に、 \( \sin \) 関数と \( \cos \) 関数はマクローリン展開(テイラー展開)を使って表すことができる。マクローリン展開は無限級数であるため、計算機で求めるときには有限の項に打ち切って求めることになる。では、何次の項まで求めればよいか?

この記事では \( [0, \frac{\pi}{4}] \) の範囲における \( \sin \) 関数と \( \cos \) 関数の値をマクローリン展開を使って求める方法を示す。このとき、double型(64bit浮動小数点型)で十分な精度を達成するための次数(項数)も示す。

結論

結論から言うと、double型で十分な精度を達成するには \( \sin \) 関数は15次まで、\( \cos \) 関数は16次まで求める必要がある。

マクローリン展開による計算方法

三角関数のマクローリン展開は以下のように表すことができる。最後の項は剰余項であり、展開を有限項で打ち切った場合の真の値と展開式との誤差を表す。剰余項の \( \theta \) は \( 0 \lt \theta \lt 1 \) の値で、\( x \) ごとに値が定まる。

\[ \sin(x) = x – \frac{x^3}{3!} + \frac{x^5}{5!} + … + (-1)^{n-1} \frac{x^{2n-1}}{(2n-1)!} + (-1)^n \frac{\cos(\theta x)}{(2n+1)!} x^{2n+1} \tag{1} \]

\[ \cos(x) = 1 – \frac{x^2}{2!} + \frac{x^4}{4!} + … + (-1)^{n-1} \frac{x^{2n-2}}{(2n-2)!} + (-1)^n \frac{\cos(\theta x)}{(2n)!} x^{2n} \tag{2} \]

この展開式を使うことで \( \sin \) や \( \cos \) の値を求めることができる。理論的には無限個の項の和を求めることでどんな x に対しても \( \sin(x) \) や \( \cos(x) \) の値を正確に求めることができる。しかしこの展開式は、 \( x = 0 \) から離れるに従い誤差が大きくなる。

幸い、三角関数には周期性がある。また、\( \sin(\frac{\pi}{2} – x) = \cos(x) \) となる。そのため、適切な変数変換を行うことにより \( x \in [0, \frac{\pi}{4}] \) の場合に帰着できる。

どこまで求めるのか?

以上のことは、適当にWebで検索すればわかることである。では、何項まで計算すれば「十分」と言えるのだろうか?\( sin(x) \approx x \) で求めた場合と同様に剰余項で誤差を評価する。誤差は浮動小数点表記の最後の桁 ulp (unit in the last place) から評価する。

ここでは64bit浮動小数点フォーマット、いわゆるdouble型を考える。ある値 \( z \) を浮動小数点歩表記 \( \tilde{z} = d.dd…dd \times 2^E \) で表した場合、ulpにおける誤差は以下の通りとなる。

\[ E_{ulp} = |z \times 2^{-E} – d.dd…d | \times 2^{52} = |z – \tilde{z} | \times 2^{-E} 2^{52} \]

sin関数の場合

\( \sin(x) \) のマクローリン展開を第 \( n \) 項、\( 2n-1\) 次まで計算した結果を \( S_{2n-1}(x) \) とし、この値と真の値との誤差で ulp を評価した結果は以下の通りとなる。ここで \( E \) は \( \sin(x) \) の値の指数部である。

\[ E_{ulp} = | \sin(x) – S_{2n-1}(x) | \times 2^{-E} 2^{52} \]

この時の剰余項を \( RS_{2n+1}(x) \) とすると (1) のとおり以下のようになる。

\[ \sin(x) – S_{2n-1}(x) = RS_{2n+1}(x) = (-1)^n \frac{\cos(\theta x)}{(2n+1)!} x^{2n+1} \]

この絶対値を上から評価すると以下のようになる。

\[ | RS_{2n+1}(x) | = \left| (-1)^n \frac{\cos(\theta x)}{(2n+1)!} x^{2n+1} \right| = \frac{\cos(\theta x)}{(2n+1)!} x^{2n+1} \le \frac{x^{2n+1}}{(2n+1)!} \]

\( \cos (\theta x) \) の評価は \( x \in [0, \frac{\pi}{4}] \) を仮定した。以上より、ulpにおける誤差 \( E_{ulp} \) および、\( E_{ulp} \) を上から評価した \( E_{ulp}^+ \) は以下のようになる。

\[ E_{ulp} = |RS_{2n+1}(x)| \times 2^{-E} 2^{52} \]

\[ E_{ulp}^+ = \frac{x^{2n+1}}{(2n+1)!} \times 2^{-E} 2^{52} \]

\( x \) が減少すると \( E_{ulp}^+(x) \) の \( x^{2n+1} \) は急激に小さくなる。一方、\( E \) は \( \sin(x) \) の指数部であるため \( 2^{-E} \) は増加する。イメージとしては以下の図のようになる。\( x = \frac{\pi}{4} \) から値を小さくすると\( E_{ulp}^+(x) \) は減少する。この時、\( \sin(x) \ge 1/2 \) だから \( E = -1 \) である。そして、\( x \) が \( \frac{\pi}{6} \) を超えて小さくなるとき、\( E = -2 \) になるため ULP での誤差が倍に上昇する。

\( x \) の減少に対して減少する部分と増加する部分があるが、\( E_{ulp}^+(x) \) では全体としては減少する部分の寄与が大きい。これはのちの記事で示す予定である。したがって、\( [0, \frac{\pi}{4}] \) の範囲で \( E_{ulp}^+(x) \) が最大となるのは \( x = \frac{\pi}{4} \) の時である。

ulpが最大になるところで0.5を下回っていれば十分な精度が出ているとみなしてよい。これまでの議論で \( x = \frac{\pi}{4} \) の時に最大になるから、この時の \( E_{ulp}^+(x) \) が0.5を下回るような \( n \) を探すと \( n=8 \) の時となる。つまり、展開式としては \( 2n-1 = 15\) 次まで求めればよいことになる。

n\( E_{ulp}^+ \)
1727290917205962
222431480116651
3329449159051
42822511172
515827879.93
662586.10315
7183.8393093
80.4169166488

cos関数の場合

\( \cos \) 関数の場合も \( \sin \) 関数と同様に項数を決めていく。

\( \cos(x) \) のマクローリン展開を第 \( n \) 項、\( 2n-2\) 次まで計算した結果を \( C_{2n-2}(x) \) とし、この値と真の値との誤差で ulp を評価した結果は以下の通りとなる。ここで \( E \) は \( \cos(x) \) の値の指数部である。

\[ E_{ulp} = | \cos(x) – C_{2n-2}(x) | \times 2^{-E} 2^{52} \]

この時の剰余項を \( RC_{2n}(x) \) とすると (2) のとおり以下のようになる。

\[ \cos(x) – C_{2n-2}(x) = RC_{2n}(x) = (-1)^n \frac{\cos(\theta x)}{(2n)!} x^{2n} \]

この絶対値を上から評価すると以下のようになる。

\[ | RC_{2n}(x) | = \left| (-1)^n \frac{\cos(\theta x)}{(2n)!} x^{2n} \right| = \frac{\cos(\theta x)}{(2n)!} x^{2n} \le \frac{x^{2n}}{(2n)!} \]

\( \cos (\theta x) \) の評価は \( x \in [0, \frac{\pi}{4}] \) を仮定した。以上より、ulpにおける誤差 \( E_{ulp} \) および、\( E_{ulp} \) を上から評価した \( E_{ulp}^+ \) は以下のようになる。

\[ E_{ulp} = |RC_{2n}(x)| \times 2^{-E} 2^{52} \]

\[ E_{ulp}^+ = \frac{x^{2n}}{(2n)!} \times 2^{-E} 2^{52} \]

\( x \) が減少すると \( E_{ulp}^+(x) \) の \( x^{2n} \) は急激に小さくなる。\( \sin(x) \) の時とは異なり、\( x \in [0, \frac{\pi}{4}] \) の間は \( \cos(x) \)の指数部は -1のままである。したがって、\( 2^{-E} \) の部分は変化せず 2 のままになる。イメージは以下の図のようになる。

したがって、\( [0, \frac{\pi}{4}] \) の範囲で \( E_{ulp}^+(x) \) が最大となるのは \( x = \frac{\pi}{4} \) の時である。

\(\sin\)関数の時と同様に考えて、ulpが最大になるところで0.5を下回っていれば十分な精度が出ているとみなしてよい。これまでの議論で \( x = \frac{\pi}{4} \) の時に最大になるから、この時の \( E_{ulp}^+(x) \) が0.5を下回るような \( n \) を探すと \( n=9 \) の時となる。つまり、展開式としては \( 2n-2 = 16\) 次まで求めればよいことになる。

n\( E_{ulp}^+ \)
12.77805E+15
2142803237657302
32936273880984
432343595556
5221679509.1
61035932.319
73511.072176
89.024190991
90.01819142057

コメント

タイトルとURLをコピーしました