きどたかのブログ

いつか誰かがこのブログからトラブルを解決しますように。

Natural Logarithm

今日はNatural Logarithmを実装した。
これもWikipediaを見ての実装。
実は途中までしか見てなかったので、
まだ改良の余地があるみたい。
また明日直そう。


x ** y = e ** (y * ln(x)) = 10 ** (y * ln(x) / ln(10))


Natural Logarithmより前に編み出した独自アルゴリズムと、
nth-root algorithmがあるので、
上記の累乗計算も出来るんだけれど、
Natural Logarithmベースの実装は思いのほか遅かった。
ただ、独自アルゴリズムは不得手な数値領域があるので、
遅くてもNatural Logarithmベースを採用した方が良いだろう。



ここから先、どうやって計算回数を減らすのかが難しい。
指数部を先に計算して良いものか・・・。
指数部を先に計算したら正確さが落ちたような気がする。
いや、もしかしたら別のところに問題があったせいかも。
もう一度指数部を先に計算する順番でやってみるか。


ln(10)√{10**(y*ln(x))} なんてことをわざわざやっている。


なんかかなり無駄に計算してるように見える。
Logarithmを軸とした累乗計算をする場合は、
たぶんこのあたりの式はとりあえずたどり着くだろう。


10 ** (9/10)を求めるとして、


例の nth-root algorithmに基づけば、
x = 9x + 10**9/ x**9ということか。
ふーむ、これは別の算出方法があるのか。
ただ漸化式を考えると微妙かなぁ・・・。


10 ** (1/10)を求めるとして、
x = 9x + 10**1/ x**9
これを早くすることが大事なんだよな、きっと。


10 ** (n/10)において以下が成り立つかもしれない。(1<= n <=9)
x = 9x + (10/x)**n / x**(9-n)


ふむ、なんかアリなようなナシなような微妙なもんだ。
この発想から転換すべきだ。


今のnth-root algorithmを使ってn√(x**m)してる部分は、
出来るだけ分母を払うようにしてみたりはもうやっている。
だから5/10はsquareRootの実装を用意したりとか。


10√(....10√(x**m))
まあ、xは10が入るのだね。
あれ、そうか、
x**{m/(10**n)}とした場合の計算順序を直す方法もあるか。
(10√(....10√x))**m
あれ、これってひょっとして
(10√(n√x))**mとかになるか?
いや、ちょっとこの式は展開を間違えてるな。
{x**(1/(10**n))}**m
{x**(10**-n)}**m


うーむ、分からない。
ただ、僕の感性がさきほど語りかけてきたことは、
「nは10の何乗だい?」ってことだな。
どこかで論理が無限ループして思考がこんがらがる。


10 ** 0.3 =1.9952623149688796013524553967395と電卓では出る。
0.3 = log(1.9952623149688796013524553967395)
10√1000なのは確か。


log(x)=ln(x)/ln(10)
log(x)*ln(10)=ln(x)
0.3*ln(10)=ln(x)
e**ln(x) = x
10**log(x)=x
どうどうめぐり。
ln(x)は求められるので、やはり指数関数を作りあげる必要があるんだろうな。


exp(0.69077552789821370520539743640531)
1+0.69077552789821370520539743640531+0.23858541497152791047527498748673
これで1.929360942869741615680672423892
さらに次は0.05493632199192385731443676217627だから
これで1.9842972648616654729951091860683
さらに次は0.00948716670618936240174388668986
これで1.9937844315678548353968530727582
ふむ、方向性はあっているようだね。


Y0.Y1Y2Y3


10**Y0 * (exp(Y1/10*ln(10)) * (exp(Y2/100*ln(10)) * (exp(Y3/1000*ln(10))
なんて分解する必要もないだろう。
10**Y0 * exp(Y1Y2Y3/1000*ln(10))


さーて、明日も車輪の発明をするか。