Neuron Izhikevicha to prosty, ale dość skuteczny model neuronu biologicznego, zaprojektowany do zastosowania w dyskretnej symulacji z krokami w czasie. W tym wyzwaniu golfowym wdrożysz ten model.
Parametry
Model ten obejmuje tylko 7 zmiennych zorganizowanych w 2 równania różniczkowe, w porównaniu do kilkudziesięciu parametrów fizjologicznie dokładnego modelu.
v
iu
są dwiema zmiennymi stanu neuronu. Tutajv
jest „szybką” zmienną reprezentującą potencjał komórki w czasie iu
jest „wolną” zmienną reprezentującą pewne właściwości błony.v
Zmienna jest najważniejsza, ponieważ jest to wyjście symulacji.a
,b
,c
, Id
są przymocowane stałe, które opisują właściwości neuronu. Różne typy neuronów mają różne stałe, w zależności od pożądanego zachowania. W szczególnościc
chodzi o potencjał resetowania, czyli potencjał błonowy, do którego komórka powraca po wzbogaceniu.I
reprezentuje prąd wejściowy do neuronu. W symulacjach sieciowych zmieni się to z czasem, ale dla naszych celów będziemy traktowaćI
jako stałą.
Model
Ten model ma bardzo prosty pseudokod. Najpierw bierzemy stałe wartości abcd
i używamy ich do inicjalizacji v
oraz u
:
v = c
u = b * c
Następnie przeglądamy kod symulacyjny tyle razy, ile potrzeba. Każda iteracja odpowiada 1 milisekundie czasu.
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
Niektóre rzeczywiste implementacje zawierają dodatkowe kroki dla dokładności numerycznej, ale nie uwzględniamy ich tutaj.
Wejście
Jako dane wejściowe, program / funkcja powinna przyjąć wartości a
, b
, c
, d
, I
, i t
(liczba kroków czasowych do symulacji). Po ustawieniu żaden z tych parametrów nie będzie się zmieniał podczas naszej prostej symulacji. Kolejność wprowadzania nie ma znaczenia: możesz określić kolejność, w jakiej program pobiera te parametry.
Wynik
Wyjściem będzie lista liczb reprezentujących potencjał błonowy komórki (podana przez zmienną v
) w trakcie symulacji. Lista może mieć dowolny odpowiedni format.
Masz wybór, czy dołączyć do wyjścia wartość 0 symulacji (wstępna konfiguracja przed upływem czasu). Na przykład dla wejścia 0.02 0.2 -50 2 10 6
(for a b c d I t
) wyjście dowolnego z nich
-50
-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068
lub
-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068
jest do zaakceptowania.
Twoje wartości nie muszą być dokładnie takie same jak powyższe, w zależności od tego, jak Twój język obsługuje zmiennoprzecinkowe.
Wdrożenie referencyjne
Oto implementacja TIO, którą napisałem w Perlu, aby zademonstrować model. Parametry są takie jak „gadający” neuron z powyższego artykułu, co służy jako demonstracja tego, jak ten model jest w stanie odtworzyć niektóre z bardziej złożonych właściwości neuronów, takich jak naprzemienne zmienianie stanów wysokiej i niskiej aktywności. Jeśli spojrzysz na wynik, możesz zobaczyć, gdzie neuron natychmiast gwałtownie podnosi kilka razy, ale potem czeka jeszcze chwilę, zanim przyspieszy jeszcze kilka razy (mimo że napięcie wejściowe komórki I
jest stałe przez cały czas).
źródło
t
kiedykolwiek będzie negatywny?Odpowiedzi:
R ,
11099 bajtówAnonimowa funkcja, która pobiera 6 argumentów. Nic szczególnego, tylko prosty port referencyjnej implementacji. Uaktualnianiem
u
,v
oraz drukowaniev
wszystkie zostały połączone w jedną linię, dzięki temu, że R jestprint
Zwraca wartość, która jest drukowana, więc można go używać w zadania. Wielkie podziękowania dla Giuseppe za uratowanie 11 bajtów!Wypróbuj online!
źródło
pryr::f()
afunction()
. Można jednak, po pewnym eksperymentowania, przesuńv
iu
„s deklaracji w ciele funkcji zachowując kolejność argumentów, aby zaoszczędzić kilkanaście bajtów: Spróbuj online!v
niekoniecznie przyjmuje wartości całkowite, potrzebujeszv>=30
jednakCzysty ,
150145140138 bajtówWypróbuj online!
Definiuje funkcję
$ :: Real Real Real Real Real Int -> [Real]
, implementując algorytm opisany w OP, zaczynając od 0-tego terminu.źródło
Python 2 , 100 bajtów
Wypróbuj online!
Zaoszczędzono 2 bajty dzięki user71546 .
źródło
0.04*v*v
dov*v/25.
powinno zaoszczędzić 1 bajt. Jeśli pływaki są zawsze podane nac
potemv*v/25
wystarczy do -2 bajtów.v>29
w mojej początkowej wersji. Jest to jednak nieprawidłowe, ponieważv
niekoniecznie jest liczbą całkowitą.JavaScript (Node.js) ,
107...103101 bajtówWkład @apsillers
Wypróbuj online!
Podejście oryginalne:
105103 bajtów. -1 bajty Dzięki Arnauld i -2 bajty Dzięki @ Kamoroso94.Wypróbuj online!
Lub jeśli wyskakujące alerty są w porządku, to
101...9997 bajtów (-1 bajtów Dzięki Arnauld, -2 bajtów Dzięki @ Kamoroso94):źródło
v>29
nie jest równoważne zv>=30
pływakami. Prawdopodobnie chcesz to zrobićv<30?0:(v=c,u+=d)
zamiast tego lub lepiej,v<30||(v=c,u+=d)
co oszczędza bajt.t-->0
na po prostut--
.for
pętlę domap
pracy na tablicy długościt
:(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))
. Funkcja zwraca tablicę zamiast rejestrowania wartości, które wydają się spełniać specyfikację.alert
Jednak nie pokonuje rozwiązania.Ruby , 94 bajty
Wypróbuj online!
Kolejny prosty port implementacji referencyjnej, lambda akceptująca 6 argumentów.
źródło
Haskell ,
112111 bajtówWypróbuj online!
Nie generuje przypadku zerowego. Zakłada, że
c
nigdy tak nie jest,>=30
ponieważ nie miałoby to sensu.Nigdy nie myślałem, że będę musiał użyćwhere
klauzuli w golfie kodowym, ale jest po prostu zbyt wiele zmiennych.EDYCJA: Dzięki @Lynn za start bajtu! Zapomniałem, że możesz umieścić
let
oświadczenia w straży. Pewnie zabija jednak czytelnośćźródło
where
dziwnąf x|let g a=b=y
składnią, aby zapisać bajt:(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))
Element , 81 bajtów
Wypróbuj online! , Strona Esolangs
Wyjaśnienie:
Ta część programu wymaga danych wejściowych. Przechowuje ona stałe
a
,b
,d
, iI
do zmiennych. Dane wejściowe dlac
nigdy nie są przechowywane w zmiennej, ale pozostają na głównym stosie podczas wykonywania. Wykonywane są trzy kopie: jedna u góry do inicjalizacjiu
, jedna w środku, która służy jako inicjałv
, a druga u dołu, aby służyła jako stałac
. Dane wejściowe fort
są rzucane natychmiast na stos sterujący, aby służyć jako podstawa pętli FOR[...]
otaczającej resztę programu.Ta część programu przyjmuje bieżącą wartość
v
i oblicza nową wartość, a następnie wykonuje się cztery kopie nowejv
wartości.Pierwszy egzemplarz
v
ma dołączony znak nowej linii i jest drukowany.Druga kopia
v
służy do testowania, czy neuron przyspieszył. Wynik tego testu jest umieszczany na stosie kontrolnym do późniejszego wykorzystania.Ta część oblicza „deltę
u
”, co oznacza kwotę do dodaniau
.Ten blok IF dodaje
d
się do powyższej sumy, jeśli neuron ulega skoku. Łączy to zwykle dwa zadania w jedno zadanie.Przechowuje zaktualizowaną wartość
u
.Ten blok IF jest kontynuacją powyższego bloku IF. Jeśli neuron przebija, usuń bieżącą wartość
v
(która jest teraz na górze głównego stosu) i zastąp ją duplikatemc
(który znajdował się na dole głównego stosu przez cały czas).I to w zasadzie wszystko. Jedna drobna uwaga jest taka, że ta rzecz przecieka pamięć: potrzeba więcej
"#
tam, aby usunąć górę stosu kontrolnego (oceniany warunek JEŻELI) po każdej iteracji pętli.Chociaż nie nazwałbym Elementu najbardziej wdzięcznym językiem golfa, to wyzwanie pozwala mi zaprezentować interesującą funkcję: ze względu na podział na główny stos i stos kontrolny, mogę wziąć instrukcję IF i podzielić warunek i ciało na wiele części z przeplotem bezwarunkowym kodem.
źródło
MATLAB, 111 bajtów
Całkiem prosta implementacja, prawdopodobnie można ją jeszcze ulepszyć.
źródło