つれづれなる備忘録

日々の発見をあるがままに綴る

gnuplotによるグラフ作成25~複素数関数のプロット

 今回はgnuplotでの複素数の取り扱いと複素数をとる関数のプロットについて紹介する。

1. 虚数単位の設定

 gnuplotでは複素数{real,imag}として定義する。例えば1+2iは{1,2}とする。関数の引数に複素数をとる場合、あらかじめ虚数単位を定義しておくと便利である。

i={0,1}

これで変数i=0+iという純虚数であるということが定義できた。

2. 複素数をとる関数のプロット

定義した虚数単位を用いて、複素数をとる関数のプロットを行うには、例えばx+i*yの複素数平面では

set isosamples 40,40
splot real(x+i*y)

splotを用いるが、プロット時にrealまたはimagを選択する必要がある。以下、realおよびimagでx+i*yをプロットしたものである。

"複素数平面のプロット(real)"
複素数平面のプロット(real)

"複素数平面のプロット(imag)"
複素数平面のプロット(imag)

下は複素数を変数とする対数関数をプロットする。

set isosamples 40,40
splot imag(log(x+i*y))

imagのプロットでは原点まわりに位相がまわっていうことがわかる。

"log(z)のプロット(imag)"
log(z)のプロット(imag)

realのプロットでは原点の特異点があることがわかる。

"log(z)のプロット(real)"
log(z)のプロット(real)

3. マンデルブロ集合のプロット

 複素数の応用として以下を参考にマンデルブロ集合をプロットする。

gnuplot / fractal / mandelbrot

以下の数列でzが発散しない複素数Aをマンデルブロ集合と呼ぶ。

\begin{eqnarray} z_{0} &=& 0.0 \\ z_{n+1} &=& z_{n}^{2} + A \end{eqnarray}

nや発散の閾値を適当な大きさに設定することで複素数Aを求める。

これを実現するには以下のようにgnuplot上で関数を定義する。

complex(x,y) = x*{1,0}+y*{0,1}
mandel(x,y,z,n) = (abs(z)>2.0 || n>=200) ?  n : mandel(x,y,z*z+complex(x,y),n+1)

複素数Aはここではcomplex(x,y)となる。compex(x,y)の代わりに上と同様にi={0,1}として虚数単位を定義してx+i*yを使用してもよい。 処理の詳細は割愛するがabs(z)が2を超えるか、繰り返し回数が200を超えた場合に、そのときのnを出力する処理になっている。 もともとはnは1000だったがn>=1000で実行するとrecursion depth limit exceededというエラーで止まるので200まで下げた。

set xrange [-1.5:0.5]
set yrange [-1:1]
set logscale z
set isosample 50
set hidden3d
set contour
splot mandel(x,y,{0,0},0) notitle

プロットの設定を上のようにして実行した結果が下のプロットになる。

"マンデルブロ集合"
マンデルブロ集合

4. まとめ

 今回はgnuplotでの複素数の取り扱いと複素数をとる関数のプロット、さらに応用としてマンデルブロ集合のプロットについて紹介した。