関数の速度(10)

sin

logのときと同様に最適な有理関数を[0, π/2]で求めよう。
ソースを少しいじるだけなので簡単に求まる。


n = 3とすると、

 h_0(x) = \frac{15120x}{15120+2520x^2+294x^4+31x^6}
 h_1(x) = \frac{5880x-620x^3}{5880+360x^2+11x^4}
 h_2(x) = \frac{2520x-360x^3+11x^5}{2520+60x^2}
 h_3(x) = \frac{5040x-840x^3+42x^5-x^7}{5040}

誤差は、

0 : error = 0.00665545
1 : error = 0.000283412
2 : error = 0.000102882
3 : error = 0.000156899

1e-5ほしいとするとまだ足りない。
n = 4とすると、

...
 h_2(x) = \frac{166320x-22260x^3+551x^5}{166320+5460x^2+75x^4}
 h_3(x) = \frac{60480x-9240x^3+364x^5-5x^7}{60480+840x^2}
 h_4(x) = \frac{362880x-60480x^3+3024x^5-72x^7+x^9}{362880}

誤差は、

...
2 : error = 3.00438e-006
3 : error = 1.77347e-006
4 : error = 3.54258e-006

h4で誤差は十分。
なんのことはない、テーラー展開でよいのだ。
これでsinを書いてみた。
[-π/2, π/2]で使える。


double sin2(double x) {
double x2 = x * x;
return x * ((((1.0 / 362880 * x2 - 1.0 / 5040) * x2
+ 1.0 / 120) * x2 - 1.0 / 6) * x2 + 1);
}

これで、11ns。sinは48nsだった。