एक मॉडल न्यूरॉन का अनुकरण करें


16

एक Izhikevich न्यूरॉन एक जैविक न्यूरॉन का एक सरल लेकिन काफी प्रभावी मॉडल है, जिसे असतत समय-स्टीयरिंग सिमुलेशन में उपयोग के लिए डिज़ाइन किया गया है। इस गोल्फिंग चुनौती में, आप इस मॉडल को लागू करेंगे।

पैरामीटर

इस मॉडल में शारीरिक रूप से सटीक मॉडल के दर्जनों मापदंडों की तुलना में केवल 2 अंतर समीकरणों में आयोजित 7 चर शामिल हैं।

  • vऔर uन्यूरॉन के दो राज्य चर हैं। यहाँ, vसमय के साथ सेल की क्षमता का प्रतिनिधित्व करने वाला "तेज़" चर है, और uकुछ झिल्ली गुणों का प्रतिनिधित्व करने वाला "धीमा" चर है। vके रूप में इस अनुकरण के उत्पादन में है चर, सबसे महत्वपूर्ण है।
  • a, b, c, और 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

कुछ वास्तविक दुनिया के कार्यान्वयन में संख्यात्मक सटीकता के लिए अतिरिक्त कदम शामिल हैं, लेकिन हम यहां शामिल नहीं हैं।

इनपुट

इनपुट के रूप में, अपने कार्यक्रम / समारोह के मूल्यों लेना चाहिए a, b, c, d, I, और t(अनुकरण करने के लिए समय चरणों की संख्या)। एक बार सेट होने पर, इनमें से कोई भी पैरामीटर हमारे सरल सिमुलेशन के दौरान नहीं बदलेगा। इनपुट का क्रम मायने नहीं रखता: आप उस क्रम को निर्दिष्ट कर सकते हैं जिसमें आपका प्रोग्राम इन मापदंडों को लेता है।

उत्पादन

आउटपुट vसिमुलेशन के दौरान सेल की झिल्ली क्षमता (चर द्वारा दिए गए ) का प्रतिनिधित्व करने वाली संख्याओं की एक सूची होगी । सूची किसी भी उपयुक्त प्रारूप में हो सकती है।

आपके पास अपने आउटपुट में सिमुलेशन के 0 वें मूल्य (किसी भी समय बीतने से पहले प्रारंभिक कॉन्फ़िगरेशन) को शामिल करने का विकल्प है। उदाहरण के लिए, 0.02 0.2 -50 2 10 6( 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

स्वीकार्य है।

आपके मूल्यों को ऊपर वाले लोगों के समान नहीं होना चाहिए, यह इस बात पर निर्भर करता है कि आपकी भाषा कैसे तैरती है।

संदर्भ कार्यान्वयन

यहाँ एक TIO कार्यान्वयन है जो मैंने मॉडल प्रदर्शित करने के लिए पर्ल में लिखा था। पैरामीटर ऊपर लिंक किए गए पेपर से एक "बकबक" न्यूरॉन के हैं, और यह एक प्रदर्शन के रूप में कार्य करता है कि यह मॉडल न्यूरॉन्स के कुछ और अधिक जटिल गुणों को कैसे फिर से बनाने में सक्षम है, जैसे कि उच्च और निम्न गतिविधि के राज्यों के बीच वैकल्पिक। आप उत्पादन को देखें, तो आप देख सकते हैं जहां न्यूरॉन तुरंत कई बार बढ़ जाता है, लेकिन फिर थोड़ी देर के इंतजार कर रहा है कई बार spiking से पहले (सेल इनपुट वोल्टेज के बावजूद Iकिया जा रहा लगातार पूरे समय)।


क्या tकभी नकारात्मक होगा?
kamoroso94

1
@ kamoroso94 नहीं, आप नकारात्मक समय का अनुकरण नहीं कर सकते।
PhiNotPi 14

जवाबों:


6

आर , 110 99 बाइट्स

बेनामी फ़ंक्शन जो 6 तर्क लेता है। कुछ भी नहीं फैंसी, संदर्भ कार्यान्वयन का सिर्फ एक सीधा बंदरगाह। को अद्यतन करने u, vऔर के मुद्रण vहै सभी एक ही लाइन में मिला दिया गया है, इस तथ्य के लिए धन्यवाद कि आर के 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()। हालांकि, अगर आप, कुछ प्रयोग के बाद, स्थानांतरित कर सकते हैं vऔर uके घोषणाओं समारोह शरीर में जबकि बहस के क्रम संरक्षण, एक दर्जन से अधिक को बचाने के लिए बाइट: यह ऑनलाइन कोशिश करो!
ग्यूसेप

चूंकि vआवश्यक रूप से पूर्णांक मान नहीं लेते हैं, आपको आवश्यकता है v>=30, हालांकि
Giuseppe

@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] , ओपी में वर्णित एल्गोरिथ्म को लागू करना, 0 वें कार्यकाल से शुरू होता है।


