モデルニューロンのシミュレーション


16

アンIzhikevichニューロンは離散時間ステッピングシミュレーションで使用するために設計された生物学的ニューロンのシンプルで非常に効果的なモデルです。このゴルフチャレンジでは、このモデルを実装します。

パラメーター

このモデルには、生理学的に正確なモデルの多数のパラメーターと比較して、2つの微分方程式に編成された7つの変数のみが含まれます。

  • vおよびuは、ニューロンの2つの状態変数です。ここで、vは、経時的な細胞電位を表す「高速」変数でuあり、特定の膜特性を表す「低速」変数です。vこれはシミュレーションの出力であるとして変数は、最も重要なものです。
  • abc、及びdニューロンの特性を記述する定数を固定されています。目的の動作に応じて、ニューロンの種類によって定数が異なります。特に、cリセット電位は、スパイクした後に細胞が戻る膜電位です。
  • Iニューロンへの入力電流を表します。ネットワークシミュレーションでは、これは時間とともに変化しますが、ここではI、固定定数として扱います。

モデル

このモデルには非常に単純な擬似コードがあります。最初に、の定数値を取得し、abcdそれらを使用して初期化vおよびを行いuます:

v = c
u = b * c

次に、シミュレーションコードを必要な回数ループします。各反復は1ミリ秒の時間を表します。

for 1..t:
  if v >= 30:    # reset after a spike
    v = c
    u = u + d
  v += 0.04*v^2 + 5*v + 140 - u + I
  u += a * (b*v - u)
  print v

特定の実際の実装には、数値の精度を高めるための追加の手順が含まれていますが、ここには含まれていません。

入力

入力として、あなたのプログラム/関数が値を取る必要がありabcdI、およびt(シミュレートするための時間ステップ数)。一度設定すると、これらのパラメーターはいずれも、単純なシミュレーション中に変更されません。入力の順序は重要ではありませ。プログラムがこれらのパラメータを取る順序を指定できます。

出力

出力はv、シミュレーションの過程での細胞の膜電位(変数によって与えられる)を表す数値のリストになります。リストは任意の適切な形式にすることができます。

出力にシミュレーションの0番目の値(任意の時間が経過する前の初期構成)を含めるかどうかを選択できます。たとえば、0.02 0.2 -50 2 10 6(for a b c d I t)の入力の場合、次のいずれかの出力

-50
-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068

または

-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068

許容できます。

あなたの値は、あなたの言語がフロートをどのように扱うかに応じて、上記のものと正確に同じである必要ありませ

参照実装

これは、モデルを示すためにPerlで書いたTIO実装です。パラメーターは、上記リンクの論文の「チャタリング」ニューロンのパラメーターであり、これは、このモデルが、高活動と低活動の状態を交互に切り替えるなど、ニューロンのより複雑な特性の一部を再現する方法のデモンストレーションとして機能します。出力を見ると、ニューロンがすぐに数回スパイクする場所を確認できますが、しばらく待ってからさらに数回スパイクします(セル入力電圧Iが常に一定であるにもかかわらず)。


ウィルtこれまで負になりますか?
kamoroso94

1
@ kamoroso94いいえ、負の時間をシミュレートすることはできません。
PhiNotPi

回答:


6

R110 99バイト

6つの引数を取る匿名関数。派手なものはなく、リファレンス実装の単純な移植版です。更新uvとの印刷vすべて単一のラインに統合されている、という事実のおかげでそのRのprintリターンあなたが割り当てにそれを使用することができますので、印刷されている値。11バイトを節約してくれたGiuseppeに感謝します!

pryr::f({v=c;u=b*c;for(i in 1:t){if(v>=30){v=c;u=u+d}
u=a*b*(v=print((.04*v+6)*v+140+I-u))-a*u+u}})

オンラインでお試しください!


