Pythonライブラリなしでlog計算してみた。math.log()関数を自作してみた。
最初に
数学の勉強でlogの計算について、四則演算で理解したいと思ったので、Pythonで math.log()
を自作してみたいと思った。自分は文系で高校の頃、数学が全然出来なかった。最近になって読解力が上がったのか数学が昔より出来るようになり、楽しくなってきたので中学・高校数学から勉強してる。それでも現役の高校生には余裕で負けるだろう。
対数関数(logのこと)
指数関数
これくらいなら8を2で割り続けて、何回割る事が出来るかで暗算出来るが真数が4096とか膨大になると大変になる。
math.log(a, b)
ライブラリ使用する場合
import math
print(math.log(25, 5))
# 実行結果
2.0
ライブラリ使用しない場合
def myLog2(x, b):
if x < b:
return 0
return 1 + myLog2(x/b, b)
print(myLog2(25, 5))
# 実行結果
2
真数を底で割って、何回割れるかを数えている。
これがシンプルで一番分かりやすい。
別のやり方
ほんとはpythonに組み込まれた math.log()
のソースコードを見れば良いのだが、そのコードの中で別の関数が使用されていたり読むの大変そうだったので諦めてしまった。
公式のドキュメントには log(x)/log(base)
で求めていると書かれている。
※このbaseが何を指しているか分からない。(to base e)と書かれているが、ネイピア数の事を指しているのか?
ご存知の方はコメント欄で教えて下さい、お願いします。
With one argument, return the natural logarithm of x (to base e).
With two arguments, return the logarithm of x to the given base, calculated as log(x)/log(base).
Changed in version 2.3: base argument added.
底の変換公式に似ているから勝手にそれだと思った。
log(x)を求める数式
Pythonコードにすると
極限なのでnの値を大きくすればするほど、より正確な値になると思う。
def ln(x):
n = 1000.0
return n * ((x ** (1/n)) - 1)
底の変換公式をPythonコードにすると
def ln(x):
n = 1000.0
return n * ((x ** (1/n)) - 1)
def mylog(b, a):
x = ln(b)/ln(a)
return x
print(round(mylog(4096, 2)))
#実行結果
12
この際のcがどれに当たるか分からないが、これでa, bが整数の場合はlogの値を計算出来るようになった。
最後に
少し最後は雑になってしまったが、もし数学が得意な方でこの記事を読んで下さっていたら base が何なのかと c がどこに行ってしまったか教えてくださると嬉しいです。
記事を読んで、数学得意な方広めて下さると幸いです。
大したコードではないですが、Githubにもコードを置いておきます。
記事に関するコメント等は
🕊:Twitter
📺:Youtube
📸:Instagram
👨🏻💻:Github
😥:Stackoverflow
でも受け付けています。
Discussion
結論
解説
公式ドキュメント math.log(x[, base])にはこのように書いてあります。
つまり、
math.log
は引数を1つか2つとることができ、という挙動となります。また、値域に関して厳密にならなければ
\log_{ base } x = \log_{ c } x / \log_{ c } base (cは任意の数で、基本的には自然対数の底とすることが多い)
\log_{ e } e = 1
であり、
であるから、
こんな感じの解説になるのですがなんとなくわかっていただけたでしょうか。
とても詳しくありがとうございます。\log_e{e} = 1 ここだけなぜ提示されたのか分かりませんでした。
def ln(x)
をc = e
みたいな感じでc
の値を使って計算出来るように出来たらより底の変換公式に近づけると思ったのですが、思いつかなかったです。すいません。
あとコメント頂いといて申し訳ないのですが、コメントでの注意書きでなく、コード本体を修正して頂けると読む際の負担が減るのでとても助かります。
Pythonドキュメントの
math.log()
の引数とbase についての説明とても助かりました。ありがとうございます。
全然当たり前の話になっちゃんですけど、以下のことを明らかにいうためです!
僕の返信で書いたコードは@unemployed さんのコードを修正したものです。@unemployed さんのコードと違う部分をコメントにて指摘させていただきました!
分かりました。ありがとうございます。
を元に書いてみたコードなんですが、逆でしょうか?実際に修正の通り
x = ln(a) / ln(b)
と直して実行したら0
になってしまったので違う気がします。その数式はあってます!
ただ、pythonでの実装との解離があります。
mylog
はおそらくですが、
このまま実行したのではないでしょうか?
実際に実行すべきは
こちらになります!
ああ〜やっと分かりました。
確かに逆でした。ありがとうございます。