概要
この記事を AI で書いて AI に評価させたところクソミソに言われました。これは技術記事としては駄目だ、と。ということで駄目なところを直して自力で記事化します。
出発点
もとは私が自分で使う用に atan の近似をやりたかった、というシンプルなものです。
組込みではテーブルを使うのが一般的ではあるのですが、何か他に良い方法が無いものかと考えていたところ見つけたのが次の記事です。
https://blogs.yahoo.co.jp/fermiumbay2/38729661.html (魚拓)
ルジャンドル多項式を利用して定積分を求めるガウス求積という方法から、アークタンジェントを求める手法だそうです。
この記事の最後の方で係数を整理していった結果が次です。
$$arctan(x)\approx\frac{x(75x^2+285)}{3x^2+5}$$
しかしいざどのくらいの精度かを調べると無視できないレベルで誤差があるようでした。
具体的には 35deg くらいで 0.18度 ほどだそうです。

改善案1
この計算の誤差はきれいな曲線状になるので(何度も波を打ったりしない)、シンプルに表の通りの誤差の最大値が最小になるようなゴールシークをかけてやります。それがこちら。
ちょっと係数をいじることでだいぶ改善するようです。
ゴールシークの対象を変えて繰り返します。


このあたりで実用可能という判断をしました。
改善案2
ところが、この多項式、そもそも1次の項が足りてないのでは、という疑問が湧きました。
そこでその項を付け加えて再度ゴールシークします。
$$arctan(x)\approx\frac{x(75x^2+ax+285)}{3x^2+5}$$
$$atan(x) \approx \frac{x(69x^2 + 5x + 286)}{3x^2+5}[deg]$$
$$※対象範囲:$0 \le x \le 1$ ($0^\circ \le \theta \le 45^\circ$)$$
というのがことの顛末になるわけです。
ChatGPT からの技術記事としての指摘事項
- Excel でフィッティングしただけと誤解されるぞ
- minimax 近似しろよ
- 式を作ったと言うよりはモデルの設計
なんかよく分からないですが、とりあえずモデルの設計かと言われたらそうかも知れないですね。
少なくとも式は項を足したので変更はしました。minimax 近似は厳密でない似たようなことをやってました。
Excel でフィッティング、って元の式があるから何か的外れ感があるのですが、ゴールシークはフィッティングなのでしょうか…
実用上の懸念点と検証
前の記事の内容を書き直してみます。
- ゼロ除算のリスク: 分母の最小値が5になるためゼロ除算の心配がない
- 単調増加性の保証: 誤差は波打つが計算自体は波を打つような構造ではない
- 不連続性(微係数): x=0,x=1 付近での連続性は担保されていない
この不連続性についてちょっと考えたのですが、そもそも論で1近傍では誤差が0に近づく構造なので連続性は高いのでは、ということに気づきました。というわけで、微分してみました。Mathjax 打つのが大変なので ChatGPT に任せました。
近似式の微分
近似式は次式である。
$$
f(x)=\frac{(69x^2+5x+286)x}{3x^2+5}
$$
まず分子を展開しておく。
$$
f(x)=\frac{69x^3+5x^2+286x}{3x^2+5}
$$
ここで、
$$
N(x)=69x^3+5x^2+286x
$$
$$
D(x)=3x^2+5
$$
と置くと、
$$
f(x)=\frac{N(x)}{D(x)}
$$
である。したがって商の微分より、
$$
f'(x)=\frac{N'(x)D(x)-N(x)D'(x)}{D(x)^2}
$$
となる。
各項を微分すると、
$$
N'(x)=207x^2+10x+286
$$
$$
D'(x)=6x
$$
よって、
$$
f'(x)=
\frac{(207x^2+10x+286)(3x^2+5)-(69x^3+5x^2+286x)(6x)}{(3x^2+5)^2}
$$
微分結果は次式となる。
$$
f'(x)=\frac{207x^4+177x^2+50x+1430}{(3x^2+5)^2}
$$
切り替え点 (x=1) における傾き
$$
f'(1)=\frac{207+177+50+1430}{(3+5)^2}
=\frac{1864}{64}
=29.125
$$
真の $\arctan(x)$ を degree 系で表した場合の導関数は、
$$
\frac{d}{dx}\arctan(x)=\frac{180}{\pi}\cdot\frac{1}{1+x^2}
$$
なので、(x=1) では
$$
\frac{180}{\pi}\cdot\frac{1}{2}\approx 28.6479
$$
となる。したがって切り替え点での傾き誤差は、
$$
29.125-28.6479\approx 0.4771
$$
近しい値ではありますが一致はしないのですね。ちなみに1以上の値を関数に入力する場合の式も微分してみたところ一致したので省略しています。
この近似式の有用性
この近似式を PC で利用する必然性はほぼ無いでしょうね。おそらく一番効果的なのは、「FPUはあるが計算の速くない組込み」だと思います。
また固定小数に変形して整数演算させることも可能だと思うのですが、現状ではそこに手を付けてません。というか思い付いてから10年も手を付けて無ければもうやらないでしょうね。

