第2回:▶︎ 複数のグラフを描く
■ リテラル
リテラル (literal) とは、 「文字の並び」の通りに解釈される量をいう。
1
や 1.1
はリテラルである。 それぞれ、整数 1
, 小数1.1
という値として評価されるからである。
■ 文字列
「文字の並び」として表される量が、文字列である。 文字列のリテラルは、ダブルクォート "
で囲まれた文字の並びである。
julia> "Hello world"
"Hello world"
文字列を連結するには、演算子 *
を用いる。
julia> h="Hello"
"Hello"
julia> w="world"
"world"
julia> h*w
"Helloworld"
julia> h*" "*w
"Hello world"
数字を表す文字列を作るには、string
関数を用いる。
julia> string(0)
"0"
julia> string(1)
"1"
julia> string(1.1)
"1.1"
■ for文
一つずつ要素を取り出すことができる量を、コレクションという。 ベクトルやRangeは、コレクションである。
for
文を用いると、コレクションから要素を一つづつ取り出して、 end
文が出現するまでの文を繰り返して、計算を行うことができる。 この繰り返される部分をブロック(block)という。 ブロックは、字下げ (indent) で表記される。 が、字下げは見やすさのためだけである。
繰り返しをループ(loop)ともいう。
ブロックは、for文以外にも出現する (例えば、 ■ if文 )。 区別したいなら for
ブロックとも称する。
次の例では、変数 i
に、ベクトルの各要素を入れて、end
文までの計算を繰り返す。 コレクションの各要素が入る変数をループ変数 (loop variable)という。
julia> for i in [1,3,2]
@show i # 式 i の値を表示する
end
i = 1
i = 3
i = 2
@show i
は、式 i
の値を表示するマクロである。
Range型を用いた for
文の例を示す。
julia> for i in 1:5
println( string(i) )
end
1
2
3
4
5
string
関数の結果を表示する。 println
関数は、印字してから、改行する命令である。
▶︎ グラフに凡例を加える
グラフの凡例(lengend)は、グラフに描かれた曲線を区別するための説明である。 PyPlotパッケージで書かれたグラフに凡例を追加するには、以下のようにする。
まず、plot
関数に label=文字列
の形式で、 その曲線に付与する文字列を指定する。 全ての曲線を描いた後に、legend
関数を付与する。
using PyPlot
xs=-1:0.1:1
plot(xs,-1*xs, label="y=-x")
plot(xs,2*xs-1, label="y=2x-1")
legend()
比例関係 $y = ax$ ($a=1,2,3,4,5$)のグラフを描こう。
using PyPlot
xs=-1:0.1:1
plot(xs, xs, label="y= x" )
plot(xs, 2*xs, label="y=2x" )
plot(xs, 3*xs, label="y=3x" )
plot(xs, 4*xs, label="y=4x" )
plot(xs, 5*xs, label="y=5x" )
end
legend()
上のプログラムを、for文を用いて繰り返しで書き直してみよう。
using PyPlot
xs=-1:0.1:1
for a in 1:5
plot(xs, a*xs, label="y="*string(a)*"x" )
end
legend()
▶︎ 冪乗関数を描く
x^y
は、冪(べき, power)ないし冪乗(べきじょう)$x^y$を表す。 $x$を底 (base)、$y$を冪指数 (exponent)という。
julia> 2^2
4
julia> 2^3
8
julia> 2^4
16
冪指数が負の整数のとき、冪の計算は失敗する (DomainError
: 定義域外の例外)。 代わりに、負の小数を指定する。
julia> 2^-2 # DomainError
ERROR: DomainError:
julia> 2^-2.0
0.25
ベクトルや等差級数の各要素に対して 冪乗を計算するには 演算子 ^
の前にピリオド.
を加える。
julia> 2.^[2,3,4]
3-element Array{Int64,1}:
4
8
16
julia> (2:4).^2
3-element Array{Int64,1}:
4
9
16
julia> 2:4.^2 # `^`は `:` よりも優先度が高い
2:16
冪乗 $y=x^a, (a=2,3,4,5)$ のグラフを描こう。
plt[:axes]()[:set_aspect]("equal")
は、 グラフの縦横比 (アスペクト比 aspect ratio) を等しくする命令である。
using PyPlot
xs=0:0.1:1
plot(xs, xs.^2 )
plot(xs, xs.^3 )
plot(xs, xs.^4 )
plot(xs, xs.^5 )
plt[:axes]()[:set_aspect]("equal")
for文を使って、繰り返しの処理をまとめる。
さらに、凡例を追加する。
using PyPlot
# 間隔を狭めた
xs=0:0.05:2
for a in 2:5
plot(xs, xs.^a , label="y=x^"*string(a) )
end
legend()
# 描画範囲を設定
xlim(-0.05,2)
ylim(-0.05,2)
plt[:axes]()[:set_aspect]("equal")
plot
命令は、全ての点を表示しようとする。 グラフの描画範囲を調整するには、関数 xlim
と ylim
を用いる。
関数 xlim(a,b)
は、x軸の描画を a から b の範囲に限定する命令である。
関数 ylim(a,b)
は、y軸の描画を a から b の範囲に限定する命令である。
▶︎ ローレンツ関数を描く
以下の曲線を、 ローレンツ関数 (Lorentzian function)という。
パラメータを $x_0 = 0, \gamma = 2$ のように選ぶと、 以下のように簡単な形となる。
まず、この曲線を描いてみる。 各要素に対して除算を行うため、/
の前にも、ピリオド.
を付与する。
julia> xs=-3:0.5:3
-3.0:0.5:3.0
julia> 1 ./ (xs.^2+1)
13-element Array{Float64,1}:
0.1
0.137931
0.2
0.307692
0.5
0.8
1.0
0.8
0.5
0.307692
0.2
0.137931
0.1
上のグラフを描こう。
using PyPlot
xs=-3:0.1:3
plot(xs, 1 ./ (xs.^2+1) )
以下のように、パラメータ $\gamma$ を導入する。
三つのパラメータ $\gamma=0.5,1,2$ について、この曲線を描く。
using PyPlot
xs=-3:0.05:3
gamma=0.5
plot(xs, (gamma/2) ./ (xs.^2+(gamma/2)^2), label=gamma )
gamma=1.0
plot(xs, (gamma/2) ./ (xs.^2+(gamma/2)^2), label=gamma )
gamma=2.0
plot(xs, (gamma/2) ./ (xs.^2+(gamma/2)^2), label=gamma )
legend()
plt[:axes]()[:set_aspect]("equal")
gammaの値が変わっても、それぞれの曲線を描く命令は変わらない。 for文を用いて、gammaの値を変えてみよう。(結果のグラフは同じである)
using PyPlot
xs=-3:0.05:3
for gamma in [0.5,1.0,2.0]
plot(xs, (gamma/2) ./ (xs.^2+(gamma/2)^2), label=gamma )
end
legend()
plt[:axes]()[:set_aspect]("equal")
ローレンツ関数には、次の性質がある。
点 $x=0$ で 最大値 $y = \frac{2}{\gamma}$
点 $x=\pm\frac{\gamma}{2}$ で、$y = \frac{1}{2}\frac{2}{\gamma}$ となること。
2つ目の性質を観察するため、最大値に対する比を描いてみる。
PyPlotパッケージに用意された関数 axhline()
は、 水平線(horizontal line)を描く。 引数 color="k"
は、黒色(black)で描くことを指定し、lw=0.5
は線幅(linewidth)を指定する。
using PyPlot
xs=-3:0.05:3
for gamma in [0.5,1.0,2.0]
plot(xs,
(gamma/2) ./ (xs.^2+(gamma/2)^2) / (2/gamma),
label=gamma )
end
legend()
axhline(1/2, color="k", lw=0.5)
plot
関数の文は、複数の行に渡って記述しているが、行が更に続くことを示す記法は、特に用意されていない。構文が行末で終わらなければ、次の行まで読みに行くことになっている。
パラメータ $\gamma$は、半値全幅 (Full Width of Half Maximum, FWHM)と呼ばれる。 $\gamma$を非常に小さくすると、 Diracのデルタ関数 (Dirac delta function)の近似(の一つ)となる。
■ 更新演算子
変数に四則演算などを行って、元の変数に再代入する場合には、 更新演算子を用いるとよい。 演算子の直後に =
の文字が入る。
julia> x=1
1
julia> # 再代入
x=x+1
2
julia> # 更新演算子
x+=1
3
演算子 +
, -
, *
, /
, ^
に対して、 更新演算子 +=
, -=
, *=
, /=
, ^=
が用意されている。
以下の例は、変数 gamma
を 2 で繰り返し割り算する。
julia> gamma=2
2
julia> for i=1:5
gamma /= 2
@show gamma
end
gamma = 1.0
gamma = 0.5
gamma = 0.25
gamma = 0.125
gamma = 0.0625
更新演算子 /=
を利用して、ローレンツ関数のパラメータ gamma
を変えてみる。
using PyPlot
xs=-3:0.05:3
gamma=2
for i in 1:5
plot(xs,
(gamma/2) ./ (xs.^2+(gamma/2)^2) / (2/gamma),
label=gamma )
gamma /= 2
end
legend()
axhline(1/2, color="k", lw=0.5)
更新演算子は、ベクトルのスカラー倍や、定数の加減にも適用できる。
julia> xs = [1,2,2,1]
4-element Array{Int64,1}:
1
2
2
1
julia> xs +=1
4-element Array{Int64,1}:
2
3
3
2
julia> xs +=1
4-element Array{Int64,1}:
3
4
4
3
julia> xs *=1
4-element Array{Int64,1}:
3
4
4
3
前節の三角形を描く例題で、更新演算子 +=
を用いて、図形を繰り返し並行移動してみよう。
using PyPlot
xs = [1,2,2,1]
ys = [1,1,3,1]
for i=1:5
plot(xs,ys)
xs += 0.5
ys += 0.5
end
plt[:axes]()[:set_aspect]("equal")
◀︎ 練習
ローレンツ関数において、パラメータ $x_0$ を変えたグラフを作成せよ。 for文を使う方法、更新演算子を使う方法の、二つで描いてみよ。
★ 今回のまとめ
文字列
for文
グラフに凡例を加える
冪乗関数
ローレンツ関数
更新演算子