はじめに
BigMathR
BigMathRは、昔作っていたオブジェクト指向言語用数学ライブラリ“GlueMath”の亜種的なものです。いずれも数学アルゴリズムコレクションですが、こちらはAPIベースです。
命名について
元々は膨大なアルゴリズムのテストバリュを生成するために、Rubyの多倍長クラスであるBigDecimalクラスを利用して、初等関数の厳密値を参照する、という設計でした。しかし作っていくと、どちらかというとBigMathの多様化(オブジェクト指向デザインで言うならポリモーフィズム)が目立っていました。それでBigMathモジュールの拡張を作ろう、という流れで、Refineされた数学モジュールということで名前は"BigMathR"となったわけです。
実際はどうかというと、たかだか初等関数ソルバーを用意するというだけで、専門数学のアルゴリズム集みたいな作りになりました。(詳細はリンク先のGITHUBページを参考のほど)
BigMathRモジュールのトップレベルでアクセスできるモジュール関数の他、サブモジュールには様々な数学関数がインクルードされているというデザインで落ち着きました。トップレベルでは、現在、指数・対数・三角・双曲線・逆三角・逆双曲線の関数を網羅しています。
どうして公開なのか?
個人メモ程度のことなら qiitaでページ開設するほどのことでもありません。こうした世に残しておくもの(個人資産)の利用される範囲はワールドワイドですから、今度は引き継ぎ手のことも考えなくてはいけません。
その意味では、シェアされるものとしては、このライブラリに限ったことではないでしょう。
固定小数点を扱うため、アルゴリズムもそれを考えての実装となっています。面白いことに、sinとcos、sinhとcoshを同時に計算する級数展開アルゴリズムも収録しています。詳しくはGITHUBページを参照してください。
目次
- 仕様
- ブランチ構造
仕様
- ブランチ構造
実は、多倍長演算による数学関数実装は、筆者にとってこれが初めてです。持てる知識をすべて投入した格好ですが、誤差関数やガンマ関数の実装がまだという課題があります。特殊関数だと漸近展開や連分数展開なども実装しなくてはいけませんし、各々収束条件が異なるので調査が必要になります。概ね処理系定義であることがボトルネックです。
数学関数は各々***_branch()
という関数で取り扱っていて、主値を計算できるならどんなアルゴリズムにも対応するという方法を取っています(/という設計に落ち着きました)。引数が無理数・非数であった場合は専門ルーチンで解を創出し、定義域だけを計算します。このため、三角関数を扱う関数では引数の範囲を $-2\pi \leq x \leq 2\pi$ に収めるという面白い機構を実装しています。
実数解 | 計算域 | 複素数解 | 計算域 |
---|---|---|---|
$e^x$ | $0\lt x \lt 1$ | $e^z=e^{x+\imath y}$ | $x\in\mathbb{R},-2\pi\leq y \leq 2\pi$ |
$2^x$ | $0\lt x \lt 1$ | $2^z=2^{x+\imath y}$ | $x\in\mathbb{R},-(2\pi/\log 2)\leq y \leq (2\pi/\log 2)$ |
$\log x$ | $1 \leq x \lt 2$ | $\log z = \log x+\imath y$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\log_2 x$ | $1 \leq x \lt 2$ | $\log z = \log x+\imath y$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\log_{10} x$ | $1 \leq x \lt 10$ | $\log z = \log x+\imath y$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\sin x$ | $-2\pi\leq x \leq 2\pi$ | $\sin z = \sin x+\imath y$ | $-2\pi\leq x \leq 2\pi, y \in \mathbb{R} $ |
$\cos x$ | $-2\pi\leq x \leq 2\pi$ | $\cos z = \cos x+\imath y$ | $-2\pi\leq x \leq 2\pi, y \in \mathbb{R} $ |
$\tan x$ | $-2\pi\leq x \leq 2\pi$ | $\tan z = \tan x+\imath y$ | $-2\pi\leq x \leq 2\pi, y \in \mathbb{R} $ |
$\csc x$ | $-2\pi\leq x \leq 2\pi$ | $\csc z = \csc x+\imath y$ | $-2\pi\leq x \leq 2\pi, y \in \mathbb{R} $ |
$\sec x$ | $-2\pi\leq x \leq 2\pi$ | $\sec z = \sec x+\imath y$ | $-2\pi\leq x \leq 2\pi, y \in \mathbb{R} $ |
$\cot x$ | $-2\pi\leq x \leq 2\pi$ | $\cot z = \cot x+\imath y$ | $-2\pi\leq x \leq 2\pi, y \in \mathbb{R} $ |
$\sinh x$ | $x \in \mathbb{R} \wedge | x | \lt 3$ | $\sinh z = \sinh x+\imath y$ | $x \in \mathbb{R}, -2\pi\leq x \leq 2\pi$ |
$\cosh x$ | $x \in \mathbb{R} \wedge | x | \lt 3$ | $\cosh z = \cosh x+\imath y$ | $x \in \mathbb{R}, -2\pi\leq x \leq 2\pi$ |
$\tanh x$ | $x \in \mathbb{R} \wedge | x | \lt 3$ | $\tanh z = \tanh x+\imath y$ | $x \in \mathbb{R}, -2\pi\leq x \leq 2\pi$ |
$\textrm{csch}\ x$ | $x \in \mathbb{R} \wedge | x | \lt 3$ | $\textrm{csch}\ z = \textrm{csch}\ x+\imath y$ | $x \in \mathbb{R}, -2\pi\leq x \leq 2\pi$ |
$\textrm{sech}\ x$ | $x \in \mathbb{R} \wedge | x | \lt 3$ | $\textrm{sech}\ z = \textrm{sech}\ x+\imath y$ | $x \in \mathbb{R}, -2\pi\leq x \leq 2\pi$ |
$\coth x$ | $x \in \mathbb{R} \wedge | x | \lt 3$ | $\coth z = \coth x+\imath y$ | $x \in \mathbb{R}, -2\pi\leq x \leq 2\pi$ |
$\sin^{-1}(x)$ | $\frac{1}{1000} \lt |x| lt 1$ | $\sin^{-1}(z)=\sin^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\cos^{-1}(x)$ | $\frac{1}{1000} \lt |x| lt 1$ | $\cos^{-1}(z)=\cos^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\tan^{-1}(x)$ | $x \in \mathbb{R}$ | $\tan^{-1}(z)=\tan^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\csc^{-1}(x)$ | $-1 \lt x \lt 1$ | $\csc^{-1}(z)=\csc^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\sec^{-1}(x)$ | $-1 \lt x \lt 1$ | $\sec^{-1}(z)=\sec^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\cot^{-1}(x)$ | $x \in \mathbb{R}$ | $\cot^{-1}(z)=\cot^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\sinh^{-1}(x)$ | $\frac{1}{1000} \lt |x| \lt 1$ | $\sinh^{-1}(z)=\sinh^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\cosh^{-1}(x)$ | $x \in \mathbb{R}$ | $\cosh^{-1}(z)=\cosh^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\tanh^{-1}(x)$ | $\frac{999}{1000} \lt |x| \lt 1$ | $\tanh^{-1}(z)=\tanh^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\textrm{csch}^{-1}(x)$ | $x \in \mathbb{R}$ | $\textrm{csch}^{-1}(z)=\textrm{csch}^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\textrm{sech}^{-1}(x)$ | $x \in \mathbb{R}$ | $\textrm{sech}^{-1}(z)=\textrm{sech}^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |
$\coth^{-1}(x)$ | $x \in \mathbb{R}$ | $\coth^{-1}(z)=\coth^{-1}(x+\imath y)$ | $x \in \mathbb{R}, y \in \mathbb{R}$ |