Una neurona Izhikevich es un modelo simple pero bastante efectivo de una neurona biológica, diseñada para su uso en una simulación discreta de tiempo. En este desafío de golf, implementará este modelo.
Parámetros
Este modelo involucra solo 7 variables organizadas en 2 ecuaciones diferenciales, en comparación con las docenas de parámetros de un modelo fisiológicamente preciso.
v
yu
son las dos variables de estado de la neurona. Aquí,v
está la variable "rápida" que representa el potencial celular a lo largo del tiempo, yu
es la variable "lenta" que representa ciertas propiedades de la membrana. Lav
variable es la más importante, ya que esta es la salida de la simulación.a
,b
,c
, Yd
son constantes que describen las propiedades de la neurona fijo. Los diferentes tipos de neuronas tienen diferentes constantes, dependiendo del comportamiento deseado. Notablemente,c
es el potencial de reinicio, que es el potencial de membrana al que la célula regresa después del aumento.I
representa la corriente de entrada a la neurona. En las simulaciones de red, esto cambiará con el tiempo, pero para nuestros propósitos lo trataremosI
como una constante fija.
El modelo
Este modelo tiene un pseudocódigo muy simple. Primero, tomamos los valores constantes de abcd
y los usamos para inicializar v
y u
:
v = c
u = b * c
A continuación, recorremos el código de simulación tantas veces como lo desee. Cada iteración representa 1 milisegundo de tiempo.
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
Ciertas implementaciones del mundo real incluyen pasos adicionales para la precisión numérica, pero no las incluimos aquí.
Entrada
Como entrada, su programa / función debe tomar los valores de a
, b
, c
, d
, I
, y t
(el número de pasos de tiempo para simular). Una vez establecidos, ninguno de estos parámetros cambiará durante nuestra simulación simple. El orden de entrada no importa: puede especificar el orden en que su programa toma estos parámetros.
Salida
La salida será una lista de números que representan el potencial de membrana de la célula (dada por variable v
) en el transcurso de la simulación. La lista puede estar en cualquier formato apropiado.
Tiene la opción de incluir el valor 0 de la simulación (la configuración inicial antes de que pase cualquier momento) en su salida. Por ejemplo, para una entrada de 0.02 0.2 -50 2 10 6
(para a b c d I t
), una salida de
-50
-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068
o
-40
-16.04
73.876224
-42.667044096
-25.8262335380956
29.0355029192068
es aceptable.
Sus valores no tienen que ser exactamente los mismos que los anteriores, dependiendo de cómo su idioma maneje los flotantes.
Implementación de referencia
Aquí hay una implementación de TIO que escribí en Perl para demostrar el modelo. Los parámetros son los de una neurona "parloteante" del documento vinculado anteriormente, y esto sirve como una demostración de cómo este modelo puede recrear algunas de las propiedades más complejas de las neuronas, como alternar entre estados de alta y baja actividad. Si observa la salida, puede ver dónde la neurona se dispara inmediatamente varias veces, pero luego espera un tiempo antes de dispararse varias veces más (a pesar de que el voltaje de entrada de la celda I
sea constante todo el tiempo).
fuente
t
Alguna vez será negativo?Respuestas:
R ,
11099 bytesFunción anónima que toma 6 argumentos. Nada de lujos, solo un puerto directo de la implementación de referencia. La actualización de
u
,v
y la impresión dev
se han combinado en una sola línea, gracias al hecho de que Rprint
devuelve el valor que se está imprimiendo, por lo que puede usarlo en la asignación. ¡Muchas gracias a Giuseppe por guardar 11 bytes!Pruébalo en línea!
fuente
pryr::f()
yfunction()
. Sin embargo, después de experimentar un poco, puede moverv
yu
las declaraciones del cuerpo de la función mientras conserva el orden de los argumentos, para guardar una docena de bytes: ¡ Pruébelo en línea!v
no necesariamente toma valores enteros, sí es necesariov>=30
, sin embargoLimpias ,
150145140138 bytesPruébalo en línea!
Define la función
$ :: Real Real Real Real Real Int -> [Real]
, implementando el algoritmo como se describe en el OP, comenzando desde el término 0.fuente
Python 2 , 100 bytes
Pruébalo en línea!
Guardado 2 bytes gracias a user71546 .
fuente
0.04*v*v
av*v/25.
debería ahorrar 1 byte. Si siempre se dan flotantes,c
entonces esv*v/25
suficiente para -2 bytes.v>29
en mi versión inicial. Sin embargo, eso no es válido porquev
no es necesariamente un número entero.JavaScript (Node.js) ,
107...103101bytesContribuido por @apsillers
Pruébalo en línea!
Enfoque Original:
105103 bytes. -1 byte Gracias Arnauld, y -2 bytes Gracias @ Kamoroso94.Pruébalo en línea!
O si las alertas emergentes están bien, entonces
101...9997 bytes (-1 byte Gracias Arnauld, -2 bytes Gracias @ Kamoroso94):fuente
v>29
no es equivalente av>=30
para flotadores. Probablemente quieras hacer en suv<30?0:(v=c,u+=d)
lugar, o mejor aún, lov<30||(v=c,u+=d)
que guarda un byte.t-->0
a simplementet--
.for
bucle en unamap
operación en una matriz de longitudt
:(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 función devuelve una matriz en lugar de valores de registro, que parece satisfacer la especificación. Sinalert
embargo, no supera la solución.Ruby , 94 bytes
Pruébalo en línea!
Otro puerto directo de la implementación de referencia, una lambda que acepta 6 argumentos.
fuente
Haskell ,
112111 bytesPruébalo en línea!
No emite el caso cero. Asume que
c
nunca es así,>=30
ya que eso no tendría sentido.Nunca pensé que tendría que usar unawhere
cláusula en un código de golf, pero hay demasiadas variables.EDITAR: ¡Gracias @Lynn por despegar un byte! Olvidé que puedes poner
let
declaraciones en guardias. Claro que mata la legibilidadfuente
where
por la extrañaf x|let g a=b=y
sintaxis para guardar un byte:(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))
Elemento , 81 bytes
Pruébalo en línea! , Página de Esolangs
Explicación:
Esta parte del programa toma entrada. Almacena constantes
a
,b
,d
, yI
en variables. La entrada parac
nunca se almacena en una variable, sino que permanece en la pila principal durante la ejecución. Se realizan tres copias: una en la parte superior para inicializaru
, una en el medio para servir como inicialv
y otra en la parte inferior para servir como constantec
. La entrada parat
se lanza inmediatamente a la pila de control para servir como base del bucle FOR (the[...]
) que rodea al resto del programa.Esta parte del programa toma el valor actual
v
y calcula el nuevo valor, y luego se hacen cuatro copias del nuevov
valor.La primera copia de
v
tiene una nueva línea adjunta y se imprime.La segunda copia de
v
se usa para probar si la neurona se ha disparado. El resultado de esta prueba se coloca en la pila de control para su uso posterior.Esta parte calcula el "delta
u
", que significa la cantidad a agregaru
.Este bloque IF se suma
d
a la suma anterior si la neurona se está disparando. Esto combina lo que normalmente serían dos tareas en una sola tarea.Esto almacena el valor actualizado de
u
.Este bloque IF es una continuación del bloque IF anterior. Si la neurona se está disparando, elimine el valor actual de
v
(que ahora está en la parte superior de la pila principal) y reemplácelo con un duplicado dec
(que ha estado en la parte inferior de la pila principal todo este tiempo).Y eso es básicamente todo lo que hay que hacer. Una nota menor es que esto pierde memoria: se necesita un extra
"#
para eliminar la parte superior de la pila de control (la condición IF evaluada) después de cada iteración de bucle.Aunque no llamaría a Element el lenguaje de golf más elegante, este desafío me permite mostrar una característica interesante: debido a la división entre la pila principal y la pila de control, puedo tomar una declaración IF y dividir la condición y el cuerpo en múltiples partes, entrelazadas con código incondicional.
fuente
MATLAB, 111 bytes
Implementación bastante simple, probablemente se puede mejorar aún más.
fuente