2
これは素晴らしい、+ 1です。ただし、引数に明示的にラベルを付けているため、pryr::f()との間にはバイトが保存されませんfunction()。ただし、いくつかの実験の後、引数の順序を保持しながらvand uの宣言を関数本体に移動して、数十バイトを節約できます。オンラインで試してみてください!
ジュゼッペ

以来、v必ずしも整数値を取ることはありません、あなたが行う必要v>=30、しかし
ジュゼッペ・

@Giuseppeありがとう、これらの改善は素晴らしいです。何らかの理由で、引数に明示的にラベル付けしないとは考えていませんでした
...-rturnbull

4

クリーン150の 145 140 138バイト

import StdEnv
$a b c d i t=map snd(iterate(\(u,v)#(w,n)=if(30.0<v)(c,u+d)(v,u)
#y=0.04*w*w+6.0*w+140.0-n+i
=(a*b*y-a*n+n,y))(b*c,c))%(0,t)

オンラインでお試しください!

関数を定義$ :: Real Real Real Real Real Int -> [Real]し、OPで説明されているように、0番目の項からアルゴリズムを実装します。


3

Python 2、100バイト

a,b,c,d,I,t=input();v=c;u=b*c
exec"if v>=30:v=c;u+=d\nv=v*v/25+6*v+140-u+I;u+=a*(b*v-u);print v\n"*t

オンラインでお試しください!

user71546のおかげで2バイト節約されました


@ovsおっと、あなたは正しい。今すぐ修正する必要があります。
ミスターXcoder

を回す0.04*v*vv*v/25.1バイト節約されます。フロートは常にために与えられた場合c、その後v*v/25のため-2バイトで十分です。
朝琴シエル

@ceilingcat私の改訂履歴を見ると、v>29私が最初のバージョンにいたことがわかります。ただし、これはv必ずしも整数ではないため無効です。
Mr Xcoder

3

JavaScript(Node.js)107 ... 103 101バイト

@apsillersによる寄稿

(a,b,c,d,I,t)=>[...Array(t)].map(_=>(v<30||(v=c,u+=d),v=v*(v/25+6)+140-u+I,u+=a*(b*v-u),v),u=b*(v=c))

オンラインでお試しください!

元のアプローチ:105 103バイト。-1バイトはArnauldに感謝し、-2バイトは@ Kamoroso94に感謝します。

(a,b,c,d,I,t)=>{for(u=b*(v=c);t--;){v<30||(v=c,u+=d);v=v*(v/25+6)+140-u+I;u+=a*(b*v-u);console.log(v)}}

オンラインでお試しください!

または、アラートをポップしても問題ない場合は、101 ... 99 97バイト(-1バイトはArnauldに感謝、-2バイトは@ Kamoroso94に感謝):

(a,b,c,d,I,t)=>{for(u=b*(v=c);t--;){v<30||(v=c,u+=d);v=v*(v/25+6)+140-u+I;u+=a*(b*v-u);alert(v)}}

var u, v;
var f = 
(a,b,c,d,I,t)=>{for(u=b*(v=c);t--;){v<30||(v=c,u+=d);v=v*(v/25+6)+140-u+I;u+=a*(b*v-u);alert(v)}}

function run() {
 f(...["a", "b", "c", "d", "I", "t"].map(x => document.getElementById(x).value * 1));
}
a = <input id="a" value="0.02"><br>
b = <input id="b" value="0.2"><br>
c = <input id="c" value="-50"><br>
d = <input id="d" value="2"><br>
I = <input id="I" value="10"><br>
t = <input id="t" value="6"><br>
<input type="button" value="Run" onclick="run()">


v>29v>=30float とは異なります。v<30?0:(v=c,u+=d)代わりに、またはv<30||(v=c,u+=d)バイトを節約することをお勧めします。
アーナルド

@Arnauldそうそう、Pythonの答えを見たとき、私はそれを最適化していないことに気付きましたが、フロートを処理していることにも気づきませんでした。; P修正済み。
朝琴シエル

2
t-->0単にに変更することで2バイトを節約できますt--
kamoroso94

