diff --git a/neural_modelling/makefiles/meanfield/meanfield_build.mk b/neural_modelling/makefiles/meanfield/meanfield_build.mk index 7d7ff6f8da6..b698a223029 100644 --- a/neural_modelling/makefiles/meanfield/meanfield_build.mk +++ b/neural_modelling/makefiles/meanfield/meanfield_build.mk @@ -120,10 +120,16 @@ else endif - ifndef CONFIG_H - $(error CONFIG_H is not set. Please select an input type header file) + ifndef PARAMS_FROM_NETWORK_H + $(error PARAMS_FROM_NETWORK_H is not set. Please select an input type header file) else - CONFIG_H := $(call replace_source_dirs,$(CONFIG_H)) + PARAMS_FROM_NETWORK_H := $(call replace_source_dirs,$(PARAMS_FROM_NETWORK_H)) + endif + + ifndef P_FIT_POLYNOMIAL_H + $(error P_FIT_POLYNOMIAL_H is not set. Please select an input type header file) + else + P_FIT_POLYNOMIAL_H := $(call replace_source_dirs,$(P_FIT_POLYNOMIAL_H)) endif ifndef INPUT_TYPE_H @@ -153,7 +159,8 @@ else MEANFIELD_INCLUDES := \ -include $(MEANFIELD_MODEL_H) \ -include $(SYNAPSE_TYPE_H) \ - -include $(CONFIG_H)\ + -include $(PARAMS_FROM_NETWORK_H)\ + -include $(P_FIT_POLYNOMIAL_H)\ -include $(MATHSBOX_H) \ -include $(INPUT_TYPE_H) \ -include $(THRESHOLD_TYPE_H) \ diff --git a/neural_modelling/makefiles/meanfield/meanfield_model_cond/Makefile b/neural_modelling/makefiles/meanfield/meanfield_model_cond/Makefile index d75120ae42f..8dc3058b4be 100644 --- a/neural_modelling/makefiles/meanfield/meanfield_model_cond/Makefile +++ b/neural_modelling/makefiles/meanfield/meanfield_model_cond/Makefile @@ -2,7 +2,8 @@ APP = $(notdir $(CURDIR)) MEANFIELD_MODEL = $(MEANFIELD_DIR)/meanfield/models/meanfield_model_impl.c MEANFIELD_MODEL_H = $(MEANFIELD_DIR)/meanfield/models/meanfield_model_impl.h -CONFIG_H = $(MEANFIELD_DIR)/meanfield/models/config.h +PARAMS_FROM_NETWORK_H = $(MEANFIELD_DIR)/meanfield/models/params_from_network.h +P_FIT_POLYNOMIAL_H = $(MEANFIELD_DIR)/meanfield/models/P_fit_polynomial.h INPUT_TYPE_H = $(MEANFIELD_DIR)/meanfield/input_types/input_type_conductance.h MATHSBOX_H = $(MEANFIELD_DIR)/meanfield/models/mathsbox.h MEANFIELD_IMPL_H = $(MEANFIELD_DIR)/meanfield/implementations/meanfield_impl_standard.h diff --git a/neural_modelling/src/meanfield/implementations/meanfield_impl_standard.h b/neural_modelling/src/meanfield/implementations/meanfield_impl_standard.h index 59e60b7ea3b..65507251d43 100644 --- a/neural_modelling/src/meanfield/implementations/meanfield_impl_standard.h +++ b/neural_modelling/src/meanfield/implementations/meanfield_impl_standard.h @@ -24,7 +24,8 @@ // Includes for model parts used in this implementation #include -#include +#include +#include #include #include @@ -40,13 +41,15 @@ //! Indices for recording of words enum word_recording_indices { //! V (somatic potential) recording index - V_RECORDING_INDEX = 0, + VE_RECORDING_INDEX = 0, + VI_RECORDING_INDEX = 1, + W_RECORDING_INDEX = 2, //! Gsyn_exc (excitatory synaptic conductance/current) recording index - GSYN_EXC_RECORDING_INDEX = 1, + GSYN_EXC_RECORDING_INDEX = 3, //! Gsyn_inh (excitatory synaptic conductance/current) recording index - GSYN_INH_RECORDING_INDEX = 2, + GSYN_INH_RECORDING_INDEX = 4, //! Number of recorded word-sized state variables - N_RECORDED_VARS = 10 + N_RECORDED_VARS = 5 }; //! Indices for recording of bitfields @@ -66,13 +69,15 @@ enum bitfield_recording_indices { };*/ -//! Array of meanfield states -> will be change in future +//! Array of meanfield states -> will be change in future , the future is now!! static meanfield_t *meanfield_array; -static config_t *config_array; +static ParamsFromNetwork_t *pNetwork_array; static mathsbox_t *mathsbox_array; +static pFitPolynomial_t *Pfit_exc_array; +static pFitPolynomial_t *Pfit_inh_array; //! Input states array static input_type_t *input_type_array; @@ -136,17 +141,35 @@ static bool meanfield_impl_initialise(uint32_t n_meanfields) { } // Allocate DTCM for config array and copy block of data - if (sizeof(config_t)) { - config_array = spin1_malloc(n_meanfields * sizeof(config_t)); - if (config_array == NULL) { + if (sizeof(ParamsFromNetwork_t)) { + pNetwork_array = spin1_malloc(n_meanfields * sizeof(ParamsFromNetwork_t)); + if (pNetwork_array == NULL) { log_error("Unable to allocate config array - Out of DTCM"); return false; } } - + + // Allocate DTCM for P fit from polyomial for exc array and copy block of data + if (sizeof(pFitPolynomial_t)) { + Pfit_exc_array = spin1_malloc(n_meanfields * sizeof(pFitPolynomial_t)); + if (Pfit_exc_array == NULL) { + log_error("Unable to allocate Pfit_exc_array - Out of DTCM"); + return false; + } + } + + // Allocate DTCM for P fit from polyomial for exc array and copy block of data + if (sizeof(pFitPolynomial_t)) { + Pfit_inh_array = spin1_malloc(n_meanfields * sizeof(pFitPolynomial_t)); + if (Pfit_inh_array == NULL) { + log_error("Unable to allocate Pfit_inh_array - Out of DTCM"); + return false; + } + } + // Allocate DTCM for mathsbox array and copy block of data if (sizeof(mathsbox_t)) { - mathsbox_array = spin1_malloc(n_meanfields * sizeof(config_t)); + mathsbox_array = spin1_malloc(n_meanfields * sizeof(mathsbox_t)); if (mathsbox_array == NULL) { log_error("Unable to allocate mathsbox array - Out of DTCM"); return false; @@ -254,13 +277,27 @@ static void neuron_impl_load_neuron_parameters( next += n_words_needed(n_meanfields * sizeof(meanfield_t)); } - if (sizeof(config_t)) { + if (sizeof(ParamsFromNetwork_t)) { log_debug("reading config parameters"); - spin1_memcpy(config_array, &address[next], - n_meanfields * sizeof(config_t)); - next += n_words_needed(n_meanfields * sizeof(config_t)); + spin1_memcpy(pNetwork_array, &address[next], + n_meanfields * sizeof(ParamsFromNetwork_t)); + next += n_words_needed(n_meanfields * sizeof(ParamsFromNetwork_t)); } - + + if (sizeof(pFitPolynomial_t)) { + log_debug("reading pFitPolynomial exc parameters"); + spin1_memcpy(Pfit_exc_array, &address[next], + n_meanfields * sizeof(pFitPolynomial_t)); + next += n_words_needed(n_meanfields * sizeof(pFitPolynomial_t)); + } + + if (sizeof(pFitPolynomial_t)) { + log_debug("reading pFitPolynomial inh parameters"); + spin1_memcpy(Pfit_inh_array, &address[next], + n_meanfields * sizeof(pFitPolynomial_t)); + next += n_words_needed(n_meanfields * sizeof(pFitPolynomial_t)); + } + if (sizeof(mathsbox_t)) { log_debug("reading mathsbox parameters"); spin1_memcpy(mathsbox_array, &address[next], @@ -315,8 +352,11 @@ static void neuron_impl_do_timestep_update( // Get the neuron itself meanfield_t *this_meanfield = &meanfield_array[meanfield_index]; - // Get the config and mathsbox params for this neuron - config_t *config_types = &config_array[meanfield_index]; + // Get the Params from network and mathsbox params for this neuron + ParamsFromNetwork_t *pNetwork_types = &pNetwork_array[meanfield_index]; + pFitPolynomial_t *Pfit_exc_types = &Pfit_exc_array[meanfield_index]; + pFitPolynomial_t *Pfit_inh_types = &Pfit_inh_array[meanfield_index]; + mathsbox_t *mathsbox_types = &mathsbox_array[meanfield_index]; // Get the input_type parameters and voltage for this neuron @@ -336,7 +376,12 @@ static void neuron_impl_do_timestep_update( // and because the index doesn't actually matter for (uint32_t i_step = n_steps_per_timestep; i_step > 0; i_step--) { // Get the voltage->firing rate - state_t firing_rate = meanfield_model_get_firing_rate(this_meanfield); + state_t firing_rate_Ve = meanfield_model_get_firing_rate_Ve( + this_meanfield); + state_t firing_rate_Vi = meanfield_model_get_firing_rate_Vi( + this_meanfield); + + state_t adaptation_W = meanfield_model_get_adaptation_W(this_meanfield); // Get the exc and inh values from the synapses input_t exc_values[NUM_EXCITATORY_RECEPTORS]; @@ -363,10 +408,14 @@ static void neuron_impl_do_timestep_update( total_inh += inh_input_values[i]; } - // Do recording if on the first step + // Do recording if on the first step if (i_step == n_steps_per_timestep) { neuron_recording_record_accum( - V_RECORDING_INDEX, meanfield_index, firing_rate); + VE_RECORDING_INDEX, meanfield_index, firing_rate_Ve); + neuron_recording_record_accum( + VI_RECORDING_INDEX, meanfield_index, firing_rate_Vi); + neuron_recording_record_accum( + W_RECORDING_INDEX, meanfield_index, adaptation_W); neuron_recording_record_accum( GSYN_EXC_RECORDING_INDEX, meanfield_index, total_exc); neuron_recording_record_accum( @@ -375,19 +424,19 @@ static void neuron_impl_do_timestep_update( // Call functions to convert exc_input and inh_input to current input_type_convert_excitatory_input_to_current( - exc_input_values, input_types, firing_rate); + exc_input_values, input_types, firing_rate_Ve); input_type_convert_inhibitory_input_to_current( - inh_input_values, input_types, firing_rate); - + inh_input_values, input_types, firing_rate_Vi); + // input_t external_bias += additional_input_get_input_value_as_current( // additional_inputs, firing_rate); // update neuron parameters - state_t result = meanfield_model_state_update( - this_meanfield, config_types, mathsbox_types); - - //reinitialise Fout_th - config_types->Fout_th = 0.0; // I don't understand what this does + state_t result = meanfield_model_state_update(this_meanfield, + pNetwork_types, + Pfit_exc_types, + Pfit_inh_types, + mathsbox_types); // determine if a spike should occur bool spike_now = @@ -411,7 +460,7 @@ static void neuron_impl_do_timestep_update( // Shape the existing input according to the included rule synapse_types_shape_input(the_synapse_type); - if (config_types->Fout_th==0.0) { + if (pNetwork_types->Fout_th==0.0) { has_spiked = true; } } @@ -452,12 +501,14 @@ static void neuron_impl_store_neuron_parameters( next += n_words_needed(n_meanfields * sizeof(meanfield_t)); } - if (sizeof(config_t)) { + /* + if (sizeof(ParamsFromNetwork_t)) { log_debug("writing input type parameters"); - spin1_memcpy(&address[next], config_array, - n_meanfields * sizeof(config_t)); - next += n_words_needed(n_meanfields * sizeof(config_t)); + spin1_memcpy(&address[next], pNetwork_array, + n_meanfields * sizeof(ParamsFromNetwork_t)); + next += n_words_needed(n_meanfields * sizeof(ParamsFromNetwork_t)); } + */ } diff --git a/neural_modelling/src/meanfield/models/P_fit_polynomial.h b/neural_modelling/src/meanfield/models/P_fit_polynomial.h new file mode 100644 index 00000000000..c2978f96905 --- /dev/null +++ b/neural_modelling/src/meanfield/models/P_fit_polynomial.h @@ -0,0 +1,25 @@ +#ifndef _P_FIT_POLYNOMIAL_H_ +#define _P_FIT_POLYNOMIAL_H_ + +#include "../../meanfield/models/meanfield_model.h" + +typedef struct pFitPolynomial_t { + // nominally 'fixed' parameters +/*! \brief a structure for the polynomial parameters coming from a single neuron fit + * MORE INFO +*/ + REAL P0; + REAL P1; + REAL P2; + REAL P3; + REAL P4; + REAL P5; + REAL P6; + REAL P7; + REAL P8; + REAL P9; + REAL P10; +} pFitPolynomial_t; + + +#endif \ No newline at end of file diff --git a/neural_modelling/src/meanfield/models/config.h b/neural_modelling/src/meanfield/models/config.h deleted file mode 100644 index 89614141f09..00000000000 --- a/neural_modelling/src/meanfield/models/config.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#include "../../meanfield/models/meanfield_model.h" - - -/*struct config_t; -typedef struct config_t config_t; -typedef struct config_t* config_t;*/ - -typedef struct config_t { - // nominally 'fixed' parameters - REAL pconnec; - REAL Qe; - REAL Qi; - REAL Te; - REAL Ti; - REAL Ee; - REAL Ei; - REAL Ntot; - REAL gei; - REAL ext_drive; - REAL afferent_exc_fraction; - - REAL Gl; - REAL Cm; - REAL El; - - REAL P0; - REAL P1; - REAL P2; - REAL P3; - REAL P4; - REAL P5; - REAL P6; - REAL P7; - REAL P8; - REAL P9; - REAL P10; - - // Variable-state parameters - //REAL fe; - //REAL fi; - - REAL muV;//:=0.0; - REAL muV0; - //muV0 = -60e-3; - REAL DmuV0;// = 10e-3; - - REAL sV;//=0.0; - REAL sV0;// = 4e-3; - REAL DsV0;// = 6e-3; - - REAL muGn;//=0.0; - - REAL TvN;//=0.0; - REAL TvN0;// = 0.5; - REAL DTvN0;// = 1.; - - REAL Vthre;//=0.0; - - REAL Fout_th;//=0.0; -} config_t; - -/* -typedef struct global_toolbox_params_t { - REAL this_h; - REAL this_time; -} global_toolbox_params_t; -*/ - - -#endif \ No newline at end of file diff --git a/neural_modelling/src/meanfield/models/mathsbox.h b/neural_modelling/src/meanfield/models/mathsbox.h index dc6abf625f9..62fa90ea0f9 100644 --- a/neural_modelling/src/meanfield/models/mathsbox.h +++ b/neural_modelling/src/meanfield/models/mathsbox.h @@ -1,9 +1,10 @@ #ifndef _MATHSBOX_H_ #define _MATHSBOX_H_ -#include +//#include #include #include +//#include "../../common/maths-util.h" //#include @@ -15,9 +16,11 @@ typedef struct mathsbox_t { REAL error_func_sample; REAL err_func; + + REAL var_sqrt; }mathsbox_t; //typedef struct mathsbox_params_t* mathsbox_pointer_t; -void error_function(REAL x, REAL factor, mathsbox_t *restrict mathsbox); +void error_function(REAL argument, mathsbox_t *restrict mathsbox); #endif \ No newline at end of file diff --git a/neural_modelling/src/meanfield/models/meanfield_model.h b/neural_modelling/src/meanfield/models/meanfield_model.h index 7c65d7c4160..7b871ed5629 100644 --- a/neural_modelling/src/meanfield/models/meanfield_model.h +++ b/neural_modelling/src/meanfield/models/meanfield_model.h @@ -33,9 +33,13 @@ struct meanfield_t; typedef struct meanfield_t meanfield_t; typedef struct meanfield_t* meanfield_pointer_t; -struct config_t; -typedef struct config_t config_t; -typedef struct config_t* config_pointer_t; +struct ParamsFromNetwork_t; +typedef struct ParamsFromNetwork_t ParamsFromNetwork_t; +typedef struct ParamsFromNetwork_t* ParamsFromNetwork_pointer_t; + +struct pFitPolynomial_t; +typedef struct pFitPolynomial_t pFitPolynomial_t; +typedef struct pFitPolynomial_t* pFitPolynomial_pointer_t; struct mathsbox_t; typedef struct mathsbox_t mathsbox_t; @@ -78,7 +82,11 @@ state_t meanfield_model_state_update( state_t meanfield_model_state_update( - meanfield_t *restrict meanfield, config_t *restrict config, mathsbox_t *restrict mathsbox); + meanfield_t *restrict meanfield, + ParamsFromNetwork_t *restrict params_from_network, + pFitPolynomial_t *restrict Pfit_exc, + pFitPolynomial_t *restrict Pfit_inh, + mathsbox_t *restrict mathsbox); //! \brief Indicates that the neuron has spiked //! \param[in, out] neuron pointer to a neuron parameter struct which contains @@ -90,7 +98,9 @@ void neuron_model_has_spiked(meanfield_t *restrict meanfield); //! all the parameters for a specific neuron //! \return the membrane voltage for a given neuron with the neuron //! parameters specified in neuron -state_t meanfield_model_get_firing_rate(const meanfield_t *meanfield); +state_t meanfield_model_get_firing_rate_Ve(const meanfield_t *meanfield); +state_t meanfield_model_get_firing_rate_Vi(const meanfield_t *meanfield); +state_t meanfield_model_get_adaptation_W(const meanfield_t *meanfield); //! \brief printout of state variables i.e. those values that might change //! \param[in] neuron: a pointer to a neuron parameter struct which contains all diff --git a/neural_modelling/src/meanfield/models/meanfield_model_impl.c b/neural_modelling/src/meanfield/models/meanfield_model_impl.c index 332d406f008..47d372936a8 100644 --- a/neural_modelling/src/meanfield/models/meanfield_model_impl.c +++ b/neural_modelling/src/meanfield/models/meanfield_model_impl.c @@ -20,8 +20,10 @@ #include "../../meanfield/models/meanfield_model_impl.h" #include -#include "../../meanfield/models/config.h" +#include "../../meanfield/models/params_from_network.h" #include "../../meanfield/models/mathsbox.h" +#include "../../meanfield/models/P_fit_polynomial.h" +//#include "../../common/maths-util.h" // i.o to use SQRT(x) and SQR(a) //! The global parameters of the Izhekevich neuron model static const global_neuron_params_t *global_params; @@ -31,29 +33,7 @@ static const global_neuron_params_t *global_params; * use cases 1.85 gives slightly better spike timings. */ //static const REAL SIMPLE_TQ_OFFSET = REAL_CONST(1.85); -/* -///////////////////////////////////////////////////////////// -#if 0 -// definition for Izhikevich neuron -static inline void neuron_ode( - REAL t, REAL stateVar[], REAL dstateVar_dt[], - neuron_t *neuron, REAL input_this_timestep) { - REAL V_now = stateVar[1]; - REAL U_now = stateVar[2]; - log_debug(" sv1 %9.4k V %9.4k --- sv2 %9.4k U %9.4k\n", stateVar[1], - neuron->V, stateVar[2], neuron->U); - - // Update V - dstateVar_dt[1] = - REAL_CONST(140.0) - + (REAL_CONST(5.0) + REAL_CONST(0.0400) * V_now) * V_now - U_now - + input_this_timestep; - - // Update U - dstateVar_dt[2] = neuron->A * (neuron->B * V_now - U_now); -} -#endif -*/ + //! \brief The original model uses 0.04, but this (1 ULP larger?) gives better //! numeric stability. @@ -61,34 +41,80 @@ static inline void neuron_ode( //! Thanks to Mantas Mikaitis for this! //static const REAL MAGIC_MULTIPLIER = REAL_CONST(0.040008544921875); - -/* #################################################################### - reuse of izk for meanfields - ################################################################### - */ - -void error_function( REAL x, REAL factor, mathsbox_t *restrict mathsbox){ -//devra coder fonction powerof - - REAL dt = x/mathsbox->error_func_sample; +void error_function(REAL argument, mathsbox_t *restrict mathsbox){ +/**************************************************************************** + * Error function with integral computing by midpoint method OK + * Will do the Simpson if ITCM is ok + * + * Sampling of error function is maybe connected to the time_step need to + * investigate. + * + * expk take : ~ 570 bytes + sqrtk take : ~1250 bytes + *****************************************************************************/ + mathsbox->err_func = 0.; + REAL step = argument/mathsbox->error_func_sample; + REAL x; REAL t; - REAL Pi = 3.1415927k; - REAL Erfc = mathsbox->err_func; - for(t=0; t==x; t+=dt){ - //Erfc += dt; //test otherwise IDTM overload - //Erfc += factor*(2/sqrtk(Pi))*expk(-(t*t)); // the real one - Erfc += factor+t*t;//fake one + REAL Pi = REAL_CONST(3.1415927);// here was a k + REAL two_over_sqrt_Pi = REAL_CONST(1.128379167); //APPROXIMATION + REAL Erf = ZERO; + REAL Erfc = ZERO; + + for(x=0; x<=argument; x+=step){ + + //Erfc += factor*(2/sqrtk(Pi))*expk(-(t*t)); // the real one overflowed ITCM because of expk and sqrtk + t = x + REAL_HALF(step); + Erf += step*two_over_sqrt_Pi*expk(-(t*t)); //working like this one + //Erf += step*two_over_sqrt_Pi*(-(t*t));//TEST + //Erf += step*(REAL_CONST(2.)/sqrtk(Pi))*expk(-(t*t)); // TEST sqrtk ONE } + Erfc = ONE-Erf; mathsbox->err_func = Erfc; - //return Erfc; +} +/* +double square_root_of(REAL number) +{ + /*! square root method take from Quake III Arena + * source code, attribute to John Carmack. + * Under GNU GPL licence. + * + * Implement here just to see if something was lighter than sqrt.c + * + */ +/* + REAL x, y, f; + REAL i; + f = REAL_CONST(1.5); + + x = REAL_HALF(number); + y = number; + + i = *(REAL *) &y; + i = 0x5f3759df - (i >> 1); + y = *(REAL *) &i; + y = y * (f - (x * y * y)); + y = y * (f - (x * y * y)); + + return number*y; + } +*/ + -void threshold_func(config_t *restrict config) + +void threshold_func(ParamsFromNetwork_t *restrict pNetwork, pFitPolynomial_t *restrict Pfit) { + /* + threshold function coming from : + Neural Computation 31, 653–680 (2019) doi:10.1162/neco_a_01173 + where P's are polynomials parameters involve in a + voltage-effective threshold. + */ /* setting by default to True the square because when use by external modules, coeff[5:]=np.zeros(3) @@ -97,152 +123,111 @@ void threshold_func(config_t *restrict config) /*NEED TO AVOID DIVISION AS POSSIBLE but not for now */ - /* - config->muV0=-0.06; - config->DmuV0=0.01; - - config->sV0=0.004; - config->DsV0=0.006; - - config->TvN0=0.5; - config->DTvN0=1.; - - config->muV=0.; - config->sV=0.; - config->muGn=0.; - config->TvN=0.; - config->Vthre=0.; - config->Fout_th=0.; - */ + + REAL muV0 = pNetwork->muV0; + REAL DmuV0 = pNetwork->DmuV0; + + REAL sV0 = pNetwork->sV0; + REAL DsV0 = pNetwork->DsV0; + + REAL TvN0 = pNetwork->TvN0; + REAL DTvN0 = pNetwork->DTvN0; + + REAL muV = pNetwork->muV; + REAL sV = pNetwork->sV; + //REAL muGn = pNetwork->muGn; + REAL TvN = pNetwork->TvN; + REAL Vthre = pNetwork->Vthre; + //REAL Fout_th = pNetwork->Fout_th; + + REAL P0 = Pfit->P0; + REAL P1 = Pfit->P1; + REAL P2 = Pfit->P2; + REAL P3 = Pfit->P3; + //REAL P4 = Pfit->P4; + REAL P5 = Pfit->P5; + REAL P6 = Pfit->P6; + REAL P7 = Pfit->P7; + REAL P8 = Pfit->P8; + REAL P9 = Pfit->P9; + REAL P10 = Pfit->P10; // + 0.\ //P4*np.log(muGn) - /* - config->Vthre = config->P0\ - + config->P1*(config->muV-config->muV0)/config->DmuV0\ - + config->P2*(config->sV-config->sV0)/config->DsV0\ - + config->P3*(config->TvN-config->TvN0)/config->DTvN0\ - + config->P5*((config->muV-config->muV0)/config->DmuV0)*((config->muV-config->muV0)/config->DmuV0)\ - + config->P6*((config->sV-config->sV0)/config->DsV0)*((config->sV-config->sV0)/config->DsV0)\ - + config->P7*((config->TvN-config->TvN0)/config->DTvN0)*((config->TvN-config->TvN0)/config->DTvN0)\ - + config->P8*(config->muV-config->muV0)/config->DmuV0*(config->sV-config->sV0)/config->DsV0\ - + config->P9*(config->muV-config->muV0)/config->DmuV0*(config->TvN-config->TvN0)/config->DTvN0\ - + config->P10*(config->sV-config->sV0)/config->DsV0*(config->TvN-config->TvN0)/config->DTvN0; - */ - - config->Vthre = config->P0; - - //return config->Vthre; + + Vthre = P0\ + + P1*(muV-muV0)/DmuV0\ + + P2*(sV-sV0)/DsV0\ + + P3*(TvN-TvN0)/DTvN0\ + + P5*((muV-muV0)/DmuV0)*((muV-muV0)/DmuV0)\ + + P6*((sV-sV0)/DsV0)*((sV-sV0)/DsV0)\ + + P7*((TvN-TvN0)/DTvN0)*((TvN-TvN0)/DTvN0)\ + + P8*((muV-muV0)/DmuV0)*((sV-sV0)/DsV0)\ + + P9*((muV-muV0)/DmuV0)*((TvN-TvN0)/DTvN0)\ + + P10*((sV-sV0)/DsV0)*((TvN-TvN0)/DTvN0); + + pNetwork->Vthre = Vthre; } -/* - REAL ONE get_fluct_regime_varsup -*/ -/* -void get_fluct_regime_varsup(REAL Ve, REAL Vi, config_t *restrict params) +void get_fluct_regime_varsup(REAL Ve, REAL Vi, REAL W, ParamsFromNetwork_t *restrict pNetwork) { - //takes 880 bytes overflowed ITCM - - REAL Fe; - REAL Fi; - REAL muGe, muGi, muG; - REAL Ue, Ui; - REAL Tm, Tv; - - - // here TOTAL (sum over synapses) excitatory and inhibitory input - - Fe = Ve * (1.-params->gei)*params->pconnec*params->Ntot; // default is 1 !! - Fi = Vi * params->gei*params->pconnec*params->Ntot; - - muGe = params->Qe*params->Te*Ve; - muGi = params->Qi*params->Ti*Vi; - - muG = params->Gl+muGe+muGi; - - params->muV = (muGe*params->Ee+muGi*params->Ei+params->Gl*params->El)/muG; - - - params->muGn = muG/params->Gl; - - Tm = params->Cm/muG; - - Ue = params->Qe/muG*(params->Ee-params->muV); - Ui = params->Qi/muG*(params->Ei-params->muV); - - - //PENSEZ a enlever autant de division que possible - - params->sV = sqrtk(Fe*(Ue*params->Te)*(Ue*params->Te)/2./(params->Te+Tm)+\ - Fi*(params->Ti*Ui)*(params->Ti*Ui)/2./(params->Ti+Tm)); - - if (params->sV < 1e-8){ - params->sV = 1e-8; - } + // Need some comments + + REAL gei = pNetwork->gei; + REAL pconnec = pNetwork->pconnec; + REAL Ntot = pNetwork->Ntot; + REAL Qe = pNetwork->Qe; + REAL Qi = pNetwork->Qi; + REAL Te = pNetwork->Te; + REAL Ti = pNetwork->Ti; + REAL Gl = pNetwork->Gl; + REAL El = pNetwork->El; + REAL Ei = pNetwork->Ei; + REAL Ee = pNetwork->Ee; + REAL Cm = pNetwork->Cm; + + + REAL Fe = Ve * (REAL_CONST(1.)-gei)*pconnec*Ntot; // default is 1 !! + REAL Fi = Vi * gei*pconnec*Ntot; + + /* normaly = Ve*Te*Qe*Ke with Ke = p*N_exc what it is? + -> here N_exc = (1-gei)*Ntot*pconnec + So give the same + */ + REAL muGe = Qe*Te*Fe; //=Ve*Qe*Te*Ke + REAL muGi = Qi*Ti*Fi; - if (Fe<1e-9)//just to insure a non zero division, - { - Fe += 1e-9; - } - else if (Fi<1e-9) - { - Fi += 1e-9; + REAL muG = Gl + muGe + muGi; + + if (muG < ACS_DBL_TINY){ + muG += ACS_DBL_TINY; } - Tv = ( Fe*(Ue*params->Te)*(Ue*params->Te) + Fi*(params->Ti*Ui)*(params->Ti*Ui))\ - /(Fe*(Ue*params->Te)*(Ue*params->Te)/(params->Te+Tm)\ - + Fi*(params->Ti*Ui)*(params->Ti*Ui)/(params->Ti+Tm)); - - params->TvN = Tv*params->Gl/params->Cm; - - //return params->muV;//, sV+1e-12, muGn, TvN -} -*/ - - -// FAKE ONE get_fluct_regime_varsup -//where all division are removed + pNetwork->muV = (muGe*Ee + muGi*Ei + Gl*El - W)/muG; //Thomas : maybe will add explicitely a and b? -void get_fluct_regime_varsup(REAL Ve, REAL Vi, config_t *restrict params) -{ - //takes 880 bytes overflowed ITCM - - REAL Fe; - REAL Fi; - REAL muGe, muGi, muG; - REAL Ue, Ui; - REAL Tm, Tv; - - - // here TOTAL (sum over synapses) excitatory and inhibitory input - - Fe = Ve * (ONE-params->gei)*params->pconnec*params->Ntot; // default is 1 !! - Fi = Vi * params->gei*params->pconnec*params->Ntot; - - muGe = params->Qe*params->Te*Ve; - muGi = params->Qi*params->Ti*Vi; - - muG = params->Gl+muGe+muGi; - params->muV = (muGe*params->Ee+muGi*params->Ei+params->Gl*params->El); //fake one + pNetwork->muGn = muG/Gl; - params->muGn = muG; //fake one + REAL Tm = Cm/muG; - Tm = params->Cm/muG; //fake one - - Ue = params->Qe; //fake one - Ui = params->Qi; //fake one - - - //PENSEZ a enlever autant de division que possible - - params->sV = Fe*(Ue*params->Te)*(Ue*params->Te)+\ - Fi*(params->Ti*Ui)*(params->Ti*Ui);// fake one - - if (params->sV < ACS_DBL_TINY){ - params->sV = ACS_DBL_TINY; - } + REAL Ue = Qe*(Ee-pNetwork->muV)/muG; + REAL Ui = Qi*(Ei-pNetwork->muV)/muG; + + /* + normaly sqrt(REAL_HALF(Fe*(Ue*Te)*(Ue*Te)/(Te+Tm) + Fi*(Ti*Ui)*(Ti*Ui)/(Ti+Tm))) + + need find a good sqrt function ... + |->sqrtk() takes too much ITCM !!! + */ + + + REAL sV_sqr = REAL_HALF(Fe*(Ue*Te)*(Ue*Te)/(Te+Tm) + Fi*(Ti*Ui)*(Ti*Ui)/(Ti+Tm));//ITCM with err_func also, 1272 bytes over + + pNetwork->sV = sV_sqr; // square_root_of(sV_sqr); + + + if (FeTvN = Tv*Gl/Cm; // Thomas : Heu, useless no?? |resp-> TvN is a dimensional so usefull var + + - Tv = ( Fe*(Ue*params->Te)*(Ue*params->Te) +\ - Fi*(params->Ti*Ui)*(params->Ti*Ui)); //fake one - - params->TvN = Tv*params->Gl; //fake one - - - //return params->muV;//, sV+1e-12, muGn, TvN } -//END of the get_fluct_regime_varsup FAKE - - -void TF(REAL Ve, REAL Vi, meanfield_t *meanfield, config_t *restrict config, +void TF(REAL Ve, REAL Vi, REAL W, + ParamsFromNetwork_t *restrict pNetwork, + pFitPolynomial_t *restrict Pfit, mathsbox_t *restrict mathsbox){ -// argument are fe, fi and pseq_params -// problem is to implement it with params and instruction coming from -// DTCM and ITCM. -// when get_fluct_regime_varsup is ON takes 1360 bytes overflowed ITCM - +/* + State-variables are directly connected to the struct + parameters are put in local in order to make the code clear. - REAL limit; - REAL argument; +*/ + + + if (pNetwork->Fout_th != ZERO){ + pNetwork->Fout_th = ACS_DBL_TINY; + } if (Ve < ACS_DBL_TINY){ - Ve = ACS_DBL_TINY; + Ve += ACS_DBL_TINY; } if (Vi < ACS_DBL_TINY){ - Vi = ACS_DBL_TINY; + Vi += ACS_DBL_TINY; } - get_fluct_regime_varsup(Ve, Vi, config); - threshold_func(config); + get_fluct_regime_varsup(Ve, Vi, W, pNetwork); + threshold_func(pNetwork, Pfit); + + + /* + normalement sqrt: + argument = (pNetwork->Vthre - pNetwork->muV)/sqrtk(REAL_CONST(2.))/pNetwork->sV; - if (config->sVsV = REAL_CONST(1e-4); + */ + if (pNetwork->sVsV += ACS_DBL_TINY; } + //factor = REAL_HALF(Gl/(pNetwork->TvN * Cm)); + REAL argument = (pNetwork->Vthre - pNetwork->muV)/(REAL_CONST(1.4142137)*pNetwork->sV); + - limit = 10;//REAL_HALF(config->Gl/(config->TvN * config->Cm)); - argument = config->Vthre;//(config->Vthre - config->muV)/sqrtk(REAL_CONST(2.))/config->sV; + error_function(argument, mathsbox); -// config->Fout_th = error_function(factor, argument, mathsbox); - error_function(limit, argument, mathsbox); + + REAL Gl = pNetwork->Gl; + REAL Cm = pNetwork->Cm; + /* + pNetwork->Fout_th = (HALF*Gl) * mathsbox->err_func / (Cm*pNetwork->TvN);// In fact = 1/(2.*Tv) * err_func , that's it'!!! + If remove that's will do less instruction + + Put TvN<-:Tv because Tv not in pNetwork + REMOVE this correction bcs TvN adimensional so usefull + */ + pNetwork->Fout_th = (HALF*Gl) * mathsbox->err_func / (Cm*pNetwork->TvN); - if (config->Fout_th < ACS_DBL_TINY){ - config->Fout_th = ACS_DBL_TINY; + if (pNetwork->Fout_th < ACS_DBL_TINY){ + pNetwork->Fout_th += ACS_DBL_TINY; } - - //return config->Fout_th; + } -void RK2_midpoint_MF(REAL h, meanfield_t *meanfield, config_t *restrict config, - mathsbox_t *restrict mathsbox) { -/* need to input T_inv time scale where the 1/T will be done (and rounding) -on the user computer before send it to the DTCM. -*/ +void RK2_midpoint_MF(REAL h, meanfield_t *meanfield, + ParamsFromNetwork_t *restrict pNetwork, + pFitPolynomial_t *restrict Pfit_exc, + pFitPolynomial_t *restrict Pfit_inh, + mathsbox_t *restrict mathsbox) { + + /* Propose for now a=0 + * + */ + REAL lastVe = meanfield->Ve; + REAL lastVi = meanfield->Vi; + REAL lastW = meanfield->w; + + REAL tauw = meanfield->tauw; REAL T_inv = meanfield->Timescale_inv; - //TF(lastVe,1.,meanfield, config, mathsbox); - REAL lastTF = ONE; //config->Fout_th; - - //configVe stand for TF1 i.e TF for exitatory pop. SO configVi is for TF2 - //In fact no configVe and configVi just config, all in the same file. - - - /*meanfield->Ve += lastVe\ - + REAL_HALF(TF(lastVe,1,meanfield, config, mathsbox) - lastVe)\ - *(REAL_CONST(2.0)-h)*h; - */ - - meanfield->Ve += lastVe + (REAL_HALF(lastTF - lastVe) * (REAL_CONST(2.0)-h) * h); - meanfield->Ve = meanfield->Ve * T_inv; -} - + REAL b = meanfield->b; + + + TF(lastVe, lastVi, lastW, pNetwork, Pfit_exc, mathsbox); + REAL lastTF_exc = pNetwork->Fout_th; + + + TF(lastVe, lastVi, lastW, pNetwork, Pfit_inh, mathsbox); + REAL lastTF_inh = pNetwork->Fout_th; + +/****************************************************** + * EULER Explicite method + * It's very instable if for now h<0.2 for 20ms + * + * NEED to give also the error of the method here : + * 0.5*h^2*u''(t_n) + o(h^2) + *******************************************************/ + + /* + + REAL k1_exc = (lastTF_exc - lastVe)*T_inv; + meanfield->Ve += h * k1_exc ; + + REAL k1_inh = (lastTF_inh - lastVi)*T_inv; + meanfield->Vi += h * k1_inh ; + + REAL k1_W = -lastW/tauw + meanfield->b * lastVe; + meanfield->w += h * k1_W; + + */ + +/*********************************** + * RUNGE-KUTTA 2nd order Midpoint * + ***********************************/ + + REAL k1_exc = (lastTF_exc - lastVe)*T_inv; + REAL alpha_exc = lastVe + h*k1_exc; + REAL k2_exc = (lastTF_exc - alpha_exc )*T_inv; + + meanfield->Ve += REAL_HALF(h*(k1_exc + k2_exc)); + + REAL k1_inh = (lastTF_inh - lastVi)*T_inv; + REAL alpha_inh = lastVi + h*k1_inh; + REAL k2_inh = (lastTF_inh - alpha_inh)*T_inv; + + meanfield->Vi += REAL_HALF(h*(k1_inh + k2_inh)); + + REAL k1_W = -lastW/tauw + b * lastVe; + REAL alpha_w = lastW + h*k1_W; + REAL k2_W = -alpha_w/tauw + b * lastVe; + + meanfield->w += REAL_HALF(h*(k1_W+k2_W)); -/*############################################################################## -end of reuse -################################################################################# -*/ -/*! - * \brief Midpoint is best balance between speed and accuracy so far. - * \details From ODE solver comparison work, paper shows that Trapezoid version - * gives better accuracy at small speed cost - * \param[in] h: threshold - * \param[in,out] neuron: The model being updated - * \param[in] input_this_timestep: the input - */ -/*static inline void rk2_kernel_midpoint( - REAL h, neuron_t *neuron, REAL input_this_timestep) { - // to match Mathematica names - REAL lastV1 = neuron->V; - REAL lastU1 = neuron->U; - REAL a = neuron->A; - REAL b = neuron->B; - - REAL pre_alph = REAL_CONST(140.0) + input_this_timestep - lastU1; - REAL alpha = pre_alph - + (REAL_CONST(5.0) + MAGIC_MULTIPLIER * lastV1) * lastV1; - REAL eta = lastV1 + REAL_HALF(h * alpha); - - // could be represented as a long fract? - REAL beta = REAL_HALF(h * (b * lastV1 - lastU1) * a); - - neuron->V += h * (pre_alph - beta - + (REAL_CONST(5.0) + MAGIC_MULTIPLIER * eta) * eta); - - neuron->U += a * h * (-lastU1 - beta + b * eta); } -*/ - void meanfield_model_set_global_neuron_params( const global_neuron_params_t *params) { @@ -376,12 +393,16 @@ void meanfield_model_set_global_neuron_params( and maybe is there some contamanation from the neightbourest neighbour MF! */ state_t meanfield_model_state_update( - meanfield_t *restrict meanfield, config_t *restrict config, mathsbox_t *restrict mathsbox){ + meanfield_t *restrict meanfield, + ParamsFromNetwork_t *restrict pNetwork, + pFitPolynomial_t *restrict Pfit_exc, + pFitPolynomial_t *restrict Pfit_inh, + mathsbox_t *restrict mathsbox){ /* uint16_t num_excitatory_inputs, const input_t *exc_input, uint16_t num_inhibitory_inputs, const input_t *inh_input, input_t external_bias, meanfield_t *restrict meanfield, - config_t *restrict config) { + ParamsFromNetwork_t *restrict pNetwork) { REAL total_exc = 0; REAL total_inh = 0; @@ -397,7 +418,12 @@ state_t meanfield_model_state_update( */ // the best AR update so far - RK2_midpoint_MF(meanfield->this_h, meanfield, config, mathsbox); + RK2_midpoint_MF(meanfield->this_h, + meanfield, + pNetwork, + Pfit_exc, + Pfit_inh, + mathsbox); meanfield->this_h = global_params->machine_timestep_ms; return meanfield->Ve; @@ -419,17 +445,27 @@ void neuron_model_has_spiked(meanfield_t *restrict meanfield) { } //change name neuron -> meanfield and membrane -> rate -state_t meanfield_model_get_firing_rate(const meanfield_t *meanfield) { +state_t meanfield_model_get_firing_rate_Ve(const meanfield_t *meanfield) { return meanfield->Ve; } +state_t meanfield_model_get_firing_rate_Vi(const meanfield_t *meanfield) { + return meanfield->Vi; +} + +state_t meanfield_model_get_adaptation_W(const meanfield_t *meanfield){ + return meanfield->w; +} + + void meanfield_model_print_state_variables(const meanfield_t *meanfield) { log_debug("Ve = %11.4k ", meanfield->Ve); - //log_debug("U = %11.4k ", meanfield->Vi); + log_debug("Vi = %11.4k ", meanfield->Vi); + log_debug("W = %11.4k ", meanfield->w); } void meanfield_model_print_parameters(const meanfield_t *meanfield) { - log_debug("Ve = %11.4k ", meanfield->Ve); + //log_debug("Ve = %11.4k ", meanfield->Ve); //log_debug("Vi = %11.4k ", meanfield->Vi); //log_debug("B = %11.4k ", neuron->B); //log_debug("C = %11.4k ", neuron->C); diff --git a/neural_modelling/src/meanfield/models/meanfield_model_impl.h b/neural_modelling/src/meanfield/models/meanfield_model_impl.h index 7baa3338fc7..ed057657fef 100644 --- a/neural_modelling/src/meanfield/models/meanfield_model_impl.h +++ b/neural_modelling/src/meanfield/models/meanfield_model_impl.h @@ -21,6 +21,7 @@ #define _MEANFIELD_MODEL_IMPL_H_ #include "../../meanfield/models/meanfield_model.h" +//#include typedef struct meanfield_t { // TODO: Parameters - make sure these match with the Python code, @@ -32,17 +33,15 @@ typedef struct meanfield_t { REAL b; REAL tauw; REAL Trefrac; - REAL Vthre; REAL Vreset; REAL delta_v; REAL ampnoise; REAL Timescale_inv; - REAL Ve; // will be used as a vector !!! OR Ve and Vi - //REAL Vi; - - //vector V = {Ve, Vi}; - + REAL Ve; + REAL Vi; + REAL w; + REAL this_h; diff --git a/neural_modelling/src/meanfield/models/params_from_network.h b/neural_modelling/src/meanfield/models/params_from_network.h new file mode 100644 index 00000000000..ee5846a2b1f --- /dev/null +++ b/neural_modelling/src/meanfield/models/params_from_network.h @@ -0,0 +1,56 @@ +#ifndef _PARAMS_FROM_NETWORK_H_ +#define _PARAMS_FROM_NETWORK_H_ + +#include "../../meanfield/models/meanfield_model.h" + +typedef struct ParamsFromNetwork_t { + // nominally 'fixed' parameters + REAL pconnec; + REAL Qe; + REAL Qi; + REAL Te; + REAL Ti; + REAL Ee; + REAL Ei; + REAL Ntot; + REAL gei; + REAL ext_drive; + REAL afferent_exc_fraction; + + REAL Gl; + REAL Cm; + REAL El; + + // Variable-state parameters + //REAL fe; + //REAL fi; + + REAL muV; + REAL muV0; + + REAL DmuV0; + + REAL sV; + REAL sV0; + REAL DsV0; + + REAL muGn; + + REAL TvN; + REAL TvN0; + REAL DTvN0; + + REAL Vthre; + + REAL Fout_th; +} ParamsFromNetwork_t; + +/* +typedef struct global_toolbox_params_t { + REAL this_h; + REAL this_time; +} global_toolbox_params_t; +*/ + + +#endif \ No newline at end of file diff --git a/spynnaker/pyNN/models/neuron/abstract_pynn_meanfield_model_standard.py b/spynnaker/pyNN/models/neuron/abstract_pynn_meanfield_model_standard.py index 9790ab5e479..c10e41de32e 100644 --- a/spynnaker/pyNN/models/neuron/abstract_pynn_meanfield_model_standard.py +++ b/spynnaker/pyNN/models/neuron/abstract_pynn_meanfield_model_standard.py @@ -32,7 +32,8 @@ class AbstractPyNNMeanfieldModelStandard(AbstractPyNNNeuronModel): default_population_parameters = _population_parameters def __init__( - self, model_name, binary, neuron_model, config, + self, model_name, binary, neuron_model, + params_from_network, p_fit_polynomial_exc, p_fit_polynomial_inh, mathsbox, input_type, synapse_type, threshold_type, additional_input_type=None): """ @@ -49,7 +50,9 @@ def __init__( :type additional_input_type: AbstractAdditionalInput or None """ super().__init__(MeanfieldImplStandard( - model_name, binary, neuron_model, config, mathsbox, input_type, + model_name, binary, neuron_model, + params_from_network, p_fit_polynomial_exc, p_fit_polynomial_inh, + mathsbox, input_type, synapse_type, threshold_type, additional_input_type)) @overrides(AbstractPyNNNeuronModel.create_vertex, diff --git a/spynnaker/pyNN/models/neuron/builds/meanfield_base.py b/spynnaker/pyNN/models/neuron/builds/meanfield_base.py index 6c8e2c82055..c5e69113336 100644 --- a/spynnaker/pyNN/models/neuron/builds/meanfield_base.py +++ b/spynnaker/pyNN/models/neuron/builds/meanfield_base.py @@ -14,8 +14,10 @@ # along with this program. If not, see . from spynnaker.pyNN.models.neuron.input_types import InputTypeConductance -from spynnaker.pyNN.models.neuron.neuron_models import MeanfieldModelEitn -from spynnaker.pyNN.models.neuron.neuron_models import Config +from spynnaker.pyNN.models.neuron.neuron_models import MeanfieldOfAdexNetwork +from spynnaker.pyNN.models.neuron.neuron_models import ParamsFromNetwork +from spynnaker.pyNN.models.neuron.neuron_models import pFitPolynomialExc +from spynnaker.pyNN.models.neuron.neuron_models import pFitPolynomialInh from spynnaker.pyNN.models.neuron.neuron_models import Mathsbox from spynnaker.pyNN.models.neuron.synapse_types import SynapseTypeExponential from spynnaker.pyNN.models.neuron.threshold_types import ThresholdTypeStatic @@ -31,58 +33,25 @@ class MeanfieldBase(AbstractPyNNMeanfieldModelStandard): :param a: :math:`a` :type a: float, iterable(float), ~pyNN.random.RandomDistribution or (mapping) function - :param b: :math:`b` - :type b: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param c: :math:`c` - :type c: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param d: :math:`d` - :type d: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param i_offset: :math:`I_{offset}` - :type i_offset: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param u: :math:`u_{init} = \\delta V_{init}` - :type u: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param v: :math:`v_{init} = V_{init}` - :type v: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param tau_syn_E: :math:`\\tau^{syn}_e` - :type tau_syn_E: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param tau_syn_I: :math:`\\tau^{syn}_i` - :type tau_syn_I: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param e_rev_E: :math:`E^{rev}_e` - :type e_rev_E: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param e_rev_I: :math:`E^{rev}_i` - :type e_rev_I: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param isyn_exc: :math:`I^{syn}_e` - :type isyn_exc: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function - :param isyn_inh: :math:`I^{syn}_i` - :type isyn_inh: float, iterable(float), ~pyNN.random.RandomDistribution - or (mapping) function """ # noinspection PyPep8Naming - @default_initial_values({"Ve", "muV", "sV", "muGn", "TvN", "Vthre", - "Fout_th", "err_func", "isyn_exc", "isyn_inh"}) + @default_initial_values({"Ve", "Vi", "w", "Fout_th", + "muV", "sV", "muGn", + "TvN", "Vthre", + "err_func", "isyn_exc", "isyn_inh"}) def __init__(self, - nbr=1, - a=0, - b=0, - tauw=1., + a=4., + b=20., + tauw=1.0, Trefrac=5.0, Vreset=-65., delta_v=-0.5, ampnoise=0.0, - Timescale_inv=0.5, - Ve=0., + Timescale_inv=200, + Ve=9., + Vi=23., + w=0.25, pconnec=0.05, q_exc=1.5, @@ -100,18 +69,6 @@ def __init__(self, Cm=200., El=-70., - p0=-0.0515518, - p1=0.00455197, - p2=-0.00760625, - p3=0.00094851, - p4=0.001, - p5=-0.0009863, - p6=-0.0026474, - p7=-0.0135417, - p8=0.0028742, - p9=0.0029213, - p10=-0.014084, - muV=0., muV0=-0.06, DmuV0=0.01, @@ -129,6 +86,31 @@ def __init__(self, Vthre=-50., Fout_th=0., + p0_exc=-0.0515518, + p1_exc=0.00455197, + p2_exc=-0.00760625, + p3_exc=0.00094851, + p4_exc=0.001, + p5_exc=-0.0009863, + p6_exc=-0.0026474, + p7_exc=-0.0135417, + p8_exc=0.0028742, + p9_exc=0.0029213, + p10_exc=-0.014084, + + p0_inh=-0.0496832, + p1_inh=0.00412289, + p2_inh=-0.0054849, + p3_inh=-0.0013451, + p4_inh=0.001, + p5_inh=-0.0010459, + p6_inh=0.00306102, + p7_inh=-0.0084485, + p8_inh=-0.0025717, + p9_inh=0.00179862, + p10_inh=-0.013830, + + tau_syn_E=5.0, tau_syn_I=5.0, e_rev_E=0.0, @@ -137,25 +119,33 @@ def __init__(self, isyn_exc=0.0, isyn_inh=0.0, - sample=100, + sample=1000, err_func=0.): # pylint: disable=too-many-arguments, too-many-locals - neuron_model = MeanfieldModelEitn(nbr, a, b, tauw, Trefrac, - Vreset, delta_v, ampnoise, - Timescale_inv, Ve) - config = Config(pconnec, q_exc, q_inh, - Tsyn_exc, Tsyn_inh, - Erev_exc, Erev_inh, - Ntot, gei, ext_drive, - afferent_exc_fraction, - Gl, Cm, El, - p0, p1, p2, p3, p4, p5, - p6, p7, p8, p9, p10, - muV, muV0,DmuV0, - sV, sV0, DsV0, - muGn, - TvN, TvN0, DTvN0, - Vthre, Fout_th) + #muVV = ((muGe*Erev_exc + muGi*Erev_inh + Gl*El - Ve*tauw*(b) + a*El) /muG)/ (1+a/muG) + #w = Ve * b * tauw + a * (El-muV0) + neuron_model = MeanfieldOfAdexNetwork(a, b, tauw, Trefrac, + Vreset, delta_v, ampnoise, + Timescale_inv, Ve, Vi, w) + params_from_network = ParamsFromNetwork(pconnec, q_exc, q_inh, + Tsyn_exc, Tsyn_inh, + Erev_exc, Erev_inh, + Ntot, gei, ext_drive, + afferent_exc_fraction, + Gl, Cm, El, + muV, muV0, DmuV0, + sV, sV0, DsV0, + muGn, + TvN, TvN0, DTvN0, + Vthre, Fout_th) + p_fit_polynomial_exc = pFitPolynomialExc(p0_exc, p1_exc, p2_exc, + p3_exc, p4_exc, p5_exc, + p6_exc, p7_exc, p8_exc, + p9_exc, p10_exc) + p_fit_polynomial_inh = pFitPolynomialInh(p0_inh, p1_inh, p2_inh, + p3_inh, p4_inh, p5_inh, + p6_inh, p7_inh, p8_inh, + p9_inh, p10_inh) mathsbox = Mathsbox(sample, err_func) synapse_type = SynapseTypeExponential( tau_syn_E, tau_syn_I, isyn_exc, isyn_inh) @@ -165,6 +155,11 @@ def __init__(self, super().__init__( model_name="meanfield_model_cond", binary="meanfield_model_cond.aplx", - neuron_model=neuron_model, config=config, mathsbox=mathsbox, - input_type=input_type, synapse_type=synapse_type, + neuron_model=neuron_model, + params_from_network=params_from_network, + p_fit_polynomial_exc = p_fit_polynomial_exc, + p_fit_polynomial_inh = p_fit_polynomial_inh, + mathsbox=mathsbox, + input_type=input_type, + synapse_type=synapse_type, threshold_type=threshold_type) diff --git a/spynnaker/pyNN/models/neuron/implementations/meanfield_impl_standard.py b/spynnaker/pyNN/models/neuron/implementations/meanfield_impl_standard.py index ac2008f81ae..eb7ac32c55c 100644 --- a/spynnaker/pyNN/models/neuron/implementations/meanfield_impl_standard.py +++ b/spynnaker/pyNN/models/neuron/implementations/meanfield_impl_standard.py @@ -37,7 +37,9 @@ class MeanfieldImplStandard(AbstractNeuronImpl): "__model_name", "__binary", "__neuron_model", - "__config", + "__params_from_network", + "__p_fit_polynomial_exc", + "__p_fit_polynomial_inh", "__mathsbox", "__input_type", "__synapse_type", @@ -47,47 +49,30 @@ class MeanfieldImplStandard(AbstractNeuronImpl): "__n_steps_per_timestep" ] - # _RECORDABLES = ["Ve", "gsyn_exc", "gsyn_inh"] - _RECORDABLES = ["Ve", "muV", "sV", "muGn", "TvN", "Vthre", - "Fout_th", "err_func", "gsyn_exc", "gsyn_inh"] + _RECORDABLES = ["Ve", "Vi", "w", "gsyn_exc", "gsyn_inh"] - # _RECORDABLE_DATA_TYPES = { - # "Ve": DataType.S1615, - # "gsyn_exc": DataType.S1615, - # "gsyn_inh": DataType.S1615 - # } _RECORDABLE_DATA_TYPES = { "Ve": DataType.S1615, - "muV": DataType.S1615, - "sV": DataType.S1615, - "muGn": DataType.S1615, - "TvN": DataType.S1615, - "Vthre": DataType.S1615, - "Fout_th": DataType.S1615, - "err_func": DataType.S1615, + "Vi": DataType.S1615, + "w": DataType.S1615, "gsyn_exc": DataType.S1615, "gsyn_inh": DataType.S1615 } - # _RECORDABLE_UNITS = { - # 'Ve': 'mV', - # 'gsyn_exc': "uS", - # 'gsyn_inh': "uS" - # } _RECORDABLE_UNITS = { - 'Ve': 'mV', - 'muV': "uS", - 'sV': "uS", - 'TvN': 'mV', - 'Vthre': "uS", - 'Fout_th': "uS", - 'err_func': 'mV', + 'Ve': 'Hz', + 'Vi': 'Hz', + 'w': "pA", 'gsyn_exc': "uS", 'gsyn_inh': "uS" } def __init__( - self, model_name, binary, neuron_model, config, mathsbox, + self, model_name, binary, neuron_model, + params_from_network, + p_fit_polynomial_exc, + p_fit_polynomial_inh, + mathsbox, input_type, synapse_type, threshold_type, additional_input_type=None): """ @@ -103,7 +88,9 @@ def __init__( self.__model_name = model_name self.__binary = binary self.__neuron_model = neuron_model - self.__config = config + self.__params_from_network = params_from_network + self.__p_fit_polynomial_exc = p_fit_polynomial_exc + self.__p_fit_polynomial_inh = p_fit_polynomial_inh self.__mathsbox = mathsbox self.__input_type = input_type self.__synapse_type = synapse_type @@ -112,8 +99,14 @@ def __init__( self.__n_steps_per_timestep = _DEFAULT_N_STEPS_PER_TIMESTEP self.__components = [ - self.__neuron_model, self.__config, self.__mathsbox, - self.__input_type, self.__threshold_type, self.__synapse_type] + self.__neuron_model, + self.__params_from_network, + self.__p_fit_polynomial_exc, + self.__p_fit_polynomial_inh, + self.__mathsbox, + self.__input_type, + self.__threshold_type, + self.__synapse_type] if self.__additional_input_type is not None: self.__components.append(self.__additional_input_type) @@ -139,7 +132,9 @@ def binary_name(self): def get_n_cpu_cycles(self, n_neurons): total = self.__neuron_model.get_n_cpu_cycles(n_neurons) total += self.__synapse_type.get_n_cpu_cycles(n_neurons) - total += self.__config.get_n_cpu_cycles(n_neurons) + total += self.__params_from_network.get_n_cpu_cycles(n_neurons) + total += self.__p_fit_polynomial_exc.get_n_cpu_cycles(n_neurons) + total += self.__p_fit_polynomial_inh.get_n_cpu_cycles(n_neurons) total += self.__input_type.get_n_cpu_cycles(n_neurons) total += self.__mathsbox.get_n_cpu_cycles(n_neurons) total += self.__threshold_type.get_n_cpu_cycles(n_neurons) @@ -152,7 +147,9 @@ def get_dtcm_usage_in_bytes(self, n_neurons): total = _N_STEPS_PER_TIMESTEP_SIZE total += self.__neuron_model.get_dtcm_usage_in_bytes(n_neurons) total += self.__synapse_type.get_dtcm_usage_in_bytes(n_neurons) - total += self.__config.get_dtcm_usage_in_bytes(n_neurons) + total += self.__params_from_network.get_dtcm_usage_in_bytes(n_neurons) + total += self.__p_fit_polynomial_exc.get_dtcm_usage_in_bytes(n_neurons) + total += self.__p_fit_polynomial_inh.get_dtcm_usage_in_bytes(n_neurons) total += self.__input_type.get_dtcm_usage_in_bytes(n_neurons) total += self.__mathsbox.get_dtcm_usage_in_bytes(n_neurons) total += self.__threshold_type.get_dtcm_usage_in_bytes(n_neurons) @@ -166,7 +163,9 @@ def get_sdram_usage_in_bytes(self, n_neurons): total = _N_STEPS_PER_TIMESTEP_SIZE total += self.__neuron_model.get_sdram_usage_in_bytes(n_neurons) total += self.__synapse_type.get_sdram_usage_in_bytes(n_neurons) - total += self.__config.get_sdram_usage_in_bytes(n_neurons) + total += self.__params_from_network.get_sdram_usage_in_bytes(n_neurons) + total += self.__p_fit_polynomial_exc.get_sdram_usage_in_bytes(n_neurons) + total += self.__p_fit_polynomial_inh.get_sdram_usage_in_bytes(n_neurons) total += self.__input_type.get_sdram_usage_in_bytes(n_neurons) total += self.__mathsbox.get_sdram_usage_in_bytes(n_neurons) total += self.__threshold_type.get_sdram_usage_in_bytes(n_neurons) diff --git a/spynnaker/pyNN/models/neuron/neuron_models/P_fit_polynomial_exc.py b/spynnaker/pyNN/models/neuron/neuron_models/P_fit_polynomial_exc.py new file mode 100644 index 00000000000..1082dafcf21 --- /dev/null +++ b/spynnaker/pyNN/models/neuron/neuron_models/P_fit_polynomial_exc.py @@ -0,0 +1,214 @@ +# Copyright (c) 2017-2019 The University of Manchester +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +from spinn_utilities.overrides import overrides +from data_specification.enums import DataType +from spinn_front_end_common.utilities.constants import ( + MICRO_TO_MILLISECOND_CONVERSION) +from .abstract_neuron_model import AbstractNeuronModel +from .abstract_input_type import AbstractInputType +from spynnaker.pyNN.models.neuron.implementations import ( + AbstractStandardNeuronComponent) + +###--transfert function inputs from 'data_test/'+NRN1+'_'+NTWK+'_fit.npy' --### +P0 = "p0_exc" +P1 = "p1_exc" +P2 = "p2_exc" +P3 = "p3_exc" +P4 = "p4_exc" +P5 = "p5_exc" +P6 = "p6_exc" +P7 = "p7_exc" +P8 = "p8_exc" +P9 = "p9_exc" +P10 = "p10_exc" + +UNITS = { + P0 : "", + P1 : "", + P2 : "", + P3 : "", + P4 : "", + P5 : "", + P6 : "", + P7 : "", + P8 : "", + P9 : "", + P10 : "", +} + + +class pFitPolynomialExc(AbstractInputType): + """ Model of neuron due to ... + """ + __slots__ = [ + "__p0_exc", "__p1_exc", "__p2_exc", "__p3_exc", "__p4_exc", "__p5_exc", + "__p6_exc", "__p7_exc", "__p8_exc", "__p9_exc", "__p10_exc" + ] + + def __init__(self, + p0_exc, p1_exc, p2_exc, p3_exc, p4_exc, p5_exc, + p6_exc, p7_exc, p8_exc, p9_exc, p10_exc): + """ + :param a: :math:`a` + :type a: float, iterable(float), ~pyNN.random.RandomDistribution or + (mapping) function + + """ + super().__init__( + + [###--TF inputs--### + DataType.S031, #p0 + DataType.S031, #p1 + DataType.S031, #p2 + DataType.S031, #p3 + DataType.S031, #p4 + DataType.S031, #p5 + DataType.S031, #p6 + DataType.S031, #p7 + DataType.S031, #p8 + DataType.S031, #p9 + DataType.S031]) #p10 + + self.__p0_exc = p0_exc + self.__p1_exc = p1_exc + self.__p2_exc = p2_exc + self.__p3_exc = p3_exc + self.__p4_exc = p4_exc + self.__p5_exc = p5_exc + self.__p6_exc = p6_exc + self.__p7_exc = p7_exc + self.__p8_exc = p8_exc + self.__p9_exc = p9_exc + self.__p10_exc = p10_exc + + @overrides(AbstractStandardNeuronComponent.get_n_cpu_cycles) + def get_n_cpu_cycles(self, n_neurons): + # A bit of a guess + return 150 * n_neurons + + @overrides(AbstractStandardNeuronComponent.add_parameters) + def add_parameters(self, parameters): + ###--TF inputs--### + parameters[P0] = self.__p0_exc + parameters[P1] = self.__p1_exc + parameters[P2] = self.__p2_exc + parameters[P3] = self.__p3_exc + parameters[P4] = self.__p4_exc + parameters[P5] = self.__p5_exc + parameters[P6] = self.__p6_exc + parameters[P7] = self.__p7_exc + parameters[P8] = self.__p8_exc + parameters[P9] = self.__p9_exc + parameters[P10] = self.__p10_exc + + @overrides(AbstractStandardNeuronComponent.add_state_variables) + def add_state_variables(self, state_variables): + pass + @overrides(AbstractStandardNeuronComponent.get_units) + def get_units(self, variable): + return UNITS[variable] + + @overrides(AbstractStandardNeuronComponent.has_variable) + def has_variable(self, variable): + return variable in UNITS + + @overrides(AbstractNeuronModel.get_global_values) + def get_global_values(self, ts): + # pylint: disable=arguments-differ + pass + + @overrides(AbstractStandardNeuronComponent.get_values) + def get_values(self, parameters, state_variables, vertex_slice, ts): + """ + :param ts: machine time step + """ + # pylint: disable=arguments-differ + + # Add the rest of the data + return [parameters[P0],#TF input + parameters[P1], + parameters[P2], + parameters[P3], + parameters[P4], + parameters[P5], + parameters[P6], + parameters[P7], + parameters[P8], + parameters[P9], + parameters[P10] + ] + + @overrides(AbstractStandardNeuronComponent.update_values) + def update_values(self, values, parameters, state_variables): + + # Decode the values + (__p0_exc, __p1_exc, __p2_exc, __p3_exc, __p4_exc, + __p5_exc, __p6_exc, __p7_exc, __p8_exc, __p9_exc, __p10_exc) = values + + @overrides(AbstractInputType.get_global_weight_scale) + def get_global_weight_scale(self): + return 1024.0 + +################### +###--TF inputs--### +################### + + @property + def p0_exc(self): + return self.__p0_exc + + @property + def p1_exc(self): + return self._p1_exc + + @property + def p2_exc(self): + return self._p2_exc + + @property + def p3_exc(self): + return self._p3_exc + + @property + def p4_exc(self): + return self._p4_exc + + @property + def p5_exc(self): + return self._p5_exc + + @property + def p6_exc(self): + return self._p6_exc + + @property + def p6_exc(self): + return self._p6_exc + + @property + def p7_exc(self): + return self._p7_exc + + @property + def p8_exc(self): + return self._p8_exc + + @property + def p9_exc(self): + return self._p9_exc + + @property + def p10_exc(self): + return self._p10_exc diff --git a/spynnaker/pyNN/models/neuron/neuron_models/P_fit_polynomial_inh.py b/spynnaker/pyNN/models/neuron/neuron_models/P_fit_polynomial_inh.py new file mode 100644 index 00000000000..b831e2e4e33 --- /dev/null +++ b/spynnaker/pyNN/models/neuron/neuron_models/P_fit_polynomial_inh.py @@ -0,0 +1,214 @@ +# Copyright (c) 2017-2019 The University of Manchester +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +from spinn_utilities.overrides import overrides +from data_specification.enums import DataType +from spinn_front_end_common.utilities.constants import ( + MICRO_TO_MILLISECOND_CONVERSION) +from .abstract_neuron_model import AbstractNeuronModel +from .abstract_input_type import AbstractInputType +from spynnaker.pyNN.models.neuron.implementations import ( + AbstractStandardNeuronComponent) + +###--transfert function inputs from 'data_test/'+NRN1+'_'+NTWK+'_fit.npy' --### +P0 = "p0_inh" +P1 = "p1_inh" +P2 = "p2_inh" +P3 = "p3_inh" +P4 = "p4_inh" +P5 = "p5_inh" +P6 = "p6_inh" +P7 = "p7_inh" +P8 = "p8_inh" +P9 = "p9_inh" +P10 = "p10_inh" + +UNITS = { + P0 : "", + P1 : "", + P2 : "", + P3 : "", + P4 : "", + P5 : "", + P6 : "", + P7 : "", + P8 : "", + P9 : "", + P10 : "", +} + + +class pFitPolynomialInh(AbstractInputType): + """ Model of neuron due to ... + """ + __slots__ = [ + "__p0_inh", "__p1_inh", "__p2_inh", "__p3_inh", "__p4_inh", "__p5_inh", + "__p6_inh", "__p7_inh", "__p8_inh", "__p9_inh", "__p10_inh" + ] + + def __init__(self, + p0_inh, p1_inh, p2_inh, p3_inh, p4_inh, p5_inh, + p6_inh, p7_inh, p8_inh, p9_inh, p10_inh): + """ + :param a: :math:`a` + :type a: float, iterable(float), ~pyNN.random.RandomDistribution or + (mapping) function + + """ + super().__init__( + + [###--TF inputs--### + DataType.S031, #p0 + DataType.S031, #p1 + DataType.S031, #p2 + DataType.S031, #p3 + DataType.S031, #p4 + DataType.S031, #p5 + DataType.S031, #p6 + DataType.S031, #p7 + DataType.S031, #p8 + DataType.S031, #p9 + DataType.S031]) #p10 + + self.__p0_inh = p0_inh + self.__p1_inh = p1_inh + self.__p2_inh = p2_inh + self.__p3_inh = p3_inh + self.__p4_inh = p4_inh + self.__p5_inh = p5_inh + self.__p6_inh = p6_inh + self.__p7_inh = p7_inh + self.__p8_inh = p8_inh + self.__p9_inh = p9_inh + self.__p10_inh = p10_inh + + @overrides(AbstractStandardNeuronComponent.get_n_cpu_cycles) + def get_n_cpu_cycles(self, n_neurons): + # A bit of a guess + return 150 * n_neurons + + @overrides(AbstractStandardNeuronComponent.add_parameters) + def add_parameters(self, parameters): + ###--TF inputs--### + parameters[P0] = self.__p0_inh + parameters[P1] = self.__p1_inh + parameters[P2] = self.__p2_inh + parameters[P3] = self.__p3_inh + parameters[P4] = self.__p4_inh + parameters[P5] = self.__p5_inh + parameters[P6] = self.__p6_inh + parameters[P7] = self.__p7_inh + parameters[P8] = self.__p8_inh + parameters[P9] = self.__p9_inh + parameters[P10] = self.__p10_inh + + @overrides(AbstractStandardNeuronComponent.add_state_variables) + def add_state_variables(self, state_variables): + pass + @overrides(AbstractStandardNeuronComponent.get_units) + def get_units(self, variable): + return UNITS[variable] + + @overrides(AbstractStandardNeuronComponent.has_variable) + def has_variable(self, variable): + return variable in UNITS + + @overrides(AbstractNeuronModel.get_global_values) + def get_global_values(self, ts): + # pylint: disable=arguments-differ + pass + + @overrides(AbstractStandardNeuronComponent.get_values) + def get_values(self, parameters, state_variables, vertex_slice, ts): + """ + :param ts: machine time step + """ + # pylint: disable=arguments-differ + + # Add the rest of the data + return [parameters[P0],#TF input + parameters[P1], + parameters[P2], + parameters[P3], + parameters[P4], + parameters[P5], + parameters[P6], + parameters[P7], + parameters[P8], + parameters[P9], + parameters[P10] + ] + + @overrides(AbstractStandardNeuronComponent.update_values) + def update_values(self, values, parameters, state_variables): + + # Decode the values + (__p0_inh, __p1_inh, __p2_inh, __p3_inh, __p4_inh, + __p5_inh, __p6_inh, __p7_inh, __p8_inh, __p9_inh, __p10_inh) = values + + @overrides(AbstractInputType.get_global_weight_scale) + def get_global_weight_scale(self): + return 1024.0 + +################### +###--TF inputs--### +################### + + @property + def p0_inh(self): + return self.__p0_inh + + @property + def p1_inh(self): + return self._p1_inh + + @property + def p2_inh(self): + return self._p2_inh + + @property + def p3_inh(self): + return self._p3_inh + + @property + def p4_inh(self): + return self._p4_inh + + @property + def p5_inh(self): + return self._p5_inh + + @property + def p6_inh(self): + return self._p6_inh + + @property + def p6_inh(self): + return self._p6_inh + + @property + def p7_inh(self): + return self._p7_inh + + @property + def p8_inh(self): + return self._p8_inh + + @property + def p9_inh(self): + return self._p9_inh + + @property + def p10_inh(self): + return self._p10_inh diff --git a/spynnaker/pyNN/models/neuron/neuron_models/__init__.py b/spynnaker/pyNN/models/neuron/neuron_models/__init__.py index 4bd31557a38..92dbf1199e8 100644 --- a/spynnaker/pyNN/models/neuron/neuron_models/__init__.py +++ b/spynnaker/pyNN/models/neuron/neuron_models/__init__.py @@ -15,12 +15,16 @@ from .abstract_neuron_model import AbstractNeuronModel from .neuron_model_izh import NeuronModelIzh -from .meanfield_model_eitn import MeanfieldModelEitn -from .config import Config +from .meanfield_of_adex_network import MeanfieldOfAdexNetwork +from .params_from_network import ParamsFromNetwork +from .P_fit_polynomial_exc import pFitPolynomialExc +from .P_fit_polynomial_inh import pFitPolynomialInh from .mathsbox import Mathsbox from .neuron_model_leaky_integrate_and_fire import ( NeuronModelLeakyIntegrateAndFire) __all__ = ["AbstractNeuronModel", "NeuronModelIzh", "NeuronModelLeakyIntegrateAndFire", - "MeanfieldModelEitn", "Config", "Mathsbox"] + "MeanfieldOfAdexNetwork", + "pFitPolynomialExc", "pFitPolynomialInh", + "ParamsFromNetwork", "Mathsbox"] diff --git a/spynnaker/pyNN/models/neuron/neuron_models/meanfield_model_eitn.py b/spynnaker/pyNN/models/neuron/neuron_models/meanfield_of_adex_network.py similarity index 76% rename from spynnaker/pyNN/models/neuron/neuron_models/meanfield_model_eitn.py rename to spynnaker/pyNN/models/neuron/neuron_models/meanfield_of_adex_network.py index 50c8f5d55fd..c192b55e8b4 100644 --- a/spynnaker/pyNN/models/neuron/neuron_models/meanfield_model_eitn.py +++ b/spynnaker/pyNN/models/neuron/neuron_models/meanfield_of_adex_network.py @@ -21,7 +21,7 @@ AbstractStandardNeuronComponent) ###--Meanfield Params--### -NBR = "nbr" +#NBR = "nbr" A = "a" B = "b" TAUW = "tauw" @@ -31,10 +31,12 @@ AMPNOISE = "ampnoise" TIMESCALE_INV = "Timescale_inv" VE = "Ve" +VI = "Vi" +W = "w" UNITS = { ###--Meanfield--### - NBR: "", + #NBR: "", A: "nS", B: "nS", TAUW: "ms", @@ -44,49 +46,31 @@ AMPNOISE: "Hz", TIMESCALE_INV: "Hz", VE: "Hz", + VI: "Hz", + W: "pA", } -class MeanfieldModelEitn(AbstractNeuronModel): - """ Model of meanfield due to Destehexe et al +class MeanfieldOfAdexNetwork(AbstractNeuronModel): + """ Model of meanfield due to A.Destehexe et al """ __slots__ = [ - "_nbr", "_a", "_b", "_tauw", "_Trefrac", "_Vreset", "_delta_v", - "_ampnoise", "_Timescale_inv", "_Ve_init" + "_a", "_b", "_tauw", "_Trefrac", "_Vreset", "_delta_v", + "_ampnoise", "_Timescale_inv", "_Ve_init", "_Vi_init", "_w_init" ] - def __init__(self, nbr, a, b, tauw, + def __init__(self, a, b, tauw, Trefrac, Vreset, delta_v, - ampnoise, Timescale_inv, Ve_init): + ampnoise, Timescale_inv, + Ve_init, Vi_init, w_init): """ :param a: :math:`a` :type a: float, iterable(float), ~pyNN.random.RandomDistribution or (mapping) function - :param b: :math:`b` - :type b: float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param c: :math:`c` - :type c: float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param d: :math:`d` - :type d: float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param v_init: :math:`v_{init}` - :type v_init: - float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param u_init: :math:`u_{init}` - :type u_init: - float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param i_offset: :math:`I_{offset}` - :type i_offset: - float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function + """ super().__init__( - [DataType.UINT32, #nbr - DataType.S1615, #a + [DataType.S1615, #a DataType.UINT32, #nbr DataType.S1615, #b DataType.S1615, #tauw DataType.S1615, #Trefrac @@ -95,9 +79,10 @@ def __init__(self, nbr, a, b, tauw, DataType.S1615, #ampnoise DataType.S1615, #Timescale_inv DataType.S1615, #Ve + DataType.S1615, #Vi + DataType.S1615, #W DataType.S1615], # this_h (= machine_time_step) [DataType.S1615]) # machine_time_step - self._nbr = nbr self._a = a self._b = b self._tauw = tauw @@ -107,6 +92,8 @@ def __init__(self, nbr, a, b, tauw, self._ampnoise = ampnoise self._Timescale_inv = Timescale_inv self._Ve_init = Ve_init + self._Vi_init = Vi_init + self._w_init = w_init @overrides(AbstractStandardNeuronComponent.get_n_cpu_cycles) def get_n_cpu_cycles(self, n_neurons): @@ -116,7 +103,7 @@ def get_n_cpu_cycles(self, n_neurons): @overrides(AbstractStandardNeuronComponent.add_parameters) def add_parameters(self, parameters): ###--neuron--### - parameters[NBR] = self._nbr + #parameters[NBR] = self._nbr parameters[A] = self._a parameters[B] = self._b parameters[TAUW] = self._tauw @@ -129,8 +116,9 @@ def add_parameters(self, parameters): @overrides(AbstractStandardNeuronComponent.add_state_variables) def add_state_variables(self, state_variables): state_variables[VE] = self._Ve_init - #state_variables[U] = self.__u_init - + state_variables[VI] = self._Vi_init + state_variables[W] = self._w_init + @overrides(AbstractStandardNeuronComponent.get_units) def get_units(self, variable): return UNITS[variable] @@ -153,11 +141,13 @@ def get_values(self, parameters, state_variables, vertex_slice, ts): # Add the rest of the data return [ - parameters[NBR],parameters[A],parameters[B],parameters[TAUW], + parameters[A],parameters[B],parameters[TAUW], parameters[TREFRAC], parameters[VRESET],parameters[DELTA_V],parameters[AMPNOISE], parameters[TIMESCALE_INV], state_variables[VE], + state_variables[VI], + state_variables[W], float(ts) / MICRO_TO_MILLISECOND_CONVERSION ] @@ -165,21 +155,24 @@ def get_values(self, parameters, state_variables, vertex_slice, ts): def update_values(self, values, parameters, state_variables): # Decode the values - (_nbr, _a, _b, _tauw, + #(#_nbr, + (_a, _b, _tauw, _Trefrac, _Vreset, _delta_v, - _ampnoise, _Timescale_inv, Ve, _this_h) = values + _ampnoise, _Timescale_inv, Ve, Vi, w, _this_h) = values # Copy the changed data only state_variables[VE] = Ve + state_variables[VI] = Vi + state_variables[W] = w #state_variables[U] = u ################ ###--Meanfield--### ################ - @property - def nbr(self): - return self._nbr + # @property + # def nbr(self): + # return self._nbr @property @@ -222,3 +215,18 @@ def Ve_init(self): """ return self._Ve_init + @property + def Vi_init(self): + """ Settable model parameter: :math:`V_{i}` + + :rtype: float + """ + return self._Vi_init + + @property + def w_init(self): + """ Settable model parameter: :math:`w` + + :rtype: float + """ + return self._w_init diff --git a/spynnaker/pyNN/models/neuron/neuron_models/config.py b/spynnaker/pyNN/models/neuron/neuron_models/params_from_network.py similarity index 76% rename from spynnaker/pyNN/models/neuron/neuron_models/config.py rename to spynnaker/pyNN/models/neuron/neuron_models/params_from_network.py index 800e5616a14..e416e7d987d 100644 --- a/spynnaker/pyNN/models/neuron/neuron_models/config.py +++ b/spynnaker/pyNN/models/neuron/neuron_models/params_from_network.py @@ -38,19 +38,6 @@ CM = "Cm" EL = "El" -###--transfert function inputs from 'data_test/'+NRN1+'_'+NTWK+'_fit.npy' --### -P0 = "p0" -P1 = "p1" -P2 = "p2" -P3 = "p3" -P4 = "p4" -P5 = "p5" -P6 = "p6" -P7 = "p7" -P8 = "p8" -P9 = "p9" -P10 = "p10" - MUV = "muV" MUV0 = "muV0" DMUV0 = "DmuV0" @@ -85,18 +72,6 @@ GL: "Gl", CM: "pF", EL: "mV", - #TF inputs - P0 : "", - P1 : "", - P2 : "", - P3 : "", - P4 : "", - P5 : "", - P6 : "", - P7 : "", - P8 : "", - P9 : "", - P10 : "", VTHRE: "mV", MUV : "", MUV0 : "", @@ -113,7 +88,7 @@ } -class Config(AbstractInputType): +class ParamsFromNetwork(AbstractInputType): """ Model of neuron due to Eugene M. Izhikevich et al """ __slots__ = [ @@ -121,8 +96,6 @@ class Config(AbstractInputType): "_Erev_exc", "_Erev_inh", "_Ntot", "_gei", "_ext_drive", "_afferent_exc_fraction", "_Gl", "_Cm", "_El", - "_p0", "_p1", "_p2", "_p3", "_p4", "_p5", - "_p6", "_p7", "_p8", "_p9", "_p10", "_Vthre", "_muV", "_muV0", "_DmuV0", "_sV", "_sV0", "_DsV0", "_muGn", "_TvN", "_TvN0", "_DTvN0", "_Vthre", "_Fout_th", ] @@ -134,8 +107,6 @@ def __init__(self, pconnec, Ntot, gei, ext_drive, afferent_exc_fraction, Gl, Cm, El, - p0, p1, p2, p3, p4, p5, - p6, p7, p8, p9, p10, muV, muV0,DmuV0, sV, sV0, DsV0, muGn, @@ -145,27 +116,7 @@ def __init__(self, pconnec, :param a: :math:`a` :type a: float, iterable(float), ~pyNN.random.RandomDistribution or (mapping) function - :param b: :math:`b` - :type b: float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param c: :math:`c` - :type c: float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param d: :math:`d` - :type d: float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param v_init: :math:`v_{init}` - :type v_init: - float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param u_init: :math:`u_{init}` - :type u_init: - float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function - :param i_offset: :math:`I_{offset}` - :type i_offset: - float, iterable(float), ~pyNN.random.RandomDistribution or - (mapping) function + """ super().__init__( @@ -184,18 +135,6 @@ def __init__(self, pconnec, DataType.S1615, #Gm DataType.S1615, #Cl DataType.S1615, #El - ###--TF inputs--### - DataType.S031, #p0 - DataType.S031, #p1 - DataType.S031, #p2 - DataType.S031, #p3 - DataType.S031, #p4 - DataType.S031, #p5 - DataType.S031, #p6 - DataType.S031, #p7 - DataType.S031, #p8 - DataType.S031, #p9 - DataType.S031, #p10 DataType.S1615, # muV DataType.S1615, # muV0 DataType.S1615, # DmuV0 @@ -223,17 +162,6 @@ def __init__(self, pconnec, self._Gl = Gl self._Cm = Cm self._El = El - self._p0 = p0 - self._p1 = p1 - self._p2 = p2 - self._p3 = p3 - self._p4 = p4 - self._p5 = p5 - self._p6 = p6 - self._p7 = p7 - self._p8 = p8 - self._p9 = p9 - self._p10 = p10 self._muV = muV self._muV0 = muV0 self._DmuV0 = DmuV0 @@ -269,18 +197,7 @@ def add_parameters(self, parameters): parameters[GL] = self._Gl parameters[CM] = self._Cm parameters[EL] = self._El - ###--TF inputs--### - parameters[P0] = self._p0 - parameters[P1] = self._p1 - parameters[P2] = self._p2 - parameters[P3] = self._p3 - parameters[P4] = self._p4 - parameters[P5] = self._p5 - parameters[P6] = self._p6 - parameters[P7] = self._p7 - parameters[P8] = self._p8 - parameters[P9] = self._p9 - parameters[P10] = self._p10 + #parameters[MUV] = self._muV parameters[MUV0] = self._muV0 parameters[DMUV0] = self._DmuV0 parameters[SV0] = self._sV0 @@ -332,17 +249,6 @@ def get_values(self, parameters, state_variables, vertex_slice, ts): parameters[GL], parameters[CM], parameters[EL], - parameters[P0],#TF input - parameters[P1], - parameters[P2], - parameters[P3], - parameters[P4], - parameters[P5], - parameters[P6], - parameters[P7], - parameters[P8], - parameters[P9], - parameters[P10], state_variables[MUV], parameters[MUV0], parameters[DMUV0], @@ -365,8 +271,6 @@ def update_values(self, values, parameters, state_variables): _Erev_exc, _Erev_inh, _Ntot, _gei, _ext_drive, _afferent_exc_fraction, _Gl, _Cm, _El, - _p0, _p1, _p2, _p3, _p4, - _p5, _p6, _p7, _p8, _p9, _p10, muV, _muV0, _DmuV0, sV, _sV0, _DsV0, muGn, @@ -447,59 +351,6 @@ def Cm(self): @property def El(self): return self._El - -################### -###--TF inputs--### -################### - - @property - def p0(self): - return self._p0 - - @property - def p1(self): - return self._p1 - - @property - def p2(self): - return self._p2 - - @property - def p3(self): - return self._p3 - - @property - def p4(self): - return self._p4 - - @property - def p5(self): - return self._p5 - - @property - def p6(self): - return self._p6 - - @property - def p6(self): - return self._p6 - - @property - def p7(self): - return self._p7 - - @property - def p8(self): - return self._p8 - - @property - def p9(self): - return self._p9 - - @property - def p10(self): - return self._p10 - @property def muV(self): diff --git a/spynnaker/pyNN/models/recorder.py b/spynnaker/pyNN/models/recorder.py index 508322884dd..d50ebd97822 100644 --- a/spynnaker/pyNN/models/recorder.py +++ b/spynnaker/pyNN/models/recorder.py @@ -25,14 +25,16 @@ from spynnaker.pyNN.models.common import ( AbstractSpikeRecordable, AbstractNeuronRecordable, AbstractEventRecordable) from spynnaker.pyNN.utilities.constants import ( - SPIKES, MEMBRANE_POTENTIAL, GSYN_EXCIT, GSYN_INHIB, REWIRING) + SPIKES, FIRING_RATE_EXC, FIRING_RATE_INH, ADAPTATION, GSYN_EXCIT, GSYN_INHIB, REWIRING) from spynnaker.pyNN.exceptions import InvalidParameterType from spynnaker.pyNN.utilities.data_cache import DataCache logger = FormatAdapter(logging.getLogger(__name__)) _DEFAULT_UNITS = { SPIKES: "spikes", - MEMBRANE_POTENTIAL: "mV", + FIRING_RATE_EXC : 'Hz', + FIRING_RATE_INH : 'Hz', + ADAPTATION : 'pA',#MEMBRANE_POTENTIAL: "mV", GSYN_EXCIT: "uS", GSYN_INHIB: "uS", REWIRING: "ms"} @@ -62,9 +64,11 @@ def __init__(self, population, vertex): # file flags, allows separate files for the recorded variables self.__write_to_files_indicators = { 'spikes': None, + 'Ve' : None, + 'Vi' : None, + 'w' : None, 'gsyn_exc': None, - 'gsyn_inh': None, - 'v': None} + 'gsyn_inh': None} self._recording_start_time = get_simulator().t self._data_cache = {} diff --git a/spynnaker/pyNN/utilities/constants.py b/spynnaker/pyNN/utilities/constants.py index f84f631619c..60a9d22d1d1 100644 --- a/spynnaker/pyNN/utilities/constants.py +++ b/spynnaker/pyNN/utilities/constants.py @@ -62,6 +62,9 @@ # names for recording components SPIKES = 'spikes' +FIRING_RATE_EXC = 'Ve' +FIRING_RATE_INH = 'Vi' +ADAPTATION = 'w' MEMBRANE_POTENTIAL = "v" GSYN_EXCIT = "gsyn_exc" GSYN_INHIB = "gsyn_inh" diff --git a/spynnaker8/extra_models/__init__.py b/spynnaker8/extra_models/__init__.py index b5bff8865a9..ad7b02682b8 100644 --- a/spynnaker8/extra_models/__init__.py +++ b/spynnaker8/extra_models/__init__.py @@ -36,6 +36,7 @@ # sPyNNaker 8 models 'IFCurDelta', 'IFCurrExpCa2Adaptive', 'IFCondExpStoc', 'Izhikevich_cond', 'IF_curr_dual_exp', 'IF_curr_exp_sEMD', + 'Meanfield', # sPyNNaker 8 plastic stuff 'WeightDependenceAdditiveTriplet',