3

अजगर २ , 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

इसे ऑनलाइन आज़माएं!

सहेजा गया 2 बाइट उपयोगकर्ता 71546 के लिए धन्यवाद ।


@ ओह, आप सही कह रहे हैं। अब तय होना चाहिए।
श्री Xcoder

टर्निंग 0.04*v*vकरने के लिए v*v/25.1 बाइट को बचाने चाहिए। यदि फ्लोट हमेशा के लिए दिए जाते हैं, cतो v*v/25-2 बाइट्स के लिए पर्याप्त होता है।
शायरु असकोतो

@ceilingcat यदि आप मेरे संशोधन इतिहास पर एक नज़र डालते हैं, तो आप देखेंगे कि v>29मेरे प्रारंभिक संस्करण में मेरे पास था । हालाँकि, यह अमान्य है क्योंकि vआवश्यक नहीं कि पूर्णांक हो।
श्री 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 बाइट थैंक्स अरनौल्ड, और -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 बाइट थैंक अरनल्ड, -2 बाइट्स थैंक्स @ कामोरोसो94):

(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 ओह हाँ, जब मैंने पायथन के उत्तर को देखा तो मुझे महसूस हुआ कि मैंने इसे ऑप्टिमाइज़ नहीं किया है, लेकिन मुझे नहीं पता था कि मैं या तो फ़्लोटिंग प्रसंस्करण कर रहा था; पी फिक्स्ड।
शायरु असाकोतो

2
आप t-->0बस को बदलकर दो बाइट्स बचा सकते हैं 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हालांकि, समाधान को हरा नहीं करता है ।
अप्सिलर्स


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एक कोड गोल्फ में एक क्लॉज का उपयोग करना होगा, लेकिन अभी बहुत सारे चर हैं।

संपादित करें: बाइट लेने के लिए धन्यवाद @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))
लिन

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लिए लूप ( [...]) के आधार के रूप में काम करने के लिए इनपुट को तुरंत नियंत्रण स्टैक पर फेंक दिया जाता है ।

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

कार्यक्रम का यह हिस्सा वर्तमान मूल्य लेता है vऔर नए मूल्य की गणना करता है, और फिर नए मूल्य की चार प्रतियां vबनाई जाती हैं।

\
.`

vएक नई पंक्ति की पहली प्रति संलग्न है और मुद्रित है।

30<!

vयदि न्यूरॉन ने नुकीला किया है, तो परीक्षण की दूसरी प्रति का उपयोग किया जाता है। इस परीक्षण का परिणाम बाद में उपयोग के लिए नियंत्रण स्टैक पर रखा गया है।

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

यह भाग "डेल्टा u" की गणना करता है , जिसका अर्थ है कि जोड़ने के लिए राशि u

[d~+]

यदि dन्यूरॉन स्पाइकिंग होता है तो यह IF ब्लॉक उपरोक्त योग में जोड़ता है। यह जोड़ती है कि आम तौर पर एक असाइनमेंट में दो असाइनमेंट क्या होंगे।

u;

इस के अद्यतन मूल्य को संग्रहीत करता है u

[#2:]

यह IF ब्लॉक उपरोक्त IF ब्लॉक की एक निरंतरता है। यदि न्यूरॉन स्पाइक कर रहा है, तो v(जो अब मुख्य स्टैक के शीर्ष पर है) के वर्तमान मूल्य को हटा दें और इसे एक डुप्लिकेट के साथ बदल देंc (जो इस पूरे समय में मुख्य स्टैक के तल पर है)।

और मूल रूप से यह सब वहाँ है। एक मामूली बात यह है कि यह बात स्मृति को लीक करती है: इसमें एक अतिरिक्त लगता है"# प्रत्येक लूप पुनरावृत्ति के बाद नियंत्रण स्टैक (मूल्यांकन की गई स्थिति) के शीर्ष को हटाने के लिए इसमें ।

यद्यपि मैं तत्व को सबसे सुंदर गोल्फ भाषा नहीं कहूंगा, यह चुनौती मुझे एक दिलचस्प विशेषता दिखाने की अनुमति देती है: मुख्य स्टैक और नियंत्रण स्टैक के बीच विभाजन के कारण, मैं एक 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

बहुत सरल कार्यान्वयन, शायद आगे सुधार किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.