1
forループmapを長さの配列の操作にリファクタリングすることでこれを101まで下げることができますt(a,b,c,d,I,t)=>[...Array(t)].map(_=>(v<30||(v=c,u+=d),v=v*(v/25+6)+140-u+I,u+=a*(b*v-u),v),u=b*(v=c))。関数は、値を記録する代わりに配列を返します。これは仕様を満たすように見えます。alertただし、ソリューションに勝るものはありません。
-apsillers


2

Haskell112 111バイト

(a#b)c d i t|let r(v,u)|v>=30=r(c,u+d)|p<-0.04*v^2+6*v+140-u+i=(p,u+a*(b*p-u))=fst<$>take t(iterate r$r(c,b*c))

オンラインでお試しください!

ゼロケースを出力しません。それcが意味をなさないので、それは決してないと仮定し>=30ます。

whereコードゴルフで句を使用する必要があるとは思わなかったが、変数が多すぎます。

編集:バイトを離陸してくれてありがとう@Lynn!letステートメントをガードに入れることができることを忘れていました。確かに読みやすさは失われます


1
バイトを保存するwhere奇妙なf x|let g a=b=y構文に置き換えることができます(a#b)c d i t|let r(v,u)|v>=30=r(c,u+d)|p<-0.04*v^2+6*v+140-u+i=(p,u+a*(b*p-u))=fst<$>take t(iterate r$r(c,b*c))
Lynn

1

要素、81バイト

_a;_b;_3:b~*u;_d;_I;_'[3:\.04*5+*140+u~-+I~++4:\
.`30<!b~*u~-+a~*u~+[d~+]u;[#2:]]

オンラインでお試しください!エソランのページ

説明:

_a;_b;_3:b~*u;_d;_I;_'[ ... ]

プログラムのこの部分は入力を受け取ります。これは、定数を格納しabd、およびI変数に。の入力cが変数に保存されることはありませんが、実行中はメインスタックに残ります。3つのコピーが作成されます。1つは初期化用でu、1つは初期値として、中央は1つで、1つvは定数として機能しcます。の入力は、プログラムの残りを囲むtFORループ([...])の基礎として機能するために、すぐに制御スタックにスローされます。

3:\.04*5+*140+u~-+I~++4:

プログラムのこの部分は、現在の値をv取得して新しい値を計算し、新しい値の4つのコピーvが作成されます。

\
.`

の最初のコピーにvは改行が追加され、印刷されます。

30<!

の2番目のコピーはv、ニューロンがスパイクしたかどうかをテストするために使用されます。このテストの結果は、後で使用するために制御スタックに配置されます。

b~*u~-+a~*u~+

この部分は、u追加する量を意味する「デルタ」を計算しuます。

[d~+]

dニューロンがスパイクしている場合、このIFブロックは上記の合計に追加されます。これにより、通常は2つの割り当てが1つの割り当てに結合されます。

u;

これにより、更新された値が保存されますu

[#2:]

このIFブロックは、上記のIFブロックの続きです。ニューロンがスパイクしている場合、現在の値v(現在はメインスタックの一番上にある)を削除し、それをc(今回はメインスタックの一番下にあった)の複製に置き換えます。

基本的にはこれですべてです。ちょっとした注意点として、これはメモリをリークするということ"#です。各ループの反復後に制御スタックの最上部(評価されたIF条件)を削除するには、余分なものが必要です。

Elementを最も優雅なゴルフ言語とは呼びませんが、この課題により興味深い機能を紹介することができます。メインスタックとコントロールスタックが分かれているため、IFステートメントを取り、条件とボディを複数に分割できます。パーツ、無条件コードとインターレース。


0

MATLAB、111バイト

function z(a,b,c,d,I,t)
v=c;u=b*c;for i=1:t if v>=30 v=c;u=u+d;end
v=.04*v^2+6*v+140-u+I
u=u+a*(b*v-u);
end
end

かなり単純な実装で、おそらくさらに改善できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.