BigMathR

# はじめに

### BigMathR
　[BigMathR](https://github.com/tribusonz-2/ruby-bigdecimal-math_r/tree/main)は、昔作っていたオブジェクト指向言語用数学ライブラリ“GlueMath”の亜種的なものです。いずれも数学アルゴリズムコレクションですが、こちらはAPIベースです。  

### 命名について

　元々は膨大なアルゴリズムのテストバリュを生成するために、Rubyの多倍長クラスであるBigDecimalクラスを利用して、初等関数の厳密値を参照する、という設計でした。しかし作っていくと、どちらかというとBigMathの多様化(オブジェクト指向デザインで言うならポリモーフィズム)が目立っていました。それでBigMathモジュールの拡張を作ろう、という流れで、Refineされた数学モジュールということで名前は"BigMathR"となったわけです。  

　実際はどうかというと、たかだか初等関数ソルバーを用意するというだけで、専門数学のアルゴリズム集みたいな作りになりました。(詳細はリンク先のGITHUBページを参考のほど)  
　BigMathRモジュールのトップレベルでアクセスできるモジュール関数の他、サブモジュールには様々な数学関数がインクルードされているというデザインで落ち着きました。トップレベルでは、現在、指数・対数・三角・双曲線・逆三角・逆双曲線の関数を網羅しています。  

### どうして公開なのか？
　個人メモ程度のことなら qiitaでページ開設するほどのことでもありません。こうした世に残しておくもの(個人資産)の利用される範囲はワールドワイドですから、今度は引き継ぎ手のことも考えなくてはいけません。  
　その意味では、シェアされるものとしては、このライブラリに限ったことではないでしょう。  
　固定小数点を扱うため、アルゴリズムもそれを考えての実装となっています。面白いことに、sinとcos、sinhとcoshを同時に計算する級数展開アルゴリズムも収録しています。詳しくは[GITHUBページ](https://github.com/tribusonz-2/ruby-bigdecimal-math_r/tree/main)を参照してください。  

# 目次
- 仕様
   - ポリモーフィズムな数学関数
   - ブランチ構造
- 免責
   - 今後の展開

# 仕様

### ポリモーフィズムな数学関数

　モジュールのトップレベルにある関数はポリモーフィズムな作りです。引数に実数を当てれば実数解、複素数を当てれば複素数解として値が返ってきます。定義域外であればエラーにはならず複素数解として解釈し値が返ってきます。例えば`BigMathR.sqrt(-1, PREC)`の解は`(0.0+1.0i)`です。  
　`hypot`も複素数に対応しておりますが、この関数は常に正の実数を返す関数です。例えば`BigMathR.hypot(3i, 4i, PREC)`の解は`5.0`です。  

※v0.2.1から誤差関数に対応しました。実数解ですが`BigMathR#erf`、`BigMathR#erfc`が使えます。

### ブランチ構造

　数学関数は各々`***_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_2 z = \log_2 x+\imath y$|$x \in \mathbb{R}, y \in \mathbb{R}$|
|$\log_{10} x$|$1 \leq x \lt 10$|$\log_{10} z = \log_{10} 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 y \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 y \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 y \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 y \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 y \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 y \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}$|

# 免責

### 今後の展開

　実は、多倍長演算による数学関数実装は、筆者にとってこれが初めてです。持てる知識をすべて投入した格好ですが、~~誤差関数や~~ガンマ関数の実装がまだという課題があります。特殊関数だと漸近展開や連分数展開なども実装しなくてはいけませんし、各々収束条件が異なるので調査が必要になります。概ね処理系定義であることがボトルネックです。  

　今後には大規模なアップデートも考えております。本当ならチームを結成して行うべきです。が、その肝心のコネクションがどうやら逃げたみたいなんですね？(少なくとも筆者はそう思います)  
　Rubyのコアコミッタのほうで検討すべきではないかと思います。提携先はコアコミッタに移ります。ただし意味はコネクションによります。  


https://github.com/tribusonz-2/ruby-bigdecimal-math_r/tree/main