모델 뉴런 시뮬레이션


16

Izhikevich 신경 세포는 단순한 이산 시간 스테핑 시뮬레이션에 사용하도록 설계 생물학적 뉴런의 또 매우 효과적인 모델이다. 이 골프 도전에서는이 모델을 구현하게됩니다.

매개 변수

이 모델은 생리적으로 정확한 모델의 수십 개의 매개 변수와 비교하여 2 개의 미분 방정식으로 구성된 7 개의 변수 만 포함합니다.

  • vu신경 세포의 두 개의 상태 변수이다. 여기서, v시간에 따른 세포 전위를 나타내는 "빠른"변수이고, u특정 막 특성을 나타내는 "느린"변수이다. v이 시뮬레이션의 출력 변수로서 가장 중요한 하나이다.
  • a, b, cd신경 세포의 특성을 설명하는 상수를 고정한다. 다른 유형의 뉴런은 원하는 행동에 따라 다른 상수를 갖습니다. 특히, 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

특정 실제 구현에는 수치 정확도를위한 추가 단계가 포함되지만 여기에는 포함되지 않습니다.

입력

입력으로, 프로그램 / 함수의 값을 취해야한다 a, b, c, d, I, 및 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 구현 입니다. 매개 변수는 위에 링크 된 논문에서 "채터 링 (chattering)"뉴런의 매개 변수이며, 이는이 모델이 높은 활동 상태와 낮은 활동 상태 사이의 교대와 같은 뉴런의보다 복잡한 특성을 어떻게 재현 할 수 있는지를 보여줍니다. 출력을 보면 뉴런이 즉시 여러 번 스파이크하는 위치를 볼 수 있지만 몇 번 더 스파이크하기 전에 잠시 기다립니다 (셀 입력 전압 I이 항상 일정하더라도).


t이제까지 부정적?
kamoroso94

1
아니요, 부정적인 시간을 시뮬레이션 할 수 없습니다.
PhiNotPi

답변:


6

R , 110 99 바이트

6 개의 인수를 취하는 익명 함수. 멋진 것은 아니며 참조 구현의 간단한 포트입니다. 의 업데이트 u, v, 그리고 인쇄 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(). 그러나 몇 가지 실험 후에 인수 순서를 유지하면서 함수 본문으로 vu의 선언을 이동 하여 수십 바이트를 절약 할 수 있습니다. 온라인으로 시도하십시오!
주세페

때문에 v반드시 정수 값을 고려하지 않습니다, 당신이 할 필요 v>=30하지만
주세페

@ 주세페 감사합니다, 그 개선은 환상적입니다. 어떤 이유로 나는 논쟁을 명시 적으로 표시하지 않는 것을 고려하지 않았다 ...
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]0 번째 항에서 시작하여 OP에 설명 된대로 알고리즘을 구현 하여 함수를 정의합니다 .


3

파이썬 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 죄송합니다. 지금 수정해야합니다.
Mr. Xcoder

켜기 0.04*v*v로하는 v*v/25.1 바이트를 저장해야합니다. 수레는 항상 주어진 경우 c다음 v*v/25을 위해 충분 -2 바이트.
Shieru Asakoto

@ceilingcat 내 개정 내역을 살펴보면 v>29초기 버전에 있음을 알 수 있습니다. 그러나 이는 유효하지 않기 v때문에 유효하지 않습니다.
Mr. Xcoder

3

자바 스크립트 (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>=30수레 와 동일하지 않습니다 . 당신은 아마하고 싶어 v<30?0:(v=c,u+=d)하지만 대신에, 또는 더 나은 v<30||(v=c,u+=d)바이트를 저장한다.
Arnauld

@Arnauld 아, 그렇습니다. 파이썬 답변을 보았을 때 나는 그것을 최적화하지 않았다는 것을 깨달았지만 플로트를 처리하고 있다는 것을 알지 못했습니다.; P 고정.
Shieru Asakoto

2
t-->0간단히 로 변경 하여 2 바이트를 절약 할 수 있습니다 t--.
kamoroso94

1
당신은 리팩토링에 의해 (101)이 아래를 얻을 수 for에 루프 map길이의 배열에 작업을 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하지만, 솔루션을.
apillers


2

하스켈 , 112 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코드 골프에서 절 하지는 않았지만 변수가 너무 많습니다.

편집 : 바이트를 벗어 주셔서 감사합니다 @ Linn! 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:]]

온라인으로 사용해보십시오! , Esolangs 페이지

설명:

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

프로그램의이 부분은 입력을받습니다. 그것은 상수 저장 a, b, d, 및 I변수로. 에 대한 입력 c은 변수에 저장되지 않지만 실행 동안 기본 스택에 유지됩니다. 세 개의 복사본이 만들어집니다. 하나는 초기화 용 u이고 다른 하나는 초기 용 v이고 다른 하나는 상 수용 c입니다. 에 대한 입력 t은 제어 스택에 즉시 던져 [...]나머지 프로그램을 둘러싼 FOR 루프 ( ) 의 기초로 사용됩니다 .

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

프로그램의이 부분은 현재 값을 가져 와서 v새 값을 계산 한 다음 새 값의 사본을 4 개 v만듭니다.

\
.`

첫 번째 사본 v에는 줄 바꿈이 추가되고 인쇄됩니다.

30<!

두 번째 사본 v 뉴런이 스파이크되었는지 테스트하는 데 사용됩니다. 이 테스트의 결과는 나중에 사용할 수 있도록 제어 스택에 배치됩니다.

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

이 부분은 u추가 할 양을 의미 하는 "델타 "를 계산합니다 u.

[d~+]

이 IF 블록 d은 뉴런이 스파이 킹하는 경우 위의 합계에 추가 됩니다. 이것은 일반적으로 두 가지 과제를 단일 과제로 결합합니다.

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.