Reports

Twitter: @mtknnktm.

QUnitの処理順とかを調べてみた

はじめに

JavaScript単体テストツールの一つとしてQUnitがあります.
最近のお気に入りです.
QUnit - jQuery JavaScript Library

解説・チュートリアルは例えば以下にあるので,よく知らない方はいろいろ参照してみてください.
お手軽かついろいろできます.
【レポート】jQueryテストスイート「QUnit」がスタンドアロン化! 使い方を早速チェック (1) QUnitとは? | エンタープライズ | マイナビニュース

で,QUnitにはJUnitなどと同じくsetupやteardown機能があります.また,IDが 'main' の要素の中身を自動でリセットしてくれる機能もあります.リセットはQUnit.reset() という関数で自動的に行われます.
それらの処理順や挙動がわからなかったので調べてみました.

処理順について

説明用QUnitサンプルコード

module("Module A",{
  setup:function(){
    【前処理 A】
  },
  teardown:function(){
    【後処理 A】
  }
});
test('A - 1', function() {
  【テスト A-1】
});
test('A - 2', function() {
  【テスト A-2】
});

module("Module B",{
  setup:function(){
    【前処理 B】
  },
  teardown:function(){
    【後処理 B】
  }
});
test('B - 1', function() {
  【テスト B-1】
});
test('B - 2', function() {
  【テスト B-2】
});

処理順

上記のソースコードは以下の順で処理されます.

  1. Module A
    1. setup関数【前処理 A】
    2. test関数【テスト A-1】
    3. teardown関数【後処理 A】
    4. QUnit.reset関数【ID=main である要素のリセット】
    5. setup関数【前処理A】
    6. test関数【テスト A-2】
    7. teardown関数【後処理 B】
    8. QUnit.reset関数【ID=main である要素のリセット】
  2. Module B
    1. setup関数【前処理 A】
    • 以下略.

QUnit.reset() の挙動

ちなみにQUnit.reset()ですが,IDが 'main' である要素の子要素を「初期状態」に戻してくれるようで,例えば,以下のように書いておくと,QUnit.reset()が呼び出されるたびに,p要素まで復元してくれます.
空っぽにするだけだと思っていたので,個人的に意外でした.


<div id='main'>
  <p>初期状態</p>
</div>

「Boid にノイズを加えて相転移させた(追実験)」のプログラムとソースコード

以前の記事(Boid にノイズを加えて相転移させた(追実験) d:id:swarm_of_trials:20081224)に使ったプログラムとソースコードJava)を公開します.
次の場所からダウンロードしてください.

プログラム自体はたいしたものではありませんが,すごくシンプルなルールから複雑な振る舞いが創発する様や,ちょっとしたパラメータの変化がシステムをガラっと変えてしまう複雑さを楽しんでいただければ幸いです.

完全に自分用に作った(動けばいいやと思って作った)ものなので,使いづらいかもしれません.
ソースコード付きなので適当に変更して使ってください.

Prey-Predator系における能力の進化 - 8. 個体の多様性・突然変異を導入したLV方程式の数値計算と考察

また,えらく間が開いてしまいました.

これまで

Prey-Predator系(被食者-捕食者系)における個体能力の進化のダイナミクスを見るために,前回(d:id:swarm_of_trials:20090111)はロトカ・ヴォルテラ方程式に集団内の能力の多様性と突然変異を導入しました.
それが以下の方程式です.
\dot{x_i} = b_i x_i - \sum_{j=1}^{M} f(a_i, h_j) x_i y_j + \mu_x \frac{x_{i-1} - 2 x_i + x_{i+1}}{2} (1)
\dot{y_i} = -c y_i + \sum_{j=1}^{N} f(a_j, h_i) d_i x_j y_i + \mu_y \frac{y_{i-1} - 2 y_i + y_{i+1}}{2} (2)
x は被食者の数で,a は回避能力,b は繁殖能力を表します.
y は捕食者の数で,h は捕食能力,d は繁殖能力を表します.
詳しいことは前回を見てください.

今回は適当な仮定を置いて,数値計算によってこの系の性質を調べ,最後にその結果について少し考察します.

仮の関数の具体化

前回,そこで作った方程式系には適切な具体的な関数がわからないものがあり,そこは,仮に未知の関数として f(x) とか置いて話を進めました.
数値計算をするためには具体的な方程式がないとできませんので,まず,適当な仮定を置いて具体的な方程式を作ります.

実際の生態系の知見から仮定するなどいろいろなやり方があると思いますが,ここでの方針は,想定できるものの内,できるだけ簡単なものを仮定するということにします.

具体的な関数の形の作成

