アニメーション

ClearAll[θ,K];
SeedRandom[42];

(*――シミュレーション設定――*)
n=120;                (*ホタル数*)
ωσ=0.05;               (*固有周波数の分散*)
Kinit=0.3;                (*初期結合 (非対角)*)
ε=0.15;               (*Hebb 学習速度*)
tmax=40;                 (*シミュレーション時間*)
maxStep=0.1;                (*数値解ステップ上限*)

(*――描画パラメータ――*)
baseR=0.006;              (*最小半径*)
pulseAmp=0.024;              (*脈動の振幅*)
haloMult=2;                  (*ハローの半径倍率*)
haloOpac=0.2;               (*ハローの透明度*)
fluoro=RGBColor[0.8,1.0,0.0];     (*蛍光イエロー (Hue,S,B)*)

(*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1. 方程式セットアップ (全 Kij を未知数に) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*)
ω=RandomVariate[NormalDistribution[1,ωσ],n];

eqθ=Table[θ[i]'[t]==ω[[i]]+1/n Sum[K[i,j][t] Sin[θ[j][t]-θ[i][t]],{j,n}],{i,n}];

eqK=Table[K[i,j]'[t]==If[i==j,0,ε (Cos[θ[i][t]-θ[j][t]]-K[i,j][t])],{i,n},{j,n}];

initθ=Table[θ[i][0]==2 π RandomReal[],{i,n}];
initK=Table[K[i,j][0]==If[i==j,0,Kinit],{i,n},{j,n}];

Print["Solving (variables: ",n+n^2,") … 少々お待ちください"];

sol=NDSolveValue[{eqθ,eqK,initθ,initK},Flatten[{Table[θ[i],{i,n}],Table[K[i,j],{i,n},{j,n}]}],{t,0,tmax},Method->{"StiffnessSwitching"},MaxStepSize->maxStep];

(*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2. 座標を円盤内にランダム配置 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*)
randDisk[]:=Module[{r=Sqrt@RandomReal[],ϕ=2 π RandomReal[]},r {Cos[ϕ],Sin[ϕ]}];
pos=Table[randDisk[],{n}];

(*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3. フレームを描く関数 (Glow+ハロー) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*)
frame[τ_?NumericQ]:=Module[{θnow,rad},θnow=Table[sol[[i]][τ],{i,n}];
rad=baseR+pulseAmp Sin[θnow]^2;
Graphics[Table[{(*ハロー：淡く大きいディスク*)Opacity[haloOpac],fluoro,Disk[pos[[i]],haloMult rad[[i]]],(*内核：Glow で発光感*)Glow[Lighter[fluoro,.3]],fluoro,Disk[pos[[i]],rad[[i]]]},{i,n}],PlotRange->1.2,Background->Black,ImageSize->600]]

(*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4. アニメーション再生 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*)
gifs=Animate[frame[τ],{τ,0,tmax},AnimationRate->1,AnimationRunning->False,AppearanceElements->{"PlayPauseButton","ProgressSlider","FasterSlowerButtons"}]

more=4;                               (*1→2→…間を (more-1) 分割*)
interp=Table[Blend[{frames[[i]],frames[[i+1]]},λ],(*単純線形ブレンド*){i,Length[frames]-1},{λ,0,1,1./more}]//Flatten;

Export["anime_smooth.gif",interp,"DisplayDurations"->0.1/more]