常微分方程式に空間変数を導入して偏微分方程式へ拡張¶

Volterra 問題を例として¶

以前扱った Volterra 問題は、自由変数が時間だけの常微分方程式で、これは、生物の数がどこでも一定ということを前提としていることを意味していた. しかし、実際の生物は空間分布が一定ではなく、そしておそらくこの分布は生物の数量変化に大きな影響を与える結構重要なファクターなんじゃないかな.

そこで、空間変数を自由変数として導入し、問題を偏微分方程式にして取り扱ってみよう. しかも、こういう問題は空間次元が 1のときと 2以上のときとで根本的に挙動が異なるので、思い切って空間次元を 2以上にとって、取り扱ってみよう.

最初は, おとなしめなモデルで¶

空間変数を新たに導入するということは、問題のモデルに新しいファクターを導入する必要が生ずる. もちろんいろいろなファクターがあり得るので、本来は慎重に考えないといけないところだ.

しかし今回は数値計算への熟達が主眼であるので、モデルとしては少し安直に、「常微分方程式からのズレがあまり無い」モデルを導入し、数値計算結果の解釈に苦労しなくて良いようにしよう.

そこで、単なる「拡散」だけを導入することにして、被食者数を $u(x, t)$ で、捕食者数を $v(x, t)$ で表すとして、 $x \in [0, L] \times [0, L]$, $t > 0$ とし、以下のようなモデルを考えよう.

