マンデルブロの解説とギャラリー

2022/10/05

フラクタル プログラム

マンデルブロの世界にはまり、マンデルブロの拡大動画をいくつかアップしてきた。


マンデルブロにつてやりたいことを一通りやったので、ここらあたりで一区切りとし、今一度マンデルブロの解説をしてみたい。


みなさんには気軽に、ギャラリーとともにお楽しみください。


マンデルブロ集合とは


フランスの数学者ブノワ・マンデルブロが研究したもの。次の漸化式が \(n→∞\)の極限で無限大に発散しないという条件を満たす複素数\(C\)の集合。

\[Z_{n+1}=Z_{n}^2+C\]

\[Z_{0}=0\]

\(C\)は複素数なので、\(C=u+iv\)とすると、この集合は\(uv\)平面上に描画することができる。下の図の紺色の部分がマンデルブロ集合である。赤とか黄色など紺以外の部分は漸化式が無限大に発散する領域であり、マンデルブロ集合ではない。


しかし絵としてはこの部分が美しい。ブラックホールは見えないが、その周辺の降着円盤が光っているのと似ている。




漸化式が発散するということについて、今少し解説する。一例として上の図の(u,v)=(0.32,0.56) という点について考えてみる。これは

\[Z_{n+1}=Z_{n}^2+C\]

\[Z_{0}=0\]

\[C=0.32+0.56i\]

という条件の漸化式の変化を見ることを意味している。\(Z_{n}\)がどのように変化するかをエクセルで計算すると下のグラフのようになる。ここでは\(Z=x+iy\)とおいて、原点から出発した\(Z\)がどのように動くかをグラフにしている。


\(Z\)は4箇所の点をぐるぐると回り続け、\(n\)をどんなに大きくしても発散することはない。実際に無限に計算することはできないので、適当な回数で計算を打ち切って、「発散しない」と判定することにする。

※発散しないとみなす回数は拡大率によって変える必要がある。今回の描画では最低繰り返し数を200回とし、倍率一兆倍では50000回になるよう変化させた。


それではuの値を少し大きくして0.34にしてみる。これは一番上の図で、右に少し動いた点に対応する。


この場合、最初は上と同じようにぐるぐる回っているが、途中からおおきくはずれるようになり、nが43ではグラフからはみ出してしまう。一度グラフからはみ出す(\(Z\)の絶対値\(\sqrt{x^2+y^2}\)が2を超える)と発散することが証明されているらしいので、43回目に発散したとみなす。


このような計算を全てのu,vについて行い、発散しないuvの点には紺色を、発散した点には、何回目に発散したかに応じた色をつけたのが、最初のマンデルブロ図である。


マンデルブロ図の拡大


マンデルブロ集合(紺色部分)の周辺は、非常に複雑になっており、ほんの少しuvが変化しただけで発散するかどうか、何回で発散するかが大きく変化する。そのため、拡大することによって、様々な模様が見えてくる。


そして拡大は無限に続けることが理論上は可能である。


実際のコンピュータで無限に拡大することはできないが、とりあえず十兆倍に拡大した模様をギャラリーとして紹介する。(画像のクリックで拡大画像表示)














拡大の動画


面白そうな場所について、少しづつ拡大した画像をつないで動画にしたものをyoutubeで公開している。ここではそのうちのいくつかを紹介する。youtubeチャンネルではこれ以外にもたくさん掲載しているので、興味のある人は御覧ください。






描画のプログラム


これらの描画には、processingというソフトを使った。電子アートとビジュアルデザインのためのオープンソースプログラミング言語。javaベースになっていて非常に使いやすく、今回のマンデルブロ描画を楽しく進めることができた。

ただし、拡大率を上げることには本当に苦労した。

最初の倍率1のマンデルブロ図形を描画するのは、比較的スムーズにできたのだが、拡大率を上げていくに従って不可解な現象が多発。頭を悩ますことになった。

分け入っても分け入ってもバグの山

そんな心境になったのも、拡大率をあげていこうとしていた時である。実際にバグも多かったのだが、本当に悩まされたのは計算精度(ビット落ちによる誤差)である。

とりあえずは倍精度浮動小数点(double)という数字を使ってプログラムを組んだのだが、ほとんどの関数は単精度浮動小数点(float)しか使えない。そしてdoubleとfloatが混在していると、誤差がどんどん蓄積して、描画が歪んだり、解像度が落ちたりする。

全ての計算について、その計算はどこまでの精度が必要なのか、その計算でその精度が保たれているのか、そもそもdoubleとかfloatの精度は何桁あるのか、そんなことを意識する必要があった。

そして拡大率一兆倍、十兆倍を超えると、いよいよdoubleではビット落ちのために、まともな計算ができなくなってくる。

これに対応するため、ビット落ちのない計算をするためのclassを作る羽目になる。苦労してなんとかできたものの、今度は時間の問題。doubleでの計算の50倍以上の時間がかかる。これまで1秒で描画できた画面なら一分、10秒かかった画面なら10分かかる。

動画は「プログラムで画像を次々と表示し、それを録画した上で早送りする」という方法で実現している。しかし一枚の画像に何分もかかるのでは、そのような手法は使えない。

動画で十兆倍を超えた部分を「ワープ」と称しているのは、しかたなく飛び飛びの画像を無理やりつないだためである。

学んだこと


今回暇潰しのつもりで始めて、ずいぶん頭を悩ませることになったが、お陰様で多くのことを学ぶことができた。
  • マンデルブロやフラクタルについての知識
  • processingによるプログラミング
  • Windowsによる画面録画
  • 動画編集(shotcutを使用)
  • youtubeへの動画投稿
なんとかこのままボケずに過ごせるかな。