こんにちは!ほけきよです。
○○の求め方シリーズ第二弾! 第一弾はコチラ
私の大学の統計学のテストでは、関数電卓*1を持ち込むことが可能でした。 √やlogの計算が必須だからです。 しかし、ある友人は関数電卓をテスト当日に忘れたのです。
「お前wwwとかとかどうやって計算するの??www」
と煽ったら、彼は
「そ、そんなんとかをテーラー展開すればええやんか!!」
と言い放ちました。天才。彼のひらめきに脱帽しました。*2
しかし、のためにテーラー展開をするのも、なんだか大層なものですね。 そこで今回は、の求め方を10個紹介します!!
TPOに適したの求め方を学びましょう!
0. 語呂合わせ
まず、の暗記法をば。
「ひとよひとよにひとみごろ」
と覚えたと思いますが、インパクトが足りません。これじゃ覚えられません。
「いよいよ、にいさんころす」
と覚えましょう
紙を使う
あなたがもしものさしを持っているならば、長さを図るだけでを求められます。ものさしの精度は高いほど、良い近似値が得られるので、なるべく精巧なものさし を用意しましょう!
1. 折り紙
最も身近なです!三平方の定理を使いましょう。冒頭の画像の通り,正方形の折り紙を対角線上におると、斜めの長さがになりますね! ものさしで斜めの長さと、折り紙の一辺の長さを求めて、比を出しましょう。
2. プリンタ用紙
テスト用紙で配られるの、大体A3用紙とかじゃないですか。 そうすれば話は早いです。縦と横の長さを測り、比を取るととなります。
縦横比が1:となる比を白銀比と呼ばれています。実は我々の身近なところに存在しているのですね!
方程式の解として
二次方程式の解はなので、精度良く求められたらOKです!!
3. 二分法
解探索のもっともナイーブな方法です。アルゴリズムは以下の通り
- グラフ上で、解を正負で挟むように2点を求める
- 2点の中点を求める
- グラフ上で、中点と正負が一致する方の点を置き換える
- 繰り返し
Wikipediaより引用
実装はコチラ
def f(x): return x**2-2 def bisection(iteration): # 初期値. 1<√2<2 は自明なのでそこから始める a = 1.0 b = 2.0 for i in range(iteration): c = (a+b)/2.0 # 中点を出す if f(a)*f(c) < 0: b = c if f(b)*f(c) < 0: a = c return c print("iteration:{} sqrt2:{}".format(10, bisection(10))) print("iteration:{} sqrt2:{}".format(20, bisection(20))) print("iteration:{} sqrt2:{}".format(100, bisection(50)))
結果はこんな感じに
iteration:10 sqrt2:1.4150390625 iteration:20 sqrt2:1.4142141342163086 iteration:100 sqrt2:1.414213562373095
だんだんと値が近づいていっているのがわかりますね。
4. ニュートン法
これも有名な方法ですね、接線を利用するのです!
- 一点を選ぶ
- グラフの接線を求める
- 接線とx軸との交点を次の点のx座標にする
Wikipediaより引用
def f(x): return x**2-2 def f_diff(x): return 2*x def newton(iteration): a = 1000 #初期値 for i in range(iteration): a -= f(a)/f_diff(a) return a print("iteration:{} sqrt2:{}".format(1, newton(10))) print("iteration:{} sqrt2:{}".format(5, newton(20))) print("iteration:{} sqrt2:{}".format(10, newton(100)))
結果はこんな感じ
iteration:1 sqrt2:1.5795487524060154 iteration:5 sqrt2:1.4142135623730951 iteration:10 sqrt2:1.4142135623730951
関数の微分が必要ですが、初期値が1000とか的はずれでも、5回もイテレーションを回せばほとんどになってるので、収束は二分法より早く、かなり優秀ですね。
反復的に求める
√がわからなくても、四則演算を繰り返し行うだけで近似値を出す方法はいくつかあるのです!覚えておいて損はないかも!?
5. 開平法
√を外す方法と言えばまずこれだろう!という有名な方法ですね。 中学校で聞いたことある人も多いのではないでしょうか。
「開平法しらん!」という方は、コチラの記事を見ましょう。やり方が載っています(開平法 )
手書きですが、手順的なものも書いてみました。
def solve_b(a,e): for b in range(10): if (a+b)*b > e: return b-1 return 9 def kaihei_2(iteration): # 初期値だけ a = 1 b = 1 sqrt2 = 1 c = a*b e = (2-c)*100 for i in range(iteration): a = (a + b) * 10 b = solve_b(a,e) a += b c = a * b e = (e - c) * 100 sqrt2 += b*0.1**(i+1) print(sqrt2) return sqrt2 kaihei_2(10)
実行結果はこんな感じ
1.4 1.41 1.414 1.4142 1.41421 1.414213 1.4142135 1.41421356 1.414213562 1.4142135623
繰り返せば繰り返すほど、精度が1桁ずつ上がるというわけです!すごい!
6. 相加相乗平均の大小関係を利用
相加相乗平均の大小関係をうまく利用すれば、√の近似値を精度良く求めることが出来ます
- 点
a
(正の数)を適当に選ぶ - 積
a*b
が2になるようにbを選ぶ - を次の点にする
- 繰り返し
def sokasojo(iteration): # 初期値a. a>0ならなんでもOK a = 1000 for i in range(iteration): b = 2/a #a*b=2となる様にbを選ぶ a = (a+b)/2 return a print("iteration:{} sqrt2:{}".format(1, sokasojo(10))) print("iteration:{} sqrt2:{}".format(5, sokasojo(20))) print("iteration:{} sqrt2:{}".format(10, sokasojo(100)))
結果はこんな感じ
iteration:1 sqrt2:1.5795487524060154 iteration:5 sqrt2:1.4142135623730951 iteration:10 sqrt2:1.4142135623730951
実は、ニュートン法と同じ結果になります。これは、反復のときに返す式が全く同じだからです。ただし、こっちの方法は、のみに有効となっています。
7. 連分数
こんな関係式が成り立ちます。*4
これも繰り返し処理に落とし込めそうですね。実装はコチラ
def renbunsu(iteration): a = 1 #初期値 for i in range(iteration): a = (2+1/a) return 1+1/a print("iteration:{} sqrt2:{}".format(1, renbunsu(10))) print("iteration:{} sqrt2:{}".format(5, renbunsu(20))) print("iteration:{} sqrt2:{}".format(10, renbunsu(100)))
iteration:1 sqrt2:1.4142135731001355 iteration:5 sqrt2:1.4142135623730954 iteration:10 sqrt2:1.4142135623730951
物理を使う
8. ボールを落とす
ボールとスピードガンを持っているのならば、√2を求めることが出来ます。 エネルギー保存則を使いましょう!
つまり、二倍の高さから物を落とすと、スピードは倍になることがわかります。 なので、高さを変えて2回ボールを落とすことで、の近似値を求めることができます!
9. 振り子
紐とおもりとストップウォッチを持っているなら、物理的にを求められます。振り子の周期を用いましょう。 振り子の振り幅が小さければ、周期は以下の式になります。
つまり、長さを変えて周期を求めることで、近似値を求めることが出来ます。 ただし、振幅が大きすぎると、上記の周期の式にずれが生じます*5
なるべく小さな振幅で測りましょう!
10. テーラー展開
最後に、話の冒頭にあったテーラー展開について。
テイラー展開っていうのは、ざっくりいうと難しい式を数学的に簡単な式に近似するヤツです。 知りたい方はこのへんの説明をみながら雰囲気を掴んでください*6。とりあえず、をでテーラー展開を実施すると、
これにを代入すると、
となります。
となります。これなら計算できそうですよね!この計算結果は、
> 1.42578125
うーん、イマイチ精度が悪いですね。ちなみに、この式は無限に続けられます。無限に精度を良くすることが可能というわけです。興味ある方はより高次の係数まで求め、より正確なを求めましょう!!
まとめ
いかがでしたか??
これでどんなときにが出ても困らないですよね! みなさんも求め方を覚えて、是非是非自薦してみてください!ではではっ!