$\left\{\begin{array}{rcl} \displaystyle \frac{\partial u}{\partial t} & = & \epsilon_1 \Delta u - C_1 uv + D_1 u, \\ \displaystyle \frac{\partial v}{\partial t} & = & \epsilon_2 \Delta v + C_2 uv - D_2 v \end{array}\right.$

ただし、係数 $\epsilon_1$, $\epsilon_2$, $C_1$, $C_2$, $D_1$, $D_2$ は全て定数で正としておこう.

そして、空間領域に関する境界条件としては周期的境界条件を課しておくことにしよう.

method of line を適用する¶

ここでは、空間領域 $\Omega = [0, L] \times [0, L]$ に対し、その分割数を $N \times N$ とし、境界条件として周期的境界条件を離散化しよう.

よって、$\Delta x = \Delta y = L/N$ として $u(x,t)$ の離散化に相当する従属変数を $ u(t) = \{ u_{i,j}(t)\}_{i, j = 1}^N$ とし、境界条件は 外側にはみ出す点を仮想的に考えたとして

$$ \left\{ \begin{array}{rcl} \displaystyle u_{0, j} & := & u_{N, j} \mbox{ for } \forall j ,\\ \displaystyle u_{N+1, j} & := & u_{1, j} \mbox{ 同上 } , \\ \displaystyle u_{i, 0} & := & u_{i, N} \mbox{ for } \forall i, \\ \displaystyle u_{i, N+1} & := & u_{i, 1} \mbox{ 同上 } \end{array} \right. $$

と解釈することになる.

こうしておいて、空間微分(ラプラシアン) $\Delta$ をたとえば差分近似で置き換える. たとえば $U$ に対する二階中心差分ならば

$$ (\Delta u)_{i,j} := \frac{ u_{i+1,j} + u_{i-1,j} + u_{i,j+1} + u_{i,j+1} - 4 u_{i,j} }{\Delta x^2} $$

となる. これらを使った場合は、全体は $i = 1,2,\cdots, N$, $j = 1,2,\cdots, N$ に対して

$$ \left\{ \begin{array}{rcl} \displaystyle \frac{d u_{i,j}(t) }{dt} & = & \epsilon_1 (\Delta u)_{i,j} - C_1 u_{i,j} v_{i,j} + D_1 u_{i,j}, \\ \displaystyle \frac{d v_{i,j}(t) }{dt} & = & \epsilon_2 (\Delta v)_{i,j} + C_2 u_{i,j} v_{i,j} - D_2 v_{i,j}, \\ \end{array} \right. $$

という $N \times N$ 元連立常微分方程式で近似できることになる.

あとは少しずつプログラムを作っていくだけだ. まずは、問題のパラメータを設定してしまおう.

In [2]:
ϵ1, ϵ2 = 0.001, 0.001
C1 = C2 = D1 = D2 = 1.0
Out[2]:
1.0
In [3]:
L = 1.0
N = 40
Δx = L/N
Δt = 0.1 * Δx^2
Out[3]:
6.250000000000001e-5

ラプラシアンに使う係数行列を下記のように定義して…

In [4]:
d = [ -2.0 for i in 1:N ]
v = [ 1 for i in 1:N-1 ]
d2 = diagm(d, 0) + diagm(v, 1) + diagm(v, -1)
d2[1,N] = d2[N, 1] = 1.0

d2 = (1/(Δx)^2) * d2
Out[4]:
40×40 Array{Float64,2}:
 -3200.0   1600.0      0.0      0.0  …      0.0      0.0      0.0   1600.0
  1600.0  -3200.0   1600.0      0.0         0.0      0.0      0.0      0.0
     0.0   1600.0  -3200.0   1600.0         0.0      0.0      0.0      0.0
     0.0      0.0   1600.0  -3200.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0   1600.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0  …      0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0  …      0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     ⋮                               ⋱                                    
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0  …      0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0         0.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0  …   1600.0      0.0      0.0      0.0
     0.0      0.0      0.0      0.0     -3200.0   1600.0      0.0      0.0
     0.0      0.0      0.0      0.0      1600.0  -3200.0   1600.0      0.0
     0.0      0.0      0.0      0.0         0.0   1600.0  -3200.0   1600.0
  1600.0      0.0      0.0      0.0         0.0      0.0   1600.0  -3200.0

下にあるように、近似データそのものである行列 $u$ に対して、上で定義した行列 $d2$ を用いて $d2 * u + u * d2$ を計算すると、これがラプラシアンを適用した結果相当になっている(線形代数が苦手な人は、for 文を使ってプログラムしたほうが良いかも).

In [144]:
function f(U)
    u, v = U[1:N,:], U[N+1:end, :]
    uv = u .* v
    
    fu = ϵ1 * ( d2 * u + u * d2 ) - C1 * uv + D1 * u
    fv = ϵ2 * ( d2 * v + v * d2 ) + C2 * uv - D2 * v
    
    res = vcat( fu, fv )
    return res
end
Out[144]:
f (generic function with 1 method)

上を見て分かるように、 $u(x)$ の近似行列 $u_{i,j}$ と $v(x)$ の近似行列 $v_{i,j}$ を受け渡しする時は、上下につなげて、一つにして扱っている.

そこで、これで連立常微分方程式の右辺(の近似)が計算できたことになるので、Runge-Kutta 法を定義する.

In [145]:
function RK(u)
    f1 = f(u)
    f2 = f(u + Δt/2 * f1)
    f3 = f(u + Δt/2 * f2)
    f4 = f(u + Δt * f3)
    return u + Δt * (f1 + 2*f2 + 2*f3 + f4)/6
end
Out[145]:
RK (generic function with 1 method)

これで計算手順の準備は整った.

次に、初期値を適当に作ろう. 今回は、ガウス型に穏やかに分布しているものを考えよう.

In [126]:
u0 = [ 0.3 + 0.4 * exp( - 4.6 * 4 * ((i-N/2)^2 + (j-N/2)^2) / (N^2) ) for i in 1:N, j in 1:N ]
v0 = [ 0.4 + 2.0 * exp( - 4.6 * 16 * ((i-N/4)^2 + (j-N/4)^2) / (N^2) ) for i in 1:N, j in 1:N ]
U0 = vcat( u0, v0 )
Out[126]:
80×40 Array{Float64,2}:
 0.300099  0.300152  0.300227  0.300332  …  0.300152  0.300099  0.300063
 0.300152  0.300232  0.300347  0.300507     0.300232  0.300152  0.300097
 0.300227  0.300347  0.300519  0.300759     0.300347  0.300227  0.300145
 0.300332  0.300507  0.300759  0.301109     0.300507  0.300332  0.300212
 0.300474  0.300725  0.301084  0.301584     0.300725  0.300474  0.300302
 0.300661  0.301012  0.301513  0.302211  …  0.301012  0.300661  0.300422
 0.300902  0.30138   0.302064  0.303016     0.30138   0.300902  0.300576
 0.301202  0.301839  0.302751  0.304021     0.301839  0.301202  0.300768
 0.301566  0.302396  0.303584  0.305238     0.302396  0.301566  0.301   
 0.301994  0.303051  0.304563  0.306669     0.303051  0.301994  0.301273
 0.302481  0.303796  0.305677  0.308298  …  0.303796  0.302481  0.301584
 0.303016  0.304616  0.306903  0.310089     0.304616  0.303016  0.301926
 0.303584  0.305485  0.308203  0.311989     0.305485  0.303584  0.302289
 ⋮                                       ⋱                              
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4       …  0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4       …  0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     

どんな初期値なのか、目で見ておこう.

In [8]:
using Plots
gr()
Out[8]:
Plots.GRBackend()
In [9]:
X = Y = Δx:Δx:L
plot(X, Y, u0 , st = :surface)
Out[9]:
<?xml version="1.0" encoding="utf-8"?> 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70
In [10]:
plot(X, Y, v0, st = :surface)
Out[10]:
<?xml version="1.0" encoding="utf-8"?> 0.50 0.75 1.00 1.25 1.50 1.75 2.00 2.25

ふむ、こんな感じか.

さて、これで準備は整ったので、早速、計算してみよう

In [11]:
using ProgressMeter
In [152]:
U = copy(U0)
sq_U = copy(U0)  

@showprogress for i in 1:200000
    U = RK(U)
    if i % 2000 == 0  # 一定数ステップおきにデータを格納するとして
        sq_U = cat(3, sq_U, U)  # 3次元目に追加していく
    end
end
Progress: 100%|█████████████████████████████████████████| Time: 0:02:54

試しに結果の数字をちょろっと見てみる.

In [153]:
sq_U
Out[153]:
80×40×101 Array{Float64,3}:
[:, :, 1] =
 0.300099  0.300152  0.300227  0.300332  …  0.300152  0.300099  0.300063
 0.300152  0.300232  0.300347  0.300507     0.300232  0.300152  0.300097
 0.300227  0.300347  0.300519  0.300759     0.300347  0.300227  0.300145
 0.300332  0.300507  0.300759  0.301109     0.300507  0.300332  0.300212
 0.300474  0.300725  0.301084  0.301584     0.300725  0.300474  0.300302
 0.300661  0.301012  0.301513  0.302211  …  0.301012  0.300661  0.300422
 0.300902  0.30138   0.302064  0.303016     0.30138   0.300902  0.300576
 0.301202  0.301839  0.302751  0.304021     0.301839  0.301202  0.300768
 0.301566  0.302396  0.303584  0.305238     0.302396  0.301566  0.301   
 0.301994  0.303051  0.304563  0.306669     0.303051  0.301994  0.301273
 0.302481  0.303796  0.305677  0.308298  …  0.303796  0.302481  0.301584
 0.303016  0.304616  0.306903  0.310089     0.304616  0.303016  0.301926
 0.303584  0.305485  0.308203  0.311989     0.305485  0.303584  0.302289
 ⋮                                       ⋱                              
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4       …  0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4       …  0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     
 0.4       0.4       0.4       0.4          0.4       0.4       0.4     

[:, :, 2] =
 0.324111  0.324108  0.324086  0.324032  …  0.324222  0.324161  0.324123
 0.324108  0.324057  0.323946  0.323739     0.324312  0.32422   0.324157
 0.324086  0.323946  0.323669  0.323185     0.324442  0.324305  0.324202
 0.324032  0.323739  0.323185  0.322238     0.324622  0.324422  0.324262
 0.323946  0.323428  0.322468  0.32085      0.324866  0.32458   0.324341
 0.323842  0.323043  0.321574  0.319115  …  0.325188  0.324788  0.324446
 0.323764  0.322673  0.320667  0.317321     0.325599  0.325055  0.324589
 0.323776  0.322455  0.320013  0.315926     0.326111  0.325389  0.324785
 0.323951  0.322548  0.319911  0.315453     0.32673   0.325796  0.325048
 0.324343  0.323075  0.320598  0.316314     0.327456  0.326275  0.325386
 0.324971  0.324078  0.322161  0.318664  …  0.328281  0.326822  0.325799
 0.325801  0.325494  0.32449   0.322333     0.329187  0.327425  0.326276
 0.32676   0.327176  0.327316  0.326867     0.330146  0.328064  0.326793
 ⋮                                       ⋱                              
 0.367151  0.367214  0.367306  0.367433     0.367214  0.367151  0.367118
 0.367126  0.367177  0.367251  0.367354     0.367177  0.367126  0.3671  
 0.367105  0.367145  0.367203  0.367284  …  0.367145  0.367105  0.367084
 0.367087  0.367118  0.367163  0.367225     0.367118  0.367087  0.367071
 0.367072  0.367095  0.367129  0.367176     0.367095  0.367072  0.36706 
 0.36706   0.367077  0.367102  0.367136     0.367077  0.36706   0.367051
 0.367051  0.367063  0.367081  0.367105     0.367063  0.367051  0.367044
 0.367044  0.367052  0.367065  0.367082  …  0.367052  0.367044  0.367039
 0.367038  0.367044  0.367053  0.367065     0.367044  0.367038  0.367035
 0.367036  0.367041  0.367049  0.367061     0.367038  0.367035  0.367033
 0.36705   0.367074  0.367116  0.367182     0.367035  0.367032  0.367033
 0.367224  0.367464  0.367877  0.368538     0.367033  0.367033  0.367061

[:, :, 3] =
 0.351393  0.351308  0.351153  0.350894  …  0.351586  0.351514  0.351457
 0.351308  0.35107   0.350657  0.349987     0.351684  0.351574  0.35147 
 0.351153  0.350657  0.349807  0.348443     0.35183   0.351662  0.351482
 0.350894  0.349987  0.348443  0.34599      0.352032  0.351783  0.351487
 0.350521  0.349031  0.346511  0.342533     0.352305  0.351944  0.351487
 0.350065  0.347852  0.344129  0.338284  …  0.352663  0.352158  0.351496
 0.34961   0.346632  0.341635  0.333828     0.35312   0.352435  0.351541
 0.349289  0.345653  0.339556  0.330058     0.353689  0.352791  0.35166 
 0.349249  0.345231  0.33848   0.327951     0.354377  0.353235  0.351895
 0.349606  0.345618  0.338869  0.328273     0.355184  0.353773  0.352276
 0.350398  0.346905  0.340896  0.331323  …  0.356101  0.3544    0.35281 
 0.351572  0.348983  0.34438   0.336821     0.357107  0.3551    0.353475
 0.352991  0.351579  0.348831  0.343984     0.358172  0.355849  0.354225
 ⋮                                       ⋱                              
 0.338105  0.338225  0.338404  0.338652     0.338225  0.338104  0.338051
 0.338056  0.338153  0.338297  0.338498     0.338153  0.338056  0.338013
 0.338013  0.33809   0.338204  0.338362  …  0.33809   0.338013  0.33798 
 0.337977  0.338036  0.338124  0.338245     0.338036  0.337977  0.337951
 0.337947  0.337991  0.338057  0.338149     0.337991  0.337947  0.337927
 0.337922  0.337955  0.338004  0.338071     0.337955  0.337922  0.337908
 0.337903  0.337927  0.337962  0.338011     0.337927  0.337903  0.337893
 0.337889  0.337905  0.33793   0.337965  …  0.337905  0.337888  0.337881
 0.337878  0.337891  0.337909  0.337935     0.337889  0.337878  0.337873
 0.337877  0.337893  0.337919  0.337957     0.337878  0.33787   0.337868
 0.337923  0.337998  0.338123  0.338317     0.33787   0.337867  0.337878
 0.338207  0.338627  0.339325  0.340417     0.337868  0.337878  0.33795 

...

[:, :, 99] =
 0.319653  0.325381  0.33125   0.33704   …  0.304698  0.309225  0.314231
 0.325381  0.332371  0.339588  0.346763     0.307418  0.312804  0.318815
 0.33125   0.339588  0.348248  0.356913     0.310094  0.316389  0.323466
 0.33704   0.346763  0.356913  0.367123     0.312627  0.319845  0.328011
 0.342489  0.353572  0.365193  0.376938     0.314904  0.323016  0.332241
 0.347304  0.359653  0.372651  0.385841  …  0.316803  0.32573   0.335929
 0.351194  0.364638  0.378837  0.393302     0.318203  0.32782   0.33885 
 0.353892  0.368193  0.383343  0.398833     0.319002  0.329134  0.340799
 0.355192  0.370055  0.385844  0.402044     0.31912   0.32956   0.341619
 0.354973  0.370067  0.386144  0.402696     0.318516  0.329033  0.341222
 0.353216  0.3682    0.3842    0.40073   …  0.317193  0.327551  0.339595
 0.350005  0.364553  0.380127  0.396275     0.315196  0.325172  0.33681 
 0.345521  0.359344  0.374183  0.389624     0.312616  0.32201   0.333013
 ⋮                                       ⋱                              
 1.78262   1.76927   1.74814   1.72003      1.77242   1.78424   1.78769 
 1.80307   1.79068   1.77112   1.74506      1.79398   1.80476   1.80782 
 1.82268   1.81122   1.7932    1.76924   …  1.81499   1.82461   1.8272  
 1.8409    1.83028   1.81374   1.79182      1.83489   1.84326   1.84528 
 1.85722   1.84731   1.83214   1.81216      1.85313   1.86018   1.86156 
 1.87117   1.86184   1.84788   1.82968      1.86921   1.87493   1.87558 
 1.8824    1.87351   1.86057   1.84395      1.88272   1.8871    1.88698 
 1.89067   1.88208   1.86999   1.85472   …  1.89332   1.89641   1.8955  
 1.89588   1.88749   1.87607   1.86194      1.90077   1.90268   1.90101 
 1.89807   1.8898    1.87893   1.86575      1.90495   1.90582   1.90348 
 1.89737   1.88923   1.87884   1.86647      1.90582   1.90589   1.90301 
 1.89404   1.88608   1.87616   1.86453      1.90348   1.90301   1.89978 

[:, :, 100] =
 0.289043  0.294457  0.300062  0.305659  …  0.27526   0.27936   0.283975
 0.294457  0.30099   0.307787  0.314604     0.277991  0.282859  0.288371
 0.300062  0.307787  0.315858  0.32399      0.280773  0.286443  0.2929  
 0.305659  0.314604  0.32399   0.33349      0.28351   0.289986  0.297399
 0.311008  0.321154  0.331841  0.342704     0.286091  0.29334   0.301677
 0.315849  0.327114  0.339028  0.351188  …  0.288397  0.296344  0.305528
 0.319917  0.332161  0.34516   0.358486     0.290308  0.298837  0.308741
 0.32297   0.335995  0.349877  0.364173     0.291717  0.300673  0.311127
 0.324816  0.338377  0.352889  0.367903     0.292534  0.301737  0.312533
 0.32533   0.339151  0.354004  0.369447     0.292705  0.301952  0.312862
 0.324471  0.338264  0.353154  0.368716  …  0.292211  0.301295  0.312082
 0.322286  0.335771  0.350399  0.365774     0.291071  0.299795  0.310232
 0.318906  0.331829  0.345921  0.36082      0.289344  0.297534  0.307418
 ⋮                                       ⋱                              
 1.62588   1.61391   1.59492   1.56963      1.61642   1.62717   1.63036 
 1.64464   1.63351   1.61589   1.5924       1.6362    1.64602   1.64886 
 1.66273   1.65241   1.63616   1.61452   …  1.65553   1.66433   1.66675 
 1.67964   1.67008   1.65515   1.63534      1.6739    1.68159   1.68352 
 1.6949    1.68601   1.67233   1.65427      1.6908    1.69735   1.69872 
 1.7081    1.69978   1.68722   1.67079      1.7058    1.71118   1.71195 
 1.71893   1.71107   1.69951   1.68455      1.71849   1.72272   1.72286 
 1.72718   1.71968   1.70897   1.69533   …  1.72858   1.73173   1.73124 
 1.73275   1.72555   1.71557   1.70308      1.73585   1.73802   1.73696 
 1.73567   1.72874   1.71942   1.70794      1.74018   1.74154   1.73999 
 1.73607   1.72944   1.72075   1.7102       1.74154   1.74231   1.74043 
 1.73417   1.72792   1.71986   1.71019      1.73999   1.74043   1.73842 

[:, :, 101] =
 0.266479  0.271625  0.277     0.28242   …  0.25366   0.257415  0.261709
 0.271625  0.277773  0.284212  0.290721     0.256388  0.260836  0.265939
 0.277     0.284212  0.291788  0.29947      0.259239  0.264403  0.270351
 0.28242   0.290721  0.29947   0.308372     0.262121  0.267997  0.274793
 0.287668  0.297038  0.30695   0.317076     0.264926  0.271477  0.279091
 0.292507  0.302878  0.313893  0.325194  …  0.267538  0.274692  0.28305 
 0.296697  0.307952  0.319956  0.332331     0.269839  0.27749   0.286479
 0.300018  0.31199   0.32482   0.338114     0.271717  0.279727  0.289197
 0.302285  0.314772  0.32822   0.342236     0.27308   0.281286  0.291058
 0.303374  0.316143  0.329973  0.344477     0.27386   0.282084  0.291957
 0.303228  0.316034  0.329992  0.344726  …  0.274021  0.282081  0.291849
 0.301864  0.314466  0.328293  0.342996     0.273562  0.281283  0.290747
 0.299373  0.311544  0.324998  0.339413     0.27252   0.279744  0.288722
 ⋮                                       ⋱                              
 1.47918   1.46855   1.45163   1.42908      1.4705    1.48019   1.48312 
 1.49623   1.48632   1.47059   1.44961      1.48848   1.49734   1.49995 
 1.51275   1.50355   1.48902   1.46966   …  1.50609   1.51405   1.51629 
 1.52827   1.51975   1.50641   1.48866      1.52287   1.52986   1.53168 
 1.54238   1.53448   1.52225   1.50608      1.53836   1.54437   1.54572 
 1.55472   1.54736   1.53617   1.52148      1.55218   1.55718   1.55803 
 1.56499   1.5581    1.54786   1.53454      1.56396   1.56799   1.56833 
 1.57303   1.56655   1.55715   1.54508   …  1.57343   1.57655   1.57641 
 1.57875   1.57264   1.564     1.55306      1.5804    1.58273   1.58216 
 1.58217   1.57643   1.56852   1.55862      1.58475   1.58645   1.58556 
 1.58341   1.5781    1.5709    1.56199      1.58645   1.58774   1.58668 
 1.58265   1.57785   1.57141   1.56347      1.58556   1.58668   1.58565 

あまり変なことにはなっていなさそうなので、プロットしてみよう.

プロットには、fill=true をつけて、色を塗って平面で表してもらおう.

In [154]:
minimum(sq_U), maximum(sq_U)
Out[154]:
(0.1976488027884744, 2.865361858704632)
In [161]:
range = (0.19, 2.87) 

contour(X, Y, sq_U[1:N,:,15], clims = range, fill=true, fmt = :png)  # なんとなくこいつをプロットしてみた.
Out[161]:

ふむ、なんとなくうまく計算できているようだな. しかし、いちいち plot コマンドを打って確認するのも疲れるので、一気に全データを画像にしてしまうことを考えよう.

まず、画像を入れておくディレクトリをコマンドで作らせよう.

In [56]:
run(`mkdir U`)
run(`mkdir V`)

次に、データを画像化するコマンドを作ろう. 基本的には、plot の直後に savefig コマンドを使うだけだ.

In [ ]:
function figureU(num)
    contour(X, Y, sq_U[1:N,:,num], clims = range, fill = true)
    savefig( "U/" * @sprintf("%04d", num) * ".png" )

    contour(X, Y, sq_U[N+1:end,:,num], clims = range, fill = true)
    savefig( "V/" * @sprintf("%04d", num) * ".png" )
end

では、全データを画像にしよう.やや時間がかかりそうだな.

In [157]:
@showprogress for n in 1:size(sq_U)[3]
    figureU(n)
end
Progress: 100%|█████████████████████████████████████████| Time: 0:03:39

これで画像ファイルがたくさんできたはずだ. julia/jyupiter のファイル操作画面から、画像を確認しよう.

ffmpeg などの、動画作成ツールが有るならば、動画にしてみよう¶

フリーのツールで ffmpeg というものがあり、これを使うと連番の画像ファイルを無理なくきれいに動画にできる. 古い juliabox にはインストールされていないが、新しい juliabox にはインストールされているようだ.

例えばこれを julia から直接呼び出して使うならば、今回は以下のようにすればよいだろう.

(詳しい人向け: terminal からコマンドを打っても良い)

In [163]:
run(`ffmpeg -r 5 -i "U/%04d.png" -pix_fmt yuv420p -s 1200x800 U/out.mp4`)  # U ディレクトリのデータ
run(`ffmpeg -r 5 -i "V/%04d.png" -pix_fmt yuv420p -s 1200x800 V/out.mp4`)  # V ディレクトリのデータ
ffmpeg version 2.8.4 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
Input #0, image2, from 'U/%04d.png':
  Duration: 00:00:04.04, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgb24(pc), 3600x2400, 25 fps, 25 tbr, 25 tbn, 25 tbc
[libx264 @ 052b5280] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 052b5280] profile High, level 3.2
[libx264 @ 052b5280] 264 - core 148 r2638 7599210 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=5 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'U/out.mp4':
  Metadata:
    encoder         : Lavf56.40.101
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 1200x800, q=-1--1, 5 fps, 10240 tbn, 5 tbc
    Metadata:
      encoder         : Lavc56.60.100 libx264
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
frame=  101 fps= 12 q=-1.0 Lsize=     703kB time=00:00:19.80 bitrate= 291.0kbits/s    
video:702kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.176905%
[libx264 @ 052b5280] frame I:1     Avg QP:13.86  size: 13607
[libx264 @ 052b5280] frame P:99    Avg QP:15.33  size:  7091
[libx264 @ 052b5280] frame B:1     Avg QP:12.14  size:  2746
[libx264 @ 052b5280] consecutive B-frames: 98.0%  2.0%  0.0%  0.0%
[libx264 @ 052b5280] mb I  I16..4: 31.4% 62.7%  6.0%
[libx264 @ 052b5280] mb P  I16..4: 23.2% 24.5%  1.1%  P16..4: 13.9%  5.1%  0.9%  0.0%  0.0%    skip:31.3%
[libx264 @ 052b5280] mb B  I16..4:  3.3%  1.1%  0.0%  B16..8: 19.7%  4.0%  0.1%  direct: 6.5%  skip:65.2%  L0:47.0% L1:52.0% BI: 1.1%
[libx264 @ 052b5280] 8x8 transform intra:50.4% inter:96.2%
[libx264 @ 052b5280] coded y,uvDC,uvAC intra: 7.8% 44.5% 15.9% inter: 4.8% 9.5% 0.2%
[libx264 @ 052b5280] i16 v,h,dc,p: 35% 39%  2% 24%
[libx264 @ 052b5280] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 44% 24% 27%  1%  1%  1%  1%  0%  1%
[libx264 @ 052b5280] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 44% 31% 20%  1%  2%  1%  1%  0%  0%
[libx264 @ 052b5280] i8c dc,h,v,p: 42% 29% 16% 13%
[libx264 @ 052b5280] Weighted P-Frames: Y:3.0% UV:3.0%
[libx264 @ 052b5280] ref P L0: 75.8%  0.5% 17.3%  6.1%  0.3%
[libx264 @ 052b5280] ref B L0: 77.5% 22.5%
[libx264 @ 052b5280] kb/s:284.49
ffmpeg version 2.8.4 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
Input #0, image2, from 'V/%04d.png':
  Duration: 00:00:04.04, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgb24(pc), 3600x2400, 25 fps, 25 tbr, 25 tbn, 25 tbc
[libx264 @ 04e7dfe0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 04e7dfe0] profile High, level 3.2
[libx264 @ 04e7dfe0] 264 - core 148 r2638 7599210 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=5 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'V/out.mp4':
  Metadata:
    encoder         : Lavf56.40.101
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 1200x800, q=-1--1, 5 fps, 10240 tbn, 5 tbc
    Metadata:
      encoder         : Lavc56.60.100 libx264
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
frame=  101 fps= 13 q=-1.0 Lsize=     671kB time=00:00:19.80 bitrate= 277.8kbits/s    
video:670kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.191219%
[libx264 @ 04e7dfe0] frame I:1     Avg QP:12.11  size: 11074
[libx264 @ 04e7dfe0] frame P:97    Avg QP:15.19  size:  6856
[libx264 @ 04e7dfe0] frame B:3     Avg QP:12.02  size:  3114
[libx264 @ 04e7dfe0] consecutive B-frames: 94.1%  5.9%  0.0%  0.0%
[libx264 @ 04e7dfe0] mb I  I16..4: 57.5% 38.2%  4.3%
[libx264 @ 04e7dfe0] mb P  I16..4: 22.9% 23.4%  1.0%  P16..4: 13.6%  5.1%  0.9%  0.0%  0.0%    skip:33.1%
[libx264 @ 04e7dfe0] mb B  I16..4:  3.4%  0.8%  0.0%  B16..8: 19.1%  3.8%  0.1%  direct:12.6%  skip:60.1%  L0:43.6% L1:55.2% BI: 1.2%
[libx264 @ 04e7dfe0] 8x8 transform intra:49.1% inter:96.4%
[libx264 @ 04e7dfe0] coded y,uvDC,uvAC intra: 7.7% 42.7% 15.5% inter: 4.7% 9.4% 0.2%
[libx264 @ 04e7dfe0] i16 v,h,dc,p: 38% 36%  2% 24%
[libx264 @ 04e7dfe0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 43% 24% 28%  1%  1%  1%  1%  0%  1%
[libx264 @ 04e7dfe0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 45% 31% 19%  1%  2%  1%  1%  0%  0%
[libx264 @ 04e7dfe0] i8c dc,h,v,p: 45% 27% 15% 14%
[libx264 @ 04e7dfe0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 04e7dfe0] ref P L0: 78.8%  0.9% 14.9%  5.4%
[libx264 @ 04e7dfe0] ref B L0: 79.5% 20.5%
[libx264 @ 04e7dfe0] kb/s:271.46

これでディレクトリ U とディレクトリ V の下に、それぞれ out.mp4 という動画ファイルができたはずだ. julia/jyupiter のファイル操作画面で、その動画ファイルをクリックして確認しよう.

レポート問題¶

今回は空間方向だけ差分化して、あとは常微分方程式として扱うという「線の方法」をとった. 時間方向も差分化したり、有限要素法を使ったり(かな-り面倒だが)他の方法で計算してみよう.

レポート問題(チャレンジング)¶

今回は空間変数の導入にあたり「拡散効果」だけを導入したが、おそらく、「敵から逃げる」「餌を追う」という効果を導入したほうが生物モデルとしては妥当だろう. それにはどうしたらよいか.いろいろ考えて、試してみよう.