From 572b42aa32d19f86e504ee4cb124402b74553b36 Mon Sep 17 00:00:00 2001 From: James Paul Turner Date: Tue, 6 Apr 2021 16:55:13 +0100 Subject: [PATCH] Remove old 'experiments' directory. --- Makefile.am | 22 - experiments/experiment_1.c | 1206 ----------------- experiments/experiment_1.py | 70 - experiments/experiment_1.sh | 25 - experiments/experiment_2.c | 1012 -------------- experiments/experiment_2.py | 158 --- experiments/experiment_2.sh | 63 - experiments/experiment_3/morris_lecar.c | 984 -------------- .../experiment_3/morris_lecar_intlab.m | 217 --- experiments/fig5/fig5.py | 205 --- experiments/fig5/fig5.sh | 76 -- experiments/fig5/ml-arpra.c | 1206 ----------------- experiments/fig5/ml-mpfi.c | 942 ------------- experiments/fig5/ml-mpfr.c | 1011 -------------- 14 files changed, 7197 deletions(-) delete mode 100644 experiments/experiment_1.c delete mode 100644 experiments/experiment_1.py delete mode 100755 experiments/experiment_1.sh delete mode 100644 experiments/experiment_2.c delete mode 100644 experiments/experiment_2.py delete mode 100755 experiments/experiment_2.sh delete mode 100644 experiments/experiment_3/morris_lecar.c delete mode 100644 experiments/experiment_3/morris_lecar_intlab.m delete mode 100644 experiments/fig5/fig5.py delete mode 100755 experiments/fig5/fig5.sh delete mode 100644 experiments/fig5/ml-arpra.c delete mode 100644 experiments/fig5/ml-mpfi.c delete mode 100644 experiments/fig5/ml-mpfr.c diff --git a/Makefile.am b/Makefile.am index cbc1f5d..d9b49e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -97,28 +97,6 @@ EXTRA_PROGRAMS += extra/hodgkin_huxley extra_hodgkin_huxley_LDADD = lib/libarpra.la extra_hodgkin_huxley_SOURCES = extra/hodgkin_huxley.c -# Experiments -EXTRA_PROGRAMS += experiments/experiment_1 -experiments_experiment_1_LDADD = lib/libarpra.la -experiments_experiment_1_SOURCES = experiments/experiment_1.c - -EXTRA_PROGRAMS += experiments/experiment_2 -experiments_experiment_2_SOURCES = experiments/experiment_2.c - -EXTRA_PROGRAMS += experiments/experiment_3/morris_lecar -experiments_experiment_3_morris_lecar_LDADD = lib/libarpra.la -experiments_experiment_3_morris_lecar_SOURCES = experiments/experiment_3/morris_lecar.c - -EXTRA_PROGRAMS += experiments/fig5/ml-arpra -experiments_fig5_ml_arpra_LDADD = lib/libarpra.la -experiments_fig5_ml_arpra_SOURCES = experiments/fig5/ml-arpra.c - -EXTRA_PROGRAMS += experiments/fig5/ml-mpfr -experiments_fig5_ml_mpfr_SOURCES = experiments/fig5/ml-mpfr.c - -EXTRA_PROGRAMS += experiments/fig5/ml-mpfi -experiments_fig5_ml_mpfi_SOURCES = experiments/fig5/ml-mpfi.c - # Documentation info_TEXINFOS = doc/arpra.texi doc_arpra_TEXINFOS = doc/fdl-1.3.texi diff --git a/experiments/experiment_1.c b/experiments/experiment_1.c deleted file mode 100644 index ce611c4..0000000 --- a/experiments/experiment_1.c +++ /dev/null @@ -1,1206 +0,0 @@ -/* - * morris_lecar.c -- Test Morris-Lecar model. - * - * Copyright 2016-2020 James Paul Turner. - * - * This file is part of the Arpra library. - * - * The Arpra library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Arpra library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the Arpra library. If not, see . - */ - -#include -#include -#include -#include - -/* - * Global variables - * ---------------- - * h Step size (msec) - * t Current time (msec) - * - * Neuron variables - * ---------------- - * N Fraction of open K+ channels - * V Membrane potential (mV) - * - * Neuron parameters - * ----------------- - * GL Maximum leak conductance (mS/cm^2) - * VL Equilibrium potential of leak conductance (mV) - * GCa Maximum Ca++ conductance (mS/cm^2) - * VCa Equilibrium potential of Ca++ conductance (mV) - * GK Maximum K+ conductance (mS/cm^2) - * VK Equilibrium potential of K+ conductance (mV) - * V1 Potential at which M_ss(V) = 0.5 (mV) - * V2 Reciprocal of voltage dependence slope of M_ss(V) (mV) - * V3 Potential at which N_ss(V) = 0.5 (mV) - * V4 Reciprocal of voltage dependence slope of N_ss(V) (mV) - * phi (s^-1) - * C Membrane capacitance (uF/cm^2) - * - * Synapse variables - * ----------------- - * R Neurotransmitter release - * S Neurotransmitter binding - * - * Synapse parameters - * ------------------ - * GSyn Maximum synapse conductance (mS/cm^2) - * VSyn Synapse conductance equilibrium potential (mV) - * thr Neuronal spike threshold (mV) - * a Transmitter release/bind rise factor - * b Transmitter release/bind decay factor - * k Steepness of activation function - */ - -// General parameters -#define p_h 0.5 -#define p_t0 0.0 -#define p_prec prec_arg -unsigned long prec_arg; -#define p_prec_internal prec_internal_arg -unsigned long prec_internal_arg; -#define p_sim_steps 1000 -#define p_report_step 20 -#define p_reduce_step 50 -#define p_reduce_rel 0.3 - -// RNG parameters -// Seeds are random if not #defined -#define p_rand_prec 53 -#define p_rng_uf_seed 707135875931353ul -#define p_rng_nf_seed 503108552855933ul - -// Poisson input parameters (group 1) -#define p_in1_size in1_size_arg -arpra_uint in1_size_arg; -#define p_in1_freq in1_freq_arg -double in1_freq_arg; -#define p_in1_V_lo -60.0 -#define p_in1_V_hi 20.0 - -// Poisson input parameters (group 2) -#define p_in2_size 0 -#define p_in2_freq 10.0 -#define p_in2_V_lo -60.0 -#define p_in2_V_hi 20.0 - -// Neuron parameters (group 1) -#define p_nrn1_size 1 -#define p_nrn1_N0 0.0 -#define p_nrn1_V0 -60.0 -#define p_nrn1_class 1 - -// Neuron parameters (group 2) -#define p_nrn2_size 0 -#define p_nrn2_N0 0.0 -#define p_nrn2_V0 -60.0 -#define p_nrn2_class 1 - -// Neuron parameters (common) -#define p_GL 2.0 -#define p_GCa 4.0 // Class 1 -//#define p_GCa 4.4 // Class 2 -#define p_GK 8.0 -#define p_VL -60.0 -#define p_VCa 120.0 -#define p_VK -80.0 -#define p_V1 -1.2 -#define p_V2 18.0 -#define p_V3 12.0 // Class 1 -//#define p_V3 2.0 // Class 2 -#define p_V4 17.4 // Class 1 -//#define p_V4 30.0 // Class 2 -#define p_phi 1.0 / 15.0 // Class 1 -//#define p_phi 1.0 / 25.0 // Class 2 -#define p_C 20.0 - -// Synapse parameters (excitatory) -#define p_syn_exc_size p_in1_size * p_nrn1_size -#define p_syn_exc_R0 0.0 -#define p_syn_exc_S0 0.0 -#define p_syn_exc_GSyn_std 0.05 -#define p_syn_exc_GSyn_mean 25.0 / p_in1_size -#define p_syn_exc_VSyn 0.0 -#define p_syn_exc_thr -50.0 -#define p_syn_exc_a 0.25 // in [1/10, 1/2] -#define p_syn_exc_b 0.15 // in [1/20, 1/4] -#define p_syn_exc_k 1.0E6 - -// Synapse parameters (inhibitory) -#define p_syn_inh_size 0 -#define p_syn_inh_R0 0.0 -#define p_syn_inh_S0 0.0 -#define p_syn_inh_GSyn_std 0.5 -#define p_syn_inh_GSyn_mean 3.0 -#define p_syn_inh_VSyn -80.0 -#define p_syn_inh_thr -50.0 -#define p_syn_inh_a 0.075 // in [1/20, 1/10] -#define p_syn_inh_b 0.035 // in [1/50, 1/20] -#define p_syn_inh_k 1.0E6 - -// ===================== end of model parameters ====================== - - -// DEBUG: print MPFR numbers to stderr -void debug (mpfr_srcptr x) { - mpfr_out_str(stderr, 10, 80, x, MPFR_RNDN); - fputs("\n", stderr); -} - -void file_init (char *grp, arpra_uint grp_size, - FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) -{ - char fname[20]; - arpra_uint i; - - for (i = 0; i < grp_size; i++) { - sprintf(fname, "%s_%03lu_c.dat", grp, i); - c[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_r.dat", grp, i); - r[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_n.dat", grp, i); - n[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_s.dat", grp, i); - s[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_d.dat", grp, i); - d[i] = fopen(fname, "w"); - } -} - -void file_clear (arpra_uint grp_size, FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) -{ - arpra_uint i; - - for (i = 0; i < grp_size; i++) { - fclose(c[i]); - fclose(r[i]); - fclose(n[i]); - fclose(s[i]); - fclose(d[i]); - } -} - -void file_write (const arpra_range *A, arpra_uint grp_size, - FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) -{ - arpra_uint i, j; - - for (i = 0; i < grp_size; i++) { - mpfr_out_str(c[i], 10, 80, &(A[i].centre), MPFR_RNDN); - fputc('\n', c[i]); - mpfr_out_str(r[i], 10, 80, &(A[i].radius), MPFR_RNDN); - fputc('\n', r[i]); - fprintf(n[i], "%lu\n", A[i].nTerms); - for (j = 0; j < A[i].nTerms; j++) { - fprintf(s[i], "%lu ", A[i].symbols[j]); - mpfr_out_str(d[i], 10, 80, &(A[i].deviations[j]), MPFR_RNDN); - fputc(' ', d[i]); - } - fputc('\n', s[i]); - fputc('\n', d[i]); - } -} - -struct dNdt_params -{ - arpra_uint grp_V; - arpra_range *V3; - arpra_range *V4; - arpra_range *phi; - arpra_range *one; - arpra_range *two; - arpra_range *neg_two; - arpra_range *N_ss; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dNdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dNdt_params *p = (struct dNdt_params *) params; - const arpra_range *N = &(x[x_grp][x_dim]); - const arpra_range *V = &(x[p->grp_V][x_dim]); - const arpra_range *V3 = p->V3; - const arpra_range *V4 = p->V4; - const arpra_range *phi = p->phi; - const arpra_range *one = p->one; - const arpra_range *two = p->two; - const arpra_range *neg_two = p->neg_two; - arpra_range *N_ss = p->N_ss; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // K+ channel activation steady-state - // N_ss = 1 / (1 + exp(-2 (V - V3) / V4)) - arpra_sub(temp1, V, V3); - arpra_mul(N_ss, neg_two, temp1); - arpra_div(N_ss, N_ss, V4); - arpra_exp(N_ss, N_ss); - arpra_add(N_ss, one, N_ss); - arpra_inv(N_ss, N_ss); - - // tau of K+ channel activation - // tau = 1 / (phi ((p + q) / 2)) - // p = exp(-(V - V3) / (2 V4)) - // q = exp( (V - V3) / (2 V4)) - arpra_mul(temp2, two, V4); - arpra_div(temp2, temp1, temp2); - arpra_neg(temp1, temp2); - arpra_exp(temp1, temp1); - arpra_exp(temp2, temp2); - arpra_add(temp1, temp1, temp2); - arpra_div(temp1, temp1, two); - arpra_mul(temp1, phi, temp1); - arpra_inv(temp1, temp1); - - // delta of K+ channel activation - // dN/dt = (N_ss - N) / tau - arpra_sub(out, N_ss, N); - arpra_div(out, out, temp1); -} - -struct dVdt_params -{ - arpra_uint grp_N; - arpra_uint grp_S; - arpra_range *GSyn; - arpra_range *VSyn; - arpra_range *GL; - arpra_range *VL; - arpra_range *GCa; - arpra_range *VCa; - arpra_range *GK; - arpra_range *VK; - arpra_range *V1; - arpra_range *V2; - arpra_range *C; - arpra_uint pre_syn_size; - arpra_range *one; - arpra_range *neg_two; - arpra_range *I; - arpra_range *M_ss; - arpra_range *temp1; -}; - -void dVdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dVdt_params *p = (struct dVdt_params *) params; - const arpra_range *V = &(x[x_grp][x_dim]); - const arpra_range *N = &(x[p->grp_N][x_dim]); - const arpra_range *S = &(x[p->grp_S][x_dim * p->pre_syn_size]); - const arpra_range *GSyn = &(p->GSyn[x_dim * p->pre_syn_size]); - const arpra_range *VSyn = p->VSyn; - const arpra_range *GL = p->GL; - const arpra_range *VL = p->VL; - const arpra_range *GCa = p->GCa; - const arpra_range *VCa = p->VCa; - const arpra_range *GK = p->GK; - const arpra_range *VK = p->VK; - const arpra_range *V1 = p->V1; - const arpra_range *V2 = p->V2; - const arpra_range *C = p->C; - const arpra_range *one = p->one; - const arpra_range *neg_two = p->neg_two; - arpra_range *I = p->I; - arpra_range *M_ss = p->M_ss; - arpra_range *temp1 = p->temp1; - arpra_uint i; - - // Ca++ channel activation steady-state - // M_ss = 1 / (1 + exp(-2 (V - V1) / V2)) - arpra_sub(M_ss, V, V1); - arpra_mul(M_ss, neg_two, M_ss); - arpra_div(M_ss, M_ss, V2); - arpra_exp(M_ss, M_ss); - arpra_add(M_ss, one, M_ss); - arpra_inv(M_ss, M_ss); - - // Synapse current - arpra_sub(temp1, VSyn, V); - for (i = 0; i < p->pre_syn_size; i++) { - arpra_mul(&(I[i]), temp1, &(GSyn[i])); - arpra_mul(&(I[i]), &(I[i]), &(S[i])); - } - arpra_sum_recursive(out, I, p->pre_syn_size); - //arpra_sum(out, I, p->pre_syn_size); - - - - - // ======== TEMP DEBUG ========== - //arpra_set_d(out, 80.0); // bifurcation at sum(I) = 80.0 - if (x_dim == 0) { - //fprintf(stderr, "sum(I): "); debug(out->centre); - //fprintf(stderr, "I[0]: "); debug(I[0].centre); - for (i = 0; i < p->pre_syn_size; i++) { - //fprintf(stderr, "I[%lu]: ", i); debug(I[i].centre); - } - } - - - - // Leak current - arpra_sub(temp1, V, VL); - arpra_mul(temp1, temp1, GL); - arpra_sub(out, out, temp1); - - // Ca++ current - arpra_sub(temp1, V, VCa); - arpra_mul(temp1, temp1, GCa); - arpra_mul(temp1, temp1, M_ss); - arpra_sub(out, out, temp1); - - // K+ current - arpra_sub(temp1, V, VK); - arpra_mul(temp1, temp1, GK); - arpra_mul(temp1, temp1, N); - arpra_sub(out, out, temp1); - - // delta of membrane potential - // dV/dt = (I + GL (VL - V) + GCa M (VCa - V) + GK N (VK - V)) / C - arpra_div(out, out, C); -} - -struct dRdt_params -{ - arpra_range *a; - arpra_range *b; - arpra_range *k; - arpra_range *VPre_lo; - arpra_range *VPre_hi; - arpra_range *threshold; - int *in; - arpra_uint pre_syn_size; - arpra_range *one; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dRdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dRdt_params *p = (struct dRdt_params *) params; - const arpra_range *R = &(x[x_grp][x_dim]); - const arpra_range *a = p->a; - const arpra_range *b = p->b; - const arpra_range *k = p->k; - const arpra_range *VPre = p->in[x_dim % p->pre_syn_size] ? p->VPre_hi : p->VPre_lo; - const arpra_range *threshold = p->threshold; - const arpra_range *one = p->one; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // Sigmoid of threshold difference - arpra_sub(temp1, VPre, threshold); - arpra_mul(temp1, temp1, k); - arpra_exp(temp1, temp1); - arpra_add(temp1, temp1, one); - arpra_inv(temp1, temp1); - - // Presynaptic transmitter release rise - arpra_mul(temp1, a, temp1); - - // Presynaptic transmitter release decay - arpra_mul(temp2, b, R); - - // delta of presynaptic transmitter release - // dR/dt = a Q - b R - // Q = 1 / (1 + e^(k(V - threshold))) - arpra_sub(out, temp1, temp2); -} - -struct dSdt_params -{ - arpra_uint grp_R; - arpra_range *a; - arpra_range *b; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dSdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dSdt_params *p = (struct dSdt_params *) params; - const arpra_range *S = &(x[x_grp][x_dim]); - const arpra_range *R = &(x[p->grp_R][x_dim]); - const arpra_range *a = p->a; - const arpra_range *b = p->b; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // Postsynaptic transmitter binding rise - arpra_mul(temp1, a, R); - - // Postsynaptic transmitter binding decay - arpra_mul(temp2, b, S); - - // delta of postsynaptic transmitter binding - // dS/dt = a R - b S - arpra_sub(out, temp1, temp2); -} - -int main (int argc, char *argv[]) -{ - arpra_uint i, j; - arpra_range h, sys_t; - - enum grps { - grp_nrn1_N, grp_nrn1_V, grp_nrn2_N, grp_nrn2_V, - grp_syn_exc_R, grp_syn_exc_S, grp_syn_inh_R, grp_syn_inh_S - }; - - // Parse args - prec_arg = atoll(argv[1]); - prec_internal_arg = atoll(argv[2]); - in1_size_arg = atoi(argv[3]); - in1_freq_arg = atoi(argv[4]); - - arpra_set_internal_precision(p_prec_internal); - - // Initialise arpra_reduce_small_rel threshold. - mpfr_t reduce_rel; - mpfr_init2(reduce_rel, 53); - mpfr_set_d(reduce_rel, p_reduce_rel, MPFR_RNDN); - - // Allocate system state - arpra_range *nrn1_N = malloc(p_nrn1_size * sizeof(arpra_range)); - arpra_range *nrn1_V = malloc(p_nrn1_size * sizeof(arpra_range)); - arpra_range *nrn2_N = malloc(p_nrn2_size * sizeof(arpra_range)); - arpra_range *nrn2_V = malloc(p_nrn2_size * sizeof(arpra_range)); - arpra_range *syn_exc_R = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *syn_exc_S = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *syn_inh_R = malloc(p_syn_inh_size * sizeof(arpra_range)); - arpra_range *syn_inh_S = malloc(p_syn_inh_size * sizeof(arpra_range)); - - // Allocate other arrays - arpra_range *syn_exc_GSyn = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *syn_inh_GSyn = malloc(p_syn_inh_size * sizeof(arpra_range)); - arpra_range *I1 = malloc(p_in1_size * sizeof(arpra_range)); - arpra_range *I2 = malloc(p_in2_size * sizeof(arpra_range)); - int *in1 = malloc(p_in1_size * sizeof(int)); - int *in2 = malloc(p_in2_size * sizeof(int)); - arpra_uint *nrn1_N_reduce_epoch = malloc(p_nrn1_size * sizeof(arpra_uint)); - arpra_uint *nrn1_V_reduce_epoch = malloc(p_nrn1_size * sizeof(arpra_uint)); - arpra_uint *nrn2_N_reduce_epoch = malloc(p_nrn2_size * sizeof(arpra_uint)); - arpra_uint *nrn2_V_reduce_epoch = malloc(p_nrn2_size * sizeof(arpra_uint)); - arpra_uint *syn_exc_R_reduce_epoch = malloc(p_syn_exc_size * sizeof(arpra_uint)); - arpra_uint *syn_exc_S_reduce_epoch = malloc(p_syn_exc_size * sizeof(arpra_uint)); - arpra_uint *syn_inh_R_reduce_epoch = malloc(p_syn_inh_size * sizeof(arpra_uint)); - arpra_uint *syn_inh_S_reduce_epoch = malloc(p_syn_inh_size * sizeof(arpra_uint)); - - mpfr_t in1_p0, in2_p0, rand_uf, rand_nf; - arpra_range GL, VL, GCa, VCa, GK, VK, V1, V2, V3, V4, phi, C, - syn_exc_VSyn, syn_exc_thr, syn_exc_a, syn_exc_b, syn_exc_k, - syn_inh_VSyn, syn_inh_thr, syn_inh_a, syn_inh_b, syn_inh_k, one, two, neg_two, - temp1, temp2, M_ss, N_ss, in1_V_lo, in1_V_hi, in2_V_lo, in2_V_hi; - - struct timespec clock_time; - - // Initialise uniform float RNG - gmp_randstate_t rng_uf; - gmp_randinit_default(rng_uf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uf_seed - unsigned long rng_uf_seed = p_rng_uf_seed; -#else - unsigned long rng_uf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uf, rng_uf_seed); - printf("GMP rand uniform float seed: %lu\n", rng_uf_seed); - - // Initialise normal float RNG - gmp_randstate_t rng_nf; - gmp_randinit_default(rng_nf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_nf_seed - unsigned long rng_nf_seed = p_rng_nf_seed; -#else - unsigned long rng_nf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_nf, rng_nf_seed); - printf("GMP rand normal float seed: %lu\n", rng_nf_seed); - - // Initialise system state - arpra_init2(&h, p_prec); - arpra_init2(&sys_t, p_prec); - for (i = 0; i < p_nrn1_size; i++) { - arpra_init2(&(nrn1_N[i]), p_prec); - arpra_init2(&(nrn1_V[i]), p_prec); - } - for (i = 0; i < p_nrn2_size; i++) { - arpra_init2(&(nrn2_N[i]), p_prec); - arpra_init2(&(nrn2_V[i]), p_prec); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_init2(&(syn_exc_R[i]), p_prec); - arpra_init2(&(syn_exc_S[i]), p_prec); - } - for (i = 0; i < p_syn_inh_size; i++) { - arpra_init2(&(syn_inh_R[i]), p_prec); - arpra_init2(&(syn_inh_S[i]), p_prec); - } - - // Initialise Poisson input parameters (group 1) - mpfr_init2(in1_p0, p_prec); - arpra_init2(&in1_V_lo, p_prec); - arpra_init2(&in1_V_hi, p_prec); - - // Initialise Poisson input parameters (group 2) - mpfr_init2(in2_p0, p_prec); - arpra_init2(&in2_V_lo, p_prec); - arpra_init2(&in2_V_hi, p_prec); - - // Initialise neuron parameters - arpra_init2(&GL, p_prec); - arpra_init2(&GCa, p_prec); - arpra_init2(&GK, p_prec); - arpra_init2(&VL, p_prec); - arpra_init2(&VCa, p_prec); - arpra_init2(&VK, p_prec); - arpra_init2(&V1, p_prec); - arpra_init2(&V2, p_prec); - arpra_init2(&V3, p_prec); - arpra_init2(&V4, p_prec); - arpra_init2(&phi, p_prec); - arpra_init2(&C, p_prec); - - // Initialise excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - arpra_init2(&(syn_exc_GSyn[i]), p_prec); - } - arpra_init2(&syn_exc_VSyn, p_prec); - arpra_init2(&syn_exc_thr, p_prec); - arpra_init2(&syn_exc_a, p_prec); - arpra_init2(&syn_exc_b, p_prec); - arpra_init2(&syn_exc_k, p_prec); - - // Initialise inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - arpra_init2(&(syn_inh_GSyn[i]), p_prec); - } - arpra_init2(&syn_inh_VSyn, p_prec); - arpra_init2(&syn_inh_thr, p_prec); - arpra_init2(&syn_inh_a, p_prec); - arpra_init2(&syn_inh_b, p_prec); - arpra_init2(&syn_inh_k, p_prec); - - // Initialise constants - arpra_init2(&one, p_prec); - arpra_init2(&two, p_prec); - arpra_init2(&neg_two, p_prec); - - // Initialise scratch space - mpfr_init2(rand_uf, p_rand_prec); - mpfr_init2(rand_nf, p_rand_prec); - arpra_init2(&temp1, p_prec); - arpra_init2(&temp2, p_prec); - arpra_init2(&M_ss, p_prec); - arpra_init2(&N_ss, p_prec); - for (i = 0; i < p_in1_size; i++) { - arpra_init2(&(I1[i]), p_prec); - } - for (i = 0; i < p_in2_size; i++) { - arpra_init2(&(I2[i]), p_prec); - } - - // Set system state - arpra_set_d(&h, p_h); - arpra_set_d(&sys_t, p_t0); - for (i = 0; i < p_nrn1_size; i++) { - arpra_set_d(&(nrn1_N[i]), p_nrn1_N0); - arpra_set_d(&(nrn1_V[i]), p_nrn1_V0); - } - for (i = 0; i < p_nrn2_size; i++) { - arpra_set_d(&(nrn2_N[i]), p_nrn2_N0); - arpra_set_d(&(nrn2_V[i]), p_nrn2_V0); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_set_d(&(syn_exc_R[i]), p_syn_exc_R0); - arpra_set_d(&(syn_exc_S[i]), p_syn_exc_S0); - } - for (i = 0; i < p_syn_inh_size; i++) { - arpra_set_d(&(syn_inh_R[i]), p_syn_inh_R0); - arpra_set_d(&(syn_inh_S[i]), p_syn_inh_S0); - } - - // Set Poisson input parameters (group 1) - mpfr_set_d(in1_p0, -(p_in1_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in1_p0, in1_p0, MPFR_RNDN); - arpra_set_d(&in1_V_lo, p_in1_V_lo); - arpra_set_d(&in1_V_hi, p_in1_V_hi); - - // Set Poisson input parameters (group 2) - mpfr_set_d(in2_p0, -(p_in2_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in2_p0, in2_p0, MPFR_RNDN); - arpra_set_d(&in2_V_lo, p_in2_V_lo); - arpra_set_d(&in2_V_hi, p_in2_V_hi); - - // Set neuron parameters - arpra_set_d(&GL, p_GL); - arpra_set_d(&GCa, p_GCa); - arpra_set_d(&GK, p_GK); - arpra_set_d(&VL, p_VL); - arpra_set_d(&VCa, p_VCa); - arpra_set_d(&VK, p_VK); - arpra_set_d(&V1, p_V1); - arpra_set_d(&V2, p_V2); - arpra_set_d(&V3, p_V3); - arpra_set_d(&V4, p_V4); - arpra_set_d(&phi, p_phi); - arpra_set_d(&C, p_C); - - // Set excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_exc_GSyn_std, MPFR_RNDN); - mpfr_add_d(rand_nf, rand_nf, p_syn_exc_GSyn_mean, MPFR_RNDN); - arpra_set_mpfr(&(syn_exc_GSyn[i]), rand_nf); - } - arpra_set_d(&syn_exc_VSyn, p_syn_exc_VSyn); - arpra_set_d(&syn_exc_thr, p_syn_exc_thr); - arpra_set_d(&syn_exc_a, p_syn_exc_a); - arpra_set_d(&syn_exc_b, p_syn_exc_b); - arpra_set_d(&syn_exc_k, p_syn_exc_k); - arpra_neg(&syn_exc_k, &syn_exc_k); - - // Set inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_inh_GSyn_std, MPFR_RNDN); - mpfr_add_d(rand_nf, rand_nf, p_syn_inh_GSyn_mean, MPFR_RNDN); - arpra_set_mpfr(&(syn_inh_GSyn[i]), rand_nf); - } - arpra_set_d(&syn_inh_VSyn, p_syn_inh_VSyn); - arpra_set_d(&syn_inh_thr, p_syn_inh_thr); - arpra_set_d(&syn_inh_a, p_syn_inh_a); - arpra_set_d(&syn_inh_b, p_syn_inh_b); - arpra_set_d(&syn_inh_k, p_syn_inh_k); - arpra_neg(&syn_inh_k, &syn_inh_k); - - // Set constants - arpra_set_d(&one, 1.0); - arpra_set_d(&two, 2.0); - arpra_set_d(&neg_two, -2.0); - - // Initialise report files - FILE **f_time_c = malloc(sizeof(FILE *));; - FILE **f_time_r = malloc(sizeof(FILE *));; - FILE **f_time_n = malloc(sizeof(FILE *));; - FILE **f_time_s = malloc(sizeof(FILE *));; - FILE **f_time_d = malloc(sizeof(FILE *));; - file_init("time", 1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); - - FILE **f_nrn1_N_c = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_r = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_n = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_s = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_d = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_N", p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); - FILE **f_nrn1_V_c = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_r = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_n = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_s = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_d = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_V", p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); - - /* FILE **f_nrn2_N_c = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_r = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_n = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_s = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_d = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_N", p_nrn2_size, f_nrn2_N_c, f_nrn2_N_r, f_nrn2_N_n, f_nrn2_N_s, f_nrn2_N_d); */ - /* FILE **f_nrn2_V_c = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_r = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_n = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_s = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_d = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_V", p_nrn2_size, f_nrn2_V_c, f_nrn2_V_r, f_nrn2_V_n, f_nrn2_V_s, f_nrn2_V_d); */ - - /* FILE **f_syn_exc_R_c = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_r = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_n = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_s = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_d = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_R", p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* FILE **f_syn_exc_S_c = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_r = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_n = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_s = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_d = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_S", p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - - /* FILE **f_syn_inh_R_c = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_r = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_n = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_s = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_d = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_R", p_syn_inh_size, f_syn_inh_R_c, f_syn_inh_R_r, f_syn_inh_R_n, f_syn_inh_R_s, f_syn_inh_R_d); */ - /* FILE **f_syn_inh_S_c = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_r = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_n = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_s = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_d = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_S", p_syn_inh_size, f_syn_inh_S_c, f_syn_inh_S_r, f_syn_inh_S_n, f_syn_inh_S_s, f_syn_inh_S_d); */ - - // Set parameter structs - struct dNdt_params params_nrn1_N = { - .grp_V = grp_nrn1_V, - .V3 = &V3, - .V4 = &V4, - .phi = &phi, - .one = &one, - .two = &two, - .neg_two = &neg_two, - .N_ss = &N_ss, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dVdt_params params_nrn1_V = { - .grp_N = grp_nrn1_N, - .grp_S = grp_syn_exc_S, - .GSyn = syn_exc_GSyn, - .VSyn = &syn_exc_VSyn, - .GL = &GL, - .VL = &VL, - .GCa = &GCa, - .VCa = &VCa, - .GK = &GK, - .VK = &VK, - .V1 = &V1, - .V2 = &V2, - .V1 = &V1, - .V2 = &V2, - .C = &C, - .pre_syn_size = p_in1_size, - .one = &one, - .neg_two = &neg_two, - .I = I1, - .M_ss = &M_ss, - .temp1 = &temp1, - }; - - struct dNdt_params params_nrn2_N = { - .grp_V = grp_nrn2_V, - .V3 = &V3, - .V4 = &V4, - .phi = &phi, - .one = &one, - .two = &two, - .neg_two = &neg_two, - .N_ss = &N_ss, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dVdt_params params_nrn2_V = { - .grp_N = grp_nrn2_N, - .grp_S = grp_syn_inh_S, - .GSyn = syn_inh_GSyn, - .VSyn = &syn_inh_VSyn, - .GL = &GL, - .VL = &VL, - .GCa = &GCa, - .VCa = &VCa, - .GK = &GK, - .VK = &VK, - .V1 = &V1, - .V2 = &V2, - .C = &C, - .pre_syn_size = p_in2_size, - .one = &one, - .neg_two = &neg_two, - .I = I2, - .M_ss = &M_ss, - .temp1 = &temp1, - }; - - struct dRdt_params params_syn_exc_R = { - .a = &syn_exc_a, - .b = &syn_exc_b, - .k = &syn_exc_k, - .VPre_lo = &in1_V_lo, - .VPre_hi = &in1_V_hi, - .threshold = &syn_exc_thr, - .in = in1, - .pre_syn_size = p_in1_size, - .one = &one, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dSdt_params params_syn_exc_S = { - .grp_R = grp_syn_exc_R, - .a = &syn_exc_a, - .b = &syn_exc_b, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dRdt_params params_syn_inh_R = { - .a = &syn_inh_a, - .b = &syn_inh_b, - .k = &syn_inh_k, - .VPre_lo = &in2_V_lo, - .VPre_hi = &in2_V_hi, - .threshold = &syn_inh_thr, - .in = in2, - .pre_syn_size = p_in2_size, - .one = &one, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dSdt_params params_syn_inh_S = { - .grp_R = grp_syn_inh_R, - .a = &syn_inh_a, - .b = &syn_inh_b, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - // ODE system - arpra_uint sys_grps = 8; - arpra_uint sys_dims[8] = { - p_nrn1_size, p_nrn1_size, p_nrn2_size, p_nrn2_size, - p_syn_exc_size, p_syn_exc_size, p_syn_inh_size, p_syn_inh_size - }; - arpra_ode_f sys_f[8] = { - dNdt, dVdt, dNdt, dVdt, dRdt, dSdt, dRdt, dSdt - }; - void *sys_params[8] = { - ¶ms_nrn1_N, ¶ms_nrn1_V, ¶ms_nrn2_N, ¶ms_nrn2_V, - ¶ms_syn_exc_R, ¶ms_syn_exc_S, ¶ms_syn_inh_R, ¶ms_syn_inh_S - }; - arpra_range *sys_x[8] = { - nrn1_N, nrn1_V, nrn2_N, nrn2_V, syn_exc_R, syn_exc_S, syn_inh_R, syn_inh_S - }; - arpra_ode_system ode_system = { - .f = sys_f, - .params = sys_params, - .t = &sys_t, - .x = sys_x, - .grps = sys_grps, - .dims = sys_dims, - }; - - // ODE stepper - arpra_ode_stepper ode_stepper; - arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_euler); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_trapezoidal); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_bogsham32); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_dopri54); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_dopri87); - - - // Begin simulation loop - // ===================== - - clock_t run_time = clock(); - - for (i = 0; i < p_sim_steps; i++) { - if (i % p_report_step == 0) printf("%lu\n", i); - - for (j = 0; j < p_nrn1_size; j++) { - nrn1_N_reduce_epoch[j] = ode_system.x[grp_nrn1_N][j].nTerms; - nrn1_V_reduce_epoch[j] = ode_system.x[grp_nrn1_V][j].nTerms; - } - for (j = 0; j < p_nrn2_size; j++) { - nrn2_N_reduce_epoch[j] = ode_system.x[grp_nrn2_N][j].nTerms; - nrn2_V_reduce_epoch[j] = ode_system.x[grp_nrn2_V][j].nTerms; - } - for (j = 0; j < p_syn_exc_size; j++) { - syn_exc_R_reduce_epoch[j] = ode_system.x[grp_syn_exc_R][j].nTerms; - syn_exc_S_reduce_epoch[j] = ode_system.x[grp_syn_exc_S][j].nTerms; - } - for (j = 0; j < p_syn_inh_size; j++) { - syn_inh_R_reduce_epoch[j] = ode_system.x[grp_syn_inh_R][j].nTerms; - syn_inh_S_reduce_epoch[j] = ode_system.x[grp_syn_inh_S][j].nTerms; - } - - // Event(s) occur if urandom >= e^-rate - for (j = 0; j < p_in1_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in1[j] = mpfr_greaterequal_p(rand_uf, in1_p0); - fprintf(stderr, "%s", (in1[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, " "); - for (j = 0; j < p_in2_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in2[j] = mpfr_greaterequal_p(rand_uf, in2_p0); - fprintf(stderr, "%s", (in2[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, "\n"); - - // Step system - arpra_ode_stepper_step(&ode_stepper, &h); - - arpra_uint reduce_n; - for (j = 0; j < p_nrn1_size; j++) { - reduce_n = ode_system.x[grp_nrn1_N][j].nTerms - nrn1_N_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn1_N][j]), &(ode_system.x[grp_nrn1_N][j]), reduce_n); - reduce_n = ode_system.x[grp_nrn1_V][j].nTerms - nrn1_V_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn1_V][j]), &(ode_system.x[grp_nrn1_V][j]), reduce_n); - } - for (j = 0; j < p_nrn2_size; j++) { - reduce_n = ode_system.x[grp_nrn2_N][j].nTerms - nrn2_N_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn2_N][j]), &(ode_system.x[grp_nrn2_N][j]), reduce_n); - reduce_n = ode_system.x[grp_nrn2_V][j].nTerms - nrn2_V_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn2_V][j]), &(ode_system.x[grp_nrn2_V][j]), reduce_n); - } - for (j = 0; j < p_syn_exc_size; j++) { - reduce_n = ode_system.x[grp_syn_exc_R][j].nTerms - syn_exc_R_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_exc_R][j]), &(ode_system.x[grp_syn_exc_R][j]), reduce_n); - reduce_n = ode_system.x[grp_syn_exc_S][j].nTerms - syn_exc_S_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_exc_S][j]), &(ode_system.x[grp_syn_exc_S][j]), reduce_n); - } - for (j = 0; j < p_syn_inh_size; j++) { - reduce_n = ode_system.x[grp_syn_inh_R][j].nTerms - syn_inh_R_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_inh_R][j]), &(ode_system.x[grp_syn_inh_R][j]), reduce_n); - reduce_n = ode_system.x[grp_syn_inh_S][j].nTerms - syn_inh_S_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_inh_S][j]), &(ode_system.x[grp_syn_inh_S][j]), reduce_n); - } - - if (i % p_reduce_step == 0) { - for (j = 0; j < p_nrn1_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_nrn1_N][j]), &(ode_system.x[grp_nrn1_N][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_nrn1_V][j]), &(ode_system.x[grp_nrn1_V][j]), reduce_rel); - } - for (j = 0; j < p_nrn2_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_nrn2_N][j]), &(ode_system.x[grp_nrn2_N][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_nrn2_V][j]), &(ode_system.x[grp_nrn2_V][j]), reduce_rel); - } - for (j = 0; j < p_syn_exc_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_syn_exc_R][j]), &(ode_system.x[grp_syn_exc_R][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_syn_exc_S][j]), &(ode_system.x[grp_syn_exc_S][j]), reduce_rel); - } - for (j = 0; j < p_syn_inh_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_syn_inh_R][j]), &(ode_system.x[grp_syn_inh_R][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_syn_inh_S][j]), &(ode_system.x[grp_syn_inh_S][j]), reduce_rel); - } - } - - file_write(&sys_t, 1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); - - file_write(nrn1_N, p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); - file_write(nrn1_V, p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); - - /* file_write(nrn2_N, p_nrn2_size, f_nrn2_N_c, f_nrn2_N_r, f_nrn2_N_n, f_nrn2_N_s, f_nrn2_N_d); */ - /* file_write(nrn2_V, p_nrn2_size, f_nrn2_V_c, f_nrn2_V_r, f_nrn2_V_n, f_nrn2_V_s, f_nrn2_V_d); */ - - /* file_write(syn_exc_R, p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* file_write(syn_exc_S, p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - - /* file_write(syn_inh_R, p_syn_inh_size, f_syn_inh_R_c, f_syn_inh_R_r, f_syn_inh_R_n, f_syn_inh_R_s, f_syn_inh_R_d); */ - /* file_write(syn_inh_S, p_syn_inh_size, f_syn_inh_S_c, f_syn_inh_S_r, f_syn_inh_S_n, f_syn_inh_S_s, f_syn_inh_S_d); */ - } - - run_time = clock() - run_time; - printf("Finished in %f seconds.\n", ((float) run_time) / CLOCKS_PER_SEC); - - // End simulation loop - // =================== - - - // Clear arpra_reduce_small_rel threshold. - mpfr_clear(reduce_rel); - - // Clear system state - arpra_clear(&h); - arpra_clear(&sys_t); - for (i = 0; i < p_nrn1_size; i++) { - arpra_clear(&(nrn1_N[i])); - arpra_clear(&(nrn1_V[i])); - } - for (i = 0; i < p_nrn2_size; i++) { - arpra_clear(&(nrn2_N[i])); - arpra_clear(&(nrn2_V[i])); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_clear(&(syn_exc_R[i])); - arpra_clear(&(syn_exc_S[i])); - } - for (i = 0; i < p_syn_inh_size; i++) { - arpra_clear(&(syn_inh_R[i])); - arpra_clear(&(syn_inh_S[i])); - } - - // Clear Poisson input parameters (group 1) - mpfr_clear(in1_p0); - arpra_clear(&in1_V_lo); - arpra_clear(&in1_V_hi); - - // Clear Poisson input parameters (group 2) - mpfr_clear(in2_p0); - arpra_clear(&in2_V_lo); - arpra_clear(&in2_V_hi); - - // Clear neuron parameters - arpra_clear(&GL); - arpra_clear(&GCa); - arpra_clear(&GK); - arpra_clear(&VL); - arpra_clear(&VCa); - arpra_clear(&VK); - arpra_clear(&V1); - arpra_clear(&V2); - arpra_clear(&V3); - arpra_clear(&V4); - arpra_clear(&phi); - arpra_clear(&C); - - // Clear excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - arpra_clear(&(syn_exc_GSyn[i])); - } - arpra_clear(&syn_exc_VSyn); - arpra_clear(&syn_exc_thr); - arpra_clear(&syn_exc_a); - arpra_clear(&syn_exc_b); - arpra_clear(&syn_exc_k); - - // Clear inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - arpra_clear(&(syn_inh_GSyn[i])); - } - arpra_clear(&syn_inh_VSyn); - arpra_clear(&syn_inh_thr); - arpra_clear(&syn_inh_a); - arpra_clear(&syn_inh_b); - arpra_clear(&syn_inh_k); - - // Clear constants - arpra_clear(&one); - arpra_clear(&two); - arpra_clear(&neg_two); - - // Clear scratch space - mpfr_clear(rand_uf); - mpfr_clear(rand_nf); - arpra_clear(&temp1); - arpra_clear(&temp2); - arpra_clear(&M_ss); - arpra_clear(&N_ss); - for (i = 0; i < p_in1_size; i++) { - arpra_clear(&(I1[i])); - } - for (i = 0; i < p_in2_size; i++) { - arpra_clear(&(I2[i])); - } - - // Free system state - free(nrn1_N); - free(nrn1_V); - free(nrn2_N); - free(nrn2_V); - free(syn_exc_R); - free(syn_exc_S); - free(syn_inh_R); - free(syn_inh_S); - - // Free other arrays - free(syn_exc_GSyn); - free(syn_inh_GSyn); - free(I1); - free(I2); - free(in1); - free(in2); - free(nrn1_N_reduce_epoch); - free(nrn1_V_reduce_epoch); - free(nrn2_N_reduce_epoch); - free(nrn2_V_reduce_epoch); - free(syn_exc_R_reduce_epoch); - free(syn_exc_S_reduce_epoch); - free(syn_inh_R_reduce_epoch); - free(syn_inh_S_reduce_epoch); - - // Clear report files - file_clear(1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); - free(f_time_c); - free(f_time_r); - free(f_time_n); - free(f_time_s); - free(f_time_d); - - file_clear(p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); - free(f_nrn1_N_c); - free(f_nrn1_N_r); - free(f_nrn1_N_n); - free(f_nrn1_N_s); - free(f_nrn1_N_d); - file_clear(p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); - free(f_nrn1_V_c); - free(f_nrn1_V_r); - free(f_nrn1_V_n); - free(f_nrn1_V_s); - free(f_nrn1_V_d); - - /* file_clear(p_nrn2_size, f_nrn2_N_c, f_nrn2_N_r, f_nrn2_N_n, f_nrn2_N_s, f_nrn2_N_d); */ - /* free(f_nrn2_N_c); */ - /* free(f_nrn2_N_r); */ - /* free(f_nrn2_N_n); */ - /* free(f_nrn2_N_s); */ - /* free(f_nrn2_N_d); */ - /* file_clear(p_nrn2_size, f_nrn2_V_c, f_nrn2_V_r, f_nrn2_V_n, f_nrn2_V_s, f_nrn2_V_d); */ - /* free(f_nrn2_V_c); */ - /* free(f_nrn2_V_r); */ - /* free(f_nrn2_V_n); */ - /* free(f_nrn2_V_s); */ - /* free(f_nrn2_V_d); */ - - /* file_clear(p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* free(f_syn_exc_R_c); */ - /* free(f_syn_exc_R_r); */ - /* free(f_syn_exc_R_n); */ - /* free(f_syn_exc_R_s); */ - /* free(f_syn_exc_R_d); */ - /* file_clear(p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - /* free(f_syn_exc_S_c); */ - /* free(f_syn_exc_S_r); */ - /* free(f_syn_exc_S_n); */ - /* free(f_syn_exc_S_s); */ - /* free(f_syn_exc_S_d); */ - - /* file_clear(p_syn_inh_size, f_syn_inh_R_c, f_syn_inh_R_r, f_syn_inh_R_n, f_syn_inh_R_s, f_syn_inh_R_d); */ - /* free(f_syn_inh_R_c); */ - /* free(f_syn_inh_R_r); */ - /* free(f_syn_inh_R_n); */ - /* free(f_syn_inh_R_s); */ - /* free(f_syn_inh_R_d); */ - /* file_clear(p_syn_inh_size, f_syn_inh_S_c, f_syn_inh_S_r, f_syn_inh_S_n, f_syn_inh_S_s, f_syn_inh_S_d); */ - /* free(f_syn_inh_S_c); */ - /* free(f_syn_inh_S_r); */ - /* free(f_syn_inh_S_n); */ - /* free(f_syn_inh_S_s); */ - /* free(f_syn_inh_S_d); */ - - arpra_ode_stepper_clear(&ode_stepper); - arpra_clear_buffers(); - gmp_randclear(rng_uf); - gmp_randclear(rng_nf); - mpfr_free_cache(); - - return 0; -} diff --git a/experiments/experiment_1.py b/experiments/experiment_1.py deleted file mode 100644 index d8d88d4..0000000 --- a/experiments/experiment_1.py +++ /dev/null @@ -1,70 +0,0 @@ - -import numpy as np -import matplotlib.pyplot as plt - -# SETUP -# %load_ext autoreload -# %autoreload 2 -# from experiments.experiment_1 import experiment_1 -# ##### - -def rad_sum (path, x, i_start, i_stop): - - with open(path + x, 'r') as xr_file: - - try: - for i in range(i_start): - xr_file.readline(); - - xr = np.array([xr_file.readline() for i in range(i_start, i_stop)], dtype=np.float64) - return np.sum(xr) - - except ValueError: - return np.inf - - -def experiment_1 (): - - xr = 'nrn1_V_000_r.dat' - yr = 'nrn1_N_000_r.dat' - xr_sum_mat = np.zeros((26, 26), dtype=np.float64) - yr_sum_mat = np.zeros((26, 26), dtype=np.float64) - - for i in range(0, 26): - inps = i * 2 - - for j in range(0, 26): - freq = j * 2 - - path = 'experiment_1_out/in_' + str(inps) + '_freq_' + str(freq) + '/' - print(path) - - xr_sum_mat[i, j] = rad_sum (path, xr, 0, 1000) - yr_sum_mat[i, j] = rad_sum (path, yr, 0, 1000) - - fig, ax = plt.subplots(1, 2) - - ax[0].matshow(np.log10(xr_sum_mat)) - ax[0].set_xticks(np.arange(0, 26, 5)) - ax[0].set_yticks(np.arange(0, 26, 5)) - ax[0].set_xticklabels(np.arange(0, 51, 10)) - ax[0].set_yticklabels(np.arange(0, 51, 10)) - ax[0].set_xlabel('Input frequency (Hz)') - ax[0].set_ylabel('Input count') - ax[0].set_title('V') - - ax[1].matshow(np.log10(yr_sum_mat)) - ax[1].set_xticks(np.arange(0, 26, 5)) - ax[1].set_yticks(np.arange(0, 26, 5)) - ax[1].set_xticklabels(np.arange(0, 51, 10)) - ax[1].set_yticklabels(np.arange(0, 51, 10)) - ax[1].set_xlabel('Input frequency (Hz)') - ax[1].set_ylabel('Input count') - ax[1].set_title('N') - - plt.show() - return - - -if __name__ == '__main__': - experiment_1() diff --git a/experiments/experiment_1.sh b/experiments/experiment_1.sh deleted file mode 100755 index 7231cee..0000000 --- a/experiments/experiment_1.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -echo Begin: ${0} -cd $(dirname ${0})/.. -make experiments/experiment_1 -cd experiments -outdir=experiment_1_out -rm -rf ${outdir} - -for inputs in {0..50..2}; do - echo inputs: ${inputs} - - for frequency in {0..50..2}; do - echo frequency: ${frequency} - - outsubdir=${outdir}/in_${inputs}_freq_${frequency} - echo Changing to ${outsubdir} - mkdir -p ${outsubdir} - cd ${outsubdir} - ../../experiment_1 53 2048 ${inputs} ${frequency} 2>/dev/null - cd ../.. - done -done - -python3 ./experiment_1.py diff --git a/experiments/experiment_2.c b/experiments/experiment_2.c deleted file mode 100644 index c70ac16..0000000 --- a/experiments/experiment_2.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * morris_lecar_mpfr.c -- Test Morris-Lecar model using MPFR. - * - * Copyright 2016-2020 James Paul Turner. - * - * This file is part of the Arpra library. - * - * The Arpra library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Arpra library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the Arpra library. If not, see . - */ - -#include -#include -#include -#include - -/* - * Global variables - * ---------------- - * h Step size (msec) - * t Current time (msec) - * - * Neuron variables - * ---------------- - * N Fraction of open K+ channels - * V Membrane potential (mV) - * - * Neuron parameters - * ----------------- - * GL Maximum leak conductance (mS/cm^2) - * VL Equilibrium potential of leak conductance (mV) - * GCa Maximum Ca++ conductance (mS/cm^2) - * VCa Equilibrium potential of Ca++ conductance (mV) - * GK Maximum K+ conductance (mS/cm^2) - * VK Equilibrium potential of K+ conductance (mV) - * V1 Potential at which M_ss(V) = 0.5 (mV) - * V2 Reciprocal of voltage dependence slope of M_ss(V) (mV) - * V3 Potential at which N_ss(V) = 0.5 (mV) - * V4 Reciprocal of voltage dependence slope of N_ss(V) (mV) - * phi (s^-1) - * C Membrane capacitance (uF/cm^2) - * - * Synapse variables - * ----------------- - * R Neurotransmitter release - * S Neurotransmitter binding - * - * Synapse parameters - * ------------------ - * GSyn Maximum synapse conductance (mS/cm^2) - * VSyn Synapse conductance equilibrium potential (mV) - * thr Neuronal spike threshold (mV) - * a Transmitter release/bind rise factor - * b Transmitter release/bind decay factor - * k Steepness of activation function - */ - -// General parameters -#define p_h 0.5 -#define p_t0 0.0 -#define p_prec prec_arg -unsigned long prec_arg; -#define p_sim_steps 1000 -#define p_report_step 20 - -// Current sum reordering -int current_order_arg; -//#define p_shuffle_current -//#define p_sort_current > -// > increasing (best case approx) -// < decreasing (worst case approx) - -// RNG parameters -// Seeds are random if not #defined -#define p_rand_prec 53 -#define p_rng_uf_seed 707135875931353ul -#define p_rng_nf_seed 503108552855933ul -//#define p_rng_uz_seed 2071328946103ul - -// Poisson input parameters (group 1) -#define p_in1_size 500 -#define p_in1_freq 50.0 -#define p_in1_V_lo -60.0 -#define p_in1_V_hi 20.0 - -// Poisson input parameters (group 2) -#define p_in2_size 0 -#define p_in2_freq 10.0 -#define p_in2_V_lo -60.0 -#define p_in2_V_hi 20.0 - -// Neuron parameters (group 1) -#define p_nrn1_size 1 -#define p_nrn1_N0 0.0 -#define p_nrn1_V0 -60.0 -#define p_nrn1_class 1 - -// Neuron parameters (group 2) -#define p_nrn2_size 0 -#define p_nrn2_N0 0.0 -#define p_nrn2_V0 -60.0 -#define p_nrn2_class 1 - -// Neuron parameters (common) -#define p_GL 2.0 -#define p_GCa 4.0 // Class 1 -//#define p_GCa 4.4 // Class 2 -#define p_GK 8.0 -#define p_VL -60.0 -#define p_VCa 120.0 -#define p_VK -80.0 -#define p_V1 -1.2 -#define p_V2 18.0 -#define p_V3 12.0 // Class 1 -//#define p_V3 2.0 // Class 2 -#define p_V4 17.4 // Class 1 -//#define p_V4 30.0 // Class 2 -#define p_phi 1.0 / 15.0 // Class 1 -//#define p_phi 1.0 / 25.0 // Class 2 -#define p_C 20.0 - -// Synapse parameters (excitatory) -#define p_syn_exc_size p_in1_size * p_nrn1_size -#define p_syn_exc_R0 0.0 -#define p_syn_exc_S0 0.0 -#define p_syn_exc_GSyn_std 0.05 -#define p_syn_exc_GSyn_mean 25.0 / p_in1_size -#define p_syn_exc_VSyn 0.0 -#define p_syn_exc_thr -50.0 -#define p_syn_exc_a 0.25 // in [1/10, 1/2] -#define p_syn_exc_b 0.15 // in [1/20, 1/4] -#define p_syn_exc_k 1.0E6 - -// Synapse parameters (inhibitory) -#define p_syn_inh_size 0 -#define p_syn_inh_R0 0.0 -#define p_syn_inh_S0 0.0 -#define p_syn_inh_GSyn_std 0.5 -#define p_syn_inh_GSyn_mean 3.0 -#define p_syn_inh_VSyn -80.0 -#define p_syn_inh_thr -50.0 -#define p_syn_inh_a 0.075 // in [1/20, 1/10] -#define p_syn_inh_b 0.035 // in [1/50, 1/20] -#define p_syn_inh_k 1.0E6 - -// ===================== end of model parameters ====================== - - -int *in1, *in2; -mpfr_t GL, VL, GCa, VCa, GK, VK, V1, V2, V3, V4, phi, C, syn_exc_VSyn, syn_exc_thr, - syn_exc_a, syn_exc_b, syn_exc_k, syn_inh_VSyn, syn_inh_thr, syn_inh_a, - syn_inh_b, syn_inh_k, one, two, neg_two, temp1, temp2, M_ss, N_ss, in1_V_lo, - in1_V_hi, in2_V_lo, in2_V_hi, in1_p0, in2_p0, rand_uf, rand_nf; -mpz_t rand_uz; -mpfr_ptr syn_exc_GSyn, syn_inh_GSyn, I_ptr_swap, I1, *I1_ptr, *I1_ptr_temp, I2, *I2_ptr, *I2_ptr_temp; -gmp_randstate_t rng_uf, rng_nf, rng_uz; - -// System state variables -mpfr_ptr nrn1_N, nrn2_N, nrn1_V, nrn2_V, syn_exc_R, syn_inh_R, syn_exc_S, syn_inh_S; -mpfr_ptr d_nrn1_N, d_nrn2_N, d_nrn1_V, d_nrn2_V, d_syn_exc_R, d_syn_inh_R, d_syn_exc_S, d_syn_inh_S; - -// DEBUG: print MPFR numbers to stderr -void debug (mpfr_srcptr x) { - mpfr_out_str(stderr, 10, 80, x, MPFR_RNDN); - fputs("\n", stderr); -} - -void file_init (char *grp, unsigned long grp_size, FILE **f) -{ - char fname[20]; - unsigned long i; - - for (i = 0; i < grp_size; i++) { - sprintf(fname, "%s_%03lu.dat", grp, i); - f[i] = fopen(fname, "w"); - } -} - -void file_clear (unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - fclose(f[i]); - } -} - -void file_write (mpfr_srcptr A, unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - mpfr_out_str(f[i], 10, 80, &(A[i]), MPFR_RNDN); - fputc('\n', f[i]); - } -} - -void dNdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_N; - mpfr_srcptr N, V; - - if (grp == 1) { - d_N = d_nrn1_N + idx; - N = nrn1_N + idx; - V = nrn1_V + idx; - } - //else if (grp == 2) { - // d_N = d_nrn2_N + idx; - // N = nrn2_N + idx; - // V = nrn2_V + idx; - //} - - // K+ channel activation steady-state - // N_ss = 1 / (1 + exp(-2 (V - V3) / V4)) - mpfr_sub(temp1, V, V3, MPFR_RNDN); - mpfr_mul(N_ss, neg_two, temp1, MPFR_RNDN); - mpfr_div(N_ss, N_ss, V4, MPFR_RNDN); - mpfr_exp(N_ss, N_ss, MPFR_RNDN); - mpfr_add(N_ss, one, N_ss, MPFR_RNDN); - mpfr_ui_div(N_ss, 1, N_ss, MPFR_RNDN); - - // tau of K+ channel activation - // tau = 1 / (phi ((p + q) / 2)) - // p = exp(-(V - V3) / (2 V4)) - // q = exp( (V - V3) / (2 V4)) - mpfr_mul(temp2, two, V4, MPFR_RNDN); - mpfr_div(temp2, temp1, temp2, MPFR_RNDN); - mpfr_neg(temp1, temp2, MPFR_RNDN); - mpfr_exp(temp1, temp1, MPFR_RNDN); - mpfr_exp(temp2, temp2, MPFR_RNDN); - mpfr_add(temp1, temp1, temp2, MPFR_RNDN); - mpfr_div(temp1, temp1, two, MPFR_RNDN); - mpfr_mul(temp1, phi, temp1, MPFR_RNDN); - mpfr_ui_div(temp1, 1, temp1, MPFR_RNDN); - - // delta of K+ channel activation - // dN/dt = (N_ss - N) / tau - mpfr_sub(d_N, N_ss, N, MPFR_RNDN); - mpfr_div(d_N, d_N, temp1, MPFR_RNDN); -} - -void dVdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_V; - mpfr_srcptr N, V; - mpfr_srcptr S, GSyn, VSyn; - mpfr_ptr I, *I_ptr, *I_ptr_temp; - unsigned long i, j, pre_size; - - if (grp == 1) { - d_V = d_nrn1_V + idx; - N = nrn1_N + idx; - V = nrn1_V + idx; - pre_size = p_in1_size; - S = syn_exc_S + (idx * pre_size); - GSyn = syn_exc_GSyn + (idx * pre_size); - VSyn = syn_exc_VSyn; - I = I1; - I_ptr = I1_ptr; - I_ptr_temp = I1_ptr_temp; - } - //else if (grp == 2) { - // d_V = d_nrn2_V + idx; - // N = nrn2_N + idx; - // V = nrn2_V + idx; - // pre_size = p_in2_size; - // S = syn_exc_S + (idx * pre_size); - // GSyn = syn_exc_GSyn + (idx * pre_size); - // VSyn = syn_exc_VSyn; - // I = I2; - // I_ptr = I2_ptr; - // I_ptr_temp = I2_ptr_temp; - //} - - // Ca++ channel activation steady-state - // M_ss = 1 / (1 + exp(-2 (V - V1) / V2)) - mpfr_sub(M_ss, V, V1, MPFR_RNDN); - mpfr_mul(M_ss, neg_two, M_ss, MPFR_RNDN); - mpfr_div(M_ss, M_ss, V2, MPFR_RNDN); - mpfr_exp(M_ss, M_ss, MPFR_RNDN); - mpfr_add(M_ss, one, M_ss, MPFR_RNDN); - mpfr_ui_div(M_ss, 1, M_ss, MPFR_RNDN); - - // Synapse current - mpfr_sub(temp1, VSyn, V, MPFR_RNDN); - mpfr_set_ui(d_V, 0, MPFR_RNDN); - for (i = 0; i < pre_size; i++) { - mpfr_mul(&(I[i]), temp1, &(GSyn[i]), MPFR_RNDN); - mpfr_mul(&(I[i]), &(I[i]), &(S[i]), MPFR_RNDN); - I_ptr[i] = &(I[i]); - } - -//#ifdef p_shuffle_current - if (current_order_arg == 0) { - // Shuffle input currents with Fisher-Yates. - for (i = 0; i < pre_size; i++) { - mpz_set_ui(rand_uz, pre_size - i); - mpz_urandomm(rand_uz, rng_uz, rand_uz); - j = i + mpz_get_ui(rand_uz); - I_ptr_swap = I_ptr[i]; - I_ptr[i] = I_ptr[j]; - I_ptr[j] = I_ptr_swap; - } - } -//#endif // p_shuffle_current - -//#ifdef p_sort_current - if (current_order_arg > 0) { - // Merge sort input currents - unsigned long pa, pb, pc, chunk_size, k; - - for (chunk_size = 1; chunk_size < pre_size; chunk_size *= 2) { - for (pa = 0; (pa + chunk_size) < pre_size; pa += (2 * chunk_size)) { - pb = pa + chunk_size; - pc = pb + chunk_size; - if (pc > pre_size) pc = pre_size; - i = pa; - j = pb; - k = pa; - while ((i < pb) && (j < pc)) { - /* if (mpfr_cmpabs(I_ptr[j], I_ptr[i]) p_sort_current 0) { */ - /* I_ptr_temp[k++] = I_ptr[i++]; */ - /* } */ - /* else { */ - /* I_ptr_temp[k++] = I_ptr[j++]; */ - /* } */ - - - // ascending (best) - if (current_order_arg == 1) { - if (mpfr_cmpabs(I_ptr[j], I_ptr[i]) > 0) { - I_ptr_temp[k++] = I_ptr[i++]; - } - else { - I_ptr_temp[k++] = I_ptr[j++]; - } - } - - - // descending (worst) - if (current_order_arg == 2) { - if (mpfr_cmpabs(I_ptr[j], I_ptr[i]) < 0) { - I_ptr_temp[k++] = I_ptr[i++]; - } - else { - I_ptr_temp[k++] = I_ptr[j++]; - } - } - - - - } - while (i < pb) { - I_ptr_temp[k++] = I_ptr[i++]; - } - while (j < pc) { - I_ptr_temp[k++] = I_ptr[j++]; - } - } - for (k = 0; k < pre_size; k++) { - I_ptr[k] = I_ptr_temp[k]; - } - } - } -//#endif // p_sort_current - - // Sum input currents - for (i = 0; i < pre_size; i++) { - mpfr_add(d_V, d_V, I_ptr[i], MPFR_RNDN); - } - - - - - // ======== TEMP DEBUG ========== - //mpfr_set_d(d_V, 80.0, MPFR_RNDN); // bifurcation at sum(I) = 80.0 - //for (i = 0; i < pre_size; i++) { - // debug(I_ptr[i]); - //} - //fprintf(stderr, "\n"); - if (idx == 0) { - //fprintf(stderr, "sum(I): "); debug(d_V); - //fprintf(stderr, "I[0]: "); debug(I); - for (i = 0; i < pre_size; i++) { - //fprintf(stderr, "I[%lu]: ", i); debug(&(I[i])); - } - } - - - - // Leak current - mpfr_sub(temp1, V, VL, MPFR_RNDN); - mpfr_mul(temp1, temp1, GL, MPFR_RNDN); - mpfr_sub(d_V, d_V, temp1, MPFR_RNDN); - - // Ca++ current - mpfr_sub(temp1, V, VCa, MPFR_RNDN); - mpfr_mul(temp1, temp1, GCa, MPFR_RNDN); - mpfr_mul(temp1, temp1, M_ss, MPFR_RNDN); - mpfr_sub(d_V, d_V, temp1, MPFR_RNDN); - - // K+ current - mpfr_sub(temp1, V, VK, MPFR_RNDN); - mpfr_mul(temp1, temp1, GK, MPFR_RNDN); - mpfr_mul(temp1, temp1, N, MPFR_RNDN); - mpfr_sub(d_V, d_V, temp1, MPFR_RNDN); - - // delta of membrane potential - // dV/dt = (I + GL (VL - V) + GCa M (VCa - V) + GK N (VK - V)) / C - mpfr_div(d_V, d_V, C, MPFR_RNDN); -} - -void dRdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_R; - mpfr_srcptr R; - mpfr_srcptr a, b, k; - mpfr_srcptr VPre, threshold; - - if (grp == 1) { - d_R = d_syn_exc_R + idx; - R = syn_exc_R + idx; - a = syn_exc_a; - b = syn_exc_b; - k = syn_exc_k; - VPre = in1[idx % p_in1_size] ? in1_V_hi : in1_V_lo; - threshold = syn_exc_thr; - } - //else if (grp == 2) { - // d_R = d_syn_inh_R + idx; - // R = syn_inh_R + idx; - // a = syn_inh_a; - // b = syn_inh_b; - // k = syn_inh_k; - // VPre = in2[idx % p_in2_size] ? in2_V_hi : in2_V_lo; - // threshold = syn_inh_thr; - //} - - // Sigmoid of threshold difference - mpfr_sub(temp1, VPre, threshold, MPFR_RNDN); - mpfr_mul(temp1, temp1, k, MPFR_RNDN); - mpfr_exp(temp1, temp1, MPFR_RNDN); - mpfr_add(temp1, temp1, one, MPFR_RNDN); - mpfr_ui_div(temp1, 1, temp1, MPFR_RNDN); - - // Presynaptic transmitter release rise - mpfr_mul(temp1, a, temp1, MPFR_RNDN); - - // Presynaptic transmitter release decay - mpfr_mul(temp2, b, R, MPFR_RNDN); - - // delta of presynaptic transmitter release - // dR/dt = a Q - b R - // Q = 1 / (1 + e^(k(V - threshold))) - mpfr_sub(d_R, temp1, temp2, MPFR_RNDN); -} - -void dSdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_S; - mpfr_srcptr R, S; - mpfr_srcptr a, b; - - if (grp == 1) { - d_S = d_syn_exc_S + idx; - R = syn_exc_R + idx; - S = syn_exc_S + idx; - a = syn_exc_a; - b = syn_exc_b; - } - //else if (grp == 2) { - // d_S = d_syn_inh_S + idx; - // R = syn_inh_R + idx; - // S = syn_inh_S + idx; - // a = syn_inh_a; - // b = syn_inh_b; - //} - - // Postsynaptic transmitter binding rise - mpfr_mul(temp1, a, R, MPFR_RNDN); - - // Postsynaptic transmitter binding decay - mpfr_mul(temp2, b, S, MPFR_RNDN); - - // delta of postsynaptic transmitter binding - // dS/dt = a R - b S - mpfr_sub(d_S, temp1, temp2, MPFR_RNDN); -} - -int main (int argc, char *argv[]) -{ - mpfr_t h, t; - unsigned long i, j; - - // Parse args - prec_arg = atoll(argv[1]); - current_order_arg = atoi(argv[2]); - - // Allocate system state - nrn1_N = malloc(p_nrn1_size * sizeof(mpfr_t)); - nrn1_V = malloc(p_nrn1_size * sizeof(mpfr_t)); - nrn2_N = malloc(p_nrn2_size * sizeof(mpfr_t)); - nrn2_V = malloc(p_nrn2_size * sizeof(mpfr_t)); - syn_exc_R = malloc(p_syn_exc_size * sizeof(mpfr_t)); - syn_exc_S = malloc(p_syn_exc_size * sizeof(mpfr_t)); - syn_inh_R = malloc(p_syn_inh_size * sizeof(mpfr_t)); - syn_inh_S = malloc(p_syn_inh_size * sizeof(mpfr_t)); - - // Allocate other arrays - d_nrn1_N = malloc(p_nrn1_size * sizeof(mpfr_t)); - d_nrn2_N = malloc(p_nrn2_size * sizeof(mpfr_t)); - d_nrn1_V = malloc(p_nrn1_size * sizeof(mpfr_t)); - d_nrn2_V = malloc(p_nrn2_size * sizeof(mpfr_t)); - d_syn_exc_R = malloc(p_syn_exc_size * sizeof(mpfr_t)); - d_syn_inh_R = malloc(p_syn_inh_size * sizeof(mpfr_t)); - d_syn_exc_S = malloc(p_syn_exc_size * sizeof(mpfr_t)); - d_syn_inh_S = malloc(p_syn_inh_size * sizeof(mpfr_t)); - syn_exc_GSyn = malloc(p_syn_exc_size * sizeof(mpfr_t)); - syn_inh_GSyn = malloc(p_syn_inh_size * sizeof(mpfr_t)); - I1 = malloc(p_in1_size * sizeof(mpfr_t)); - I1_ptr = malloc(p_in1_size * sizeof(mpfr_ptr)); - I1_ptr_temp = malloc(p_in1_size * sizeof(mpfr_ptr)); - I2 = malloc(p_in2_size * sizeof(mpfr_t)); - I2_ptr = malloc(p_in2_size * sizeof(mpfr_ptr)); - I2_ptr_temp = malloc(p_in2_size * sizeof(mpfr_ptr)); - in1 = malloc(p_in1_size * sizeof(int)); - in2 = malloc(p_in2_size * sizeof(int)); - - struct timespec clock_time; - - // Initialise uniform float RNG - gmp_randinit_default(rng_uf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uf_seed - unsigned long rng_uf_seed = p_rng_uf_seed; -#else - unsigned long rng_uf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uf, rng_uf_seed); - printf("GMP rand uniform float seed: %lu\n", rng_uf_seed); - - // Initialise normal float RNG - gmp_randinit_default(rng_nf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_nf_seed - unsigned long rng_nf_seed = p_rng_nf_seed; -#else - unsigned long rng_nf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_nf, rng_nf_seed); - printf("GMP rand normal float seed: %lu\n", rng_nf_seed); - - // Initialise uniform integer RNG - gmp_randinit_default(rng_uz); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uz_seed - unsigned long rng_uz_seed = p_rng_uz_seed; -#else - unsigned long rng_uz_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uz, rng_uz_seed); - printf("GMP rand uniform integer seed: %lu\n", rng_uz_seed); - - // Initialise system state - mpfr_init2(h, p_prec); - mpfr_init2(t, p_prec); - for (i = 0; i < p_nrn1_size; i++) { - mpfr_init2(&(nrn1_N[i]), p_prec); - mpfr_init2(&(nrn1_V[i]), p_prec); - mpfr_init2(&(d_nrn1_N[i]), p_prec); - mpfr_init2(&(d_nrn1_V[i]), p_prec); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfr_init2(&(nrn2_N[i]), p_prec); - mpfr_init2(&(nrn2_V[i]), p_prec); - mpfr_init2(&(d_nrn2_N[i]), p_prec); - mpfr_init2(&(d_nrn2_V[i]), p_prec); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_init2(&(syn_exc_R[i]), p_prec); - mpfr_init2(&(syn_exc_S[i]), p_prec); - mpfr_init2(&(d_syn_exc_R[i]), p_prec); - mpfr_init2(&(d_syn_exc_S[i]), p_prec); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_init2(&(syn_inh_R[i]), p_prec); - mpfr_init2(&(syn_inh_S[i]), p_prec); - mpfr_init2(&(d_syn_inh_R[i]), p_prec); - mpfr_init2(&(d_syn_inh_S[i]), p_prec); - } - - // Initialise Poisson input parameters (group 1) - mpfr_init2(in1_p0, p_prec); - mpfr_init2(in1_V_lo, p_prec); - mpfr_init2(in1_V_hi, p_prec); - - // Initialise Poisson input parameters (group 2) - mpfr_init2(in2_p0, p_prec); - mpfr_init2(in2_V_lo, p_prec); - mpfr_init2(in2_V_hi, p_prec); - - // Initialise neuron parameters - mpfr_init2(GL, p_prec); - mpfr_init2(GCa, p_prec); - mpfr_init2(GK, p_prec); - mpfr_init2(VL, p_prec); - mpfr_init2(VCa, p_prec); - mpfr_init2(VK, p_prec); - mpfr_init2(V1, p_prec); - mpfr_init2(V2, p_prec); - mpfr_init2(V3, p_prec); - mpfr_init2(V4, p_prec); - mpfr_init2(phi, p_prec); - mpfr_init2(C, p_prec); - - // Initialise excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_init2(&(syn_exc_GSyn[i]), p_prec); - } - mpfr_init2(syn_exc_VSyn, p_prec); - mpfr_init2(syn_exc_thr, p_prec); - mpfr_init2(syn_exc_a, p_prec); - mpfr_init2(syn_exc_b, p_prec); - mpfr_init2(syn_exc_k, p_prec); - - // Initialise inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_init2(&(syn_inh_GSyn[i]), p_prec); - } - mpfr_init2(syn_inh_VSyn, p_prec); - mpfr_init2(syn_inh_thr, p_prec); - mpfr_init2(syn_inh_a, p_prec); - mpfr_init2(syn_inh_b, p_prec); - mpfr_init2(syn_inh_k, p_prec); - - // Initialise constants - mpfr_init2(one, p_prec); - mpfr_init2(two, p_prec); - mpfr_init2(neg_two, p_prec); - - // Initialise scratch space - mpfr_init2(rand_uf, p_rand_prec); - mpfr_init2(rand_nf, p_rand_prec); - mpz_init(rand_uz); - mpfr_init2(temp1, p_prec); - mpfr_init2(temp2, p_prec); - mpfr_init2(M_ss, p_prec); - mpfr_init2(N_ss, p_prec); - for (i = 0; i < p_in1_size; i++) { - mpfr_init2(&(I1[i]), p_prec); - } - for (i = 0; i < p_in2_size; i++) { - mpfr_init2(&(I2[i]), p_prec); - } - - // Set system state - mpfr_set_d(h, p_h, MPFR_RNDN); - mpfr_set_d(t, p_t0, MPFR_RNDN); - for (i = 0; i < p_nrn1_size; i++) { - mpfr_set_d(&(nrn1_N[i]), p_nrn1_N0, MPFR_RNDN); - mpfr_set_d(&(nrn1_V[i]), p_nrn1_V0, MPFR_RNDN); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfr_set_d(&(nrn2_N[i]), p_nrn2_N0, MPFR_RNDN); - mpfr_set_d(&(nrn2_V[i]), p_nrn2_V0, MPFR_RNDN); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_set_d(&(syn_exc_R[i]), p_syn_exc_R0, MPFR_RNDN); - mpfr_set_d(&(syn_exc_S[i]), p_syn_exc_S0, MPFR_RNDN); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_set_d(&(syn_inh_R[i]), p_syn_inh_R0, MPFR_RNDN); - mpfr_set_d(&(syn_inh_S[i]), p_syn_inh_S0, MPFR_RNDN); - } - - // Set Poisson input parameters (group 1) - mpfr_set_d(in1_p0, -(p_in1_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in1_p0, in1_p0, MPFR_RNDN); - mpfr_set_d(in1_V_lo, p_in1_V_lo, MPFR_RNDN); - mpfr_set_d(in1_V_hi, p_in1_V_hi, MPFR_RNDN); - - // Set Poisson input parameters (group 2) - mpfr_set_d(in2_p0, -(p_in2_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in2_p0, in2_p0, MPFR_RNDN); - mpfr_set_d(in2_V_lo, p_in2_V_lo, MPFR_RNDN); - mpfr_set_d(in2_V_hi, p_in2_V_hi, MPFR_RNDN); - - // Set neuron parameters - mpfr_set_d(GL, p_GL, MPFR_RNDN); - mpfr_set_d(GCa, p_GCa, MPFR_RNDN); - mpfr_set_d(GK, p_GK, MPFR_RNDN); - mpfr_set_d(VL, p_VL, MPFR_RNDN); - mpfr_set_d(VCa, p_VCa, MPFR_RNDN); - mpfr_set_d(VK, p_VK, MPFR_RNDN); - mpfr_set_d(V1, p_V1, MPFR_RNDN); - mpfr_set_d(V2, p_V2, MPFR_RNDN); - mpfr_set_d(V3, p_V3, MPFR_RNDN); - mpfr_set_d(V4, p_V4, MPFR_RNDN); - mpfr_set_d(phi, p_phi, MPFR_RNDN); - mpfr_set_d(C, p_C, MPFR_RNDN); - - // Set excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_exc_GSyn_std, MPFR_RNDN); - mpfr_add_d(&(syn_exc_GSyn[i]), rand_nf, p_syn_exc_GSyn_mean, MPFR_RNDN); - } - mpfr_set_d(syn_exc_VSyn, p_syn_exc_VSyn, MPFR_RNDN); - mpfr_set_d(syn_exc_thr, p_syn_exc_thr, MPFR_RNDN); - mpfr_set_d(syn_exc_a, p_syn_exc_a, MPFR_RNDN); - mpfr_set_d(syn_exc_b, p_syn_exc_b, MPFR_RNDN); - mpfr_set_d(syn_exc_k, p_syn_exc_k, MPFR_RNDN); - mpfr_neg(syn_exc_k, syn_exc_k, MPFR_RNDN); - - // Set inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_inh_GSyn_std, MPFR_RNDN); - mpfr_add_d(&(syn_inh_GSyn[i]), rand_nf, p_syn_inh_GSyn_mean, MPFR_RNDN); - } - mpfr_set_d(syn_inh_VSyn, p_syn_inh_VSyn, MPFR_RNDN); - mpfr_set_d(syn_inh_thr, p_syn_inh_thr, MPFR_RNDN); - mpfr_set_d(syn_inh_a, p_syn_inh_a, MPFR_RNDN); - mpfr_set_d(syn_inh_b, p_syn_inh_b, MPFR_RNDN); - mpfr_set_d(syn_inh_k, p_syn_inh_k, MPFR_RNDN); - mpfr_neg(syn_inh_k, syn_inh_k, MPFR_RNDN); - - // Set constants - mpfr_set_d(one, 1.0, MPFR_RNDN); - mpfr_set_d(two, 2.0, MPFR_RNDN); - mpfr_set_d(neg_two, -2.0, MPFR_RNDN); - - // Initialise report files - FILE **f_time = malloc(sizeof(FILE *));; - file_init("time", 1, f_time); - - FILE **f_nrn1_N = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_N", p_nrn1_size, f_nrn1_N); - FILE **f_nrn1_V = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_V", p_nrn1_size, f_nrn1_V); - - /* FILE **f_nrn2_N = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_N", p_nrn2_size, f_nrn2_N); */ - /* FILE **f_nrn2_V = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_V", p_nrn2_size, f_nrn2_V); */ - - /* FILE **f_syn_exc_R = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_R", p_syn_exc_size, f_syn_exc_R); */ - /* FILE **f_syn_exc_S = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_S", p_syn_exc_size, f_syn_exc_S); */ - - /* FILE **f_syn_inh_R = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_R", p_syn_inh_size, f_syn_inh_R); */ - /* FILE **f_syn_inh_S = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_S", p_syn_inh_size, f_syn_inh_S); */ - - - // Begin simulation loop - // ===================== - - clock_t run_time = clock(); - - for (i = 0; i < p_sim_steps; i++) { - if (i % p_report_step == 0) printf("%lu\n", i); - - // Event(s) occur if urandom >= e^-rate - for (j = 0; j < p_in1_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in1[j] = mpfr_greaterequal_p(rand_uf, in1_p0); - fprintf(stderr, "%s", (in1[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, " "); - for (j = 0; j < p_in2_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in2[j] = mpfr_greaterequal_p(rand_uf, in2_p0); - fprintf(stderr, "%s", (in2[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, "\n"); - - // Compute derivatives - for (j = 0; j < p_nrn1_size; j++) { - dNdt(j, 1); - dVdt(j, 1); - } - for (j = 0; j < p_nrn2_size; j++) { - dNdt(j, 2); - dVdt(j, 2); - } - for (j = 0; j < p_syn_exc_size; j++) { - dRdt(j, 1); - dSdt(j, 1); - } - for (j = 0; j < p_syn_inh_size; j++) { - dRdt(j, 2); - dSdt(j, 2); - } - - // Step system - mpfr_add(t, t, h, MPFR_RNDN); - for (j = 0; j < p_nrn1_size; j++) { - mpfr_mul(&(d_nrn1_N[j]), &(d_nrn1_N[j]), h, MPFR_RNDN); - mpfr_add(&(nrn1_N[j]), &(nrn1_N[j]), &(d_nrn1_N[j]), MPFR_RNDN); - mpfr_mul(&(d_nrn1_V[j]), &(d_nrn1_V[j]), h, MPFR_RNDN); - mpfr_add(&(nrn1_V[j]), &(nrn1_V[j]), &(d_nrn1_V[j]), MPFR_RNDN); - } - for (j = 0; j < p_nrn2_size; j++) { - mpfr_mul(&(d_nrn2_N[j]), &(d_nrn2_N[j]), h, MPFR_RNDN); - mpfr_add(&(nrn2_N[j]), &(nrn2_N[j]), &(d_nrn2_N[j]), MPFR_RNDN); - mpfr_mul(&(d_nrn2_V[j]), &(d_nrn2_V[j]), h, MPFR_RNDN); - mpfr_add(&(nrn2_V[j]), &(nrn2_V[j]), &(d_nrn2_V[j]), MPFR_RNDN); - } - for (j = 0; j < p_syn_exc_size; j++) { - mpfr_mul(&(d_syn_exc_R[j]), &(d_syn_exc_R[j]), h, MPFR_RNDN); - mpfr_add(&(syn_exc_R[j]), &(syn_exc_R[j]), &(d_syn_exc_R[j]), MPFR_RNDN); - mpfr_mul(&(d_syn_exc_S[j]), &(d_syn_exc_S[j]), h, MPFR_RNDN); - mpfr_add(&(syn_exc_S[j]), &(syn_exc_S[j]), &(d_syn_exc_S[j]), MPFR_RNDN); - } - for (j = 0; j < p_syn_inh_size; j++) { - mpfr_mul(&(d_syn_inh_R[j]), &(d_syn_inh_R[j]), h, MPFR_RNDN); - mpfr_add(&(syn_inh_R[j]), &(syn_inh_R[j]), &(d_syn_inh_R[j]), MPFR_RNDN); - mpfr_mul(&(d_syn_inh_S[j]), &(d_syn_inh_S[j]), h, MPFR_RNDN); - mpfr_add(&(syn_inh_S[j]), &(syn_inh_S[j]), &(d_syn_inh_S[j]), MPFR_RNDN); - } - - file_write(t, 1, f_time); - - file_write(nrn1_N, p_nrn1_size, f_nrn1_N); - file_write(nrn1_V, p_nrn1_size, f_nrn1_V); - - /* file_write(nrn2_N, p_nrn2_size, f_nrn2_N); */ - /* file_write(nrn2_V, p_nrn2_size, f_nrn2_V); */ - - /* file_write(syn_exc_R, p_syn_exc_size, f_syn_exc_R); */ - /* file_write(syn_exc_S, p_syn_exc_size, f_syn_exc_S); */ - - /* file_write(syn_inh_R, p_syn_inh_size, f_syn_inh_R); */ - /* file_write(syn_inh_S, p_syn_inh_size, f_syn_inh_S); */ - } - - run_time = clock() - run_time; - printf("Finished in %f seconds.\n", ((float) run_time) / CLOCKS_PER_SEC); - - // End simulation loop - // =================== - - - // Clear system state - mpfr_clear(h); - mpfr_clear(t); - for (i = 0; i < p_nrn1_size; i++) { - mpfr_clear(&(nrn1_N[i])); - mpfr_clear(&(nrn1_V[i])); - mpfr_clear(&(d_nrn1_N[i])); - mpfr_clear(&(d_nrn1_V[i])); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfr_clear(&(nrn2_N[i])); - mpfr_clear(&(nrn2_V[i])); - mpfr_clear(&(d_nrn2_N[i])); - mpfr_clear(&(d_nrn2_V[i])); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_clear(&(syn_exc_R[i])); - mpfr_clear(&(syn_exc_S[i])); - mpfr_clear(&(d_syn_exc_R[i])); - mpfr_clear(&(d_syn_exc_S[i])); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_clear(&(syn_inh_R[i])); - mpfr_clear(&(syn_inh_S[i])); - mpfr_clear(&(d_syn_inh_R[i])); - mpfr_clear(&(d_syn_inh_S[i])); - } - - // Clear Poisson input parameters (group 1) - mpfr_clear(in1_p0); - mpfr_clear(in1_V_lo); - mpfr_clear(in1_V_hi); - - // Clear Poisson input parameters (group 2) - mpfr_clear(in2_p0); - mpfr_clear(in2_V_lo); - mpfr_clear(in2_V_hi); - - // Clear neuron parameters - mpfr_clear(GL); - mpfr_clear(GCa); - mpfr_clear(GK); - mpfr_clear(VL); - mpfr_clear(VCa); - mpfr_clear(VK); - mpfr_clear(V1); - mpfr_clear(V2); - mpfr_clear(V3); - mpfr_clear(V4); - mpfr_clear(phi); - mpfr_clear(C); - - // Clear excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_clear(&(syn_exc_GSyn[i])); - } - mpfr_clear(syn_exc_VSyn); - mpfr_clear(syn_exc_thr); - mpfr_clear(syn_exc_a); - mpfr_clear(syn_exc_b); - mpfr_clear(syn_exc_k); - - // Clear inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_clear(&(syn_inh_GSyn[i])); - } - mpfr_clear(syn_inh_VSyn); - mpfr_clear(syn_inh_thr); - mpfr_clear(syn_inh_a); - mpfr_clear(syn_inh_b); - mpfr_clear(syn_inh_k); - - // Clear constants - mpfr_clear(one); - mpfr_clear(two); - mpfr_clear(neg_two); - - // Clear scratch space - mpfr_clear(rand_uf); - mpfr_clear(rand_nf); - mpz_clear(rand_uz); - mpfr_clear(temp1); - mpfr_clear(temp2); - mpfr_clear(M_ss); - mpfr_clear(N_ss); - for (i = 0; i < p_in1_size; i++) { - mpfr_clear(&(I1[i])); - } - for (i = 0; i < p_in2_size; i++) { - mpfr_clear(&(I2[i])); - } - - // Free system state - free(nrn1_N); - free(nrn1_V); - free(nrn2_N); - free(nrn2_V); - free(syn_exc_R); - free(syn_exc_S); - free(syn_inh_R); - free(syn_inh_S); - - // Free other arrays - free(d_nrn1_N); - free(d_nrn2_N); - free(d_nrn1_V); - free(d_nrn2_V); - free(d_syn_exc_R); - free(d_syn_inh_R); - free(d_syn_exc_S); - free(d_syn_inh_S); - free(syn_exc_GSyn); - free(syn_inh_GSyn); - free(I1); - free(I1_ptr); - free(I1_ptr_temp); - free(I2); - free(I2_ptr); - free(I2_ptr_temp); - free(in1); - free(in2); - - // Clear report files - file_clear(1, f_time); - free(f_time); - - file_clear(p_nrn1_size, f_nrn1_N); - free(f_nrn1_N); - file_clear(p_nrn1_size, f_nrn1_V); - free(f_nrn1_V); - - /* file_clear(p_nrn2_size, f_nrn2_N); */ - /* free(f_nrn2_N); */ - /* file_clear(p_nrn2_size, f_nrn2_V); */ - /* free(f_nrn2_V); */ - - /* file_clear(p_syn_exc_size, f_syn_exc_R); */ - /* free(f_syn_exc_R); */ - /* file_clear(p_syn_exc_size, f_syn_exc_S); */ - /* free(f_syn_exc_S); */ - - /* file_clear(p_syn_inh_size, f_syn_inh_R); */ - /* free(f_syn_inh_R); */ - /* file_clear(p_syn_inh_size, f_syn_inh_S); */ - /* free(f_syn_inh_S); */ - - gmp_randclear(rng_uf); - gmp_randclear(rng_nf); - gmp_randclear(rng_uz); - mpfr_free_cache(); - - return 0; -} diff --git a/experiments/experiment_2.py b/experiments/experiment_2.py deleted file mode 100644 index f0d5c2d..0000000 --- a/experiments/experiment_2.py +++ /dev/null @@ -1,158 +0,0 @@ - -import numpy as np -import matplotlib.pyplot as plt -from contextlib import ExitStack -from itertools import islice - -# SETUP -# %load_ext autoreload -# %autoreload 2 -# from experiments.experiment_2 import experiment_2 -# ##### - - -def experiment_2 (): - - v_name = 'nrn1_V_000' - n_name = 'nrn1_N_000' - t_name = 'time_000' - - samples = 100 - v = [None] * samples - n = [None] * samples - t = [None] * samples - - fig = plt.figure() - fig.canvas.set_window_title('Experiment 2') - ax_traj = fig.add_subplot(121) - ax_x = fig.add_subplot(222) - ax_y = fig.add_subplot(224, sharex=ax_x) - - # for i in range(samples): - # [v[i], n[i], t[i]] = arpra_mpfr_read(path='experiment_2_out/i_' + str(i)) - # [v_asc, n_asc, t_asc] = arpra_mpfr_read(path='experiment_2_out/ascending') - # [v_desc, n_desc, t_desc] = arpra_mpfr_read(path='experiment_2_out/descending') - # [v_hp, n_hp, t_hp] = arpra_mpfr_read(path='experiment_2_out/high_prec') - [v_arp_c, v_arp_r, n_arp_c, n_arp_r, t_arp_c, t_arp_r] = arpra_read(path='experiment_2_out/arpra') - - # v_mean = np.mean(v, axis=0) - # v_std = np.std(v, axis=0) - # n_mean = np.mean(n, axis=0) - # n_std = np.std(n, axis=0) - - # for i in range(samples): - # ax_x.plot(t[i], v[i], 'b') - # ax_y.plot(t[i], n[i], 'b') - # ax_x.plot(t_asc, v_asc, 'y') - # ax_y.plot(t_asc, n_asc, 'y') - # ax_x.plot(t_desc, v_desc, 'y') - # ax_y.plot(t_desc, n_desc, 'y') - # ax_x.plot(t_hp, v_hp, 'k') - # ax_y.plot(t_hp, n_hp, 'k') - # ax_traj.plot(v_hp, n_hp, 'b') - - v_arp_lo = v_arp_c - v_arp_r - v_arp_hi = v_arp_c + v_arp_r - n_arp_lo = n_arp_c - n_arp_r - n_arp_hi = n_arp_c + n_arp_r - ax_x.plot(t_arp_c, v_arp_lo, 'r') - ax_x.plot(t_arp_c, v_arp_hi, 'r') - ax_y.plot(t_arp_c, n_arp_lo, 'r') - ax_y.plot(t_arp_c, n_arp_hi, 'r') - - # v_mean_std_lo = v_mean - v_std - # v_mean_std_hi = v_mean + v_std - # n_mean_std_lo = n_mean - n_std - # n_mean_std_hi = n_mean + n_std - # ax_x.plot(t_arp_c, v_mean_std_lo, 'r') - # ax_x.plot(t_arp_c, v_mean_std_hi, 'r') - # ax_y.plot(t_arp_c, n_mean_std_lo, 'r') - # ax_y.plot(t_arp_c, n_mean_std_hi, 'r') - - plt.show() - return - - - fig = plt.figure() - fig.canvas.set_window_title('Experiment 2') - ax_v1 = fig.add_subplot(411) - ax_v2 = fig.add_subplot(412, sharex=ax_v1) - ax_n1 = fig.add_subplot(413, sharex=ax_v1) - ax_n2 = fig.add_subplot(414, sharex=ax_v1) - - plt.show() - return - - -def arpra_read (path='.', x='nrn1_V_000', y='nrn1_N_000', t='time_000', - i_start=None, i_stop=None, i_step=None): - - with ExitStack() as stack: - xc_file = stack.enter_context(open(path + '/' + x + '_c.dat', 'r')) - xr_file = stack.enter_context(open(path + '/' + x + '_r.dat', 'r')) - yc_file = stack.enter_context(open(path + '/' + y + '_c.dat', 'r')) - yr_file = stack.enter_context(open(path + '/' + y + '_r.dat', 'r')) - tc_file = stack.enter_context(open(path + '/' + t + '_c.dat', 'r')) - tr_file = stack.enter_context(open(path + '/' + t + '_r.dat', 'r')) - - xc = np.genfromtxt(islice(xc_file, i_start, i_stop, i_step), dtype=np.float64) - xr = np.genfromtxt(islice(xr_file, i_start, i_stop, i_step), dtype=np.float64) - yc = np.genfromtxt(islice(yc_file, i_start, i_stop, i_step), dtype=np.float64) - yr = np.genfromtxt(islice(yr_file, i_start, i_stop, i_step), dtype=np.float64) - tc = np.genfromtxt(islice(tc_file, i_start, i_stop, i_step), dtype=np.float64) - tr = np.genfromtxt(islice(tr_file, i_start, i_stop, i_step), dtype=np.float64) - - return [xc, xr, yc, yr, tc, tr] - - -def arpra_mpfr_read (path='.', x='nrn1_V_000', y='nrn1_N_000', t='time_000', - i_start=None, i_stop=None, i_step=None): - - with ExitStack() as stack: - x_file = stack.enter_context(open(path + '/' + x + '.dat', 'r')) - y_file = stack.enter_context(open(path + '/' + y + '.dat', 'r')) - t_file = stack.enter_context(open(path + '/' + t + '.dat', 'r')) - - xx = np.genfromtxt(islice(x_file, i_start, i_stop, i_step), dtype=np.float64) - yy = np.genfromtxt(islice(y_file, i_start, i_stop, i_step), dtype=np.float64) - tt = np.genfromtxt(islice(t_file, i_start, i_stop, i_step), dtype=np.float64) - - return [xx, yy, tt] - - -def arpra_mpfr_plot (x, y, t, path='.', fmt='b', - ax_traj=None, ax_x=None, ax_y=None, - i_start=None, i_stop=None, i_step=None): - - with ExitStack() as stack: - x_file = stack.enter_context(open(path + '/' + x + '.dat', 'r')) - y_file = stack.enter_context(open(path + '/' + y + '.dat', 'r')) - t_file = stack.enter_context(open(path + '/' + t + '.dat', 'r')) - - xx = np.genfromtxt(islice(x_file, i_start, i_stop, i_step), dtype=np.float64) - yy = np.genfromtxt(islice(y_file, i_start, i_stop, i_step), dtype=np.float64) - tt = np.genfromtxt(islice(t_file, i_start, i_stop, i_step), dtype=np.float64) - - if ax_traj: - # Plot (x, y) trajectory - ax_traj.set_xlabel(x) - ax_traj.set_ylabel(y) - ax_traj.plot(xx, yy, fmt) - - if ax_x: - # Plot x through time - ax_x.set_xlabel('time') - ax_x.set_ylabel(x) - ax_x.plot(tt, xx, fmt, label=x) - - if ax_y: - # Plot y through time - ax_y.set_xlabel('time') - ax_y.set_ylabel(y) - ax_y.plot(tt, yy, fmt, label=y) - - return - - -if __name__ == '__main__': - experiment_2() diff --git a/experiments/experiment_2.sh b/experiments/experiment_2.sh deleted file mode 100755 index 202ae82..0000000 --- a/experiments/experiment_2.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -echo Begin: ${0} -cd $(dirname ${0})/.. -make experiments/experiment_1 -make experiments/experiment_2 -cd experiments -outdir=experiment_2_out -rm -rf ${outdir} - -# for i in {0..99}; do -# echo MPFR ${i} -# outsubdir=${outdir}/i_${i} -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../experiment_2 24 0" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. -# done - -# echo MPFR ascending -# outsubdir=${outdir}/ascending -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../experiment_2 24 1" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. - -# echo MPFR descending -# outsubdir=${outdir}/descending -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../experiment_2 24 2" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. - -# echo MPFR high precision -# outsubdir=${outdir}/high_prec -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../experiment_2 2048 0" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. - -echo Arpra bounds -outsubdir=${outdir}/arpra -echo Changing to ${outsubdir} -mkdir -p ${outsubdir} -cd ${outsubdir} -cmd="../../experiment_1 24 2048 500 50" -echo ${cmd} -${cmd} 2>/dev/null -cd ../.. - -python3 ./experiment_2.py diff --git a/experiments/experiment_3/morris_lecar.c b/experiments/experiment_3/morris_lecar.c deleted file mode 100644 index cea6aad..0000000 --- a/experiments/experiment_3/morris_lecar.c +++ /dev/null @@ -1,984 +0,0 @@ -/* - * morris_lecar.c -- Test Morris-Lecar model. - * - * Copyright 2016-2020 James Paul Turner. - * - * This file is part of the Arpra library. - * - * The Arpra library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Arpra library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the Arpra library. If not, see . - */ - -#include -#include -#include -#include - -/* - * Global variables - * ---------------- - * h Step size (msec) - * t Current time (msec) - * - * Neuron variables - * ---------------- - * N Fraction of open K+ channels - * V Membrane potential (mV) - * - * Neuron parameters - * ----------------- - * GL Maximum leak conductance (mS/cm^2) - * VL Equilibrium potential of leak conductance (mV) - * GCa Maximum Ca++ conductance (mS/cm^2) - * VCa Equilibrium potential of Ca++ conductance (mV) - * GK Maximum K+ conductance (mS/cm^2) - * VK Equilibrium potential of K+ conductance (mV) - * V1 Potential at which M_ss(V) = 0.5 (mV) - * V2 Reciprocal of voltage dependence slope of M_ss(V) (mV) - * V3 Potential at which N_ss(V) = 0.5 (mV) - * V4 Reciprocal of voltage dependence slope of N_ss(V) (mV) - * phi (s^-1) - * C Membrane capacitance (uF/cm^2) - * - * Synapse variables - * ----------------- - * R Neurotransmitter release - * S Neurotransmitter binding - * - * Synapse parameters - * ------------------ - * GSyn Maximum synapse conductance (mS/cm^2) - * VSyn Synapse conductance equilibrium potential (mV) - * thr Neuronal spike threshold (mV) - * a Transmitter release/bind rise factor - * b Transmitter release/bind decay factor - * k Steepness of activation function - */ - -// General parameters -#define p_h 0.5 -#define p_t0 0.0 -#define p_prec 53 -#define p_prec_internal 1024 -#define p_sim_steps 1000 -#define p_report_step 20 -#define p_reduce_step 50 -#define p_reduce_rel 0.3 - -// RNG parameters -// Seeds are random if not #defined -#define p_rand_prec 53 -#define p_rng_uf_seed 707135875931353ul -#define p_rng_nf_seed 503108552855933ul - -// Poisson input parameters (group 1) -#define p_in1_size 50 -#define p_in1_freq 50.0 -#define p_in1_V_lo -60.0 -#define p_in1_V_hi 20.0 - -// Neuron parameters (group 1) -#define p_nrn1_size 1 -#define p_nrn1_N0 0.0 -#define p_nrn1_V0 -60.0 - -// Neuron parameters (common) -#define p_GL 2.0 -#define p_GCa 4.0 // Class 1 -//#define p_GCa 4.4 // Class 2 -#define p_GK 8.0 -#define p_VL -60.0 -#define p_VCa 120.0 -#define p_VK -80.0 -#define p_V1 -1.2 -#define p_V2 18.0 -#define p_V3 12.0 // Class 1 -//#define p_V3 2.0 // Class 2 -#define p_V4 17.4 // Class 1 -//#define p_V4 30.0 // Class 2 -#define p_phi 1.0 / 15.0 // Class 1 -//#define p_phi 1.0 / 25.0 // Class 2 -#define p_C 20.0 - -// Synapse parameters (excitatory) -#define p_syn_exc_size p_in1_size * p_nrn1_size -#define p_syn_exc_R0 0.0 -#define p_syn_exc_S0 0.0 -#define p_syn_exc_GSyn_std 0.05 -#define p_syn_exc_GSyn_mean 25.0 / p_in1_size -#define p_syn_exc_VSyn 0.0 -#define p_syn_exc_thr -50.0 -#define p_syn_exc_a 0.25 // in [1/10, 1/2] -#define p_syn_exc_b 0.15 // in [1/20, 1/4] -#define p_syn_exc_k 1.0E6 - -// ===================== end of model parameters ====================== - - -// DEBUG: print MPFR numbers to stderr -void debug (mpfr_srcptr x) { - mpfr_out_str(stderr, 10, 80, x, MPFR_RNDN); - fputs("\n", stderr); -} - -void file_init (char *grp, unsigned long grp_size, FILE **f) -{ - char fname[20]; - unsigned long i; - - for (i = 0; i < grp_size; i++) { - sprintf(fname, "%s_%03lu.dat", grp, i); - f[i] = fopen(fname, "w"); - } -} - -void file_clear (unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - fclose(f[i]); - } -} - -void file_write (const arpra_range *A, unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - mpfr_out_str(f[i], 10, 40, &(A[i].true_range.left), MPFR_RNDN); - fputs(" ", f[i]); - mpfr_out_str(f[i], 10, 40, &(A[i].true_range.right), MPFR_RNDN); - fputs("\n", f[i]); - } -} - -/* void file_init (char *grp, arpra_uint grp_size, */ -/* FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) */ -/* { */ -/* char fname[20]; */ -/* arpra_uint i; */ - -/* for (i = 0; i < grp_size; i++) { */ -/* sprintf(fname, "%s_%03lu_c.dat", grp, i); */ -/* c[i] = fopen(fname, "w"); */ -/* sprintf(fname, "%s_%03lu_r.dat", grp, i); */ -/* r[i] = fopen(fname, "w"); */ -/* sprintf(fname, "%s_%03lu_n.dat", grp, i); */ -/* n[i] = fopen(fname, "w"); */ -/* sprintf(fname, "%s_%03lu_s.dat", grp, i); */ -/* s[i] = fopen(fname, "w"); */ -/* sprintf(fname, "%s_%03lu_d.dat", grp, i); */ -/* d[i] = fopen(fname, "w"); */ -/* } */ -/* } */ - -/* void file_clear (arpra_uint grp_size, FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) */ -/* { */ -/* arpra_uint i; */ - -/* for (i = 0; i < grp_size; i++) { */ -/* fclose(c[i]); */ -/* fclose(r[i]); */ -/* fclose(n[i]); */ -/* fclose(s[i]); */ -/* fclose(d[i]); */ -/* } */ -/* } */ - -/* void file_write (const arpra_range *A, arpra_uint grp_size, */ -/* FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) */ -/* { */ -/* arpra_uint i, j; */ - -/* for (i = 0; i < grp_size; i++) { */ -/* mpfr_out_str(c[i], 10, 80, &(A[i].centre), MPFR_RNDN); */ -/* fputc('\n', c[i]); */ -/* mpfr_out_str(r[i], 10, 80, &(A[i].radius), MPFR_RNDN); */ -/* fputc('\n', r[i]); */ -/* fprintf(n[i], "%lu\n", A[i].nTerms); */ -/* for (j = 0; j < A[i].nTerms; j++) { */ -/* fprintf(s[i], "%lu ", A[i].symbols[j]); */ -/* mpfr_out_str(d[i], 10, 80, &(A[i].deviations[j]), MPFR_RNDN); */ -/* fputc(' ', d[i]); */ -/* } */ -/* fputc('\n', s[i]); */ -/* fputc('\n', d[i]); */ -/* } */ -/* } */ - -struct dNdt_params -{ - arpra_uint grp_V; - arpra_range *V3; - arpra_range *V4; - arpra_range *phi; - arpra_range *one; - arpra_range *two; - arpra_range *neg_two; - arpra_range *N_ss; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dNdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dNdt_params *p = (struct dNdt_params *) params; - const arpra_range *N = &(x[x_grp][x_dim]); - const arpra_range *V = &(x[p->grp_V][x_dim]); - const arpra_range *V3 = p->V3; - const arpra_range *V4 = p->V4; - const arpra_range *phi = p->phi; - const arpra_range *one = p->one; - const arpra_range *two = p->two; - const arpra_range *neg_two = p->neg_two; - arpra_range *N_ss = p->N_ss; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // K+ channel activation steady-state - // N_ss = 1 / (1 + exp(-2 (V - V3) / V4)) - arpra_sub(temp1, V, V3); - arpra_mul(N_ss, neg_two, temp1); - arpra_div(N_ss, N_ss, V4); - arpra_exp(N_ss, N_ss); - arpra_add(N_ss, one, N_ss); - arpra_inv(N_ss, N_ss); - - // tau of K+ channel activation - // tau = 1 / (phi ((p + q) / 2)) - // p = exp(-(V - V3) / (2 V4)) - // q = exp( (V - V3) / (2 V4)) - arpra_mul(temp2, two, V4); - arpra_div(temp2, temp1, temp2); - arpra_neg(temp1, temp2); - arpra_exp(temp1, temp1); - arpra_exp(temp2, temp2); - arpra_add(temp1, temp1, temp2); - arpra_div(temp1, temp1, two); - arpra_mul(temp1, phi, temp1); - arpra_inv(temp1, temp1); - - // delta of K+ channel activation - // dN/dt = (N_ss - N) / tau - arpra_sub(out, N_ss, N); - arpra_div(out, out, temp1); -} - -struct dVdt_params -{ - arpra_uint grp_N; - arpra_uint grp_S; - arpra_range *GSyn; - arpra_range *VSyn; - arpra_range *GL; - arpra_range *VL; - arpra_range *GCa; - arpra_range *VCa; - arpra_range *GK; - arpra_range *VK; - arpra_range *V1; - arpra_range *V2; - arpra_range *C; - arpra_uint pre_syn_size; - arpra_range *one; - arpra_range *neg_two; - arpra_range *I; - arpra_range *M_ss; - arpra_range *temp1; -}; - -void dVdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dVdt_params *p = (struct dVdt_params *) params; - const arpra_range *V = &(x[x_grp][x_dim]); - const arpra_range *N = &(x[p->grp_N][x_dim]); - const arpra_range *S = &(x[p->grp_S][x_dim * p->pre_syn_size]); - const arpra_range *GSyn = &(p->GSyn[x_dim * p->pre_syn_size]); - const arpra_range *VSyn = p->VSyn; - const arpra_range *GL = p->GL; - const arpra_range *VL = p->VL; - const arpra_range *GCa = p->GCa; - const arpra_range *VCa = p->VCa; - const arpra_range *GK = p->GK; - const arpra_range *VK = p->VK; - const arpra_range *V1 = p->V1; - const arpra_range *V2 = p->V2; - const arpra_range *C = p->C; - const arpra_range *one = p->one; - const arpra_range *neg_two = p->neg_two; - arpra_range *I = p->I; - arpra_range *M_ss = p->M_ss; - arpra_range *temp1 = p->temp1; - arpra_uint i; - - // Ca++ channel activation steady-state - // M_ss = 1 / (1 + exp(-2 (V - V1) / V2)) - arpra_sub(M_ss, V, V1); - arpra_mul(M_ss, neg_two, M_ss); - arpra_div(M_ss, M_ss, V2); - arpra_exp(M_ss, M_ss); - arpra_add(M_ss, one, M_ss); - arpra_inv(M_ss, M_ss); - - // Synapse current - arpra_set_zero(out); - arpra_sub(temp1, VSyn, V); - for (i = 0; i < p->pre_syn_size; i++) { - arpra_mul(&(I[i]), temp1, &(GSyn[i])); - arpra_mul(&(I[i]), &(I[i]), &(S[i])); - - arpra_add(out, out, &(I[i])); - } - //arpra_sum_recursive(out, I, p->pre_syn_size); - //arpra_sum(out, I, p->pre_syn_size); - - - - - // ======== TEMP DEBUG ========== - //arpra_set_d(out, 80.0); // bifurcation at sum(I) = 80.0 - if (x_dim == 0) { - //fprintf(stderr, "sum(I): "); debug(out->centre); - //fprintf(stderr, "I[0]: "); debug(I[0].centre); - for (i = 0; i < p->pre_syn_size; i++) { - //fprintf(stderr, "I[%lu]: ", i); debug(I[i].centre); - } - } - - - - // Leak current - arpra_sub(temp1, V, VL); - arpra_mul(temp1, temp1, GL); - arpra_sub(out, out, temp1); - - // Ca++ current - arpra_sub(temp1, V, VCa); - arpra_mul(temp1, temp1, GCa); - arpra_mul(temp1, temp1, M_ss); - arpra_sub(out, out, temp1); - - // K+ current - arpra_sub(temp1, V, VK); - arpra_mul(temp1, temp1, GK); - arpra_mul(temp1, temp1, N); - arpra_sub(out, out, temp1); - - // delta of membrane potential - // dV/dt = (I + GL (VL - V) + GCa M (VCa - V) + GK N (VK - V)) / C - arpra_div(out, out, C); -} - -struct dRdt_params -{ - arpra_range *a; - arpra_range *b; - arpra_range *k; - arpra_range *VPre_lo; - arpra_range *VPre_hi; - arpra_range *threshold; - int *in; - arpra_uint pre_syn_size; - arpra_range *one; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dRdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dRdt_params *p = (struct dRdt_params *) params; - const arpra_range *R = &(x[x_grp][x_dim]); - const arpra_range *a = p->a; - const arpra_range *b = p->b; - const arpra_range *k = p->k; - const arpra_range *VPre = p->in[x_dim % p->pre_syn_size] ? p->VPre_hi : p->VPre_lo; - const arpra_range *threshold = p->threshold; - const arpra_range *one = p->one; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // Sigmoid of threshold difference - arpra_sub(temp1, VPre, threshold); - arpra_mul(temp1, temp1, k); - arpra_exp(temp1, temp1); - arpra_add(temp1, temp1, one); - arpra_inv(temp1, temp1); - - // Presynaptic transmitter release rise - arpra_mul(temp1, a, temp1); - - // Presynaptic transmitter release decay - arpra_mul(temp2, b, R); - - // delta of presynaptic transmitter release - // dR/dt = a Q - b R - // Q = 1 / (1 + e^(k(V - threshold))) - arpra_sub(out, temp1, temp2); -} - -struct dSdt_params -{ - arpra_uint grp_R; - arpra_range *a; - arpra_range *b; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dSdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dSdt_params *p = (struct dSdt_params *) params; - const arpra_range *S = &(x[x_grp][x_dim]); - const arpra_range *R = &(x[p->grp_R][x_dim]); - const arpra_range *a = p->a; - const arpra_range *b = p->b; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // Postsynaptic transmitter binding rise - arpra_mul(temp1, a, R); - - // Postsynaptic transmitter binding decay - arpra_mul(temp2, b, S); - - // delta of postsynaptic transmitter binding - // dS/dt = a R - b S - arpra_sub(out, temp1, temp2); -} - -int main (int argc, char *argv[]) -{ - arpra_uint i, j; - arpra_range h, sys_t; - - // Input and conductance files - FILE *in_file = fopen("input.dat", "w"); - FILE *g_file = fopen("conductance.dat", "w"); - - enum grps { grp_nrn1_N, grp_nrn1_V, grp_syn_exc_R, grp_syn_exc_S }; - - arpra_set_internal_precision(p_prec_internal); - - // Initialise arpra_reduce_small_rel threshold. - mpfr_t reduce_rel; - mpfr_init2(reduce_rel, 53); - mpfr_set_d(reduce_rel, p_reduce_rel, MPFR_RNDN); - - // Allocate system state - arpra_range *nrn1_N = malloc(p_nrn1_size * sizeof(arpra_range)); - arpra_range *nrn1_V = malloc(p_nrn1_size * sizeof(arpra_range)); - arpra_range *syn_exc_R = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *syn_exc_S = malloc(p_syn_exc_size * sizeof(arpra_range)); - - // Allocate other arrays - arpra_range *syn_exc_GSyn = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *I1 = malloc(p_in1_size * sizeof(arpra_range)); - int *in1 = malloc(p_in1_size * sizeof(int)); - arpra_uint *nrn1_N_reduce_epoch = malloc(p_nrn1_size * sizeof(arpra_uint)); - arpra_uint *nrn1_V_reduce_epoch = malloc(p_nrn1_size * sizeof(arpra_uint)); - arpra_uint *syn_exc_R_reduce_epoch = malloc(p_syn_exc_size * sizeof(arpra_uint)); - arpra_uint *syn_exc_S_reduce_epoch = malloc(p_syn_exc_size * sizeof(arpra_uint)); - - mpfr_t in1_p0, rand_uf, rand_nf; - arpra_range GL, VL, GCa, VCa, GK, VK, V1, V2, V3, V4, phi, C, - syn_exc_VSyn, syn_exc_thr, syn_exc_a, syn_exc_b, syn_exc_k, - syn_VSyn, syn_thr, syn_a, syn_b, syn_k, one, two, neg_two, - temp1, temp2, M_ss, N_ss, in1_V_lo, in1_V_hi; - - struct timespec clock_time; - - // Initialise uniform float RNG - gmp_randstate_t rng_uf; - gmp_randinit_default(rng_uf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uf_seed - unsigned long rng_uf_seed = p_rng_uf_seed; -#else - unsigned long rng_uf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uf, rng_uf_seed); - printf("GMP rand uniform float seed: %lu\n", rng_uf_seed); - - // Initialise normal float RNG - gmp_randstate_t rng_nf; - gmp_randinit_default(rng_nf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_nf_seed - unsigned long rng_nf_seed = p_rng_nf_seed; -#else - unsigned long rng_nf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_nf, rng_nf_seed); - printf("GMP rand normal float seed: %lu\n", rng_nf_seed); - - // Initialise system state - arpra_init2(&h, p_prec); - arpra_init2(&sys_t, p_prec); - for (i = 0; i < p_nrn1_size; i++) { - arpra_init2(&(nrn1_N[i]), p_prec); - arpra_init2(&(nrn1_V[i]), p_prec); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_init2(&(syn_exc_R[i]), p_prec); - arpra_init2(&(syn_exc_S[i]), p_prec); - } - - // Initialise Poisson input parameters (group 1) - mpfr_init2(in1_p0, p_prec); - arpra_init2(&in1_V_lo, p_prec); - arpra_init2(&in1_V_hi, p_prec); - - // Initialise neuron parameters - arpra_init2(&GL, p_prec); - arpra_init2(&GCa, p_prec); - arpra_init2(&GK, p_prec); - arpra_init2(&VL, p_prec); - arpra_init2(&VCa, p_prec); - arpra_init2(&VK, p_prec); - arpra_init2(&V1, p_prec); - arpra_init2(&V2, p_prec); - arpra_init2(&V3, p_prec); - arpra_init2(&V4, p_prec); - arpra_init2(&phi, p_prec); - arpra_init2(&C, p_prec); - - // Initialise excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - arpra_init2(&(syn_exc_GSyn[i]), p_prec); - } - arpra_init2(&syn_exc_VSyn, p_prec); - arpra_init2(&syn_exc_thr, p_prec); - arpra_init2(&syn_exc_a, p_prec); - arpra_init2(&syn_exc_b, p_prec); - arpra_init2(&syn_exc_k, p_prec); - - // Initialise constants - arpra_init2(&one, p_prec); - arpra_init2(&two, p_prec); - arpra_init2(&neg_two, p_prec); - - // Initialise scratch space - mpfr_init2(rand_uf, p_rand_prec); - mpfr_init2(rand_nf, p_rand_prec); - arpra_init2(&temp1, p_prec); - arpra_init2(&temp2, p_prec); - arpra_init2(&M_ss, p_prec); - arpra_init2(&N_ss, p_prec); - for (i = 0; i < p_in1_size; i++) { - arpra_init2(&(I1[i]), p_prec); - } - - // Set system state - arpra_set_d(&h, p_h); - arpra_set_d(&sys_t, p_t0); - for (i = 0; i < p_nrn1_size; i++) { - arpra_set_d(&(nrn1_N[i]), p_nrn1_N0); - arpra_set_d(&(nrn1_V[i]), p_nrn1_V0); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_set_d(&(syn_exc_R[i]), p_syn_exc_R0); - arpra_set_d(&(syn_exc_S[i]), p_syn_exc_S0); - } - - // Set Poisson input parameters (group 1) - mpfr_set_d(in1_p0, -(p_in1_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in1_p0, in1_p0, MPFR_RNDN); - arpra_set_d(&in1_V_lo, p_in1_V_lo); - arpra_set_d(&in1_V_hi, p_in1_V_hi); - - // Set neuron parameters - arpra_set_d(&GL, p_GL); - arpra_set_d(&GCa, p_GCa); - arpra_set_d(&GK, p_GK); - arpra_set_d(&VL, p_VL); - arpra_set_d(&VCa, p_VCa); - arpra_set_d(&VK, p_VK); - arpra_set_d(&V1, p_V1); - arpra_set_d(&V2, p_V2); - arpra_set_d(&V3, p_V3); - arpra_set_d(&V4, p_V4); - arpra_set_d(&phi, p_phi); - arpra_set_d(&C, p_C); - - // Set excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_exc_GSyn_std, MPFR_RNDN); - mpfr_add_d(rand_nf, rand_nf, p_syn_exc_GSyn_mean, MPFR_RNDN); - arpra_set_mpfr(&(syn_exc_GSyn[i]), rand_nf); - } - arpra_set_d(&syn_exc_VSyn, p_syn_exc_VSyn); - arpra_set_d(&syn_exc_thr, p_syn_exc_thr); - arpra_set_d(&syn_exc_a, p_syn_exc_a); - arpra_set_d(&syn_exc_b, p_syn_exc_b); - arpra_set_d(&syn_exc_k, p_syn_exc_k); - arpra_neg(&syn_exc_k, &syn_exc_k); - - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_out_str(g_file, 10, 80, &(syn_exc_GSyn[i].centre), MPFR_RNDN); - fprintf(g_file, "\n"); - } - - // Set constants - arpra_set_d(&one, 1.0); - arpra_set_d(&two, 2.0); - arpra_set_d(&neg_two, -2.0); - - // Initialise report files - FILE **f_time = malloc(sizeof(FILE *));; - file_init("time", 1, f_time); - - FILE **f_nrn1_N = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_N", p_nrn1_size, f_nrn1_N); - FILE **f_nrn1_V = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_V", p_nrn1_size, f_nrn1_V); - - /* // Initialise report files */ - /* FILE **f_time_c = malloc(sizeof(FILE *));; */ - /* FILE **f_time_r = malloc(sizeof(FILE *));; */ - /* FILE **f_time_n = malloc(sizeof(FILE *));; */ - /* FILE **f_time_s = malloc(sizeof(FILE *));; */ - /* FILE **f_time_d = malloc(sizeof(FILE *));; */ - /* file_init("time", 1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); */ - - /* FILE **f_nrn1_N_c = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_N_r = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_N_n = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_N_s = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_N_d = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* file_init("nrn1_N", p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); */ - /* FILE **f_nrn1_V_c = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_V_r = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_V_n = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_V_s = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* FILE **f_nrn1_V_d = malloc(p_nrn1_size * sizeof(FILE *)); */ - /* file_init("nrn1_V", p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); */ - - /* FILE **f_syn_exc_R_c = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_r = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_n = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_s = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_d = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_R", p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* FILE **f_syn_exc_S_c = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_r = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_n = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_s = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_d = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_S", p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - - // Set parameter structs - struct dNdt_params params_nrn1_N = { - .grp_V = grp_nrn1_V, - .V3 = &V3, - .V4 = &V4, - .phi = &phi, - .one = &one, - .two = &two, - .neg_two = &neg_two, - .N_ss = &N_ss, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dVdt_params params_nrn1_V = { - .grp_N = grp_nrn1_N, - .grp_S = grp_syn_exc_S, - .GSyn = syn_exc_GSyn, - .VSyn = &syn_exc_VSyn, - .GL = &GL, - .VL = &VL, - .GCa = &GCa, - .VCa = &VCa, - .GK = &GK, - .VK = &VK, - .V1 = &V1, - .V2 = &V2, - .V1 = &V1, - .V2 = &V2, - .C = &C, - .pre_syn_size = p_in1_size, - .one = &one, - .neg_two = &neg_two, - .I = I1, - .M_ss = &M_ss, - .temp1 = &temp1, - }; - - struct dRdt_params params_syn_exc_R = { - .a = &syn_exc_a, - .b = &syn_exc_b, - .k = &syn_exc_k, - .VPre_lo = &in1_V_lo, - .VPre_hi = &in1_V_hi, - .threshold = &syn_exc_thr, - .in = in1, - .pre_syn_size = p_in1_size, - .one = &one, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dSdt_params params_syn_exc_S = { - .grp_R = grp_syn_exc_R, - .a = &syn_exc_a, - .b = &syn_exc_b, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - // ODE system - arpra_uint sys_grps = 4; - arpra_uint sys_dims[4] = { - p_nrn1_size, p_nrn1_size, p_syn_exc_size, p_syn_exc_size - }; - arpra_ode_f sys_f[4] = { - dNdt, dVdt, dRdt, dSdt - }; - void *sys_params[4] = { - ¶ms_nrn1_N, ¶ms_nrn1_V, ¶ms_syn_exc_R, ¶ms_syn_exc_S - }; - arpra_range *sys_x[4] = { - nrn1_N, nrn1_V, syn_exc_R, syn_exc_S - }; - arpra_ode_system ode_system = { - .f = sys_f, - .params = sys_params, - .t = &sys_t, - .x = sys_x, - .grps = sys_grps, - .dims = sys_dims, - }; - - // ODE stepper - arpra_ode_stepper ode_stepper; - arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_euler); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_trapezoidal); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_bogsham32); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_dopri54); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_dopri87); - - - // Begin simulation loop - // ===================== - - clock_t run_time = clock(); - - for (i = 0; i < p_sim_steps; i++) { - if (i % p_report_step == 0) printf("%lu\n", i); - - for (j = 0; j < p_nrn1_size; j++) { - nrn1_N_reduce_epoch[j] = ode_system.x[grp_nrn1_N][j].nTerms; - nrn1_V_reduce_epoch[j] = ode_system.x[grp_nrn1_V][j].nTerms; - } - for (j = 0; j < p_syn_exc_size; j++) { - syn_exc_R_reduce_epoch[j] = ode_system.x[grp_syn_exc_R][j].nTerms; - syn_exc_S_reduce_epoch[j] = ode_system.x[grp_syn_exc_S][j].nTerms; - } - - // Event(s) occur if urandom >= e^-rate - for (j = 0; j < p_in1_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in1[j] = mpfr_greaterequal_p(rand_uf, in1_p0); - //fprintf(stderr, "%s", (in1[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - fprintf(in_file, "%d ", in1[j]); - } - //fprintf(stderr, "\n"); - fprintf(in_file, "\n"); - - // Step system - arpra_ode_stepper_step(&ode_stepper, &h); - - arpra_uint reduce_n; - for (j = 0; j < p_nrn1_size; j++) { - reduce_n = ode_system.x[grp_nrn1_N][j].nTerms - nrn1_N_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn1_N][j]), &(ode_system.x[grp_nrn1_N][j]), reduce_n); - reduce_n = ode_system.x[grp_nrn1_V][j].nTerms - nrn1_V_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn1_V][j]), &(ode_system.x[grp_nrn1_V][j]), reduce_n); - } - for (j = 0; j < p_syn_exc_size; j++) { - reduce_n = ode_system.x[grp_syn_exc_R][j].nTerms - syn_exc_R_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_exc_R][j]), &(ode_system.x[grp_syn_exc_R][j]), reduce_n); - reduce_n = ode_system.x[grp_syn_exc_S][j].nTerms - syn_exc_S_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_exc_S][j]), &(ode_system.x[grp_syn_exc_S][j]), reduce_n); - } - - if (i % p_reduce_step == 0) { - for (j = 0; j < p_nrn1_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_nrn1_N][j]), &(ode_system.x[grp_nrn1_N][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_nrn1_V][j]), &(ode_system.x[grp_nrn1_V][j]), reduce_rel); - } - for (j = 0; j < p_syn_exc_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_syn_exc_R][j]), &(ode_system.x[grp_syn_exc_R][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_syn_exc_S][j]), &(ode_system.x[grp_syn_exc_S][j]), reduce_rel); - } - } - - file_write(&sys_t, 1, f_time); - - file_write(nrn1_N, p_nrn1_size, f_nrn1_N); - file_write(nrn1_V, p_nrn1_size, f_nrn1_V); - - /* file_write(&sys_t, 1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); */ - - /* file_write(nrn1_N, p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); */ - /* file_write(nrn1_V, p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); */ - - /* file_write(syn_exc_R, p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* file_write(syn_exc_S, p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - } - - run_time = clock() - run_time; - printf("Finished in %f seconds.\n", ((float) run_time) / CLOCKS_PER_SEC); - - // End simulation loop - // =================== - - - // Clear arpra_reduce_small_rel threshold. - mpfr_clear(reduce_rel); - - // Clear system state - arpra_clear(&h); - arpra_clear(&sys_t); - for (i = 0; i < p_nrn1_size; i++) { - arpra_clear(&(nrn1_N[i])); - arpra_clear(&(nrn1_V[i])); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_clear(&(syn_exc_R[i])); - arpra_clear(&(syn_exc_S[i])); - } - - // Clear Poisson input parameters (group 1) - mpfr_clear(in1_p0); - arpra_clear(&in1_V_lo); - arpra_clear(&in1_V_hi); - - // Clear neuron parameters - arpra_clear(&GL); - arpra_clear(&GCa); - arpra_clear(&GK); - arpra_clear(&VL); - arpra_clear(&VCa); - arpra_clear(&VK); - arpra_clear(&V1); - arpra_clear(&V2); - arpra_clear(&V3); - arpra_clear(&V4); - arpra_clear(&phi); - arpra_clear(&C); - - // Clear excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - arpra_clear(&(syn_exc_GSyn[i])); - } - arpra_clear(&syn_exc_VSyn); - arpra_clear(&syn_exc_thr); - arpra_clear(&syn_exc_a); - arpra_clear(&syn_exc_b); - arpra_clear(&syn_exc_k); - - // Clear constants - arpra_clear(&one); - arpra_clear(&two); - arpra_clear(&neg_two); - - // Clear scratch space - mpfr_clear(rand_uf); - mpfr_clear(rand_nf); - arpra_clear(&temp1); - arpra_clear(&temp2); - arpra_clear(&M_ss); - arpra_clear(&N_ss); - for (i = 0; i < p_in1_size; i++) { - arpra_clear(&(I1[i])); - } - - // Free system state - free(nrn1_N); - free(nrn1_V); - free(syn_exc_R); - free(syn_exc_S); - - // Free other arrays - free(syn_exc_GSyn); - free(I1); - free(in1); - free(nrn1_N_reduce_epoch); - free(nrn1_V_reduce_epoch); - free(syn_exc_R_reduce_epoch); - free(syn_exc_S_reduce_epoch); - - // Clear report files - file_clear(1, f_time); - free(f_time); - file_clear(p_nrn1_size, f_nrn1_N); - free(f_nrn1_N); - file_clear(p_nrn1_size, f_nrn1_V); - free(f_nrn1_V); - - /* file_clear(1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); */ - /* free(f_time_c); */ - /* free(f_time_r); */ - /* free(f_time_n); */ - /* free(f_time_s); */ - /* free(f_time_d); */ - - /* file_clear(p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); */ - /* free(f_nrn1_N_c); */ - /* free(f_nrn1_N_r); */ - /* free(f_nrn1_N_n); */ - /* free(f_nrn1_N_s); */ - /* free(f_nrn1_N_d); */ - /* file_clear(p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); */ - /* free(f_nrn1_V_c); */ - /* free(f_nrn1_V_r); */ - /* free(f_nrn1_V_n); */ - /* free(f_nrn1_V_s); */ - /* free(f_nrn1_V_d); */ - - /* file_clear(p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* free(f_syn_exc_R_c); */ - /* free(f_syn_exc_R_r); */ - /* free(f_syn_exc_R_n); */ - /* free(f_syn_exc_R_s); */ - /* free(f_syn_exc_R_d); */ - /* file_clear(p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - /* free(f_syn_exc_S_c); */ - /* free(f_syn_exc_S_r); */ - /* free(f_syn_exc_S_n); */ - /* free(f_syn_exc_S_s); */ - /* free(f_syn_exc_S_d); */ - - fclose(in_file); - fclose(g_file); - - arpra_ode_stepper_clear(&ode_stepper); - arpra_clear_buffers(); - gmp_randclear(rng_uf); - gmp_randclear(rng_nf); - mpfr_free_cache(); - - return 0; -} diff --git a/experiments/experiment_3/morris_lecar_intlab.m b/experiments/experiment_3/morris_lecar_intlab.m deleted file mode 100644 index fe10d2a..0000000 --- a/experiments/experiment_3/morris_lecar_intlab.m +++ /dev/null @@ -1,217 +0,0 @@ - -format long; -intvalinit('DisplayInfsup') -affariinit(); -affariinit('DisplayIntval'); - -% General parameters -global h = affari(0.5); -global t = affari(0.0); -global sim_steps = 1000; -global report_step = 20; -global iter; - -% Neuron parameters -global N = affari(0.0); -global V = affari(-60.0); -global GL = affari(2.0); -global GCa = affari(4.0); % Class 1 -%global GCa = affari(4.4); % Class 2 -global GK = affari(8.0); -global VL = affari(-60.0); -global VCa = affari(120.0); -global VK = affari(-80.0); -global V1 = affari(-1.2); -global V2 = affari(18.0); -global V3 = affari(12.0); % Class 1 -%global V3 = affari(2.0); % Class 2 -global V4 = affari(17.4); % Class 1 -%global V4 = affari(30.0); % Class 2 -global phi = affari(1.0 / 15.0); % Class 1 -%global phi = affari(1.0 / 25.0); % Class 2 -global C = affari(20.0); - -% Synapse parameters (excitatory) -global in_size = 50; -global R = affari(zeros(in_size, 1)); -global d_R = affari(zeros(in_size, 1)); -global S = affari(zeros(in_size, 1)); -global I = affari(zeros(in_size, 1)); -global syn_a = affari(0.25); -global syn_b = affari(0.15); -global syn_k = affari(-1.0E6); -global threshold = affari(-50.0); -global VSyn = affari(0.0); -global GSyn = affari(dlmread('conductance.dat')); -global in = dlmread('input.dat'); -global in_V_lo = affari(-60.0); -global in_V_hi = affari(20.0); -global VPre = affari(zeros(in_size, 1)); - - -% ===================== end of model parameters ====================== - - -function d_N = dNdt () - global N V V3 V4 phi; - - % K+ channel activation steady-state - % N_ss = 1 / (1 + exp(-2 (V - V3) / V4)) - temp1 = V .- V3; - N_ss = -2 .* temp1; - N_ss = N_ss ./ V4; - N_ss = exp(N_ss); - N_ss = 1 .+ N_ss; - N_ss = 1 ./ N_ss; - - % tau of K+ channel activation - % tau = 1 / (phi ((p + q) / 2)) - % p = exp(-(V - V3) / (2 V4)) - % q = exp( (V - V3) / (2 V4)) - temp2 = 2 .* V4; - temp2 = temp1 / temp2; - temp1 = -temp2; - temp1 = exp(temp1); - temp2 = exp(temp2); - temp1 = temp1 .+ temp2; - temp1 = temp1 ./ 2; - temp1 = phi * temp1; - temp1 = 1 ./ temp1; - - % delta of K+ channel activation - % dN/dt = (N_ss - N) / tau - d_N = N_ss .- N; - d_N = d_N ./ temp1; -end - - -function d_V = dVdt () - global N S V V1 V2 VSyn VL VCa VK GSyn GL GCa GK C in_size; - - % Ca++ channel activation steady-state - % M_ss = 1 / (1 + exp(-2 (V - V1) / V2)) - M_ss = V .- V1; - M_ss = -2 .* M_ss; - M_ss = M_ss ./ V2; - M_ss = exp(M_ss); - M_ss = 1 .+ M_ss; - M_ss = 1 ./ M_ss; - - % Synapse current - temp1 = VSyn - V; - d_V = affari(0); - for i = 1:in_size - I(i) = temp1 * GSyn(i); - I(i) = I(i) * S(i); - d_V = d_V + I(i); - end - - % Leak current - temp1 = V .- VL; - temp1 = temp1 .* GL; - d_V = d_V .- temp1; - - % Ca++ current - temp1 = V .- VCa; - temp1 = temp1 .* GCa; - temp1 = temp1 .* M_ss; - d_V = d_V .- temp1; - - % K+ current - temp1 = V .- VK; - temp1 = temp1 .* GK; - temp1 = temp1 .* N; - d_V = d_V .- temp1; - - % delta of membrane potential - % dV/dt = (I + GL (VL - V) + GCa M (VCa - V) + GK N (VK - V)) / C - d_V = d_V ./ C; -end - - -function d_R = dRdt () - global R in in_V_lo in_V_hi VPre syn_a syn_b syn_k threshold in_size iter; - - VPre(in(iter, :) == 1) = in_V_hi; - VPre(in(iter, :) == 0) = in_V_lo; - - % Sigmoid of threshold difference - temp1 = VPre .- threshold; - temp1 = temp1 .* syn_k; - temp1 = exp(temp1); - temp1 = temp1 .+ 1; - temp1 = 1 ./ temp1; - - % Presynaptic transmitter release rise - temp1 = syn_a .* temp1; - - % Presynaptic transmitter release decay - temp2 = syn_b .* R; - - % delta of presynaptic transmitter release - % dR/dt = a Q - b R - % Q = 1 / (1 + e^(k(V - threshold))) - d_R = temp1 .- temp2; -end - - -function d_S = dSdt () - global R S syn_a syn_b; - - % Postsynaptic transmitter binding rise - temp1 = syn_a .* R; - - % Postsynaptic transmitter binding decay - temp2 = syn_b .* S; - - % delta of postsynaptic transmitter binding - % dS/dt = a R - b S - d_S = temp1 .- temp2; -end - - -% Initialise report files -N_file = fopen('nrn1_N_intlab.dat', 'w'); -V_file = fopen('nrn1_V_intlab.dat', 'w'); - - -% Begin simulation loop -% ===================== - -tic; - -for iter = 1:sim_steps - if mod(iter, report_step) == 0 - disp (iter); - end - - % Compute derivatives - d_N = dNdt(); - d_V = dVdt(); - d_R = dRdt(); - d_S = dSdt(); - - % Step system - t = t .+ h; - d_N = d_N .* h; - N = N .+ d_N; - d_V = d_V .* h; - V = V .+ d_V; - for j = 1:in_size - d_R(j) = d_R(j) .* h; - R(j) = R(j) .+ d_R(j); - d_S(j) = d_S(j) .* h; - S(j) = S(j) .+ d_S(j); - end - - N - V - - fprintf(N_file, '%.60f %.60f\n', N.inf, N.sup); - fprintf(V_file, '%.60f %.60f\n', V.inf, V.sup); -end - -toc; - -fclose(N_file); -fclose(V_file); diff --git a/experiments/fig5/fig5.py b/experiments/fig5/fig5.py deleted file mode 100644 index 1b0f11c..0000000 --- a/experiments/fig5/fig5.py +++ /dev/null @@ -1,205 +0,0 @@ - -import numpy as np -import matplotlib.pyplot as plt -from contextlib import ExitStack -from itertools import islice - -# SETUP -# %load_ext autoreload -# %autoreload 2 -# from experiments.experiment_2 import experiment_2 -# ##### - - -def experiment_2 (): - - experiment = 'fig2' - experiment_new = 'fig5' - - v_name = 'nrn1_V_000' - n_name = 'nrn1_N_000' - t_name = 'time_000' - - samples = 100 - v = [None] * samples - n = [None] * samples - t = [None] * samples - - fig = plt.figure() - fig.canvas.set_window_title(experiment_new) - - # ax_traj = fig.add_subplot(121) - # ax_x = fig.add_subplot(222) - # ax_y = fig.add_subplot(224, sharex=ax_x) - - - ax_x = fig.add_subplot(221) - ax_y = fig.add_subplot(223, sharex=ax_x) - ax_diff_x = fig.add_subplot(222) - ax_diff_y = fig.add_subplot(224, sharex=ax_diff_x) - - - for i in range(samples): - [v[i], n[i], t[i]] = arpra_mpfr_read(path=experiment + '_out/i_' + str(i)) - [v_asc, n_asc, t_asc] = arpra_mpfr_read(path=experiment + '_out/ascending') - [v_desc, n_desc, t_desc] = arpra_mpfr_read(path=experiment +'_out/descending') - [v_hp, n_hp, t_hp] = arpra_mpfr_read(path=experiment + '_out/high_prec') - [v_ia, n_ia, t_ia] = arpra_mpfi_read(path=experiment + '_out/mpfi') - [v_arp_c, v_arp_r, n_arp_c, n_arp_r, t_arp_c, t_arp_r] = arpra_read(path=experiment_new + '_out/arpra') - - v_mean = np.mean(v, axis=0) - v_std = np.std(v, axis=0) - n_mean = np.mean(n, axis=0) - n_std = np.std(n, axis=0) - - v_arp_lo = v_arp_c - v_arp_r - v_arp_hi = v_arp_c + v_arp_r - n_arp_lo = n_arp_c - n_arp_r - n_arp_hi = n_arp_c + n_arp_r - - v_mean_std_lo = v_mean - v_std - v_mean_std_hi = v_mean + v_std - n_mean_std_lo = n_mean - n_std - n_mean_std_hi = n_mean + n_std - - v_arp_diff_lo = np.abs(v_arp_lo - v_mean_std_lo) - v_arp_diff_hi = np.abs(v_arp_hi - v_mean_std_hi) - v_arp_diff = np.maximum(v_arp_diff_lo, v_arp_diff_hi) - n_arp_diff_lo = np.abs(n_arp_lo - n_mean_std_lo) - n_arp_diff_hi = np.abs(n_arp_hi - n_mean_std_hi) - n_arp_diff = np.maximum(n_arp_diff_lo, n_arp_diff_hi) - - # for i in range(samples): - # ax_x.plot(t[i], v[i], 'b') - # ax_y.plot(t[i], n[i], 'b') - # ax_x.plot(t_asc, v_asc, 'y') - # ax_y.plot(t_asc, n_asc, 'y') - # ax_x.plot(t_desc, v_desc, 'y') - # ax_y.plot(t_desc, n_desc, 'y') - # ax_x.plot(t_hp, v_hp, 'k') - # ax_y.plot(t_hp, n_hp, 'k') - # ax_traj.plot(v_hp, n_hp, 'b') - - - ax_x.plot(t_arp_c, v_arp_lo, 'r', label='affine') - ax_x.plot(t_arp_c, v_arp_hi, 'r') - ax_y.plot(t_arp_c, n_arp_lo, 'r', label='affine') - ax_y.plot(t_arp_c, n_arp_hi, 'r') - - # ax_x.plot(t_arp_c, v_ia[:, 0], 'g', label='interval') - # ax_x.plot(t_arp_c, v_ia[:, 1], 'g') - # ax_y.plot(t_arp_c, n_ia[:, 0], 'g', label='interval') - # ax_y.plot(t_arp_c, n_ia[:, 1], 'g') - - ax_x.plot(t_arp_c, v_mean_std_lo, 'b', label='floating-point') - ax_x.plot(t_arp_c, v_mean_std_hi, 'b') - ax_y.plot(t_arp_c, n_mean_std_lo, 'b') - ax_y.plot(t_arp_c, n_mean_std_hi, 'b', label='floating-point') - - ax_diff_x.plot(t_arp_c, v_arp_diff, 'r') - ax_diff_y.plot(t_arp_c, n_arp_diff, 'r') - - - ax_x.set_ylim([-70, 50]) - ax_y.set_ylim([-0.2, 0.5]) - ax_x.set_xlabel('time') - ax_x.set_ylabel('V') - ax_y.set_xlabel('time') - ax_y.set_ylabel('N') - ax_x.legend() - ax_y.legend() - - ax_diff_x.set_yscale('log') - ax_diff_y.set_yscale('log') - - plt.show() - return - - -def arpra_read (path='.', x='nrn1_V_000', y='nrn1_N_000', t='time_000', - i_start=None, i_stop=None, i_step=None): - - with ExitStack() as stack: - xc_file = stack.enter_context(open(path + '/' + x + '_c.dat', 'r')) - xr_file = stack.enter_context(open(path + '/' + x + '_r.dat', 'r')) - yc_file = stack.enter_context(open(path + '/' + y + '_c.dat', 'r')) - yr_file = stack.enter_context(open(path + '/' + y + '_r.dat', 'r')) - tc_file = stack.enter_context(open(path + '/' + t + '_c.dat', 'r')) - tr_file = stack.enter_context(open(path + '/' + t + '_r.dat', 'r')) - - xc = np.genfromtxt(islice(xc_file, i_start, i_stop, i_step), dtype=np.float64) - xr = np.genfromtxt(islice(xr_file, i_start, i_stop, i_step), dtype=np.float64) - yc = np.genfromtxt(islice(yc_file, i_start, i_stop, i_step), dtype=np.float64) - yr = np.genfromtxt(islice(yr_file, i_start, i_stop, i_step), dtype=np.float64) - tc = np.genfromtxt(islice(tc_file, i_start, i_stop, i_step), dtype=np.float64) - tr = np.genfromtxt(islice(tr_file, i_start, i_stop, i_step), dtype=np.float64) - - return [xc, xr, yc, yr, tc, tr] - - -def arpra_mpfr_read (path='.', x='nrn1_V_000', y='nrn1_N_000', t='time_000', - i_start=None, i_stop=None, i_step=None): - - with ExitStack() as stack: - x_file = stack.enter_context(open(path + '/' + x + '.dat', 'r')) - y_file = stack.enter_context(open(path + '/' + y + '.dat', 'r')) - t_file = stack.enter_context(open(path + '/' + t + '.dat', 'r')) - - xx = np.genfromtxt(islice(x_file, i_start, i_stop, i_step), dtype=np.float64) - yy = np.genfromtxt(islice(y_file, i_start, i_stop, i_step), dtype=np.float64) - tt = np.genfromtxt(islice(t_file, i_start, i_stop, i_step), dtype=np.float64) - - return [xx, yy, tt] - - -def arpra_mpfi_read (path='.', x='nrn1_V_000', y='nrn1_N_000', t='time_000', - i_start=None, i_stop=None, i_step=None): - - with ExitStack() as stack: - x_file = stack.enter_context(open(path + '/' + x + '.dat', 'r')) - y_file = stack.enter_context(open(path + '/' + y + '.dat', 'r')) - t_file = stack.enter_context(open(path + '/' + t + '.dat', 'r')) - - xx = np.genfromtxt(islice(x_file, i_start, i_stop, i_step), dtype=np.float64) - yy = np.genfromtxt(islice(y_file, i_start, i_stop, i_step), dtype=np.float64) - tt = np.genfromtxt(islice(t_file, i_start, i_stop, i_step), dtype=np.float64) - - return [xx, yy, tt] - - -def arpra_mpfr_plot (x, y, t, path='.', fmt='b', - ax_traj=None, ax_x=None, ax_y=None, - i_start=None, i_stop=None, i_step=None): - - with ExitStack() as stack: - x_file = stack.enter_context(open(path + '/' + x + '.dat', 'r')) - y_file = stack.enter_context(open(path + '/' + y + '.dat', 'r')) - t_file = stack.enter_context(open(path + '/' + t + '.dat', 'r')) - - xx = np.genfromtxt(islice(x_file, i_start, i_stop, i_step), dtype=np.float64) - yy = np.genfromtxt(islice(y_file, i_start, i_stop, i_step), dtype=np.float64) - tt = np.genfromtxt(islice(t_file, i_start, i_stop, i_step), dtype=np.float64) - - if ax_traj: - # Plot (x, y) trajectory - ax_traj.set_xlabel(x) - ax_traj.set_ylabel(y) - ax_traj.plot(xx, yy, fmt) - - if ax_x: - # Plot x through time - ax_x.set_xlabel('time') - ax_x.set_ylabel(x) - ax_x.plot(tt, xx, fmt, label=x) - - if ax_y: - # Plot y through time - ax_y.set_xlabel('time') - ax_y.set_ylabel(y) - ax_y.plot(tt, yy, fmt, label=y) - - return - - -if __name__ == '__main__': - experiment_2() diff --git a/experiments/fig5/fig5.sh b/experiments/fig5/fig5.sh deleted file mode 100755 index b35669e..0000000 --- a/experiments/fig5/fig5.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -fig="fig5" - -echo Begin: ${0} -cd $(dirname ${0})/../.. -make experiments/${fig}/ml-arpra -make experiments/${fig}/ml-mpfr -make experiments/${fig}/ml-mpfi -cd experiments/${fig} -outdir=${fig}_out -rm -rf ${outdir} - -# for i in {0..99}; do -# echo MPFR ${i} -# outsubdir=${outdir}/i_${i} -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../ml-mpfr 53 0" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. -# done - -# echo MPFR ascending -# outsubdir=${outdir}/ascending -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../ml-mpfr 53 1" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. - -# echo MPFR descending -# outsubdir=${outdir}/descending -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../ml-mpfr 53 2" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. - -# echo MPFR high precision -# outsubdir=${outdir}/high_prec -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../ml-mpfr 2048 0" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. - -# echo MPFI interval bounds -# outsubdir=${outdir}/mpfi -# echo Changing to ${outsubdir} -# mkdir -p ${outsubdir} -# cd ${outsubdir} -# cmd="../../ml-mpfi" -# echo ${cmd} -# ${cmd} 2>/dev/null -# cd ../.. - -echo Arpra bounds -outsubdir=${outdir}/arpra -echo Changing to ${outsubdir} -mkdir -p ${outsubdir} -cd ${outsubdir} -cmd="../../ml-arpra 53 2048 500 50" -echo ${cmd} -${cmd} 2>/dev/null -cd ../.. - -python3 ./${fig}.py diff --git a/experiments/fig5/ml-arpra.c b/experiments/fig5/ml-arpra.c deleted file mode 100644 index ce611c4..0000000 --- a/experiments/fig5/ml-arpra.c +++ /dev/null @@ -1,1206 +0,0 @@ -/* - * morris_lecar.c -- Test Morris-Lecar model. - * - * Copyright 2016-2020 James Paul Turner. - * - * This file is part of the Arpra library. - * - * The Arpra library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Arpra library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the Arpra library. If not, see . - */ - -#include -#include -#include -#include - -/* - * Global variables - * ---------------- - * h Step size (msec) - * t Current time (msec) - * - * Neuron variables - * ---------------- - * N Fraction of open K+ channels - * V Membrane potential (mV) - * - * Neuron parameters - * ----------------- - * GL Maximum leak conductance (mS/cm^2) - * VL Equilibrium potential of leak conductance (mV) - * GCa Maximum Ca++ conductance (mS/cm^2) - * VCa Equilibrium potential of Ca++ conductance (mV) - * GK Maximum K+ conductance (mS/cm^2) - * VK Equilibrium potential of K+ conductance (mV) - * V1 Potential at which M_ss(V) = 0.5 (mV) - * V2 Reciprocal of voltage dependence slope of M_ss(V) (mV) - * V3 Potential at which N_ss(V) = 0.5 (mV) - * V4 Reciprocal of voltage dependence slope of N_ss(V) (mV) - * phi (s^-1) - * C Membrane capacitance (uF/cm^2) - * - * Synapse variables - * ----------------- - * R Neurotransmitter release - * S Neurotransmitter binding - * - * Synapse parameters - * ------------------ - * GSyn Maximum synapse conductance (mS/cm^2) - * VSyn Synapse conductance equilibrium potential (mV) - * thr Neuronal spike threshold (mV) - * a Transmitter release/bind rise factor - * b Transmitter release/bind decay factor - * k Steepness of activation function - */ - -// General parameters -#define p_h 0.5 -#define p_t0 0.0 -#define p_prec prec_arg -unsigned long prec_arg; -#define p_prec_internal prec_internal_arg -unsigned long prec_internal_arg; -#define p_sim_steps 1000 -#define p_report_step 20 -#define p_reduce_step 50 -#define p_reduce_rel 0.3 - -// RNG parameters -// Seeds are random if not #defined -#define p_rand_prec 53 -#define p_rng_uf_seed 707135875931353ul -#define p_rng_nf_seed 503108552855933ul - -// Poisson input parameters (group 1) -#define p_in1_size in1_size_arg -arpra_uint in1_size_arg; -#define p_in1_freq in1_freq_arg -double in1_freq_arg; -#define p_in1_V_lo -60.0 -#define p_in1_V_hi 20.0 - -// Poisson input parameters (group 2) -#define p_in2_size 0 -#define p_in2_freq 10.0 -#define p_in2_V_lo -60.0 -#define p_in2_V_hi 20.0 - -// Neuron parameters (group 1) -#define p_nrn1_size 1 -#define p_nrn1_N0 0.0 -#define p_nrn1_V0 -60.0 -#define p_nrn1_class 1 - -// Neuron parameters (group 2) -#define p_nrn2_size 0 -#define p_nrn2_N0 0.0 -#define p_nrn2_V0 -60.0 -#define p_nrn2_class 1 - -// Neuron parameters (common) -#define p_GL 2.0 -#define p_GCa 4.0 // Class 1 -//#define p_GCa 4.4 // Class 2 -#define p_GK 8.0 -#define p_VL -60.0 -#define p_VCa 120.0 -#define p_VK -80.0 -#define p_V1 -1.2 -#define p_V2 18.0 -#define p_V3 12.0 // Class 1 -//#define p_V3 2.0 // Class 2 -#define p_V4 17.4 // Class 1 -//#define p_V4 30.0 // Class 2 -#define p_phi 1.0 / 15.0 // Class 1 -//#define p_phi 1.0 / 25.0 // Class 2 -#define p_C 20.0 - -// Synapse parameters (excitatory) -#define p_syn_exc_size p_in1_size * p_nrn1_size -#define p_syn_exc_R0 0.0 -#define p_syn_exc_S0 0.0 -#define p_syn_exc_GSyn_std 0.05 -#define p_syn_exc_GSyn_mean 25.0 / p_in1_size -#define p_syn_exc_VSyn 0.0 -#define p_syn_exc_thr -50.0 -#define p_syn_exc_a 0.25 // in [1/10, 1/2] -#define p_syn_exc_b 0.15 // in [1/20, 1/4] -#define p_syn_exc_k 1.0E6 - -// Synapse parameters (inhibitory) -#define p_syn_inh_size 0 -#define p_syn_inh_R0 0.0 -#define p_syn_inh_S0 0.0 -#define p_syn_inh_GSyn_std 0.5 -#define p_syn_inh_GSyn_mean 3.0 -#define p_syn_inh_VSyn -80.0 -#define p_syn_inh_thr -50.0 -#define p_syn_inh_a 0.075 // in [1/20, 1/10] -#define p_syn_inh_b 0.035 // in [1/50, 1/20] -#define p_syn_inh_k 1.0E6 - -// ===================== end of model parameters ====================== - - -// DEBUG: print MPFR numbers to stderr -void debug (mpfr_srcptr x) { - mpfr_out_str(stderr, 10, 80, x, MPFR_RNDN); - fputs("\n", stderr); -} - -void file_init (char *grp, arpra_uint grp_size, - FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) -{ - char fname[20]; - arpra_uint i; - - for (i = 0; i < grp_size; i++) { - sprintf(fname, "%s_%03lu_c.dat", grp, i); - c[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_r.dat", grp, i); - r[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_n.dat", grp, i); - n[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_s.dat", grp, i); - s[i] = fopen(fname, "w"); - sprintf(fname, "%s_%03lu_d.dat", grp, i); - d[i] = fopen(fname, "w"); - } -} - -void file_clear (arpra_uint grp_size, FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) -{ - arpra_uint i; - - for (i = 0; i < grp_size; i++) { - fclose(c[i]); - fclose(r[i]); - fclose(n[i]); - fclose(s[i]); - fclose(d[i]); - } -} - -void file_write (const arpra_range *A, arpra_uint grp_size, - FILE **c, FILE **r, FILE **n, FILE **s, FILE **d) -{ - arpra_uint i, j; - - for (i = 0; i < grp_size; i++) { - mpfr_out_str(c[i], 10, 80, &(A[i].centre), MPFR_RNDN); - fputc('\n', c[i]); - mpfr_out_str(r[i], 10, 80, &(A[i].radius), MPFR_RNDN); - fputc('\n', r[i]); - fprintf(n[i], "%lu\n", A[i].nTerms); - for (j = 0; j < A[i].nTerms; j++) { - fprintf(s[i], "%lu ", A[i].symbols[j]); - mpfr_out_str(d[i], 10, 80, &(A[i].deviations[j]), MPFR_RNDN); - fputc(' ', d[i]); - } - fputc('\n', s[i]); - fputc('\n', d[i]); - } -} - -struct dNdt_params -{ - arpra_uint grp_V; - arpra_range *V3; - arpra_range *V4; - arpra_range *phi; - arpra_range *one; - arpra_range *two; - arpra_range *neg_two; - arpra_range *N_ss; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dNdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dNdt_params *p = (struct dNdt_params *) params; - const arpra_range *N = &(x[x_grp][x_dim]); - const arpra_range *V = &(x[p->grp_V][x_dim]); - const arpra_range *V3 = p->V3; - const arpra_range *V4 = p->V4; - const arpra_range *phi = p->phi; - const arpra_range *one = p->one; - const arpra_range *two = p->two; - const arpra_range *neg_two = p->neg_two; - arpra_range *N_ss = p->N_ss; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // K+ channel activation steady-state - // N_ss = 1 / (1 + exp(-2 (V - V3) / V4)) - arpra_sub(temp1, V, V3); - arpra_mul(N_ss, neg_two, temp1); - arpra_div(N_ss, N_ss, V4); - arpra_exp(N_ss, N_ss); - arpra_add(N_ss, one, N_ss); - arpra_inv(N_ss, N_ss); - - // tau of K+ channel activation - // tau = 1 / (phi ((p + q) / 2)) - // p = exp(-(V - V3) / (2 V4)) - // q = exp( (V - V3) / (2 V4)) - arpra_mul(temp2, two, V4); - arpra_div(temp2, temp1, temp2); - arpra_neg(temp1, temp2); - arpra_exp(temp1, temp1); - arpra_exp(temp2, temp2); - arpra_add(temp1, temp1, temp2); - arpra_div(temp1, temp1, two); - arpra_mul(temp1, phi, temp1); - arpra_inv(temp1, temp1); - - // delta of K+ channel activation - // dN/dt = (N_ss - N) / tau - arpra_sub(out, N_ss, N); - arpra_div(out, out, temp1); -} - -struct dVdt_params -{ - arpra_uint grp_N; - arpra_uint grp_S; - arpra_range *GSyn; - arpra_range *VSyn; - arpra_range *GL; - arpra_range *VL; - arpra_range *GCa; - arpra_range *VCa; - arpra_range *GK; - arpra_range *VK; - arpra_range *V1; - arpra_range *V2; - arpra_range *C; - arpra_uint pre_syn_size; - arpra_range *one; - arpra_range *neg_two; - arpra_range *I; - arpra_range *M_ss; - arpra_range *temp1; -}; - -void dVdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dVdt_params *p = (struct dVdt_params *) params; - const arpra_range *V = &(x[x_grp][x_dim]); - const arpra_range *N = &(x[p->grp_N][x_dim]); - const arpra_range *S = &(x[p->grp_S][x_dim * p->pre_syn_size]); - const arpra_range *GSyn = &(p->GSyn[x_dim * p->pre_syn_size]); - const arpra_range *VSyn = p->VSyn; - const arpra_range *GL = p->GL; - const arpra_range *VL = p->VL; - const arpra_range *GCa = p->GCa; - const arpra_range *VCa = p->VCa; - const arpra_range *GK = p->GK; - const arpra_range *VK = p->VK; - const arpra_range *V1 = p->V1; - const arpra_range *V2 = p->V2; - const arpra_range *C = p->C; - const arpra_range *one = p->one; - const arpra_range *neg_two = p->neg_two; - arpra_range *I = p->I; - arpra_range *M_ss = p->M_ss; - arpra_range *temp1 = p->temp1; - arpra_uint i; - - // Ca++ channel activation steady-state - // M_ss = 1 / (1 + exp(-2 (V - V1) / V2)) - arpra_sub(M_ss, V, V1); - arpra_mul(M_ss, neg_two, M_ss); - arpra_div(M_ss, M_ss, V2); - arpra_exp(M_ss, M_ss); - arpra_add(M_ss, one, M_ss); - arpra_inv(M_ss, M_ss); - - // Synapse current - arpra_sub(temp1, VSyn, V); - for (i = 0; i < p->pre_syn_size; i++) { - arpra_mul(&(I[i]), temp1, &(GSyn[i])); - arpra_mul(&(I[i]), &(I[i]), &(S[i])); - } - arpra_sum_recursive(out, I, p->pre_syn_size); - //arpra_sum(out, I, p->pre_syn_size); - - - - - // ======== TEMP DEBUG ========== - //arpra_set_d(out, 80.0); // bifurcation at sum(I) = 80.0 - if (x_dim == 0) { - //fprintf(stderr, "sum(I): "); debug(out->centre); - //fprintf(stderr, "I[0]: "); debug(I[0].centre); - for (i = 0; i < p->pre_syn_size; i++) { - //fprintf(stderr, "I[%lu]: ", i); debug(I[i].centre); - } - } - - - - // Leak current - arpra_sub(temp1, V, VL); - arpra_mul(temp1, temp1, GL); - arpra_sub(out, out, temp1); - - // Ca++ current - arpra_sub(temp1, V, VCa); - arpra_mul(temp1, temp1, GCa); - arpra_mul(temp1, temp1, M_ss); - arpra_sub(out, out, temp1); - - // K+ current - arpra_sub(temp1, V, VK); - arpra_mul(temp1, temp1, GK); - arpra_mul(temp1, temp1, N); - arpra_sub(out, out, temp1); - - // delta of membrane potential - // dV/dt = (I + GL (VL - V) + GCa M (VCa - V) + GK N (VK - V)) / C - arpra_div(out, out, C); -} - -struct dRdt_params -{ - arpra_range *a; - arpra_range *b; - arpra_range *k; - arpra_range *VPre_lo; - arpra_range *VPre_hi; - arpra_range *threshold; - int *in; - arpra_uint pre_syn_size; - arpra_range *one; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dRdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dRdt_params *p = (struct dRdt_params *) params; - const arpra_range *R = &(x[x_grp][x_dim]); - const arpra_range *a = p->a; - const arpra_range *b = p->b; - const arpra_range *k = p->k; - const arpra_range *VPre = p->in[x_dim % p->pre_syn_size] ? p->VPre_hi : p->VPre_lo; - const arpra_range *threshold = p->threshold; - const arpra_range *one = p->one; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // Sigmoid of threshold difference - arpra_sub(temp1, VPre, threshold); - arpra_mul(temp1, temp1, k); - arpra_exp(temp1, temp1); - arpra_add(temp1, temp1, one); - arpra_inv(temp1, temp1); - - // Presynaptic transmitter release rise - arpra_mul(temp1, a, temp1); - - // Presynaptic transmitter release decay - arpra_mul(temp2, b, R); - - // delta of presynaptic transmitter release - // dR/dt = a Q - b R - // Q = 1 / (1 + e^(k(V - threshold))) - arpra_sub(out, temp1, temp2); -} - -struct dSdt_params -{ - arpra_uint grp_R; - arpra_range *a; - arpra_range *b; - arpra_range *temp1; - arpra_range *temp2; -}; - -void dSdt (arpra_range *out, const void *params, - const arpra_range *t, const arpra_range **x, - const arpra_uint x_grp, const arpra_uint x_dim) -{ - const struct dSdt_params *p = (struct dSdt_params *) params; - const arpra_range *S = &(x[x_grp][x_dim]); - const arpra_range *R = &(x[p->grp_R][x_dim]); - const arpra_range *a = p->a; - const arpra_range *b = p->b; - arpra_range *temp1 = p->temp1; - arpra_range *temp2 = p->temp2; - - // Postsynaptic transmitter binding rise - arpra_mul(temp1, a, R); - - // Postsynaptic transmitter binding decay - arpra_mul(temp2, b, S); - - // delta of postsynaptic transmitter binding - // dS/dt = a R - b S - arpra_sub(out, temp1, temp2); -} - -int main (int argc, char *argv[]) -{ - arpra_uint i, j; - arpra_range h, sys_t; - - enum grps { - grp_nrn1_N, grp_nrn1_V, grp_nrn2_N, grp_nrn2_V, - grp_syn_exc_R, grp_syn_exc_S, grp_syn_inh_R, grp_syn_inh_S - }; - - // Parse args - prec_arg = atoll(argv[1]); - prec_internal_arg = atoll(argv[2]); - in1_size_arg = atoi(argv[3]); - in1_freq_arg = atoi(argv[4]); - - arpra_set_internal_precision(p_prec_internal); - - // Initialise arpra_reduce_small_rel threshold. - mpfr_t reduce_rel; - mpfr_init2(reduce_rel, 53); - mpfr_set_d(reduce_rel, p_reduce_rel, MPFR_RNDN); - - // Allocate system state - arpra_range *nrn1_N = malloc(p_nrn1_size * sizeof(arpra_range)); - arpra_range *nrn1_V = malloc(p_nrn1_size * sizeof(arpra_range)); - arpra_range *nrn2_N = malloc(p_nrn2_size * sizeof(arpra_range)); - arpra_range *nrn2_V = malloc(p_nrn2_size * sizeof(arpra_range)); - arpra_range *syn_exc_R = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *syn_exc_S = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *syn_inh_R = malloc(p_syn_inh_size * sizeof(arpra_range)); - arpra_range *syn_inh_S = malloc(p_syn_inh_size * sizeof(arpra_range)); - - // Allocate other arrays - arpra_range *syn_exc_GSyn = malloc(p_syn_exc_size * sizeof(arpra_range)); - arpra_range *syn_inh_GSyn = malloc(p_syn_inh_size * sizeof(arpra_range)); - arpra_range *I1 = malloc(p_in1_size * sizeof(arpra_range)); - arpra_range *I2 = malloc(p_in2_size * sizeof(arpra_range)); - int *in1 = malloc(p_in1_size * sizeof(int)); - int *in2 = malloc(p_in2_size * sizeof(int)); - arpra_uint *nrn1_N_reduce_epoch = malloc(p_nrn1_size * sizeof(arpra_uint)); - arpra_uint *nrn1_V_reduce_epoch = malloc(p_nrn1_size * sizeof(arpra_uint)); - arpra_uint *nrn2_N_reduce_epoch = malloc(p_nrn2_size * sizeof(arpra_uint)); - arpra_uint *nrn2_V_reduce_epoch = malloc(p_nrn2_size * sizeof(arpra_uint)); - arpra_uint *syn_exc_R_reduce_epoch = malloc(p_syn_exc_size * sizeof(arpra_uint)); - arpra_uint *syn_exc_S_reduce_epoch = malloc(p_syn_exc_size * sizeof(arpra_uint)); - arpra_uint *syn_inh_R_reduce_epoch = malloc(p_syn_inh_size * sizeof(arpra_uint)); - arpra_uint *syn_inh_S_reduce_epoch = malloc(p_syn_inh_size * sizeof(arpra_uint)); - - mpfr_t in1_p0, in2_p0, rand_uf, rand_nf; - arpra_range GL, VL, GCa, VCa, GK, VK, V1, V2, V3, V4, phi, C, - syn_exc_VSyn, syn_exc_thr, syn_exc_a, syn_exc_b, syn_exc_k, - syn_inh_VSyn, syn_inh_thr, syn_inh_a, syn_inh_b, syn_inh_k, one, two, neg_two, - temp1, temp2, M_ss, N_ss, in1_V_lo, in1_V_hi, in2_V_lo, in2_V_hi; - - struct timespec clock_time; - - // Initialise uniform float RNG - gmp_randstate_t rng_uf; - gmp_randinit_default(rng_uf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uf_seed - unsigned long rng_uf_seed = p_rng_uf_seed; -#else - unsigned long rng_uf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uf, rng_uf_seed); - printf("GMP rand uniform float seed: %lu\n", rng_uf_seed); - - // Initialise normal float RNG - gmp_randstate_t rng_nf; - gmp_randinit_default(rng_nf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_nf_seed - unsigned long rng_nf_seed = p_rng_nf_seed; -#else - unsigned long rng_nf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_nf, rng_nf_seed); - printf("GMP rand normal float seed: %lu\n", rng_nf_seed); - - // Initialise system state - arpra_init2(&h, p_prec); - arpra_init2(&sys_t, p_prec); - for (i = 0; i < p_nrn1_size; i++) { - arpra_init2(&(nrn1_N[i]), p_prec); - arpra_init2(&(nrn1_V[i]), p_prec); - } - for (i = 0; i < p_nrn2_size; i++) { - arpra_init2(&(nrn2_N[i]), p_prec); - arpra_init2(&(nrn2_V[i]), p_prec); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_init2(&(syn_exc_R[i]), p_prec); - arpra_init2(&(syn_exc_S[i]), p_prec); - } - for (i = 0; i < p_syn_inh_size; i++) { - arpra_init2(&(syn_inh_R[i]), p_prec); - arpra_init2(&(syn_inh_S[i]), p_prec); - } - - // Initialise Poisson input parameters (group 1) - mpfr_init2(in1_p0, p_prec); - arpra_init2(&in1_V_lo, p_prec); - arpra_init2(&in1_V_hi, p_prec); - - // Initialise Poisson input parameters (group 2) - mpfr_init2(in2_p0, p_prec); - arpra_init2(&in2_V_lo, p_prec); - arpra_init2(&in2_V_hi, p_prec); - - // Initialise neuron parameters - arpra_init2(&GL, p_prec); - arpra_init2(&GCa, p_prec); - arpra_init2(&GK, p_prec); - arpra_init2(&VL, p_prec); - arpra_init2(&VCa, p_prec); - arpra_init2(&VK, p_prec); - arpra_init2(&V1, p_prec); - arpra_init2(&V2, p_prec); - arpra_init2(&V3, p_prec); - arpra_init2(&V4, p_prec); - arpra_init2(&phi, p_prec); - arpra_init2(&C, p_prec); - - // Initialise excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - arpra_init2(&(syn_exc_GSyn[i]), p_prec); - } - arpra_init2(&syn_exc_VSyn, p_prec); - arpra_init2(&syn_exc_thr, p_prec); - arpra_init2(&syn_exc_a, p_prec); - arpra_init2(&syn_exc_b, p_prec); - arpra_init2(&syn_exc_k, p_prec); - - // Initialise inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - arpra_init2(&(syn_inh_GSyn[i]), p_prec); - } - arpra_init2(&syn_inh_VSyn, p_prec); - arpra_init2(&syn_inh_thr, p_prec); - arpra_init2(&syn_inh_a, p_prec); - arpra_init2(&syn_inh_b, p_prec); - arpra_init2(&syn_inh_k, p_prec); - - // Initialise constants - arpra_init2(&one, p_prec); - arpra_init2(&two, p_prec); - arpra_init2(&neg_two, p_prec); - - // Initialise scratch space - mpfr_init2(rand_uf, p_rand_prec); - mpfr_init2(rand_nf, p_rand_prec); - arpra_init2(&temp1, p_prec); - arpra_init2(&temp2, p_prec); - arpra_init2(&M_ss, p_prec); - arpra_init2(&N_ss, p_prec); - for (i = 0; i < p_in1_size; i++) { - arpra_init2(&(I1[i]), p_prec); - } - for (i = 0; i < p_in2_size; i++) { - arpra_init2(&(I2[i]), p_prec); - } - - // Set system state - arpra_set_d(&h, p_h); - arpra_set_d(&sys_t, p_t0); - for (i = 0; i < p_nrn1_size; i++) { - arpra_set_d(&(nrn1_N[i]), p_nrn1_N0); - arpra_set_d(&(nrn1_V[i]), p_nrn1_V0); - } - for (i = 0; i < p_nrn2_size; i++) { - arpra_set_d(&(nrn2_N[i]), p_nrn2_N0); - arpra_set_d(&(nrn2_V[i]), p_nrn2_V0); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_set_d(&(syn_exc_R[i]), p_syn_exc_R0); - arpra_set_d(&(syn_exc_S[i]), p_syn_exc_S0); - } - for (i = 0; i < p_syn_inh_size; i++) { - arpra_set_d(&(syn_inh_R[i]), p_syn_inh_R0); - arpra_set_d(&(syn_inh_S[i]), p_syn_inh_S0); - } - - // Set Poisson input parameters (group 1) - mpfr_set_d(in1_p0, -(p_in1_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in1_p0, in1_p0, MPFR_RNDN); - arpra_set_d(&in1_V_lo, p_in1_V_lo); - arpra_set_d(&in1_V_hi, p_in1_V_hi); - - // Set Poisson input parameters (group 2) - mpfr_set_d(in2_p0, -(p_in2_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in2_p0, in2_p0, MPFR_RNDN); - arpra_set_d(&in2_V_lo, p_in2_V_lo); - arpra_set_d(&in2_V_hi, p_in2_V_hi); - - // Set neuron parameters - arpra_set_d(&GL, p_GL); - arpra_set_d(&GCa, p_GCa); - arpra_set_d(&GK, p_GK); - arpra_set_d(&VL, p_VL); - arpra_set_d(&VCa, p_VCa); - arpra_set_d(&VK, p_VK); - arpra_set_d(&V1, p_V1); - arpra_set_d(&V2, p_V2); - arpra_set_d(&V3, p_V3); - arpra_set_d(&V4, p_V4); - arpra_set_d(&phi, p_phi); - arpra_set_d(&C, p_C); - - // Set excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_exc_GSyn_std, MPFR_RNDN); - mpfr_add_d(rand_nf, rand_nf, p_syn_exc_GSyn_mean, MPFR_RNDN); - arpra_set_mpfr(&(syn_exc_GSyn[i]), rand_nf); - } - arpra_set_d(&syn_exc_VSyn, p_syn_exc_VSyn); - arpra_set_d(&syn_exc_thr, p_syn_exc_thr); - arpra_set_d(&syn_exc_a, p_syn_exc_a); - arpra_set_d(&syn_exc_b, p_syn_exc_b); - arpra_set_d(&syn_exc_k, p_syn_exc_k); - arpra_neg(&syn_exc_k, &syn_exc_k); - - // Set inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_inh_GSyn_std, MPFR_RNDN); - mpfr_add_d(rand_nf, rand_nf, p_syn_inh_GSyn_mean, MPFR_RNDN); - arpra_set_mpfr(&(syn_inh_GSyn[i]), rand_nf); - } - arpra_set_d(&syn_inh_VSyn, p_syn_inh_VSyn); - arpra_set_d(&syn_inh_thr, p_syn_inh_thr); - arpra_set_d(&syn_inh_a, p_syn_inh_a); - arpra_set_d(&syn_inh_b, p_syn_inh_b); - arpra_set_d(&syn_inh_k, p_syn_inh_k); - arpra_neg(&syn_inh_k, &syn_inh_k); - - // Set constants - arpra_set_d(&one, 1.0); - arpra_set_d(&two, 2.0); - arpra_set_d(&neg_two, -2.0); - - // Initialise report files - FILE **f_time_c = malloc(sizeof(FILE *));; - FILE **f_time_r = malloc(sizeof(FILE *));; - FILE **f_time_n = malloc(sizeof(FILE *));; - FILE **f_time_s = malloc(sizeof(FILE *));; - FILE **f_time_d = malloc(sizeof(FILE *));; - file_init("time", 1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); - - FILE **f_nrn1_N_c = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_r = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_n = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_s = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_N_d = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_N", p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); - FILE **f_nrn1_V_c = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_r = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_n = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_s = malloc(p_nrn1_size * sizeof(FILE *)); - FILE **f_nrn1_V_d = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_V", p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); - - /* FILE **f_nrn2_N_c = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_r = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_n = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_s = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_N_d = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_N", p_nrn2_size, f_nrn2_N_c, f_nrn2_N_r, f_nrn2_N_n, f_nrn2_N_s, f_nrn2_N_d); */ - /* FILE **f_nrn2_V_c = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_r = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_n = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_s = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* FILE **f_nrn2_V_d = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_V", p_nrn2_size, f_nrn2_V_c, f_nrn2_V_r, f_nrn2_V_n, f_nrn2_V_s, f_nrn2_V_d); */ - - /* FILE **f_syn_exc_R_c = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_r = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_n = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_s = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_R_d = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_R", p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* FILE **f_syn_exc_S_c = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_r = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_n = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_s = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* FILE **f_syn_exc_S_d = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_S", p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - - /* FILE **f_syn_inh_R_c = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_r = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_n = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_s = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_R_d = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_R", p_syn_inh_size, f_syn_inh_R_c, f_syn_inh_R_r, f_syn_inh_R_n, f_syn_inh_R_s, f_syn_inh_R_d); */ - /* FILE **f_syn_inh_S_c = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_r = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_n = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_s = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* FILE **f_syn_inh_S_d = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_S", p_syn_inh_size, f_syn_inh_S_c, f_syn_inh_S_r, f_syn_inh_S_n, f_syn_inh_S_s, f_syn_inh_S_d); */ - - // Set parameter structs - struct dNdt_params params_nrn1_N = { - .grp_V = grp_nrn1_V, - .V3 = &V3, - .V4 = &V4, - .phi = &phi, - .one = &one, - .two = &two, - .neg_two = &neg_two, - .N_ss = &N_ss, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dVdt_params params_nrn1_V = { - .grp_N = grp_nrn1_N, - .grp_S = grp_syn_exc_S, - .GSyn = syn_exc_GSyn, - .VSyn = &syn_exc_VSyn, - .GL = &GL, - .VL = &VL, - .GCa = &GCa, - .VCa = &VCa, - .GK = &GK, - .VK = &VK, - .V1 = &V1, - .V2 = &V2, - .V1 = &V1, - .V2 = &V2, - .C = &C, - .pre_syn_size = p_in1_size, - .one = &one, - .neg_two = &neg_two, - .I = I1, - .M_ss = &M_ss, - .temp1 = &temp1, - }; - - struct dNdt_params params_nrn2_N = { - .grp_V = grp_nrn2_V, - .V3 = &V3, - .V4 = &V4, - .phi = &phi, - .one = &one, - .two = &two, - .neg_two = &neg_two, - .N_ss = &N_ss, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dVdt_params params_nrn2_V = { - .grp_N = grp_nrn2_N, - .grp_S = grp_syn_inh_S, - .GSyn = syn_inh_GSyn, - .VSyn = &syn_inh_VSyn, - .GL = &GL, - .VL = &VL, - .GCa = &GCa, - .VCa = &VCa, - .GK = &GK, - .VK = &VK, - .V1 = &V1, - .V2 = &V2, - .C = &C, - .pre_syn_size = p_in2_size, - .one = &one, - .neg_two = &neg_two, - .I = I2, - .M_ss = &M_ss, - .temp1 = &temp1, - }; - - struct dRdt_params params_syn_exc_R = { - .a = &syn_exc_a, - .b = &syn_exc_b, - .k = &syn_exc_k, - .VPre_lo = &in1_V_lo, - .VPre_hi = &in1_V_hi, - .threshold = &syn_exc_thr, - .in = in1, - .pre_syn_size = p_in1_size, - .one = &one, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dSdt_params params_syn_exc_S = { - .grp_R = grp_syn_exc_R, - .a = &syn_exc_a, - .b = &syn_exc_b, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dRdt_params params_syn_inh_R = { - .a = &syn_inh_a, - .b = &syn_inh_b, - .k = &syn_inh_k, - .VPre_lo = &in2_V_lo, - .VPre_hi = &in2_V_hi, - .threshold = &syn_inh_thr, - .in = in2, - .pre_syn_size = p_in2_size, - .one = &one, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - struct dSdt_params params_syn_inh_S = { - .grp_R = grp_syn_inh_R, - .a = &syn_inh_a, - .b = &syn_inh_b, - .temp1 = &temp1, - .temp2 = &temp2, - }; - - // ODE system - arpra_uint sys_grps = 8; - arpra_uint sys_dims[8] = { - p_nrn1_size, p_nrn1_size, p_nrn2_size, p_nrn2_size, - p_syn_exc_size, p_syn_exc_size, p_syn_inh_size, p_syn_inh_size - }; - arpra_ode_f sys_f[8] = { - dNdt, dVdt, dNdt, dVdt, dRdt, dSdt, dRdt, dSdt - }; - void *sys_params[8] = { - ¶ms_nrn1_N, ¶ms_nrn1_V, ¶ms_nrn2_N, ¶ms_nrn2_V, - ¶ms_syn_exc_R, ¶ms_syn_exc_S, ¶ms_syn_inh_R, ¶ms_syn_inh_S - }; - arpra_range *sys_x[8] = { - nrn1_N, nrn1_V, nrn2_N, nrn2_V, syn_exc_R, syn_exc_S, syn_inh_R, syn_inh_S - }; - arpra_ode_system ode_system = { - .f = sys_f, - .params = sys_params, - .t = &sys_t, - .x = sys_x, - .grps = sys_grps, - .dims = sys_dims, - }; - - // ODE stepper - arpra_ode_stepper ode_stepper; - arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_euler); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_trapezoidal); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_bogsham32); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_dopri54); - //arpra_ode_stepper_init(&ode_stepper, &ode_system, arpra_ode_dopri87); - - - // Begin simulation loop - // ===================== - - clock_t run_time = clock(); - - for (i = 0; i < p_sim_steps; i++) { - if (i % p_report_step == 0) printf("%lu\n", i); - - for (j = 0; j < p_nrn1_size; j++) { - nrn1_N_reduce_epoch[j] = ode_system.x[grp_nrn1_N][j].nTerms; - nrn1_V_reduce_epoch[j] = ode_system.x[grp_nrn1_V][j].nTerms; - } - for (j = 0; j < p_nrn2_size; j++) { - nrn2_N_reduce_epoch[j] = ode_system.x[grp_nrn2_N][j].nTerms; - nrn2_V_reduce_epoch[j] = ode_system.x[grp_nrn2_V][j].nTerms; - } - for (j = 0; j < p_syn_exc_size; j++) { - syn_exc_R_reduce_epoch[j] = ode_system.x[grp_syn_exc_R][j].nTerms; - syn_exc_S_reduce_epoch[j] = ode_system.x[grp_syn_exc_S][j].nTerms; - } - for (j = 0; j < p_syn_inh_size; j++) { - syn_inh_R_reduce_epoch[j] = ode_system.x[grp_syn_inh_R][j].nTerms; - syn_inh_S_reduce_epoch[j] = ode_system.x[grp_syn_inh_S][j].nTerms; - } - - // Event(s) occur if urandom >= e^-rate - for (j = 0; j < p_in1_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in1[j] = mpfr_greaterequal_p(rand_uf, in1_p0); - fprintf(stderr, "%s", (in1[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, " "); - for (j = 0; j < p_in2_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in2[j] = mpfr_greaterequal_p(rand_uf, in2_p0); - fprintf(stderr, "%s", (in2[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, "\n"); - - // Step system - arpra_ode_stepper_step(&ode_stepper, &h); - - arpra_uint reduce_n; - for (j = 0; j < p_nrn1_size; j++) { - reduce_n = ode_system.x[grp_nrn1_N][j].nTerms - nrn1_N_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn1_N][j]), &(ode_system.x[grp_nrn1_N][j]), reduce_n); - reduce_n = ode_system.x[grp_nrn1_V][j].nTerms - nrn1_V_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn1_V][j]), &(ode_system.x[grp_nrn1_V][j]), reduce_n); - } - for (j = 0; j < p_nrn2_size; j++) { - reduce_n = ode_system.x[grp_nrn2_N][j].nTerms - nrn2_N_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn2_N][j]), &(ode_system.x[grp_nrn2_N][j]), reduce_n); - reduce_n = ode_system.x[grp_nrn2_V][j].nTerms - nrn2_V_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_nrn2_V][j]), &(ode_system.x[grp_nrn2_V][j]), reduce_n); - } - for (j = 0; j < p_syn_exc_size; j++) { - reduce_n = ode_system.x[grp_syn_exc_R][j].nTerms - syn_exc_R_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_exc_R][j]), &(ode_system.x[grp_syn_exc_R][j]), reduce_n); - reduce_n = ode_system.x[grp_syn_exc_S][j].nTerms - syn_exc_S_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_exc_S][j]), &(ode_system.x[grp_syn_exc_S][j]), reduce_n); - } - for (j = 0; j < p_syn_inh_size; j++) { - reduce_n = ode_system.x[grp_syn_inh_R][j].nTerms - syn_inh_R_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_inh_R][j]), &(ode_system.x[grp_syn_inh_R][j]), reduce_n); - reduce_n = ode_system.x[grp_syn_inh_S][j].nTerms - syn_inh_S_reduce_epoch[j]; - arpra_reduce_last_n(&(ode_system.x[grp_syn_inh_S][j]), &(ode_system.x[grp_syn_inh_S][j]), reduce_n); - } - - if (i % p_reduce_step == 0) { - for (j = 0; j < p_nrn1_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_nrn1_N][j]), &(ode_system.x[grp_nrn1_N][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_nrn1_V][j]), &(ode_system.x[grp_nrn1_V][j]), reduce_rel); - } - for (j = 0; j < p_nrn2_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_nrn2_N][j]), &(ode_system.x[grp_nrn2_N][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_nrn2_V][j]), &(ode_system.x[grp_nrn2_V][j]), reduce_rel); - } - for (j = 0; j < p_syn_exc_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_syn_exc_R][j]), &(ode_system.x[grp_syn_exc_R][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_syn_exc_S][j]), &(ode_system.x[grp_syn_exc_S][j]), reduce_rel); - } - for (j = 0; j < p_syn_inh_size; j++) { - arpra_reduce_small_rel(&(ode_system.x[grp_syn_inh_R][j]), &(ode_system.x[grp_syn_inh_R][j]), reduce_rel); - arpra_reduce_small_rel(&(ode_system.x[grp_syn_inh_S][j]), &(ode_system.x[grp_syn_inh_S][j]), reduce_rel); - } - } - - file_write(&sys_t, 1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); - - file_write(nrn1_N, p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); - file_write(nrn1_V, p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); - - /* file_write(nrn2_N, p_nrn2_size, f_nrn2_N_c, f_nrn2_N_r, f_nrn2_N_n, f_nrn2_N_s, f_nrn2_N_d); */ - /* file_write(nrn2_V, p_nrn2_size, f_nrn2_V_c, f_nrn2_V_r, f_nrn2_V_n, f_nrn2_V_s, f_nrn2_V_d); */ - - /* file_write(syn_exc_R, p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* file_write(syn_exc_S, p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - - /* file_write(syn_inh_R, p_syn_inh_size, f_syn_inh_R_c, f_syn_inh_R_r, f_syn_inh_R_n, f_syn_inh_R_s, f_syn_inh_R_d); */ - /* file_write(syn_inh_S, p_syn_inh_size, f_syn_inh_S_c, f_syn_inh_S_r, f_syn_inh_S_n, f_syn_inh_S_s, f_syn_inh_S_d); */ - } - - run_time = clock() - run_time; - printf("Finished in %f seconds.\n", ((float) run_time) / CLOCKS_PER_SEC); - - // End simulation loop - // =================== - - - // Clear arpra_reduce_small_rel threshold. - mpfr_clear(reduce_rel); - - // Clear system state - arpra_clear(&h); - arpra_clear(&sys_t); - for (i = 0; i < p_nrn1_size; i++) { - arpra_clear(&(nrn1_N[i])); - arpra_clear(&(nrn1_V[i])); - } - for (i = 0; i < p_nrn2_size; i++) { - arpra_clear(&(nrn2_N[i])); - arpra_clear(&(nrn2_V[i])); - } - for (i = 0; i < p_syn_exc_size; i++) { - arpra_clear(&(syn_exc_R[i])); - arpra_clear(&(syn_exc_S[i])); - } - for (i = 0; i < p_syn_inh_size; i++) { - arpra_clear(&(syn_inh_R[i])); - arpra_clear(&(syn_inh_S[i])); - } - - // Clear Poisson input parameters (group 1) - mpfr_clear(in1_p0); - arpra_clear(&in1_V_lo); - arpra_clear(&in1_V_hi); - - // Clear Poisson input parameters (group 2) - mpfr_clear(in2_p0); - arpra_clear(&in2_V_lo); - arpra_clear(&in2_V_hi); - - // Clear neuron parameters - arpra_clear(&GL); - arpra_clear(&GCa); - arpra_clear(&GK); - arpra_clear(&VL); - arpra_clear(&VCa); - arpra_clear(&VK); - arpra_clear(&V1); - arpra_clear(&V2); - arpra_clear(&V3); - arpra_clear(&V4); - arpra_clear(&phi); - arpra_clear(&C); - - // Clear excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - arpra_clear(&(syn_exc_GSyn[i])); - } - arpra_clear(&syn_exc_VSyn); - arpra_clear(&syn_exc_thr); - arpra_clear(&syn_exc_a); - arpra_clear(&syn_exc_b); - arpra_clear(&syn_exc_k); - - // Clear inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - arpra_clear(&(syn_inh_GSyn[i])); - } - arpra_clear(&syn_inh_VSyn); - arpra_clear(&syn_inh_thr); - arpra_clear(&syn_inh_a); - arpra_clear(&syn_inh_b); - arpra_clear(&syn_inh_k); - - // Clear constants - arpra_clear(&one); - arpra_clear(&two); - arpra_clear(&neg_two); - - // Clear scratch space - mpfr_clear(rand_uf); - mpfr_clear(rand_nf); - arpra_clear(&temp1); - arpra_clear(&temp2); - arpra_clear(&M_ss); - arpra_clear(&N_ss); - for (i = 0; i < p_in1_size; i++) { - arpra_clear(&(I1[i])); - } - for (i = 0; i < p_in2_size; i++) { - arpra_clear(&(I2[i])); - } - - // Free system state - free(nrn1_N); - free(nrn1_V); - free(nrn2_N); - free(nrn2_V); - free(syn_exc_R); - free(syn_exc_S); - free(syn_inh_R); - free(syn_inh_S); - - // Free other arrays - free(syn_exc_GSyn); - free(syn_inh_GSyn); - free(I1); - free(I2); - free(in1); - free(in2); - free(nrn1_N_reduce_epoch); - free(nrn1_V_reduce_epoch); - free(nrn2_N_reduce_epoch); - free(nrn2_V_reduce_epoch); - free(syn_exc_R_reduce_epoch); - free(syn_exc_S_reduce_epoch); - free(syn_inh_R_reduce_epoch); - free(syn_inh_S_reduce_epoch); - - // Clear report files - file_clear(1, f_time_c, f_time_r, f_time_n, f_time_s, f_time_d); - free(f_time_c); - free(f_time_r); - free(f_time_n); - free(f_time_s); - free(f_time_d); - - file_clear(p_nrn1_size, f_nrn1_N_c, f_nrn1_N_r, f_nrn1_N_n, f_nrn1_N_s, f_nrn1_N_d); - free(f_nrn1_N_c); - free(f_nrn1_N_r); - free(f_nrn1_N_n); - free(f_nrn1_N_s); - free(f_nrn1_N_d); - file_clear(p_nrn1_size, f_nrn1_V_c, f_nrn1_V_r, f_nrn1_V_n, f_nrn1_V_s, f_nrn1_V_d); - free(f_nrn1_V_c); - free(f_nrn1_V_r); - free(f_nrn1_V_n); - free(f_nrn1_V_s); - free(f_nrn1_V_d); - - /* file_clear(p_nrn2_size, f_nrn2_N_c, f_nrn2_N_r, f_nrn2_N_n, f_nrn2_N_s, f_nrn2_N_d); */ - /* free(f_nrn2_N_c); */ - /* free(f_nrn2_N_r); */ - /* free(f_nrn2_N_n); */ - /* free(f_nrn2_N_s); */ - /* free(f_nrn2_N_d); */ - /* file_clear(p_nrn2_size, f_nrn2_V_c, f_nrn2_V_r, f_nrn2_V_n, f_nrn2_V_s, f_nrn2_V_d); */ - /* free(f_nrn2_V_c); */ - /* free(f_nrn2_V_r); */ - /* free(f_nrn2_V_n); */ - /* free(f_nrn2_V_s); */ - /* free(f_nrn2_V_d); */ - - /* file_clear(p_syn_exc_size, f_syn_exc_R_c, f_syn_exc_R_r, f_syn_exc_R_n, f_syn_exc_R_s, f_syn_exc_R_d); */ - /* free(f_syn_exc_R_c); */ - /* free(f_syn_exc_R_r); */ - /* free(f_syn_exc_R_n); */ - /* free(f_syn_exc_R_s); */ - /* free(f_syn_exc_R_d); */ - /* file_clear(p_syn_exc_size, f_syn_exc_S_c, f_syn_exc_S_r, f_syn_exc_S_n, f_syn_exc_S_s, f_syn_exc_S_d); */ - /* free(f_syn_exc_S_c); */ - /* free(f_syn_exc_S_r); */ - /* free(f_syn_exc_S_n); */ - /* free(f_syn_exc_S_s); */ - /* free(f_syn_exc_S_d); */ - - /* file_clear(p_syn_inh_size, f_syn_inh_R_c, f_syn_inh_R_r, f_syn_inh_R_n, f_syn_inh_R_s, f_syn_inh_R_d); */ - /* free(f_syn_inh_R_c); */ - /* free(f_syn_inh_R_r); */ - /* free(f_syn_inh_R_n); */ - /* free(f_syn_inh_R_s); */ - /* free(f_syn_inh_R_d); */ - /* file_clear(p_syn_inh_size, f_syn_inh_S_c, f_syn_inh_S_r, f_syn_inh_S_n, f_syn_inh_S_s, f_syn_inh_S_d); */ - /* free(f_syn_inh_S_c); */ - /* free(f_syn_inh_S_r); */ - /* free(f_syn_inh_S_n); */ - /* free(f_syn_inh_S_s); */ - /* free(f_syn_inh_S_d); */ - - arpra_ode_stepper_clear(&ode_stepper); - arpra_clear_buffers(); - gmp_randclear(rng_uf); - gmp_randclear(rng_nf); - mpfr_free_cache(); - - return 0; -} diff --git a/experiments/fig5/ml-mpfi.c b/experiments/fig5/ml-mpfi.c deleted file mode 100644 index f22617d..0000000 --- a/experiments/fig5/ml-mpfi.c +++ /dev/null @@ -1,942 +0,0 @@ -/* - * morris_lecar_mpfi.c -- Test Morris-Lecar model using MPFI. - * - * Copyright 2016-2020 James Paul Turner. - * - * This file is part of the Arpra library. - * - * The Arpra library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Arpra library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the Arpra library. If not, see . - */ - -#include -#include -#include -#include - -/* - * Global variables - * ---------------- - * h Step size (msec) - * t Current time (msec) - * - * Neuron variables - * ---------------- - * N Fraction of open K+ channels - * V Membrane potential (mV) - * - * Neuron parameters - * ----------------- - * GL Maximum leak conductance (mS/cm^2) - * VL Equilibrium potential of leak conductance (mV) - * GCa Maximum Ca++ conductance (mS/cm^2) - * VCa Equilibrium potential of Ca++ conductance (mV) - * GK Maximum K+ conductance (mS/cm^2) - * VK Equilibrium potential of K+ conductance (mV) - * V1 Potential at which M_ss(V) = 0.5 (mV) - * V2 Reciprocal of voltage dependence slope of M_ss(V) (mV) - * V3 Potential at which N_ss(V) = 0.5 (mV) - * V4 Reciprocal of voltage dependence slope of N_ss(V) (mV) - * phi (s^-1) - * C Membrane capacitance (uF/cm^2) - * - * Synapse variables - * ----------------- - * R Neurotransmitter release - * S Neurotransmitter binding - * - * Synapse parameters - * ------------------ - * GSyn Maximum synapse conductance (mS/cm^2) - * VSyn Synapse conductance equilibrium potential (mV) - * thr Neuronal spike threshold (mV) - * a Transmitter release/bind rise factor - * b Transmitter release/bind decay factor - * k Steepness of activation function - */ - -// General parameters -#define p_h 0.5 -#define p_t0 0.0 -#define p_prec 53 -#define p_error_prec 256 -#define p_sim_steps 1000 -#define p_report_step 20 - -// RNG parameters -// Seeds are random if not #defined -#define p_rand_prec 53 -#define p_rng_uf_seed 707135875931353ul -#define p_rng_nf_seed 503108552855933ul - -// Poisson input parameters (group 1) -#define p_in1_size 500 -#define p_in1_freq 50.0 -#define p_in1_V_lo -60.0 -#define p_in1_V_hi 20.0 - -// Poisson input parameters (group 2) -#define p_in2_size 0 -#define p_in2_freq 10.0 -#define p_in2_V_lo -60.0 -#define p_in2_V_hi 20.0 - -// Neuron parameters (group 1) -#define p_nrn1_size 1 -#define p_nrn1_N0 0.0 -#define p_nrn1_V0 -60.0 -#define p_nrn1_class 1 - -// Neuron parameters (group 2) -#define p_nrn2_size 0 -#define p_nrn2_N0 0.0 -#define p_nrn2_V0 -60.0 -#define p_nrn2_class 1 - -// Neuron parameters (common) -#define p_GL 2.0 -#define p_GCa 4.0 // Class 1 -//#define p_GCa 4.4 // Class 2 -#define p_GK 8.0 -#define p_VL -60.0 -#define p_VCa 120.0 -#define p_VK -80.0 -#define p_V1 -1.2 -#define p_V2 18.0 -#define p_V3 12.0 // Class 1 -//#define p_V3 2.0 // Class 2 -#define p_V4 17.4 // Class 1 -//#define p_V4 30.0 // Class 2 -#define p_phi 1.0 / 15.0 // Class 1 -//#define p_phi 1.0 / 25.0 // Class 2 -#define p_C 20.0 - -// Synapse parameters (excitatory) -#define p_syn_exc_size p_in1_size * p_nrn1_size -#define p_syn_exc_R0 0.0 -#define p_syn_exc_S0 0.0 -#define p_syn_exc_GSyn_std 0.05 -#define p_syn_exc_GSyn_mean 25.0 / p_in1_size -#define p_syn_exc_VSyn 0.0 -#define p_syn_exc_thr -50.0 -#define p_syn_exc_a 0.25 // in [1/10, 1/2] -#define p_syn_exc_b 0.15 // in [1/20, 1/4] -#define p_syn_exc_k 1.0E6 - -// Synapse parameters (inhibitory) -#define p_syn_inh_size 0 -#define p_syn_inh_R0 0.0 -#define p_syn_inh_S0 0.0 -#define p_syn_inh_GSyn_std 0.5 -#define p_syn_inh_GSyn_mean 3.0 -#define p_syn_inh_VSyn -80.0 -#define p_syn_inh_thr -50.0 -#define p_syn_inh_a 0.075 // in [1/20, 1/10] -#define p_syn_inh_b 0.035 // in [1/50, 1/20] -#define p_syn_inh_k 1.0E6 - -// ===================== end of model parameters ====================== - - -int *in1, *in2; -mpfr_t rand_uf, rand_nf, temp_error, in1_p0, in2_p0; -mpfr_ptr temp_sum_error1, *temp_sum_error1_ptr, temp_sum_error2, *temp_sum_error2_ptr; -mpfi_t GL, VL, GCa, VCa, GK, VK, V1, V2, V3, V4, phi, C, syn_exc_VSyn, syn_exc_thr, - syn_exc_a, syn_exc_b, syn_exc_k, syn_inh_VSyn, syn_inh_thr, syn_inh_a, - syn_inh_b, syn_inh_k, one, two, neg_two, temp_sum, temp1, temp2, M_ss, N_ss, - in1_V_lo, in1_V_hi, in2_V_lo, in2_V_hi; -mpfi_ptr syn_exc_GSyn, syn_inh_GSyn, I1, I2; -gmp_randstate_t rng_uf, rng_nf; - -// System state variables -mpfi_ptr nrn1_N, nrn2_N, nrn1_V, nrn2_V, syn_exc_R, syn_inh_R, syn_exc_S, syn_inh_S; -mpfi_ptr d_nrn1_N, d_nrn2_N, d_nrn1_V, d_nrn2_V, d_syn_exc_R, d_syn_inh_R, d_syn_exc_S, d_syn_inh_S; - -// DEBUG: print MPFI numbers to stderr -void debug_i (mpfi_srcptr x) { - fputs("[", stderr); - mpfr_out_str(stderr, 10, 40, &(x->left), MPFR_RNDN); - fputs(", ", stderr); - mpfr_out_str(stderr, 10, 40, &(x->right), MPFR_RNDN); - fputs("]\n", stderr); -} - -// DEBUG: print MPFR numbers to stderr -void debug_r (mpfr_srcptr x) { - mpfr_out_str(stderr, 10, 60, x, MPFR_RNDN); - fputs("\n", stderr); -} - -void file_init (char *grp, unsigned long grp_size, FILE **f) -{ - char fname[20]; - unsigned long i; - - for (i = 0; i < grp_size; i++) { - sprintf(fname, "%s_%03lu.dat", grp, i); - f[i] = fopen(fname, "w"); - } -} - -void file_clear (unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - fclose(f[i]); - } -} - -void file_write (mpfi_srcptr A, unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - mpfr_out_str(f[i], 10, 40, &(A[i].left), MPFR_RNDN); - fputs(" ", f[i]); - mpfr_out_str(f[i], 10, 40, &(A[i].right), MPFR_RNDN); - fputs("\n", f[i]); - } -} - -void dNdt (const unsigned long idx, int grp) -{ - mpfi_ptr d_N; - mpfi_srcptr N, V; - - if (grp == 1) { - d_N = d_nrn1_N + idx; - N = nrn1_N + idx; - V = nrn1_V + idx; - } - //else if (grp == 2) { - // d_N = d_nrn2_N + idx; - // N = nrn2_N + idx; - // V = nrn2_V + idx; - //} - - // K+ channel activation steady-state - // N_ss = 1 / (1 + exp(-2 (V - V3) / V4)) - mpfi_sub(temp1, V, V3); - mpfi_mul(N_ss, neg_two, temp1); - mpfi_div(N_ss, N_ss, V4); - mpfi_exp(N_ss, N_ss); - mpfi_add(N_ss, one, N_ss); - mpfi_ui_div(N_ss, 1, N_ss); - - // tau of K+ channel activation - // tau = 1 / (phi ((p + q) / 2)) - // p = exp(-(V - V3) / (2 V4)) - // q = exp( (V - V3) / (2 V4)) - mpfi_mul(temp2, two, V4); - mpfi_div(temp2, temp1, temp2); - mpfi_neg(temp1, temp2); - mpfi_exp(temp1, temp1); - mpfi_exp(temp2, temp2); - mpfi_add(temp1, temp1, temp2); - mpfi_div(temp1, temp1, two); - mpfi_mul(temp1, phi, temp1); - mpfi_ui_div(temp1, 1, temp1); - - // delta of K+ channel activation - // dN/dt = (N_ss - N) / tau - mpfi_sub(d_N, N_ss, N); - mpfi_div(d_N, d_N, temp1); -} - -void dVdt (const unsigned long idx, int grp) -{ - mpfi_ptr d_V; - mpfi_srcptr N, V; - mpfi_srcptr S, GSyn, VSyn; - mpfr_ptr temp_sum_error, *temp_sum_error_ptr; - mpfi_ptr I; - unsigned long i, pre_size; - - if (grp == 1) { - d_V = d_nrn1_V + idx; - N = nrn1_N + idx; - V = nrn1_V + idx; - pre_size = p_in1_size; - S = syn_exc_S + (idx * pre_size); - GSyn = syn_exc_GSyn + (idx * pre_size); - VSyn = syn_exc_VSyn; - temp_sum_error = temp_sum_error1; - temp_sum_error_ptr = temp_sum_error1_ptr; - I = I1; - } - //else if (grp == 2) { - // d_V = d_nrn2_V + idx; - // N = nrn2_N + idx; - // V = nrn2_V + idx; - // pre_size = p_in2_size; - // S = syn_exc_S + (idx * pre_size); - // GSyn = syn_exc_GSyn + (idx * pre_size); - // VSyn = syn_exc_VSyn; - // temp_sum_error = temp_sum_error2; - // temp_sum_error_ptr = temp_sum_error2_ptr; - // I = I2; - //} - - // Ca++ channel activation steady-state - // M_ss = 1 / (1 + exp(-2 (V - V1) / V2)) - mpfi_sub(M_ss, V, V1); - mpfi_mul(M_ss, neg_two, M_ss); - mpfi_div(M_ss, M_ss, V2); - mpfi_exp(M_ss, M_ss); - mpfi_add(M_ss, one, M_ss); - mpfi_ui_div(M_ss, 1, M_ss); - - // Synapse current - mpfi_sub(temp1, VSyn, V); - mpfi_set_ui(temp_sum, 0); - for (i = 0; i < pre_size; i++) { - mpfi_mul(&(I[i]), temp1, &(GSyn[i])); - mpfi_mul(&(I[i]), &(I[i]), &(S[i])); - mpfi_add(temp_sum, temp_sum, &(I[i])); - if (mpfr_cmpabs(&(I[i].left), &(I[i].right)) <= 0) { - mpfr_set(&(temp_sum_error[i]), &(I[i].right), MPFR_RNDU); - } - else { - mpfr_abs(&(temp_sum_error[i]), &(I[i].left), MPFR_RNDU); - } - } - - // Compute error(sum(I)) = (n - 1) u sum(|I|) - mpfr_set_si_2exp(temp_error, 1, -p_prec, MPFR_RNDU); - mpfr_mul_ui(temp_error, temp_error, (pre_size - 1), MPFR_RNDU); - mpfr_sum(temp_sum_error_ptr[0], temp_sum_error_ptr, pre_size, MPFR_RNDU); - mpfr_mul(temp_error, temp_error, temp_sum_error_ptr[0], MPFR_RNDU); - mpfr_sub(&(temp_sum->left), &(temp_sum->left), temp_error, MPFR_RNDD); - mpfr_add(&(temp_sum->right), &(temp_sum->right), temp_error, MPFR_RNDU); - mpfi_set(d_V, temp_sum); - - - - // ======== TEMP DEBUG ========== - //mpfi_set_d(d_V, 80.0); // bifurcation at sum(I) = 80.0 - if (idx == 0) { - //fprintf(stderr, "sum(I): "); debug_i(d_V); - //fprintf(stderr, "I[0]: "); debug_i(I); - for (i = 0; i < pre_size; i++) { - //fprintf(stderr, "I[%lu]: ", i); debug_i(&(I[i])); - } - } - - - - // Leak current - mpfi_sub(temp1, V, VL); - mpfi_mul(temp1, temp1, GL); - mpfi_sub(d_V, d_V, temp1); - - // Ca++ current - mpfi_sub(temp1, V, VCa); - mpfi_mul(temp1, temp1, GCa); - mpfi_mul(temp1, temp1, M_ss); - mpfi_sub(d_V, d_V, temp1); - - // K+ current - mpfi_sub(temp1, V, VK); - mpfi_mul(temp1, temp1, GK); - mpfi_mul(temp1, temp1, N); - mpfi_sub(d_V, d_V, temp1); - - // delta of membrane potential - // dV/dt = (I + GL (VL - V) + GCa M (VCa - V) + GK N (VK - V)) / C - mpfi_div(d_V, d_V, C); -} - -void dRdt (const unsigned long idx, int grp) -{ - mpfi_ptr d_R; - mpfi_srcptr R; - mpfi_srcptr a, b, k; - mpfi_srcptr VPre, threshold; - - if (grp == 1) { - d_R = d_syn_exc_R + idx; - R = syn_exc_R + idx; - a = syn_exc_a; - b = syn_exc_b; - k = syn_exc_k; - VPre = in1[idx % p_in1_size] ? in1_V_hi : in1_V_lo; - threshold = syn_exc_thr; - } - //else if (grp == 2) { - // d_R = d_syn_inh_R + idx; - // R = syn_inh_R + idx; - // a = syn_inh_a; - // b = syn_inh_b; - // k = syn_inh_k; - // VPre = in2[idx % p_in2_size] ? in2_V_hi : in2_V_lo; - // threshold = syn_inh_thr; - //} - - // Sigmoid of threshold difference - mpfi_sub(temp1, VPre, threshold); - mpfi_mul(temp1, temp1, k); - mpfi_exp(temp1, temp1); - mpfi_add(temp1, temp1, one); - mpfi_ui_div(temp1, 1, temp1); - - // Presynaptic transmitter release rise - mpfi_mul(temp1, a, temp1); - - // Presynaptic transmitter release decay - mpfi_mul(temp2, b, R); - - // delta of presynaptic transmitter release - // dR/dt = a Q - b R - // Q = 1 / (1 + e^(k(V - threshold))) - mpfi_sub(d_R, temp1, temp2); -} - -void dSdt (const unsigned long idx, int grp) -{ - mpfi_ptr d_S; - mpfi_srcptr R, S; - mpfi_srcptr a, b; - - if (grp == 1) { - d_S = d_syn_exc_S + idx; - R = syn_exc_R + idx; - S = syn_exc_S + idx; - a = syn_exc_a; - b = syn_exc_b; - } - //else if (grp == 2) { - // d_S = d_syn_inh_S + idx; - // R = syn_inh_R + idx; - // S = syn_inh_S + idx; - // a = syn_inh_a; - // b = syn_inh_b; - //} - - // Postsynaptic transmitter binding rise - mpfi_mul(temp1, a, R); - - // Postsynaptic transmitter binding decay - mpfi_mul(temp2, b, S); - - // delta of postsynaptic transmitter binding - // dS/dt = a R - b S - mpfi_sub(d_S, temp1, temp2); -} - -int main (int argc, char *argv[]) -{ - mpfi_t h, t; - unsigned long i, j; - - // Allocate system state - nrn1_N = malloc(p_nrn1_size * sizeof(mpfi_t)); - nrn1_V = malloc(p_nrn1_size * sizeof(mpfi_t)); - nrn2_N = malloc(p_nrn2_size * sizeof(mpfi_t)); - nrn2_V = malloc(p_nrn2_size * sizeof(mpfi_t)); - syn_exc_R = malloc(p_syn_exc_size * sizeof(mpfi_t)); - syn_exc_S = malloc(p_syn_exc_size * sizeof(mpfi_t)); - syn_inh_R = malloc(p_syn_inh_size * sizeof(mpfi_t)); - syn_inh_S = malloc(p_syn_inh_size * sizeof(mpfi_t)); - - // Allocate other arrays - d_nrn1_N = malloc(p_nrn1_size * sizeof(mpfi_t)); - d_nrn2_N = malloc(p_nrn2_size * sizeof(mpfi_t)); - d_nrn1_V = malloc(p_nrn1_size * sizeof(mpfi_t)); - d_nrn2_V = malloc(p_nrn2_size * sizeof(mpfi_t)); - d_syn_exc_R = malloc(p_syn_exc_size * sizeof(mpfi_t)); - d_syn_inh_R = malloc(p_syn_inh_size * sizeof(mpfi_t)); - d_syn_exc_S = malloc(p_syn_exc_size * sizeof(mpfi_t)); - d_syn_inh_S = malloc(p_syn_inh_size * sizeof(mpfi_t)); - syn_exc_GSyn = malloc(p_syn_exc_size * sizeof(mpfi_t)); - syn_inh_GSyn = malloc(p_syn_inh_size * sizeof(mpfi_t)); - temp_sum_error1 = malloc(p_in1_size * sizeof(mpfr_t)); - temp_sum_error2 = malloc(p_in2_size * sizeof(mpfr_t)); - temp_sum_error1_ptr = malloc(p_in1_size * sizeof(mpfr_ptr)); - temp_sum_error2_ptr = malloc(p_in2_size * sizeof(mpfr_ptr)); - I1 = malloc(p_in1_size * sizeof(mpfi_t)); - I2 = malloc(p_in2_size * sizeof(mpfi_t)); - in1 = malloc(p_in1_size * sizeof(int)); - in2 = malloc(p_in2_size * sizeof(int)); - - struct timespec clock_time; - - // Initialise uniform float RNG - gmp_randinit_default(rng_uf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uf_seed - unsigned long rng_uf_seed = p_rng_uf_seed; -#else - unsigned long rng_uf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uf, rng_uf_seed); - printf("GMP rand uniform float seed: %lu\n", rng_uf_seed); - - // Initialise normal float RNG - gmp_randinit_default(rng_nf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_nf_seed - unsigned long rng_nf_seed = p_rng_nf_seed; -#else - unsigned long rng_nf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_nf, rng_nf_seed); - printf("GMP rand normal float seed: %lu\n", rng_nf_seed); - - // Initialise system state - mpfi_init2(h, p_prec); - mpfi_init2(t, p_prec); - for (i = 0; i < p_nrn1_size; i++) { - mpfi_init2(&(nrn1_N[i]), p_prec); - mpfi_init2(&(nrn1_V[i]), p_prec); - mpfi_init2(&(d_nrn1_N[i]), p_prec); - mpfi_init2(&(d_nrn1_V[i]), p_prec); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfi_init2(&(nrn2_N[i]), p_prec); - mpfi_init2(&(nrn2_V[i]), p_prec); - mpfi_init2(&(d_nrn2_N[i]), p_prec); - mpfi_init2(&(d_nrn2_V[i]), p_prec); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfi_init2(&(syn_exc_R[i]), p_prec); - mpfi_init2(&(syn_exc_S[i]), p_prec); - mpfi_init2(&(d_syn_exc_R[i]), p_prec); - mpfi_init2(&(d_syn_exc_S[i]), p_prec); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfi_init2(&(syn_inh_R[i]), p_prec); - mpfi_init2(&(syn_inh_S[i]), p_prec); - mpfi_init2(&(d_syn_inh_R[i]), p_prec); - mpfi_init2(&(d_syn_inh_S[i]), p_prec); - } - - // Initialise Poisson input parameters (group 1) - mpfr_init2(in1_p0, p_prec); - mpfi_init2(in1_V_lo, p_prec); - mpfi_init2(in1_V_hi, p_prec); - - // Initialise Poisson input parameters (group 2) - mpfr_init2(in2_p0, p_prec); - mpfi_init2(in2_V_lo, p_prec); - mpfi_init2(in2_V_hi, p_prec); - - // Initialise neuron parameters - mpfi_init2(GL, p_prec); - mpfi_init2(GCa, p_prec); - mpfi_init2(GK, p_prec); - mpfi_init2(VL, p_prec); - mpfi_init2(VCa, p_prec); - mpfi_init2(VK, p_prec); - mpfi_init2(V1, p_prec); - mpfi_init2(V2, p_prec); - mpfi_init2(V3, p_prec); - mpfi_init2(V4, p_prec); - mpfi_init2(phi, p_prec); - mpfi_init2(C, p_prec); - - // Initialise excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - mpfi_init2(&(syn_exc_GSyn[i]), p_prec); - } - mpfi_init2(syn_exc_VSyn, p_prec); - mpfi_init2(syn_exc_thr, p_prec); - mpfi_init2(syn_exc_a, p_prec); - mpfi_init2(syn_exc_b, p_prec); - mpfi_init2(syn_exc_k, p_prec); - - // Initialise inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - mpfi_init2(&(syn_inh_GSyn[i]), p_prec); - } - mpfi_init2(syn_inh_VSyn, p_prec); - mpfi_init2(syn_inh_thr, p_prec); - mpfi_init2(syn_inh_a, p_prec); - mpfi_init2(syn_inh_b, p_prec); - mpfi_init2(syn_inh_k, p_prec); - - // Initialise constants - mpfi_init2(one, p_prec); - mpfi_init2(two, p_prec); - mpfi_init2(neg_two, p_prec); - - // Initialise scratch space - mpfr_init2(rand_uf, p_rand_prec); - mpfr_init2(rand_nf, p_rand_prec); - mpfr_init2(temp_error, p_error_prec); - mpfi_init2(temp_sum, p_error_prec); - mpfi_init2(temp1, p_prec); - mpfi_init2(temp2, p_prec); - mpfi_init2(M_ss, p_prec); - mpfi_init2(N_ss, p_prec); - - // Set system state - mpfi_set_d(h, p_h); - mpfi_set_d(t, p_t0); - for (i = 0; i < p_nrn1_size; i++) { - mpfi_set_d(&(nrn1_N[i]), p_nrn1_N0); - mpfi_set_d(&(nrn1_V[i]), p_nrn1_V0); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfi_set_d(&(nrn2_N[i]), p_nrn2_N0); - mpfi_set_d(&(nrn2_V[i]), p_nrn2_V0); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfi_set_d(&(syn_exc_R[i]), p_syn_exc_R0); - mpfi_set_d(&(syn_exc_S[i]), p_syn_exc_S0); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfi_set_d(&(syn_inh_R[i]), p_syn_inh_R0); - mpfi_set_d(&(syn_inh_S[i]), p_syn_inh_S0); - } - - // Set Poisson input parameters (group 1) - mpfr_set_d(in1_p0, -(p_in1_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in1_p0, in1_p0, MPFR_RNDN); - mpfi_set_d(in1_V_lo, p_in1_V_lo); - mpfi_set_d(in1_V_hi, p_in1_V_hi); - for (i = 0; i < p_in1_size; i++) { - mpfr_init2(&(temp_sum_error1[i]), p_error_prec); - temp_sum_error1_ptr[i] = &(temp_sum_error1[i]); - mpfi_init2(&(I1[i]), p_prec); - } - - // Set Poisson input parameters (group 2) - mpfr_set_d(in2_p0, -(p_in2_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in2_p0, in2_p0, MPFR_RNDN); - mpfi_set_d(in2_V_lo, p_in2_V_lo); - mpfi_set_d(in2_V_hi, p_in2_V_hi); - for (i = 0; i < p_in2_size; i++) { - mpfr_init2(&(temp_sum_error2[i]), p_error_prec); - temp_sum_error2_ptr[i] = &(temp_sum_error2[i]); - mpfi_init2(&(I2[i]), p_prec); - } - - // Set neuron parameters - mpfi_set_d(GL, p_GL); - mpfi_set_d(GCa, p_GCa); - mpfi_set_d(GK, p_GK); - mpfi_set_d(VL, p_VL); - mpfi_set_d(VCa, p_VCa); - mpfi_set_d(VK, p_VK); - mpfi_set_d(V1, p_V1); - mpfi_set_d(V2, p_V2); - mpfi_set_d(V3, p_V3); - mpfi_set_d(V4, p_V4); - mpfi_set_d(phi, p_phi); - mpfi_set_d(C, p_C); - - // Set excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_exc_GSyn_std, MPFR_RNDN); - mpfr_add_d(rand_nf, rand_nf, p_syn_exc_GSyn_mean, MPFR_RNDN); - mpfi_set_fr(&(syn_exc_GSyn[i]), rand_nf); - } - mpfi_set_d(syn_exc_VSyn, p_syn_exc_VSyn); - mpfi_set_d(syn_exc_thr, p_syn_exc_thr); - mpfi_set_d(syn_exc_a, p_syn_exc_a); - mpfi_set_d(syn_exc_b, p_syn_exc_b); - mpfi_set_d(syn_exc_k, p_syn_exc_k); - mpfi_neg(syn_exc_k, syn_exc_k); - - // Set inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_inh_GSyn_std, MPFR_RNDN); - mpfr_add_d(rand_nf, rand_nf, p_syn_inh_GSyn_mean, MPFR_RNDN); - mpfi_set_fr(&(syn_inh_GSyn[i]), rand_nf); - } - mpfi_set_d(syn_inh_VSyn, p_syn_inh_VSyn); - mpfi_set_d(syn_inh_thr, p_syn_inh_thr); - mpfi_set_d(syn_inh_a, p_syn_inh_a); - mpfi_set_d(syn_inh_b, p_syn_inh_b); - mpfi_set_d(syn_inh_k, p_syn_inh_k); - mpfi_neg(syn_inh_k, syn_inh_k); - - // Set constants - mpfi_set_d(one, 1.0); - mpfi_set_d(two, 2.0); - mpfi_set_d(neg_two, -2.0); - - // Initialise report files - FILE **f_time = malloc(sizeof(FILE *));; - file_init("time", 1, f_time); - - FILE **f_nrn1_N = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_N", p_nrn1_size, f_nrn1_N); - FILE **f_nrn1_V = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_V", p_nrn1_size, f_nrn1_V); - - /* FILE **f_nrn2_N = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_N", p_nrn2_size, f_nrn2_N); */ - /* FILE **f_nrn2_V = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_V", p_nrn2_size, f_nrn2_V); */ - - /* FILE **f_syn_exc_R = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_R", p_syn_exc_size, f_syn_exc_R); */ - /* FILE **f_syn_exc_S = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_S", p_syn_exc_size, f_syn_exc_S); */ - - /* FILE **f_syn_inh_R = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_R", p_syn_inh_size, f_syn_inh_R); */ - /* FILE **f_syn_inh_S = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_S", p_syn_inh_size, f_syn_inh_S); */ - - - // Begin simulation loop - // ===================== - - clock_t run_time = clock(); - - for (i = 0; i < p_sim_steps; i++) { - if (i % p_report_step == 0) printf("%lu\n", i); - - // Event(s) occur if urandom >= e^-rate - for (j = 0; j < p_in1_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in1[j] = mpfr_greaterequal_p(rand_uf, in1_p0); - fprintf(stderr, "%s", (in1[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, " "); - for (j = 0; j < p_in2_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in2[j] = mpfr_greaterequal_p(rand_uf, in2_p0); - fprintf(stderr, "%s", (in2[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, "\n"); - - // Compute derivatives - for (j = 0; j < p_nrn1_size; j++) { - dNdt(j, 1); - dVdt(j, 1); - } - for (j = 0; j < p_nrn2_size; j++) { - dNdt(j, 2); - dVdt(j, 2); - } - for (j = 0; j < p_syn_exc_size; j++) { - dRdt(j, 1); - dSdt(j, 1); - } - for (j = 0; j < p_syn_inh_size; j++) { - dRdt(j, 2); - dSdt(j, 2); - } - - // Step system - mpfi_add(t, t, h); - for (j = 0; j < p_nrn1_size; j++) { - mpfi_mul(&(d_nrn1_N[j]), &(d_nrn1_N[j]), h); - mpfi_add(&(nrn1_N[j]), &(nrn1_N[j]), &(d_nrn1_N[j])); - mpfi_mul(&(d_nrn1_V[j]), &(d_nrn1_V[j]), h); - mpfi_add(&(nrn1_V[j]), &(nrn1_V[j]), &(d_nrn1_V[j])); - } - for (j = 0; j < p_nrn2_size; j++) { - mpfi_mul(&(d_nrn2_N[j]), &(d_nrn2_N[j]), h); - mpfi_add(&(nrn2_N[j]), &(nrn2_N[j]), &(d_nrn2_N[j])); - mpfi_mul(&(d_nrn2_V[j]), &(d_nrn2_V[j]), h); - mpfi_add(&(nrn2_V[j]), &(nrn2_V[j]), &(d_nrn2_V[j])); - } - for (j = 0; j < p_syn_exc_size; j++) { - mpfi_mul(&(d_syn_exc_R[j]), &(d_syn_exc_R[j]), h); - mpfi_add(&(syn_exc_R[j]), &(syn_exc_R[j]), &(d_syn_exc_R[j])); - mpfi_mul(&(d_syn_exc_S[j]), &(d_syn_exc_S[j]), h); - mpfi_add(&(syn_exc_S[j]), &(syn_exc_S[j]), &(d_syn_exc_S[j])); - } - for (j = 0; j < p_syn_inh_size; j++) { - mpfi_mul(&(d_syn_inh_R[j]), &(d_syn_inh_R[j]), h); - mpfi_add(&(syn_inh_R[j]), &(syn_inh_R[j]), &(d_syn_inh_R[j])); - mpfi_mul(&(d_syn_inh_S[j]), &(d_syn_inh_S[j]), h); - mpfi_add(&(syn_inh_S[j]), &(syn_inh_S[j]), &(d_syn_inh_S[j])); - } - - file_write(t, 1, f_time); - - file_write(nrn1_N, p_nrn1_size, f_nrn1_N); - file_write(nrn1_V, p_nrn1_size, f_nrn1_V); - - /* file_write(nrn2_N, p_nrn2_size, f_nrn2_N); */ - /* file_write(nrn2_V, p_nrn2_size, f_nrn2_V); */ - - /* file_write(syn_exc_R, p_syn_exc_size, f_syn_exc_R); */ - /* file_write(syn_exc_S, p_syn_exc_size, f_syn_exc_S); */ - - /* file_write(syn_inh_R, p_syn_inh_size, f_syn_inh_R); */ - /* file_write(syn_inh_S, p_syn_inh_size, f_syn_inh_S); */ - } - - run_time = clock() - run_time; - printf("Finished in %f seconds.\n", ((float) run_time) / CLOCKS_PER_SEC); - - // End simulation loop - // =================== - - - // Clear system state - mpfi_clear(h); - mpfi_clear(t); - for (i = 0; i < p_nrn1_size; i++) { - mpfi_clear(&(nrn1_N[i])); - mpfi_clear(&(nrn1_V[i])); - mpfi_clear(&(d_nrn1_N[i])); - mpfi_clear(&(d_nrn1_V[i])); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfi_clear(&(nrn2_N[i])); - mpfi_clear(&(nrn2_V[i])); - mpfi_clear(&(d_nrn2_N[i])); - mpfi_clear(&(d_nrn2_V[i])); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfi_clear(&(syn_exc_R[i])); - mpfi_clear(&(syn_exc_S[i])); - mpfi_clear(&(d_syn_exc_R[i])); - mpfi_clear(&(d_syn_exc_S[i])); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfi_clear(&(syn_inh_R[i])); - mpfi_clear(&(syn_inh_S[i])); - mpfi_clear(&(d_syn_inh_R[i])); - mpfi_clear(&(d_syn_inh_S[i])); - } - - // Clear Poisson input parameters (group 1) - mpfr_clear(in1_p0); - mpfi_clear(in1_V_lo); - mpfi_clear(in1_V_hi); - for (i = 0; i < p_in1_size; i++) { - mpfr_clear(&(temp_sum_error1[i])); - mpfi_clear(&(I1[i])); - } - - // Clear Poisson input parameters (group 2) - mpfr_clear(in2_p0); - mpfi_clear(in2_V_lo); - mpfi_clear(in2_V_hi); - for (i = 0; i < p_in2_size; i++) { - mpfr_clear(&(temp_sum_error2[i])); - mpfi_clear(&(I2[i])); - } - - // Clear neuron parameters - mpfi_clear(GL); - mpfi_clear(GCa); - mpfi_clear(GK); - mpfi_clear(VL); - mpfi_clear(VCa); - mpfi_clear(VK); - mpfi_clear(V1); - mpfi_clear(V2); - mpfi_clear(V3); - mpfi_clear(V4); - mpfi_clear(phi); - mpfi_clear(C); - - // Clear excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - mpfi_clear(&(syn_exc_GSyn[i])); - } - mpfi_clear(syn_exc_VSyn); - mpfi_clear(syn_exc_thr); - mpfi_clear(syn_exc_a); - mpfi_clear(syn_exc_b); - mpfi_clear(syn_exc_k); - - // Clear inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - mpfi_clear(&(syn_inh_GSyn[i])); - } - mpfi_clear(syn_inh_VSyn); - mpfi_clear(syn_inh_thr); - mpfi_clear(syn_inh_a); - mpfi_clear(syn_inh_b); - mpfi_clear(syn_inh_k); - - // Clear constants - mpfi_clear(one); - mpfi_clear(two); - mpfi_clear(neg_two); - - // Clear scratch space - mpfr_clear(rand_uf); - mpfr_clear(rand_nf); - mpfr_clear(temp_error); - mpfi_clear(temp_sum); - mpfi_clear(temp1); - mpfi_clear(temp2); - mpfi_clear(M_ss); - mpfi_clear(N_ss); - - // Free system state - free(nrn1_N); - free(nrn1_V); - free(nrn2_N); - free(nrn2_V); - free(syn_exc_R); - free(syn_exc_S); - free(syn_inh_R); - free(syn_inh_S); - - // Free other arrays - free(d_nrn1_N); - free(d_nrn2_N); - free(d_nrn1_V); - free(d_nrn2_V); - free(d_syn_exc_R); - free(d_syn_inh_R); - free(d_syn_exc_S); - free(d_syn_inh_S); - free(syn_exc_GSyn); - free(syn_inh_GSyn); - free(temp_sum_error1); - free(temp_sum_error2); - free(temp_sum_error1_ptr); - free(temp_sum_error2_ptr); - free(I1); - free(I2); - free(in1); - free(in2); - - // Clear report files - file_clear(1, f_time); - free(f_time); - - file_clear(p_nrn1_size, f_nrn1_N); - free(f_nrn1_N); - file_clear(p_nrn1_size, f_nrn1_V); - free(f_nrn1_V); - - /* file_clear(p_nrn2_size, f_nrn2_N); */ - /* free(f_nrn2_N); */ - /* file_clear(p_nrn2_size, f_nrn2_V); */ - /* free(f_nrn2_V); */ - - /* file_clear(p_syn_exc_size, f_syn_exc_R); */ - /* free(f_syn_exc_R); */ - /* file_clear(p_syn_exc_size, f_syn_exc_S); */ - /* free(f_syn_exc_S); */ - - /* file_clear(p_syn_inh_size, f_syn_inh_R); */ - /* free(f_syn_inh_R); */ - /* file_clear(p_syn_inh_size, f_syn_inh_S); */ - /* free(f_syn_inh_S); */ - - gmp_randclear(rng_uf); - gmp_randclear(rng_nf); - mpfr_free_cache(); - - return 0; -} diff --git a/experiments/fig5/ml-mpfr.c b/experiments/fig5/ml-mpfr.c deleted file mode 100644 index cf8cdbe..0000000 --- a/experiments/fig5/ml-mpfr.c +++ /dev/null @@ -1,1011 +0,0 @@ -/* - * morris_lecar_mpfr.c -- Test Morris-Lecar model using MPFR. - * - * Copyright 2016-2020 James Paul Turner. - * - * This file is part of the Arpra library. - * - * The Arpra library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Arpra library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the Arpra library. If not, see . - */ - -#include -#include -#include -#include - -/* - * Global variables - * ---------------- - * h Step size (msec) - * t Current time (msec) - * - * Neuron variables - * ---------------- - * N Fraction of open K+ channels - * V Membrane potential (mV) - * - * Neuron parameters - * ----------------- - * GL Maximum leak conductance (mS/cm^2) - * VL Equilibrium potential of leak conductance (mV) - * GCa Maximum Ca++ conductance (mS/cm^2) - * VCa Equilibrium potential of Ca++ conductance (mV) - * GK Maximum K+ conductance (mS/cm^2) - * VK Equilibrium potential of K+ conductance (mV) - * V1 Potential at which M_ss(V) = 0.5 (mV) - * V2 Reciprocal of voltage dependence slope of M_ss(V) (mV) - * V3 Potential at which N_ss(V) = 0.5 (mV) - * V4 Reciprocal of voltage dependence slope of N_ss(V) (mV) - * phi (s^-1) - * C Membrane capacitance (uF/cm^2) - * - * Synapse variables - * ----------------- - * R Neurotransmitter release - * S Neurotransmitter binding - * - * Synapse parameters - * ------------------ - * GSyn Maximum synapse conductance (mS/cm^2) - * VSyn Synapse conductance equilibrium potential (mV) - * thr Neuronal spike threshold (mV) - * a Transmitter release/bind rise factor - * b Transmitter release/bind decay factor - * k Steepness of activation function - */ - -// General parameters -#define p_h 0.5 -#define p_t0 0.0 -#define p_prec prec_arg -unsigned long prec_arg; -#define p_sim_steps 1000 -#define p_report_step 20 - -// Current sum reordering -int current_order_arg; -//#define p_shuffle_current -//#define p_sort_current > -// > increasing (best case approx) -// < decreasing (worst case approx) - -// RNG parameters -// Seeds are random if not #defined -#define p_rand_prec 53 -#define p_rng_uf_seed 707135875931353ul -#define p_rng_nf_seed 503108552855933ul - -// Poisson input parameters (group 1) -#define p_in1_size 500 -#define p_in1_freq 50.0 -#define p_in1_V_lo -60.0 -#define p_in1_V_hi 20.0 - -// Poisson input parameters (group 2) -#define p_in2_size 0 -#define p_in2_freq 10.0 -#define p_in2_V_lo -60.0 -#define p_in2_V_hi 20.0 - -// Neuron parameters (group 1) -#define p_nrn1_size 1 -#define p_nrn1_N0 0.0 -#define p_nrn1_V0 -60.0 -#define p_nrn1_class 1 - -// Neuron parameters (group 2) -#define p_nrn2_size 0 -#define p_nrn2_N0 0.0 -#define p_nrn2_V0 -60.0 -#define p_nrn2_class 1 - -// Neuron parameters (common) -#define p_GL 2.0 -#define p_GCa 4.0 // Class 1 -//#define p_GCa 4.4 // Class 2 -#define p_GK 8.0 -#define p_VL -60.0 -#define p_VCa 120.0 -#define p_VK -80.0 -#define p_V1 -1.2 -#define p_V2 18.0 -#define p_V3 12.0 // Class 1 -//#define p_V3 2.0 // Class 2 -#define p_V4 17.4 // Class 1 -//#define p_V4 30.0 // Class 2 -#define p_phi 1.0 / 15.0 // Class 1 -//#define p_phi 1.0 / 25.0 // Class 2 -#define p_C 20.0 - -// Synapse parameters (excitatory) -#define p_syn_exc_size p_in1_size * p_nrn1_size -#define p_syn_exc_R0 0.0 -#define p_syn_exc_S0 0.0 -#define p_syn_exc_GSyn_std 0.05 -#define p_syn_exc_GSyn_mean 25.0 / p_in1_size -#define p_syn_exc_VSyn 0.0 -#define p_syn_exc_thr -50.0 -#define p_syn_exc_a 0.25 // in [1/10, 1/2] -#define p_syn_exc_b 0.15 // in [1/20, 1/4] -#define p_syn_exc_k 1.0E6 - -// Synapse parameters (inhibitory) -#define p_syn_inh_size 0 -#define p_syn_inh_R0 0.0 -#define p_syn_inh_S0 0.0 -#define p_syn_inh_GSyn_std 0.5 -#define p_syn_inh_GSyn_mean 3.0 -#define p_syn_inh_VSyn -80.0 -#define p_syn_inh_thr -50.0 -#define p_syn_inh_a 0.075 // in [1/20, 1/10] -#define p_syn_inh_b 0.035 // in [1/50, 1/20] -#define p_syn_inh_k 1.0E6 - -// ===================== end of model parameters ====================== - - -int *in1, *in2; -mpfr_t GL, VL, GCa, VCa, GK, VK, V1, V2, V3, V4, phi, C, syn_exc_VSyn, syn_exc_thr, - syn_exc_a, syn_exc_b, syn_exc_k, syn_inh_VSyn, syn_inh_thr, syn_inh_a, - syn_inh_b, syn_inh_k, one, two, neg_two, temp1, temp2, M_ss, N_ss, in1_V_lo, - in1_V_hi, in2_V_lo, in2_V_hi, in1_p0, in2_p0, rand_uf, rand_nf; -mpz_t rand_uz; -mpfr_ptr syn_exc_GSyn, syn_inh_GSyn, I_ptr_swap, I1, *I1_ptr, *I1_ptr_temp, I2, *I2_ptr, *I2_ptr_temp; -gmp_randstate_t rng_uf, rng_nf, rng_uz; - -// System state variables -mpfr_ptr nrn1_N, nrn2_N, nrn1_V, nrn2_V, syn_exc_R, syn_inh_R, syn_exc_S, syn_inh_S; -mpfr_ptr d_nrn1_N, d_nrn2_N, d_nrn1_V, d_nrn2_V, d_syn_exc_R, d_syn_inh_R, d_syn_exc_S, d_syn_inh_S; - -// DEBUG: print MPFR numbers to stderr -void debug (mpfr_srcptr x) { - mpfr_out_str(stderr, 10, 80, x, MPFR_RNDN); - fputs("\n", stderr); -} - -void file_init (char *grp, unsigned long grp_size, FILE **f) -{ - char fname[20]; - unsigned long i; - - for (i = 0; i < grp_size; i++) { - sprintf(fname, "%s_%03lu.dat", grp, i); - f[i] = fopen(fname, "w"); - } -} - -void file_clear (unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - fclose(f[i]); - } -} - -void file_write (mpfr_srcptr A, unsigned long grp_size, FILE **f) -{ - unsigned long i; - - for (i = 0; i < grp_size; i++) { - mpfr_out_str(f[i], 10, 80, &(A[i]), MPFR_RNDN); - fputc('\n', f[i]); - } -} - -void dNdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_N; - mpfr_srcptr N, V; - - if (grp == 1) { - d_N = d_nrn1_N + idx; - N = nrn1_N + idx; - V = nrn1_V + idx; - } - //else if (grp == 2) { - // d_N = d_nrn2_N + idx; - // N = nrn2_N + idx; - // V = nrn2_V + idx; - //} - - // K+ channel activation steady-state - // N_ss = 1 / (1 + exp(-2 (V - V3) / V4)) - mpfr_sub(temp1, V, V3, MPFR_RNDN); - mpfr_mul(N_ss, neg_two, temp1, MPFR_RNDN); - mpfr_div(N_ss, N_ss, V4, MPFR_RNDN); - mpfr_exp(N_ss, N_ss, MPFR_RNDN); - mpfr_add(N_ss, one, N_ss, MPFR_RNDN); - mpfr_ui_div(N_ss, 1, N_ss, MPFR_RNDN); - - // tau of K+ channel activation - // tau = 1 / (phi ((p + q) / 2)) - // p = exp(-(V - V3) / (2 V4)) - // q = exp( (V - V3) / (2 V4)) - mpfr_mul(temp2, two, V4, MPFR_RNDN); - mpfr_div(temp2, temp1, temp2, MPFR_RNDN); - mpfr_neg(temp1, temp2, MPFR_RNDN); - mpfr_exp(temp1, temp1, MPFR_RNDN); - mpfr_exp(temp2, temp2, MPFR_RNDN); - mpfr_add(temp1, temp1, temp2, MPFR_RNDN); - mpfr_div(temp1, temp1, two, MPFR_RNDN); - mpfr_mul(temp1, phi, temp1, MPFR_RNDN); - mpfr_ui_div(temp1, 1, temp1, MPFR_RNDN); - - // delta of K+ channel activation - // dN/dt = (N_ss - N) / tau - mpfr_sub(d_N, N_ss, N, MPFR_RNDN); - mpfr_div(d_N, d_N, temp1, MPFR_RNDN); -} - -void dVdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_V; - mpfr_srcptr N, V; - mpfr_srcptr S, GSyn, VSyn; - mpfr_ptr I, *I_ptr, *I_ptr_temp; - unsigned long i, j, pre_size; - - if (grp == 1) { - d_V = d_nrn1_V + idx; - N = nrn1_N + idx; - V = nrn1_V + idx; - pre_size = p_in1_size; - S = syn_exc_S + (idx * pre_size); - GSyn = syn_exc_GSyn + (idx * pre_size); - VSyn = syn_exc_VSyn; - I = I1; - I_ptr = I1_ptr; - I_ptr_temp = I1_ptr_temp; - } - //else if (grp == 2) { - // d_V = d_nrn2_V + idx; - // N = nrn2_N + idx; - // V = nrn2_V + idx; - // pre_size = p_in2_size; - // S = syn_exc_S + (idx * pre_size); - // GSyn = syn_exc_GSyn + (idx * pre_size); - // VSyn = syn_exc_VSyn; - // I = I2; - // I_ptr = I2_ptr; - // I_ptr_temp = I2_ptr_temp; - //} - - // Ca++ channel activation steady-state - // M_ss = 1 / (1 + exp(-2 (V - V1) / V2)) - mpfr_sub(M_ss, V, V1, MPFR_RNDN); - mpfr_mul(M_ss, neg_two, M_ss, MPFR_RNDN); - mpfr_div(M_ss, M_ss, V2, MPFR_RNDN); - mpfr_exp(M_ss, M_ss, MPFR_RNDN); - mpfr_add(M_ss, one, M_ss, MPFR_RNDN); - mpfr_ui_div(M_ss, 1, M_ss, MPFR_RNDN); - - // Synapse current - mpfr_sub(temp1, VSyn, V, MPFR_RNDN); - mpfr_set_ui(d_V, 0, MPFR_RNDN); - for (i = 0; i < pre_size; i++) { - mpfr_mul(&(I[i]), temp1, &(GSyn[i]), MPFR_RNDN); - mpfr_mul(&(I[i]), &(I[i]), &(S[i]), MPFR_RNDN); - I_ptr[i] = &(I[i]); - } - -//#ifdef p_shuffle_current - if (current_order_arg == 0) { - // Shuffle input currents with Fisher-Yates. - for (i = 0; i < pre_size; i++) { - mpz_set_ui(rand_uz, pre_size - i); - mpz_urandomm(rand_uz, rng_uz, rand_uz); - j = i + mpz_get_ui(rand_uz); - I_ptr_swap = I_ptr[i]; - I_ptr[i] = I_ptr[j]; - I_ptr[j] = I_ptr_swap; - } - } -//#endif // p_shuffle_current - -//#ifdef p_sort_current - if (current_order_arg > 0) { - // Merge sort input currents - unsigned long pa, pb, pc, chunk_size, k; - - for (chunk_size = 1; chunk_size < pre_size; chunk_size *= 2) { - for (pa = 0; (pa + chunk_size) < pre_size; pa += (2 * chunk_size)) { - pb = pa + chunk_size; - pc = pb + chunk_size; - if (pc > pre_size) pc = pre_size; - i = pa; - j = pb; - k = pa; - while ((i < pb) && (j < pc)) { - /* if (mpfr_cmpabs(I_ptr[j], I_ptr[i]) p_sort_current 0) { */ - /* I_ptr_temp[k++] = I_ptr[i++]; */ - /* } */ - /* else { */ - /* I_ptr_temp[k++] = I_ptr[j++]; */ - /* } */ - - - // ascending (best) - if (current_order_arg == 1) { - if (mpfr_cmpabs(I_ptr[j], I_ptr[i]) > 0) { - I_ptr_temp[k++] = I_ptr[i++]; - } - else { - I_ptr_temp[k++] = I_ptr[j++]; - } - } - - - // descending (worst) - if (current_order_arg == 2) { - if (mpfr_cmpabs(I_ptr[j], I_ptr[i]) < 0) { - I_ptr_temp[k++] = I_ptr[i++]; - } - else { - I_ptr_temp[k++] = I_ptr[j++]; - } - } - - - - } - while (i < pb) { - I_ptr_temp[k++] = I_ptr[i++]; - } - while (j < pc) { - I_ptr_temp[k++] = I_ptr[j++]; - } - } - for (k = 0; k < pre_size; k++) { - I_ptr[k] = I_ptr_temp[k]; - } - } - } -//#endif // p_sort_current - - // Sum input currents - for (i = 0; i < pre_size; i++) { - mpfr_add(d_V, d_V, I_ptr[i], MPFR_RNDN); - } - - - - - // ======== TEMP DEBUG ========== - //mpfr_set_d(d_V, 80.0, MPFR_RNDN); // bifurcation at sum(I) = 80.0 - //for (i = 0; i < pre_size; i++) { - // debug(I_ptr[i]); - //} - //fprintf(stderr, "\n"); - if (idx == 0) { - //fprintf(stderr, "sum(I): "); debug(d_V); - //fprintf(stderr, "I[0]: "); debug(I); - for (i = 0; i < pre_size; i++) { - //fprintf(stderr, "I[%lu]: ", i); debug(&(I[i])); - } - } - - - - // Leak current - mpfr_sub(temp1, V, VL, MPFR_RNDN); - mpfr_mul(temp1, temp1, GL, MPFR_RNDN); - mpfr_sub(d_V, d_V, temp1, MPFR_RNDN); - - // Ca++ current - mpfr_sub(temp1, V, VCa, MPFR_RNDN); - mpfr_mul(temp1, temp1, GCa, MPFR_RNDN); - mpfr_mul(temp1, temp1, M_ss, MPFR_RNDN); - mpfr_sub(d_V, d_V, temp1, MPFR_RNDN); - - // K+ current - mpfr_sub(temp1, V, VK, MPFR_RNDN); - mpfr_mul(temp1, temp1, GK, MPFR_RNDN); - mpfr_mul(temp1, temp1, N, MPFR_RNDN); - mpfr_sub(d_V, d_V, temp1, MPFR_RNDN); - - // delta of membrane potential - // dV/dt = (I + GL (VL - V) + GCa M (VCa - V) + GK N (VK - V)) / C - mpfr_div(d_V, d_V, C, MPFR_RNDN); -} - -void dRdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_R; - mpfr_srcptr R; - mpfr_srcptr a, b, k; - mpfr_srcptr VPre, threshold; - - if (grp == 1) { - d_R = d_syn_exc_R + idx; - R = syn_exc_R + idx; - a = syn_exc_a; - b = syn_exc_b; - k = syn_exc_k; - VPre = in1[idx % p_in1_size] ? in1_V_hi : in1_V_lo; - threshold = syn_exc_thr; - } - //else if (grp == 2) { - // d_R = d_syn_inh_R + idx; - // R = syn_inh_R + idx; - // a = syn_inh_a; - // b = syn_inh_b; - // k = syn_inh_k; - // VPre = in2[idx % p_in2_size] ? in2_V_hi : in2_V_lo; - // threshold = syn_inh_thr; - //} - - // Sigmoid of threshold difference - mpfr_sub(temp1, VPre, threshold, MPFR_RNDN); - mpfr_mul(temp1, temp1, k, MPFR_RNDN); - mpfr_exp(temp1, temp1, MPFR_RNDN); - mpfr_add(temp1, temp1, one, MPFR_RNDN); - mpfr_ui_div(temp1, 1, temp1, MPFR_RNDN); - - // Presynaptic transmitter release rise - mpfr_mul(temp1, a, temp1, MPFR_RNDN); - - // Presynaptic transmitter release decay - mpfr_mul(temp2, b, R, MPFR_RNDN); - - // delta of presynaptic transmitter release - // dR/dt = a Q - b R - // Q = 1 / (1 + e^(k(V - threshold))) - mpfr_sub(d_R, temp1, temp2, MPFR_RNDN); -} - -void dSdt (const unsigned long idx, int grp) -{ - mpfr_ptr d_S; - mpfr_srcptr R, S; - mpfr_srcptr a, b; - - if (grp == 1) { - d_S = d_syn_exc_S + idx; - R = syn_exc_R + idx; - S = syn_exc_S + idx; - a = syn_exc_a; - b = syn_exc_b; - } - //else if (grp == 2) { - // d_S = d_syn_inh_S + idx; - // R = syn_inh_R + idx; - // S = syn_inh_S + idx; - // a = syn_inh_a; - // b = syn_inh_b; - //} - - // Postsynaptic transmitter binding rise - mpfr_mul(temp1, a, R, MPFR_RNDN); - - // Postsynaptic transmitter binding decay - mpfr_mul(temp2, b, S, MPFR_RNDN); - - // delta of postsynaptic transmitter binding - // dS/dt = a R - b S - mpfr_sub(d_S, temp1, temp2, MPFR_RNDN); -} - -int main (int argc, char *argv[]) -{ - mpfr_t h, t; - unsigned long i, j; - - // Parse args - prec_arg = atoll(argv[1]); - current_order_arg = atoi(argv[2]); - - // Allocate system state - nrn1_N = malloc(p_nrn1_size * sizeof(mpfr_t)); - nrn1_V = malloc(p_nrn1_size * sizeof(mpfr_t)); - nrn2_N = malloc(p_nrn2_size * sizeof(mpfr_t)); - nrn2_V = malloc(p_nrn2_size * sizeof(mpfr_t)); - syn_exc_R = malloc(p_syn_exc_size * sizeof(mpfr_t)); - syn_exc_S = malloc(p_syn_exc_size * sizeof(mpfr_t)); - syn_inh_R = malloc(p_syn_inh_size * sizeof(mpfr_t)); - syn_inh_S = malloc(p_syn_inh_size * sizeof(mpfr_t)); - - // Allocate other arrays - d_nrn1_N = malloc(p_nrn1_size * sizeof(mpfr_t)); - d_nrn2_N = malloc(p_nrn2_size * sizeof(mpfr_t)); - d_nrn1_V = malloc(p_nrn1_size * sizeof(mpfr_t)); - d_nrn2_V = malloc(p_nrn2_size * sizeof(mpfr_t)); - d_syn_exc_R = malloc(p_syn_exc_size * sizeof(mpfr_t)); - d_syn_inh_R = malloc(p_syn_inh_size * sizeof(mpfr_t)); - d_syn_exc_S = malloc(p_syn_exc_size * sizeof(mpfr_t)); - d_syn_inh_S = malloc(p_syn_inh_size * sizeof(mpfr_t)); - syn_exc_GSyn = malloc(p_syn_exc_size * sizeof(mpfr_t)); - syn_inh_GSyn = malloc(p_syn_inh_size * sizeof(mpfr_t)); - I1 = malloc(p_in1_size * sizeof(mpfr_t)); - I1_ptr = malloc(p_in1_size * sizeof(mpfr_ptr)); - I1_ptr_temp = malloc(p_in1_size * sizeof(mpfr_ptr)); - I2 = malloc(p_in2_size * sizeof(mpfr_t)); - I2_ptr = malloc(p_in2_size * sizeof(mpfr_ptr)); - I2_ptr_temp = malloc(p_in2_size * sizeof(mpfr_ptr)); - in1 = malloc(p_in1_size * sizeof(int)); - in2 = malloc(p_in2_size * sizeof(int)); - - struct timespec clock_time; - - // Initialise uniform float RNG - gmp_randinit_default(rng_uf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uf_seed - unsigned long rng_uf_seed = p_rng_uf_seed; -#else - unsigned long rng_uf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uf, rng_uf_seed); - printf("GMP rand uniform float seed: %lu\n", rng_uf_seed); - - // Initialise normal float RNG - gmp_randinit_default(rng_nf); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_nf_seed - unsigned long rng_nf_seed = p_rng_nf_seed; -#else - unsigned long rng_nf_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_nf, rng_nf_seed); - printf("GMP rand normal float seed: %lu\n", rng_nf_seed); - - // Initialise uniform integer RNG - gmp_randinit_default(rng_uz); - clock_gettime(CLOCK_REALTIME, &clock_time); -#ifdef p_rng_uz_seed - unsigned long rng_uz_seed = p_rng_uz_seed; -#else - unsigned long rng_uz_seed = clock_time.tv_sec + clock_time.tv_nsec; -#endif - gmp_randseed_ui(rng_uz, rng_uz_seed); - printf("GMP rand uniform integer seed: %lu\n", rng_uz_seed); - - // Initialise system state - mpfr_init2(h, p_prec); - mpfr_init2(t, p_prec); - for (i = 0; i < p_nrn1_size; i++) { - mpfr_init2(&(nrn1_N[i]), p_prec); - mpfr_init2(&(nrn1_V[i]), p_prec); - mpfr_init2(&(d_nrn1_N[i]), p_prec); - mpfr_init2(&(d_nrn1_V[i]), p_prec); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfr_init2(&(nrn2_N[i]), p_prec); - mpfr_init2(&(nrn2_V[i]), p_prec); - mpfr_init2(&(d_nrn2_N[i]), p_prec); - mpfr_init2(&(d_nrn2_V[i]), p_prec); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_init2(&(syn_exc_R[i]), p_prec); - mpfr_init2(&(syn_exc_S[i]), p_prec); - mpfr_init2(&(d_syn_exc_R[i]), p_prec); - mpfr_init2(&(d_syn_exc_S[i]), p_prec); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_init2(&(syn_inh_R[i]), p_prec); - mpfr_init2(&(syn_inh_S[i]), p_prec); - mpfr_init2(&(d_syn_inh_R[i]), p_prec); - mpfr_init2(&(d_syn_inh_S[i]), p_prec); - } - - // Initialise Poisson input parameters (group 1) - mpfr_init2(in1_p0, p_prec); - mpfr_init2(in1_V_lo, p_prec); - mpfr_init2(in1_V_hi, p_prec); - - // Initialise Poisson input parameters (group 2) - mpfr_init2(in2_p0, p_prec); - mpfr_init2(in2_V_lo, p_prec); - mpfr_init2(in2_V_hi, p_prec); - - // Initialise neuron parameters - mpfr_init2(GL, p_prec); - mpfr_init2(GCa, p_prec); - mpfr_init2(GK, p_prec); - mpfr_init2(VL, p_prec); - mpfr_init2(VCa, p_prec); - mpfr_init2(VK, p_prec); - mpfr_init2(V1, p_prec); - mpfr_init2(V2, p_prec); - mpfr_init2(V3, p_prec); - mpfr_init2(V4, p_prec); - mpfr_init2(phi, p_prec); - mpfr_init2(C, p_prec); - - // Initialise excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_init2(&(syn_exc_GSyn[i]), p_prec); - } - mpfr_init2(syn_exc_VSyn, p_prec); - mpfr_init2(syn_exc_thr, p_prec); - mpfr_init2(syn_exc_a, p_prec); - mpfr_init2(syn_exc_b, p_prec); - mpfr_init2(syn_exc_k, p_prec); - - // Initialise inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_init2(&(syn_inh_GSyn[i]), p_prec); - } - mpfr_init2(syn_inh_VSyn, p_prec); - mpfr_init2(syn_inh_thr, p_prec); - mpfr_init2(syn_inh_a, p_prec); - mpfr_init2(syn_inh_b, p_prec); - mpfr_init2(syn_inh_k, p_prec); - - // Initialise constants - mpfr_init2(one, p_prec); - mpfr_init2(two, p_prec); - mpfr_init2(neg_two, p_prec); - - // Initialise scratch space - mpfr_init2(rand_uf, p_rand_prec); - mpfr_init2(rand_nf, p_rand_prec); - mpz_init(rand_uz); - mpfr_init2(temp1, p_prec); - mpfr_init2(temp2, p_prec); - mpfr_init2(M_ss, p_prec); - mpfr_init2(N_ss, p_prec); - for (i = 0; i < p_in1_size; i++) { - mpfr_init2(&(I1[i]), p_prec); - } - for (i = 0; i < p_in2_size; i++) { - mpfr_init2(&(I2[i]), p_prec); - } - - // Set system state - mpfr_set_d(h, p_h, MPFR_RNDN); - mpfr_set_d(t, p_t0, MPFR_RNDN); - for (i = 0; i < p_nrn1_size; i++) { - mpfr_set_d(&(nrn1_N[i]), p_nrn1_N0, MPFR_RNDN); - mpfr_set_d(&(nrn1_V[i]), p_nrn1_V0, MPFR_RNDN); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfr_set_d(&(nrn2_N[i]), p_nrn2_N0, MPFR_RNDN); - mpfr_set_d(&(nrn2_V[i]), p_nrn2_V0, MPFR_RNDN); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_set_d(&(syn_exc_R[i]), p_syn_exc_R0, MPFR_RNDN); - mpfr_set_d(&(syn_exc_S[i]), p_syn_exc_S0, MPFR_RNDN); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_set_d(&(syn_inh_R[i]), p_syn_inh_R0, MPFR_RNDN); - mpfr_set_d(&(syn_inh_S[i]), p_syn_inh_S0, MPFR_RNDN); - } - - // Set Poisson input parameters (group 1) - mpfr_set_d(in1_p0, -(p_in1_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in1_p0, in1_p0, MPFR_RNDN); - mpfr_set_d(in1_V_lo, p_in1_V_lo, MPFR_RNDN); - mpfr_set_d(in1_V_hi, p_in1_V_hi, MPFR_RNDN); - - // Set Poisson input parameters (group 2) - mpfr_set_d(in2_p0, -(p_in2_freq / 1000) * p_h, MPFR_RNDN); - mpfr_exp(in2_p0, in2_p0, MPFR_RNDN); - mpfr_set_d(in2_V_lo, p_in2_V_lo, MPFR_RNDN); - mpfr_set_d(in2_V_hi, p_in2_V_hi, MPFR_RNDN); - - // Set neuron parameters - mpfr_set_d(GL, p_GL, MPFR_RNDN); - mpfr_set_d(GCa, p_GCa, MPFR_RNDN); - mpfr_set_d(GK, p_GK, MPFR_RNDN); - mpfr_set_d(VL, p_VL, MPFR_RNDN); - mpfr_set_d(VCa, p_VCa, MPFR_RNDN); - mpfr_set_d(VK, p_VK, MPFR_RNDN); - mpfr_set_d(V1, p_V1, MPFR_RNDN); - mpfr_set_d(V2, p_V2, MPFR_RNDN); - mpfr_set_d(V3, p_V3, MPFR_RNDN); - mpfr_set_d(V4, p_V4, MPFR_RNDN); - mpfr_set_d(phi, p_phi, MPFR_RNDN); - mpfr_set_d(C, p_C, MPFR_RNDN); - - // Set excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_exc_GSyn_std, MPFR_RNDN); - mpfr_add_d(&(syn_exc_GSyn[i]), rand_nf, p_syn_exc_GSyn_mean, MPFR_RNDN); - } - mpfr_set_d(syn_exc_VSyn, p_syn_exc_VSyn, MPFR_RNDN); - mpfr_set_d(syn_exc_thr, p_syn_exc_thr, MPFR_RNDN); - mpfr_set_d(syn_exc_a, p_syn_exc_a, MPFR_RNDN); - mpfr_set_d(syn_exc_b, p_syn_exc_b, MPFR_RNDN); - mpfr_set_d(syn_exc_k, p_syn_exc_k, MPFR_RNDN); - mpfr_neg(syn_exc_k, syn_exc_k, MPFR_RNDN); - - // Set inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - //mpfr_nrandom(rand_nf, rng_nf, MPFR_RNDN); - mpfr_grandom(rand_nf, NULL, rng_nf, MPFR_RNDN); - mpfr_mul_d(rand_nf, rand_nf, p_syn_inh_GSyn_std, MPFR_RNDN); - mpfr_add_d(&(syn_inh_GSyn[i]), rand_nf, p_syn_inh_GSyn_mean, MPFR_RNDN); - } - mpfr_set_d(syn_inh_VSyn, p_syn_inh_VSyn, MPFR_RNDN); - mpfr_set_d(syn_inh_thr, p_syn_inh_thr, MPFR_RNDN); - mpfr_set_d(syn_inh_a, p_syn_inh_a, MPFR_RNDN); - mpfr_set_d(syn_inh_b, p_syn_inh_b, MPFR_RNDN); - mpfr_set_d(syn_inh_k, p_syn_inh_k, MPFR_RNDN); - mpfr_neg(syn_inh_k, syn_inh_k, MPFR_RNDN); - - // Set constants - mpfr_set_d(one, 1.0, MPFR_RNDN); - mpfr_set_d(two, 2.0, MPFR_RNDN); - mpfr_set_d(neg_two, -2.0, MPFR_RNDN); - - // Initialise report files - FILE **f_time = malloc(sizeof(FILE *));; - file_init("time", 1, f_time); - - FILE **f_nrn1_N = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_N", p_nrn1_size, f_nrn1_N); - FILE **f_nrn1_V = malloc(p_nrn1_size * sizeof(FILE *)); - file_init("nrn1_V", p_nrn1_size, f_nrn1_V); - - /* FILE **f_nrn2_N = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_N", p_nrn2_size, f_nrn2_N); */ - /* FILE **f_nrn2_V = malloc(p_nrn2_size * sizeof(FILE *)); */ - /* file_init("nrn2_V", p_nrn2_size, f_nrn2_V); */ - - /* FILE **f_syn_exc_R = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_R", p_syn_exc_size, f_syn_exc_R); */ - /* FILE **f_syn_exc_S = malloc(p_syn_exc_size * sizeof(FILE *)); */ - /* file_init("syn_exc_S", p_syn_exc_size, f_syn_exc_S); */ - - /* FILE **f_syn_inh_R = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_R", p_syn_inh_size, f_syn_inh_R); */ - /* FILE **f_syn_inh_S = malloc(p_syn_inh_size * sizeof(FILE *)); */ - /* file_init("syn_inh_S", p_syn_inh_size, f_syn_inh_S); */ - - - // Begin simulation loop - // ===================== - - clock_t run_time = clock(); - - for (i = 0; i < p_sim_steps; i++) { - if (i % p_report_step == 0) printf("%lu\n", i); - - // Event(s) occur if urandom >= e^-rate - for (j = 0; j < p_in1_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in1[j] = mpfr_greaterequal_p(rand_uf, in1_p0); - fprintf(stderr, "%s", (in1[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, " "); - for (j = 0; j < p_in2_size; j++) { - mpfr_urandom(rand_uf, rng_uf, MPFR_RNDN); - in2[j] = mpfr_greaterequal_p(rand_uf, in2_p0); - fprintf(stderr, "%s", (in2[j] ? "\x1B[31m\xE2\x96\xA3\x1B[0m" : "\xE2\x96\xA3")); - } - fprintf(stderr, "\n"); - - // Compute derivatives - for (j = 0; j < p_nrn1_size; j++) { - dNdt(j, 1); - dVdt(j, 1); - } - for (j = 0; j < p_nrn2_size; j++) { - dNdt(j, 2); - dVdt(j, 2); - } - for (j = 0; j < p_syn_exc_size; j++) { - dRdt(j, 1); - dSdt(j, 1); - } - for (j = 0; j < p_syn_inh_size; j++) { - dRdt(j, 2); - dSdt(j, 2); - } - - // Step system - mpfr_add(t, t, h, MPFR_RNDN); - for (j = 0; j < p_nrn1_size; j++) { - mpfr_mul(&(d_nrn1_N[j]), &(d_nrn1_N[j]), h, MPFR_RNDN); - mpfr_add(&(nrn1_N[j]), &(nrn1_N[j]), &(d_nrn1_N[j]), MPFR_RNDN); - mpfr_mul(&(d_nrn1_V[j]), &(d_nrn1_V[j]), h, MPFR_RNDN); - mpfr_add(&(nrn1_V[j]), &(nrn1_V[j]), &(d_nrn1_V[j]), MPFR_RNDN); - } - for (j = 0; j < p_nrn2_size; j++) { - mpfr_mul(&(d_nrn2_N[j]), &(d_nrn2_N[j]), h, MPFR_RNDN); - mpfr_add(&(nrn2_N[j]), &(nrn2_N[j]), &(d_nrn2_N[j]), MPFR_RNDN); - mpfr_mul(&(d_nrn2_V[j]), &(d_nrn2_V[j]), h, MPFR_RNDN); - mpfr_add(&(nrn2_V[j]), &(nrn2_V[j]), &(d_nrn2_V[j]), MPFR_RNDN); - } - for (j = 0; j < p_syn_exc_size; j++) { - mpfr_mul(&(d_syn_exc_R[j]), &(d_syn_exc_R[j]), h, MPFR_RNDN); - mpfr_add(&(syn_exc_R[j]), &(syn_exc_R[j]), &(d_syn_exc_R[j]), MPFR_RNDN); - mpfr_mul(&(d_syn_exc_S[j]), &(d_syn_exc_S[j]), h, MPFR_RNDN); - mpfr_add(&(syn_exc_S[j]), &(syn_exc_S[j]), &(d_syn_exc_S[j]), MPFR_RNDN); - } - for (j = 0; j < p_syn_inh_size; j++) { - mpfr_mul(&(d_syn_inh_R[j]), &(d_syn_inh_R[j]), h, MPFR_RNDN); - mpfr_add(&(syn_inh_R[j]), &(syn_inh_R[j]), &(d_syn_inh_R[j]), MPFR_RNDN); - mpfr_mul(&(d_syn_inh_S[j]), &(d_syn_inh_S[j]), h, MPFR_RNDN); - mpfr_add(&(syn_inh_S[j]), &(syn_inh_S[j]), &(d_syn_inh_S[j]), MPFR_RNDN); - } - - file_write(t, 1, f_time); - - file_write(nrn1_N, p_nrn1_size, f_nrn1_N); - file_write(nrn1_V, p_nrn1_size, f_nrn1_V); - - /* file_write(nrn2_N, p_nrn2_size, f_nrn2_N); */ - /* file_write(nrn2_V, p_nrn2_size, f_nrn2_V); */ - - /* file_write(syn_exc_R, p_syn_exc_size, f_syn_exc_R); */ - /* file_write(syn_exc_S, p_syn_exc_size, f_syn_exc_S); */ - - /* file_write(syn_inh_R, p_syn_inh_size, f_syn_inh_R); */ - /* file_write(syn_inh_S, p_syn_inh_size, f_syn_inh_S); */ - } - - run_time = clock() - run_time; - printf("Finished in %f seconds.\n", ((float) run_time) / CLOCKS_PER_SEC); - - // End simulation loop - // =================== - - - // Clear system state - mpfr_clear(h); - mpfr_clear(t); - for (i = 0; i < p_nrn1_size; i++) { - mpfr_clear(&(nrn1_N[i])); - mpfr_clear(&(nrn1_V[i])); - mpfr_clear(&(d_nrn1_N[i])); - mpfr_clear(&(d_nrn1_V[i])); - } - for (i = 0; i < p_nrn2_size; i++) { - mpfr_clear(&(nrn2_N[i])); - mpfr_clear(&(nrn2_V[i])); - mpfr_clear(&(d_nrn2_N[i])); - mpfr_clear(&(d_nrn2_V[i])); - } - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_clear(&(syn_exc_R[i])); - mpfr_clear(&(syn_exc_S[i])); - mpfr_clear(&(d_syn_exc_R[i])); - mpfr_clear(&(d_syn_exc_S[i])); - } - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_clear(&(syn_inh_R[i])); - mpfr_clear(&(syn_inh_S[i])); - mpfr_clear(&(d_syn_inh_R[i])); - mpfr_clear(&(d_syn_inh_S[i])); - } - - // Clear Poisson input parameters (group 1) - mpfr_clear(in1_p0); - mpfr_clear(in1_V_lo); - mpfr_clear(in1_V_hi); - - // Clear Poisson input parameters (group 2) - mpfr_clear(in2_p0); - mpfr_clear(in2_V_lo); - mpfr_clear(in2_V_hi); - - // Clear neuron parameters - mpfr_clear(GL); - mpfr_clear(GCa); - mpfr_clear(GK); - mpfr_clear(VL); - mpfr_clear(VCa); - mpfr_clear(VK); - mpfr_clear(V1); - mpfr_clear(V2); - mpfr_clear(V3); - mpfr_clear(V4); - mpfr_clear(phi); - mpfr_clear(C); - - // Clear excitatory synapse parameters - for (i = 0; i < p_syn_exc_size; i++) { - mpfr_clear(&(syn_exc_GSyn[i])); - } - mpfr_clear(syn_exc_VSyn); - mpfr_clear(syn_exc_thr); - mpfr_clear(syn_exc_a); - mpfr_clear(syn_exc_b); - mpfr_clear(syn_exc_k); - - // Clear inhibitory synapse parameters - for (i = 0; i < p_syn_inh_size; i++) { - mpfr_clear(&(syn_inh_GSyn[i])); - } - mpfr_clear(syn_inh_VSyn); - mpfr_clear(syn_inh_thr); - mpfr_clear(syn_inh_a); - mpfr_clear(syn_inh_b); - mpfr_clear(syn_inh_k); - - // Clear constants - mpfr_clear(one); - mpfr_clear(two); - mpfr_clear(neg_two); - - // Clear scratch space - mpfr_clear(rand_uf); - mpfr_clear(rand_nf); - mpz_clear(rand_uz); - mpfr_clear(temp1); - mpfr_clear(temp2); - mpfr_clear(M_ss); - mpfr_clear(N_ss); - for (i = 0; i < p_in1_size; i++) { - mpfr_clear(&(I1[i])); - } - for (i = 0; i < p_in2_size; i++) { - mpfr_clear(&(I2[i])); - } - - // Free system state - free(nrn1_N); - free(nrn1_V); - free(nrn2_N); - free(nrn2_V); - free(syn_exc_R); - free(syn_exc_S); - free(syn_inh_R); - free(syn_inh_S); - - // Free other arrays - free(d_nrn1_N); - free(d_nrn2_N); - free(d_nrn1_V); - free(d_nrn2_V); - free(d_syn_exc_R); - free(d_syn_inh_R); - free(d_syn_exc_S); - free(d_syn_inh_S); - free(syn_exc_GSyn); - free(syn_inh_GSyn); - free(I1); - free(I1_ptr); - free(I1_ptr_temp); - free(I2); - free(I2_ptr); - free(I2_ptr_temp); - free(in1); - free(in2); - - // Clear report files - file_clear(1, f_time); - free(f_time); - - file_clear(p_nrn1_size, f_nrn1_N); - free(f_nrn1_N); - file_clear(p_nrn1_size, f_nrn1_V); - free(f_nrn1_V); - - /* file_clear(p_nrn2_size, f_nrn2_N); */ - /* free(f_nrn2_N); */ - /* file_clear(p_nrn2_size, f_nrn2_V); */ - /* free(f_nrn2_V); */ - - /* file_clear(p_syn_exc_size, f_syn_exc_R); */ - /* free(f_syn_exc_R); */ - /* file_clear(p_syn_exc_size, f_syn_exc_S); */ - /* free(f_syn_exc_S); */ - - /* file_clear(p_syn_inh_size, f_syn_inh_R); */ - /* free(f_syn_inh_R); */ - /* file_clear(p_syn_inh_size, f_syn_inh_S); */ - /* free(f_syn_inh_S); */ - - gmp_randclear(rng_uf); - gmp_randclear(rng_nf); - gmp_randclear(rng_uz); - mpfr_free_cache(); - - return 0; -}