Un neurone Izhikevich est un modèle simple mais assez efficace d'un neurone biologique, conçu pour être utilisé dans une simulation discrète de pas de temps. Dans ce défi de golf, vous implémenterez ce modèle.
Paramètres
Ce modèle ne comporte que 7 variables organisées en 2 équations différentielles, par rapport aux dizaines de paramètres d'un modèle physiologiquement précis.
v
etu
sont les deux variables d'état du neurone. Ici,v
est la variable "rapide" représentant le potentiel cellulaire au fil du temps, etu
est la variable "lente" représentant certaines propriétés de la membrane. Lav
variable est la plus importante, car il s'agit de la sortie de la simulation.a
,b
,c
, Etd
sont fixées des constantes qui décrivent les propriétés du neurone. Différents types de neurones ont différentes constantes, selon le comportement souhaité. Notamment,c
est le potentiel de réinitialisation, qui est le potentiel de membrane vers lequel la cellule revient après le dopage.I
représente le courant d'entrée du neurone. Dans les simulations de réseau, cela changera avec le temps, mais pour nos besoins, nous traiteronsI
comme une constante fixe.
Le modèle
Ce modèle a un pseudocode très simple. Tout d'abord, nous prenons les valeurs constantes de abcd
et les utilisons pour initialiser v
et u
:
v = c
u = b * c
Ensuite, nous parcourons le code de simulation autant de fois que souhaité. Chaque itération représente 1 milliseconde de temps.
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
Certaines implémentations réelles incluent des étapes supplémentaires pour la précision numérique, mais nous ne les incluons pas ici.
Contribution
Comme entrée, votre programme / fonction doit prendre les valeurs de a
, b
, c
, d
, I
et t
(le nombre de pas de temps à Simuler). Une fois définis, aucun de ces paramètres ne changera lors de notre simulation simple. L'ordre d'entrée n'a pas d' importance: vous pouvez spécifier l'ordre dans lequel votre programme prend ces paramètres.
Production
La sortie sera une liste de nombres représentant le potentiel de membrane de la cellule (donnée par variable v
) au cours de la simulation. La liste peut être dans n'importe quel format approprié.
Vous avez le choix d'inclure ou non la 0ème valeur de la simulation (la configuration initiale avant la fin du temps) dans votre sortie. Par exemple, pour une entrée de 0.02 0.2 -50 2 10 6
(pour a b c d I t
), une sortie de
-50
-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068
ou
-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068
est acceptable.
Vos valeurs ne pas doivent être exactement les mêmes que celles ci - dessus, selon la façon dont vos flotteurs poignées de langue.
Implémentation de référence
Voici une implémentation TIO que j'ai écrite en Perl pour démontrer le modèle. Les paramètres sont ceux d'un neurone "bavardant" du document lié ci-dessus, et cela sert de démonstration de la façon dont ce modèle est capable de recréer certaines des propriétés les plus complexes des neurones, telles que l'alternance entre des états d'activité élevée et faible. Si vous regardez la sortie, vous pouvez voir où le neurone pointe immédiatement plusieurs fois, mais attend ensuite un certain temps avant de monter plusieurs fois (malgré la tension d'entrée de la cellule I
constante tout le temps).
la source
t
jamais négatif?Réponses:
R ,
11099 octetsFonction anonyme qui prend 6 arguments. Rien d'extraordinaire, juste un port simple de l'implémentation de référence. La mise à jour de
u
,v
et l'impression dev
ont toutes été combinées en une seule ligne, grâce au fait que Rprint
renvoie la valeur qui est imprimée, vous pouvez donc l'utiliser dans l'affectation. Un grand merci à Giuseppe pour avoir économisé 11 octets!Essayez-le en ligne!
la source
pryr::f()
etfunction()
. Cependant, vous pouvez, après quelques expérimentations, déplacerv
etu
déclarer les déclarations dans le corps de la fonction tout en préservant l'ordre des arguments, pour économiser une douzaine d'octets: Essayez-le en ligne!v
ne prend pas nécessairement des valeurs entières, vous en avez besoinv>=30
, cependantClean ,
150145140138 octetsEssayez-le en ligne!
Définit la fonction
$ :: Real Real Real Real Real Int -> [Real]
, implémentant l'algorithme comme décrit dans l'OP, à partir du 0ème terme.la source
Python 2 , 100 octets
Essayez-le en ligne!
Enregistré 2 octets grâce à user71546 .
la source
0.04*v*v
àv*v/25.
devrait enregistrer 1 octet. Si les flotteurs sont toujours donnés pourc
ensuitev*v/25
suffit pour -2 octets.v>29
dans ma version initiale. Cependant, cela n'est pas valide car cev
n'est pas nécessairement un entier.JavaScript (Node.js) ,
107...103101 octetsContribué par @apsillers
Essayez-le en ligne!
Approche originale:
105103 octets. -1 octet Merci Arnauld, et -2 octets Merci @ Kamoroso94.Essayez-le en ligne!
Ou si les alertes popping sont OK, alors
101...9997 octets (-1 octet Merci Arnauld, -2 octets Merci @ Kamoroso94):la source
v>29
n'est pas équivalent àv>=30
pour les flottants. Vous voudrez probablement le faire à lav<30?0:(v=c,u+=d)
place, ou mieux encore,v<30||(v=c,u+=d)
ce qui économise un octet.t-->0
simplement àt--
.for
boucle en unemap
opération sur un tableau de longueurt
:(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))
. La fonction renvoie un tableau au lieu de consigner des valeurs, ce qui semble satisfaire la spécification. Ne bat pas laalert
solution, cependant.Rubis , 94 octets
Essayez-le en ligne!
Un autre port simple de l'implémentation de référence, un lambda acceptant 6 arguments.
la source
Haskell ,
112111 octetsEssayez-le en ligne!
Ne produit pas le cas zéro. Suppose que ce
c
n'est jamais>=30
puisque cela n'aurait pas de sens.Je n'ai jamais pensé que je devrais utiliser unewhere
clause dans un golf de code, mais il y a tout simplement trop de variables.EDIT: Merci @Lynn pour avoir décollé un octet! J'ai oublié que vous pouvez mettre des
let
déclarations en garde. Bien sûr, tue la lisibilitéla source
where
par l'étrangef x|let g a=b=y
syntaxe pour enregistrer un octet:(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))
Élément , 81 octets
Essayez-le en ligne! , Page Esolangs
Explication:
Cette partie du programme prend des informations. Il stocke les constantes
a
,b
,d
etI
en variables. L'entrée pourc
n'est jamais stockée dans une variable, mais reste plutôt sur la pile principale pendant l'exécution. Trois copies sont faites: une en haut pour l'initialisationu
, une au milieu pour servir d'initialev
et une en bas pour servir de constantec
. L'entrée fort
est immédiatement lancée sur la pile de contrôle pour servir de base à la boucle FOR (la[...]
) entourant le reste du programme.Cette partie du programme prend la valeur actuelle de
v
et calcule la nouvelle valeur, puis quatre copies de la nouvellev
valeur sont effectuées.Le premier exemplaire de
v
a une nouvelle ligne en annexe et est imprimé.La deuxième copie de
v
est utilisée pour tester si le neurone a atteint un pic. Le résultat de ce test est placé sur la pile de contrôle pour une utilisation ultérieure.Cette partie calcule le "delta
u
", c'est-à-dire le montant à ajouteru
.Ce bloc IF s'ajoute
d
à la somme ci-dessus si le neurone augmente. Cela combine ce qui serait normalement deux affectations en une seule affectation.Cela stocke la valeur mise à jour de
u
.Ce bloc IF est une continuation du bloc IF ci-dessus. Si le neurone augmente, supprimez la valeur actuelle de
v
(qui se trouve maintenant en haut de la pile principale) et remplacez-la par un doublon dec
(qui a été au bas de la pile principale pendant tout ce temps).Et c'est essentiellement tout ce qu'il y a à faire. Une remarque mineure est que cette chose fuit la mémoire: cela prend un supplément
"#
pour supprimer le haut de la pile de contrôle (la condition IF évaluée) après chaque itération de boucle.Bien que je n'appellerais pas Element le langage de golf le plus gracieux, ce défi me permet de présenter une fonctionnalité intéressante: en raison de la division entre la pile principale et la pile de contrôle, je peux prendre une instruction IF et diviser la condition et le corps en plusieurs parties entrelacées avec un code inconditionnel.
la source
MATLAB, 111 octets
Une implémentation assez simple, peut probablement être encore améliorée.
la source