LoginSignup
3
0

More than 5 years have passed since last update.

Swarm oscillatorsの計算

Last updated at Posted at 2018-09-17

目的

  • Swarm Oscillatorsの数値計算
  • Julia v1.0を試す
  • Jupyter notebook

Swarm Oscillatorsのモデル

Swarm Oscillatorは直訳すれば「群れ動く振動子」であり、その名の通り、周辺との相互作用により集団的な挙動を見せます。Swarm oscillatorモデルは、内部自由度と空間自由度を持つ素子が相互作用する多素子系のモデルです。

素子はそれぞれ内部状態(位相)$\psi$を持ち、位置$\boldsymbol{r}$に存在するとします。
平面上に$n$個の粒子が存在するとき、それらの内部状態(位相)は$n$行ベクトル$\boldsymbol{\psi}$、位置は$n$行2列行列$\boldsymbol{r}$とおきます。このとき、$i$番目の粒子の位相は$\psi_i$、位置は$\boldsymbol{r_i}$です。$i$番目の粒子と$j$番目の粒子における位相の差を$\Psi_{ji}=\psi_j-\psi_i$、位置の差をベクトル$\boldsymbol{R_{ji}}=\boldsymbol{r_j}-\boldsymbol{r_i}$とおくと、$i$番目の素子の時間発展は

\frac{d}{dt}\psi_i=\sum_{\{j|j\neq i\}}e^{-|\boldsymbol{R_{ji}}|}\sin(\Psi_{ji}+\alpha|\boldsymbol{R_{ji}}|-c_1)\\
\frac{d}{dt}\boldsymbol{r_i}=c_3 \sum_{\{j|j\neq i\}}\boldsymbol{\hat{R}_{ji}} e^{-|\boldsymbol{R_{ji}}|}\sin(\Psi_{ji}+\alpha|\boldsymbol{R_{ji}}|-c_2)

で書き表されます。ここで、$\boldsymbol{\hat{R}_{ji}}$は規格化されたものであることを示します。

イメージとしては、素子が位相$\psi$に応じてz軸方向に振動している感じです。素子自身からの距離に応じて指数減衰する正弦波の(つまり同心円状の)場があり、それが他の素子の位相や位置に影響を与えるといったような感じでしょうか。

数値計算

using LinearAlgebra
using Plots
gr(size=(340,300),titlefont=font("sans-serif",9))

const n=50 #素子数
const L=25 #系のサイズ
const c1=1.5
const c2=0.5
const c3=2.0
const α=0.5
const dt=0.05 #時間刻み

function(ψ,r)
    a=zeros(n)
    for i=1:n
        sum=0
        for j=1:n
            if j==i; continue;end
            sum+=exp(-norm(r[j,:]-r[i,:]))*sin(ψ[j]-ψ[i]+α*norm(r[j,:]-r[i,:])-c1)
        end
        a[i]=sum
    end
    return a
end

function dr(ψ,r)
    a=zeros(n,2)
    for i=1:n
        sum=[0,0]
        for j=1:n
            if j==i; continue; end
            sum+=(normalize(r[j,:]-r[i,:]).*exp(-norm(r[j,:]-r[i,:]))*sin(ψ[j]-ψ[i]+α*norm(r[j,:]-r[i,:])-c2))
        end
        a[i,:]=sum
    end
    return c3*a
end

function oneStep!(ψ,r)
    ψ.=mod.(ψ+(ψ,r)*dt,2π)
    r.=mod.(r+dr(ψ,r)*dt,L)
end

function draw(gen,ψ,r)
    t=round(gen*dt;digits=2)
    scatter(r[:,1],r[:,2],
        xlab="x",xlims=(0,L),
        ylab="y",ylims=(0,L),
        zcolor=ψ,
        leg=false,
        cbar=true,
        cbarlims=(0,2π),
        title="t = $t, (gen = $gen),\n c=[$c1,$c2,$c3],alpha=$α")
end

psi=rand(0:0.01:2π, n)
pos=rand(0:0.01:L,n,2)

@time anim = @animate for m in 0:5000
    oneStep!(psi,pos)
    draw(m,psi,pos)
end every 100

@time gif(anim,"tmp/swarm_osillators.gif",fps=4)

26.595608 seconds (263.93 M allocations: 22.255 GiB, 11.16% gc time)
0.633165 seconds (701 allocations: 39.125 KiB)

swarm_osillators_H.gif
$n=50,L=25,c_1=1.5,c_2=0.5,c_3=2.0,\alpha=0.5,dt=0.05$のときのSwarm Oscillators(動的曲線相).

swarm_osillators_A.gif
$n=50,L=25,c_1=5.5,c_2=0.5,c_3=2.0,\alpha=0.5,dt=0.05$のときのSwarm Oscillators(凝集相).

swarm_osillators_C.gif
$n=50,L=10,c_1=2.0,c_2=3.0,c_3=2.0,\alpha=1.0,dt=0.05$のときのSwarm Oscillators(格子相).

6つのパラメータ$n,L,c_1,c_2,c_3,\alpha$を調節することで様々な集団的挙動を示します。

つまづいたところ

標準ライブラリの読み込み

Julia v1.0から標準ライブラリがBase.以下ではなくなったため、使うときは明示的にusingする必要があります。今回の場合、normalizeを使うためにusing LinearAlgebraと書かなければいけません。

constの威力

グローバル変数にconstをつけるとだいぶ早くなる(~100sec -> ~25sec)

round

以前は


round(m*dt,3)

で3桁表示ができた。現在は

round(m*dt;digits=2)

で小数第2位まで表示指定するようになっている。コンマではなくセミコロンであることに注意。(20180918追記)セミコロンでなくコンマでもOKです。

round(m*dt,digits=2)

参考文献

3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0