/* See {nmsim_neuron_class.h} */ /* Last edited on 2019-01-06 00:16:40 by jstolfi */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include nmsim_neuron_class_t* nmsim_neuron_class_new ( double V_B, double V_R, double c_B, double M_R, double M_mu, double G_R, double G_mu, double H_R, double H_mu, struct nmsim_firing_func_t *Phi ) { nmsim_neuron_class_t* pm = notnull(malloc(sizeof(nmsim_neuron_class_t)), "no mem"); (*pm) = (nmsim_neuron_class_t) { .V_B = V_B, .V_R = V_R, .c_B = c_B, .M_R = M_R, .M_mu = M_mu, .G_R = G_R, .G_mu = G_mu, .H_R = H_R, .H_mu = H_mu, .Phi = Phi }; return pm; } void nmsim_neuron_class_write(FILE *wr, nmsim_neuron_class_t *parms) { auto void write_parm(char *name, double v); /* Writes a line "{name} = {v}". */ filefmt_write_header(wr, nmsim_neuron_class_FILE_TYPE, nmsim_neuron_class_VERSION); write_parm("V_R", parms->V_R); write_parm("V_B", parms->V_B); write_parm("c_B", parms->c_B); write_parm("M_R", parms->M_R); write_parm("G_R", parms->G_R); write_parm("H_R", parms->H_R); write_tau_parm_from_mu("M_tau", parms->M_mu); write_tau_parm_from_mu("G_tau", parms->G_mu); write_tau_parm_from_mu("H_tau", parms->H_mu); filefmt_write_footer(wr, nmsim_neuron_class_FILE_TYPE); void write_parm(char *name, double v) { fprintf(wr, "%s = %9.7f\n", name, v); } void write_tau_parm_from_mu(char *name, double mu) { double tau; if (mu == 0) { tau = 0; } else if (mu == INF) { tau = INF; } else { tau = -timeStep*log(mu); } write_parm("G_tau", tau); } } nmsim_neuron_class_t *nmsim_neuron_class_read(FILE *rd, double timeStep) { auto double read_mu_from_tau_parm(char *name); /* Reads a line \"{name} = {value}\", including the end-of-line, and then converts {value} from a characteristic time to a decay factor based on the given {timeStep}. */ double read_mu_from_tau_parm(char *name) { double tau = read_double_parm(rd, name, 0.0, INF); if (tau < 0.02*timeStep) { return 0.0; } else if (tau == INF) { return 1.0; } else { return exp(-timeStep/tau); } } /* Read header line: */ filefmt_read_header(rd, nmsim_neuron_class_FILE_TYPE, nmsim_neuron_class_VERSION); /* Read the parameters: */ double V_B = read_double_parm(rd, "V_B", -200.0, +200.0); double V_R = read_double_parm(rd, "V_R", -200.0, +200.0); double c_B = read_mu_from_tau_parm("tau_V"); double M_R = read_double_parm(rd, "M_R", 0.0, 1.0); double M_mu = read_mu_from_tau_parm("tau_L"); double G_R = read_double_parm(rd, "G_R", 0.0, 1.0); double G_mu = read_mu_from_tau_parm("tau_G"); double H_R = read_double_parm(rd, "H_R", 0.0, 1.0); double H_mu = read_mu_from_tau_parm("tau_H"); /* Read name and parameters of the firing function: */ char *Phi_name = nget_string(rd, "Phi"); double V_M = fget_double(rd); double V_D = fget_double(rd); int32_t deg = fget_int32(rd); fget_eol(rd); struct nmsim_firing_func_t *Phi = nmsim_firing_func_new(Phi_name, V_M, V_D, deg); nmsim_neuron_class_t *parms = nmsim_neuron_class_new ( V_B, V_R, c_B, M_R, M_mu, G_R, G_mu, H_R, H_mu, Phi ); /* Read footer line: */ filefmt_read_footer(rd, nmsim_neuron_class_FILE_TYPE); return parms; }