Holograph1c Attract0r

日々の数学やプログラミングに関係する話。

cosを無限に繰り返したら

みなさん、突然ですがお手持ちの関数電卓を弧度法にして\cosを連打してみてください。

iPhoneの場合なら、左下の方にRadというボタンがあると思いますのでそこを押すと度数法から弧度法へと切り替わります。

 

 

 

 

……どうでしたか?

こんな風になったのではないかと思います。

f:id:mikan_alpha:20190118210345p:plain

30回ほどcosを連打した結果

ボタンを押していくと、だんだんとこの0.739 \ldotsという値に近づいていく様子が確認できたと思います。「なんでこんな中途半端な数がでるんだろう」とか、いろいろ疑問が浮かんできます。なので、今回はこの値について探っていきましょう。

まず、上でやった操作をきちんと数学の言葉で再構成します。

予想1.
\begin{align}
a_0 &= 0 \\
a_{n+1} &= \cos a_n
\end{align}

上記のように数列(a_n)_nを定めたとき、\lim_{n \to \infty} a_n = 0.739 \ldots \,となる。

ちなみに、あとでわかりますが初期値a_0は0でなくても同じ話になります。(電卓で0以外の値から始めてみてください)

では、この数列について調べてみましょう。

収束する様子をビジュアライズする

先程定義した数列がどんな挙動を示すのかを調べるために、こんな図を用意しました。

f:id:mikan_alpha:20190118214231p:plain

みんな大好きDesmos

数列の極限を調べるときにy=xを使うのは常套手段です。簡単に説明します。

f:id:mikan_alpha:20190118215908p:plain

a_2の計算方法

 まず、a_1はすぐに計算できて、a_1 = \cos 0 = 1だと分かります。
そうしたら、画像のようにy=xにぶつけることで今得た値をx軸に移すことができます。これで、x=a_1=\cos 0という点を得ることができました。

f:id:mikan_alpha:20190118215917p:plain

a_2の計算方法

x=a_1y=\cos xに代入、つまり画像のように上にぶつければその交点のy座標は\cos a_1=a_2です。これをさっきのようにy=xを使ってx軸に移せば、めでたくx=a_2の位置を求めることができました。

この手続を繰り返すことによってa_3, \, a_4, \, a_5, \, \cdotsの値を連鎖的に得ることができて、図にすればこんな感じになります。

f:id:mikan_alpha:20190118222859p:plain

数列(a_n)の挙動

どうやら、a_n の値は y=xy=\cos x の交点に近づいていきそうです。

予想2.
\lim_{n \to \infty} a_n は、方程式 x=\cos x の解である。

方程式 x = cos(x)

先ほどまでの話で、どうやらこの式について考えればいいことが分かりました。

\begin{align}
f(x) = \cos x - x
\end{align}

f(x)=0を満たすようなxを探せばいいわけです。

でも、どうやって解けばいいのでしょうか?
中学、高校でやるような代数方程式とは訳が違って因数分解したりなどはできそうにありません。したがってここでは、近似的に解を求めます。

そこで出てくるのが、ニュートン法という手法です。

qiita.com

詳しいことは、こちらのサイト様に載っていますのでそちらを見ていただくことにします。

実際に計算してみましょう。

まず計算のためにf(x)導関数が必要になるので求めておきます。

\begin{align}
f'(x) = - \sin x - 1
\end{align}

したがって、解を近似する計算式はこんな風になります。

\begin{align}
x &= x_0 - \frac{f(x_0)}{f'(x_0)} \\
&= x_0 + \frac{\cos x_0 - x_0}{\sin x_0 + 1}
\end{align}

これを用いて、Pythonに計算させてみましょう。
適当に、x_0=3としておきます。

import math

x = 3.0

while True:

    # ニュートン法による新しいxを求める
    x2 =  x + (math.cos(x) - x) / (math.sin(x) + 1)

    # 計算後の値が誤差の範囲内になったら計算終了
    if abs(x2 - x) < 0.0001:
        break

    # 計算後の値をxとして計算を繰り返す
    x = x2

# 計算結果の表示
print(x2)

計算結果は……

 

0.7390851332151618になりました!
最初電卓で出した値と小数第五位まで一致しています。

これで、おおよそ予想は正しかったと言うことができそうです。

あとがき

今回は、方程式の近似解しか求めませんでした。もしかしたら、この0.739 \ldotsという値は積分表示したりできるのかもしれない、と思っています。

それよりもそもそも、今回厳密な証明というのが一切登場していません。というのも、説明しようにも私自身どうすれば厳密な証明を与えられるのか分からないからです……。誰か教えてください。

 

ここまで書いて気づいたんですが、予想2ってただ数列の定義式を言い換えただけですね……。やっぱりまだ勉強不足みたいです。

2019.01.20追記:
続編ができました。近似解ではなくて厳密に解を求めます。

mikan-alpha.hatenablog.com

参考

不動点 - Wikipedia