まず, f(a, h)について考えます.これは回避能力 a の被食者が捕食能力 h の捕食者に捕食される確率(以下捕食率)を表します.
この関数がちゃんと捕食率を表すためには,少なくとも以下の三点を満たしている必要があります.

  • 確率なので  f(a, h) \in [0,1]
  • 回避能力 a が高いことは捕食率 f を減少させるはずなので, \partial f(a, h) / \partial a \leq 0
  • 捕食能力 h が高いことは捕食率 f を増加させるはずなので, \partial f(a, h) / \partial h \geq 0

この三点を満たす関数として f(a, h) = 1 / (1 + \exp(-\gamma (h - a))) と仮定します(\gamma \in \mathcal{R^+}).


次に, a = g(b) h = g'(d) について考えます.
これらは被食者の能力 a と b,捕食者の能力 h と d にトレードオフ関係があることを表しています.
トレードオフなので,これらの関数の条件はそれぞれ以下のようになります.

  • b の増加は a の減少なので, d g(b) / d b < 0
  • d の増加は h の減少なので, d g'(d) / d d < 0

そこで次のようにしました.

  •  a = \frac{A}{B} (B - b)
  •  d = \frac{D}{H} (H - h)

大文字は対応する小文字で表される能力の最大値を表します.
ここから,上の用にインデックス i を用いて各能力を表すと次のようになります.

  •  a_i = A \frac{N - i}{N}
  •  b_i = B \frac{i}{N}
  •  d_i = D \frac{M - i}{M}
  •  h_i = H \frac{i}{M}

これで未知の関数は無くなりました.

数値計算

パラメータはたくさんありますが適当に設定して数値計算しました.
ここでは,突然変異率  \mu_x, \mu_y のみ変えて方程式の挙動を調べます.
以下で示す図は式 1, 2 を数値計算したもので,初期状態からある程度時間が経過した後の軌道を書いています.
横軸は被食者の総数  \sum_{i=1}^N x_i,縦軸は捕食者の総数  \sum_{i=1}^N y_i にして示しています.
この経過時間は各図が見やすいように設定ごとに調整しています.

まず,個体の多様性はあるが,突然変異は全く起こらない場合( \mu_x = 0, \mu_y = 0)場合についてやってみました.
f:id:swarm_of_trials:20090322181001p:image
被食者数の初期値を変えて 4 つの軌道を書いています.
sum(x) = p は  \sum_{i=1}^N x_i = p であることを表します.
また,初期値において  x_i = x_j \forall i, j (i \not= j) としました.

同図より初期値によって軌道が変わっていることがわかります.
このことから  \mu_x = 0, \mu_y = 0 の式1,2は中立安定な周期解を持つことがわかります.
この性質はロトカ・ヴォルテラ方程式系と同様です.
すなわち,被食者・捕食者系の解軌道の性質は個体の多様性を導入しても変わらないということが予想されます.

次に,突然変異率が非常に小さい場合( \mu_x = 0.01, \mu_y = 0.01)の場合についてやってみました.
f:id:swarm_of_trials:20090322181000p:image
こちらの設定では初期値を変えても,最終的には同様の軌道になりました.
このことから  \mu_x = 0.01, \mu_y = 0.01 の式1,2は漸近安定な周期解(リミットサイクル)を持つことがわかります.

次に,被食者の突然変異率が小さく,捕食者の突然変異率が大きい場合( \mu_x = 0.01, \mu_y = 1.0)場合についてやってみました.
f:id:swarm_of_trials:20090322180959p:image
こちらの設定でも初期値に最終的な軌道は依存せず,同じ周期軌道に収束しました.
このことから  \mu_x = 0.01, \mu_y = 1.0 の式1,2も  \mu_x = 0.01, \mu_y = 0.01 の場合と同様に漸近安定な周期解(リミットサイクル)を持つことが予想されます.

次に, \mu_x = 1.0, \mu_y = 0.01 の場合についてやってみました.
f:id:swarm_of_trials:20090322180958p:image
この設定では初期値に最終的な軌道は依存せず,同じ点に収束しました.
このことから  \mu_x = 1.0, \mu_y = 0.01 の式1,2は漸近安定な不動点(固定点アトラクタ)を持つことがわかります.

次に, \mu_x = 1.0, \mu_y = 1.0 の場合についてやってみました.
f:id:swarm_of_trials:20090322180956p:image
この設定でも初期値に最終的な軌道は依存せず,同じ点に収束しました.
このことから  \mu_x = 1.0, \mu_y = 1.0 の式1,2も  \mu_x = 1.0, \mu_y = 0.01 の場合と同様に漸近安定な不動点(固定点アトラクタ)を持つことがわかります.

結果のまとめ

Prey-Predator系(被食者・捕食者系)における個体能力の進化のダイナミクスを見るために,ロトカ・ヴォルテラ方程式系に集団内の能力の多様性と突然変異を導入(前回(d:id:swarm_of_trials:20090111))し,それの数値計算をしました.
その結果,被食者・捕食者系は個体の多様性・突然変異を考慮に入れることで,ロトカ・ヴォルテラ方程式系とは大きく異なった解軌道の性質を持つことがわかりました.
第一に突然変異を考えず,個体の多様性のみを考慮に入れた場合では,本記事の方程式系は中立安定な周期解を持ち,その点でロトカ・ヴォルテラ方程式系と同様の性質を持っていました.
ただし,少しでも突然変異が存在すると,本記事の方程式系は安定な軌道(アトラクタ)を持ちました.
これは元のロトカ・ヴォルテラ方程式系とは大きく異なる性質です.
さらに,被食者の突然変異率に依存してアトラクタの種類が変化し,(やってみた範囲では)捕食者の突然変異率には依存しませんでした.
具体的には,被食者の突然変異率が小さいと本記事の方程式系はリミットサイクルを持ちます.
そして,被食者の突然変異率が大きい場合,固定点アトラクタを持ちます.
分岐に関してはちゃんと調べていませんが,被食者の突然変異率に関してホップ分岐が存在していることがわかります.

この結果の意味するところ

突然変異を考慮に入れる / 入れない,突然変異率の大小の違いが被食者・捕食者系の振る舞いを大きく変えることは何を意味するのでしょうか?
あまり深く考えず,思ったことを書いてみます.

ロトカ・ヴォルテラ方程式系で考えている個体数動力学に多様性や突然変異を導入することは考えているスケールを大きく変えることであると言えます.
おそらく元のロトカ・ヴォルテラ方程式系は,個体数が多いことを想定して,個体の多様性を無視しています.
そのため個体の多様性を考慮することは考えている系の大きさを変えることと言えます.

また,元のロトカ・ヴォルテラ方程式系は,被食者と捕食者の数の変化は突然変異が起こる頻度よりずっと早いと想定して,突然変異の存在を無視していると思われます.
そのため突然変異を考慮することは考えている系のタイムスケールを変えることと言えます.
突然変異が頻繁に起こるか,または,個体数の変動がすごくゆっくりな場合に相当すると考えています.
一方の突然変異が,他方に比べて非常に大きい場合というのも,世代交代などの早さが両者で異なることを表していると言えます.

すなわち本記事の結果は,被食者・捕食者系では見ているスケールを変えると系の性質は全く変わってしまうということを示唆しています.
また,本記事ではいくつかの仮定を置いて,ロトカ・ヴォルテラ方程式系のスケールを変えてみましたが,他のスケールの変え方もあり,それはまた別の結果を導き出す可能性があります.
フィールド・実験室において被食者・捕食者系にも関わらずロトカ・ヴォルテラ方程式系とは全くことなった挙動を示す場合*1,このような想定しているスケールの違いがあるのかもしれません.

今後は

もうちょっとちゃんと解析できたらいいと思います(せめて分岐に関する相図ぐらい...).

また,上の「この結果の意味するところ」はかなり適当に考察しているので,もうちょっとちゃんと考えてみたいです.

*1:とはいうものの,そういうことがあるのか私は知らないのですが

Prey-Predator系における能力の進化 - 7. LV方程式に個体の能力に関する多様性と突然変異を導入

これまで

Prey-Predator系(被食者-捕食者系)における個体能力の進化のダイナミクスを見たいので,エージェントベースドモデルを作って進化シミュレーションしてみようとしていましたが,失敗しました(前回: d:id:swarm_of_trials:20081221).
今回は,早々にあきらめていたロトカ・ヴォルテラ方程式で被食者・捕食者の能力の共進化をもう一度考え直してみようと思います.

ロトカ・ヴォルテラ方程式の拡張

個体の能力を考慮したLV方程式の記述

進化の対象として考える個体の能力は第4回 進化する能力を考察する(d:id:swarm_of_trials:20080821)と同様に次のようにしたいと思います.

  • 被食者: 捕食者から逃げる能力(回避能力)a,繁殖能力 b
  • 捕食者: 被食者を捕まえる能力(捕食能力)h,繁殖能力 d

能力に関する値(a, b, d, h)を考えてロトカ・ヴォルテラ方程式を書くと,次のようになりました.
\dot{x} = b x - f(a, h) x y (1)
\dot{y} = -c y + f(a, h) d x y (2)
ここで f(a, h)は回避能力 a の被食者が捕食能力 h の捕食者に捕食される確率です.
各項の意味は以下のようになります.

  • 式1の第1項 被食者による自然増(生まれた数 - 自然死した数)
  • 式1の第2項 被食者が捕食者に食べられる数
  • 式2の第1項 捕食者の自然死
  • 式2の第2項 被食者を食べることのできた捕食者が生む子供の数

ここで,ひとつ仮定を導入します.
それは各能力 a と b ,h と d の間にはトレードオフが存在し,一方が決まると他方が一意に決まるというものです.
すなわち, a = g(b) d g(b) / d b < 0), h = g'(d) d g'(d) / d d < 0)(その逆も可)ということです.
なぜ,トレードオフを仮定するかというと,各能力の値は大きければ大きいほど良いため,このような仮定がなければ進化によってどんどん大きくなっていくことが自明だからです.
実際,繁殖行為中は無防備になりがち・出産などによって体力が減少するなどの制約も考えられるので,あながち不自然な仮定でもない気がします.

個体能力の多様性の導入

個体の能力が進化するためにはその能力に多様性が無ければなりません.そうでないと選択が起こらないので.
上で考慮した個体の能力は被食者・捕食者共に 2 つで,それらにトレードオフを仮定したことで,ある能力を持った個体を一つの番号 i でラベル付けすることができます.
すなわち,番号 i の被食者の能力を  a_i, b_i と表現できます.
とすると,ロトカ・ヴォルテラ方程式は次のようにできます.
\dot{x_i} = b_i x_i - \sum_{j=1}^{M} f(a_i, h_j) x_i y_j (3)
\dot{y_i} = -c y_i + \sum_{j=1}^{N} f(a_j, h_i) d_i x_j y_i (4)
ここで,N は被食者,M 捕食者の番号の最大値です.
式3の第2項は各能力の捕食者(j が 1 から N )について出会って(確率は x_i y_jに比例)捕食される確率f(a_i, h_j)を計算して和を取っています.
N, M をものすごく大きくすれば個体の能力は連続的に変化する(a, b, d, h が実数)として考えてもいいかなと思います.

突然変異の導入

次に突然変異の導入をします.
ここで,突然変異を「能力が少し変化する」と考え, i の個体の子が i + 1 になるいうことにします.
突然変異率を被食者は \mu_x,捕食者は \mu_yとすると,方程式は以下のようになります.
\dot{x_i} = b_i x_i - \sum_{j=1}^{M} f(a_i, h_j) x_i y_j + \mu_x ( \frac{x_{i-1}}{2} + \frac{x_{i+1}}{2} - x_i) (5)
\dot{y_i} = -c y_i + \sum_{j=1}^{N} f(a_j, h_i) d_i x_j y_i + \mu_y ( \frac{y_{i-1}}{2} + \frac{y_{i+1}}{2} - y_i) (6)

ちなみに式5,6を整理すると以下のようになるので,
\dot{x_i} = b_i x_i - \sum_{j=1}^{M} f(a_i, h_j) x_i y_j + \mu_x \frac{x_{i-1} - 2 x_i + x_{i+1}}{2} (5')
\dot{y_i} = -c y_i + \sum_{j=1}^{N} f(a_j, h_i) d_i x_j y_i + \mu_y \frac{y_{i-1} - 2 y_i + y_{i+1}}{2} (6')
 1 << N, Mかつ i と i + 1 の能力の差が非常に小さい場合(例えば|a_i - a_{i + 1}| << 1)の場合には,次のように式5,6の右辺第3項は偏微分形式にすることができます(ただし偏微分の分子部分の書き方がかなり怪しいです..).
\dot{x_i} = b_i x_i - \sum_{j=1}^{M} f(a_i, h_j) x_i y_j  + \frac{\mu_x}{2} \frac{\partial^2 x_{i}}{\partial i^2} (5'')
\dot{y_i} = -c y_i + \sum_{j=1}^{N} f(a_j, h_i) d_i x_j y_i + \frac{\mu_y}{2} \frac{\partial^2 y_{i}}{\partial i^2} (6'')
これは反応拡散方程式と呼ばれる方程式の一種です.

つぎは,

上で立てた方程式を数値解析してみようと思います.

追記(2009/03/22)

方程式に結構なミスがあったので修正しました.

  • 式1,3,5,5',5''の右辺第一項 a(またはa_i)を b(b_i)に置換.繁殖を表す項なので a じゃくなて b なので.
  • 式4,6,6',6''の右辺第一項 c_i の i を削除.ここでは捕食者の自然死率 c に関する多様性は考えていないので.

失礼しました.

目次を変更

目次の扱いが変だったので,ヘッダに目次を書くことにしました.
今までは2058年の日記としてトップに表示されるようにしていました.
目視の変な扱い方はなくなった,なんか,でも余計見にくくなったような..

タイトル

ところで,このブログのタイトル "Swarm of Trials" って英語的に正しい and 自然なんでしょうか..
ググっても英文ページは 2 件ぐらいしかヒットしない.
ブログを作った当初から不安だったりしますw.恥ずかしいことになってなければいいけど.