NEURON
singlech.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 #include <OS/list.h>
3 #include "nrnoc2iv.h"
4 #include "ndatclas.h"
5 #include "ivocvect.h"
6 #include "ocmatrix.h"
7 #include "classreg.h"
8 #include "singlech.h"
9 #include "membfunc.h"
10 #include "random1.h"
11 #include "NegExp.h"
12 
13 extern "C" {
14 
15 extern double exprand(double); // must be changed!
16 
17 } // extern "C"
18 void hoc_reg_singlechan(int, void (*)(...));
19 void _singlechan_declare(void (*)(double, double*, Datum*), int*, int);
20 void _nrn_single_react(int, int, double);
21 
22 /*
23 encoded in the order of the rates and to_states below is the order
24 in which the _nrn_single_react statements are made.
25 */
26 
28  public:
30  virtual ~SingleChanState();
31  void rate(int to_state, double value);
32 
33  public:
34  int cond_;
35 
36  int n_;
37  int size_;
38  double* tau_;
39  int* to_state_;
40 };
41 
42 
44  public:
45  int type_;
46  void (*f_)(double, double*, Datum*);
47  int* slist_;
48  int n_;
49 };
50 
51 std::vector<SingleChanInfo*> infolist;
53 
54 #define NS 3
56  size_ = NS;
57  to_state_ = new int[size_];
58  tau_ = new double[size_];
59  n_ = 0;
60  cond_ = 0;
61 }
62 
64  delete[] to_state_;
65  delete[] tau_;
66 }
67 
68 void SingleChanState::rate(int to_state, double value) {
69  if (n_ >= size_) {
70  int i;
71  int size = 2 * size_;
72  int* s = new int[size];
73  double* r = new double[size];
74  for (i = 0; i < size; ++i) {
75  s[i] = to_state_[i];
76  r[i] = tau_[i];
77  }
78  delete[] to_state_;
79  delete[] tau_;
80  to_state_ = s;
81  tau_ = r;
82  size_ = size;
83  }
84  to_state_[n_] = to_state;
85  tau_[n_] = 1 / value;
86  ++n_;
87 }
88 
89 void hoc_reg_singlechan(int type, void (*f)(...)) {
91  info->type_ = type;
92  infolist.push_back(info);
93  (*f)();
94 #if 0
95  if (nrn_istty_) {
96  printf("Allow single channel model for %s\n", memb_func[info->type_].sym->name);
97  }
98 #endif
99 }
100 
101 void _singlechan_declare(void (*f)(double, double*, Datum*), int* slist, int n) {
102  if (infolist.empty()) {
103  return;
104  }
105  SingleChanInfo* info = infolist.back();
106  info->f_ = f;
107  info->slist_ = slist;
108  info->n_ = n;
109 }
110 
111 void _nrn_single_react(int i, int j, double rate) {
112  // printf("_nrn_single_react %d %d %g\n", i, j, rate);
113  current_chan->state_[i].rate(j, rate);
114 }
115 
116 
118  r_ = NULL;
120  nprop_ = new NrnProperty(name);
121  for (const auto& il: infolist) {
122  if (il->type_ == nprop_->type()) {
123  info_ = il;
124  }
125  }
126  if (!info_) {
127  hoc_execerror(name, "cannot be a SingleChannel");
128  }
129  state_ = new SingleChanState[info_->n_];
130  set_rates(0.);
131 }
132 
134  r_ = NULL;
136  state_ = NULL;
137  nprop_ = NULL;
138  info_ = new SingleChanInfo();
139  info_->type_ = -1;
140  info_->f_ = NULL;
141  info_->slist_ = NULL;
142  info_->n_ = 0;
143  set_rates(m);
144 }
145 
147  if (state_) {
148  delete[] state_;
149  }
150  if (nprop_) {
151  delete nprop_;
152  } else {
153  delete info_;
154  }
155  if (r_) {
157  }
158 }
159 void SingleChan::set_rates(double v) {
160  int i, n = info_->n_;
161  if (info_->f_) {
162  for (i = 0; i < n; ++i) {
163  state_[i].n_ = 0;
164  }
165  current_chan = (SingleChan*) this;
166  (*info_->f_)(v, nprop_->prop()->param, nprop_->prop()->dparam);
167  }
168 }
170  assert(nprop_ == NULL);
171  if (state_) {
172  delete[] state_;
173  }
174  info_->n_ = m->nrow();
175  state_ = new SingleChanState[n()];
176  int i, j;
177  for (i = 0; i < n(); ++i) {
178  SingleChanState& s = state_[i];
179  s.n_ = 0;
180  for (j = 0; j < n(); ++j) {
181  double val = m->getval(i, j);
182  if (val > 0.) {
183  s.rate(j, 1. / val);
184  }
185  }
186  }
187 }
188 void SingleChan::set_rates(int i, int j, double tau) {
189  assert(i < n() && j < n() && tau > 0.0);
190  SingleChanState& s = state_[i];
191  int k;
192  for (k = 0; k < n(); ++k) {
193  if (j == s.to_state_[k]) {
194  s.tau_[k] = tau;
195  return;
196  }
197  }
198  assert(k < n());
199 }
200 
201 const char* SingleChan::name(int i) {
202  return NULL;
203 }
204 int SingleChan::index(const char* name) {
205  return -1;
206 }
207 int SingleChan::cond(int i) {
208  return state_[i].cond_;
209 }
210 void SingleChan::cond(int i, int cond) {
211  state_[i].cond_ = cond;
212 }
214  current_ = i;
215 }
217  return current_;
218 }
220  return cond(current_);
221 }
222 
224  double dt = 1e15;
225  double t;
226  int i, j = 0, n = state_[current_].n_;
228 
229  for (i = 0; i < n; ++i) {
230  if ((t = s.tau_[i] * (this->*erand_)()) < dt) {
231  dt = t;
232  j = i;
233  }
234  }
235  current_ = s.to_state_[j];
236  return dt;
237 }
238 
240  return exprand(1);
241 }
243  return (*r_->rand)();
244 }
246  if (r) {
247  hoc_obj_ref(r->obj_);
248  delete r->rand;
249  r->rand = new NegativeExpntl(1.0, r->gen);
251  } else {
253  }
254  if (r_) {
256  }
257  r_ = r;
258 }
259 
261  return info_->n_;
262 }
263 
265  double dt = 0;
266  int i = cond(current_);
267  do {
268  dt += state_transition();
269  } while (cond(current_) == i);
270  return dt;
271 }
272 
274  int i;
275  int n = dt->size();
276  state->resize(n);
277  for (i = 0; i < n; ++i) {
278  state->elem(i) = current_;
279  dt->elem(i) = state_transition();
280  }
281 }
282 
284  int i;
285  int n = dt->size();
286  cond->resize(n);
287  for (i = 0; i < n; ++i) {
288  cond->elem(i) = current_cond();
289  dt->elem(i) = cond_transition();
290  }
291 }
292 
294  m->resize(n(), n());
295  m->zero();
296  int i, j;
297  for (i = 0; i < n(); ++i) {
298  SingleChanState& s = state_[i];
299  for (j = 0; j < s.n_; ++j) {
300  *m->mep(i, s.to_state_[j]) += 1 / s.tau_[j];
301  }
302  }
303 }
304 
305 static double set_rates(void* v) {
306  SingleChan* s = (SingleChan*) v;
307  if (hoc_is_object_arg(1)) {
308  s->set_rates(matrix_arg(1));
309  } else if (ifarg(3)) {
310  int i, j;
311  double val;
312  i = (int) chkarg(1, 0., s->n() - 1);
313  j = (int) chkarg(2, 0., s->n() - 1);
314  val = chkarg(3, 1e-10, 1e10);
315  s->set_rates(i, j, val);
316  } else {
317  s->set_rates(*getarg(1));
318  }
319  return 0.;
320 }
321 
322 static double get_rates(void* v) {
323  SingleChan* s = (SingleChan*) v;
324  s->get_rates(matrix_arg(1));
325  return 1.;
326 }
327 
328 static double set_rand(void* v) {
329  SingleChan* s = (SingleChan*) v;
330  Object* ob = *hoc_objgetarg(1);
331  check_obj_type(ob, "Random");
332  Rand* r = (Rand*) (ob->u.this_pointer);
333  s->setrand(r);
334  return 1.;
335 }
336 
337 static double cond(void* v) {
338  SingleChan* s = (SingleChan*) v;
339  int i = (int) chkarg(1, 0, s->n());
340  if (ifarg(2)) {
341  s->cond(i, (int) *getarg(2));
342  }
343  return double(s->cond(i));
344 }
345 static double current_state(void* v) {
346  SingleChan* s = (SingleChan*) v;
347  if (ifarg(1)) {
348  s->current_state((int) chkarg(1, 0, s->n()));
349  }
350  return (double) s->current_state();
351 }
352 static double current_cond(void* v) {
353  SingleChan* s = (SingleChan*) v;
354  return (double) s->cond(s->current_state());
355 }
356 static double state_transition(void* v) {
357  SingleChan* s = (SingleChan*) v;
358  return s->state_transition();
359 }
360 static double cond_transition(void* v) {
361  SingleChan* s = (SingleChan*) v;
362  return s->cond_transition();
363 }
364 
365 static double state_transitions(void* v) {
366  SingleChan* s = (SingleChan*) v;
368  return 1.;
369 }
370 static double cond_transitions(void* v) {
371  SingleChan* s = (SingleChan*) v;
373  return 1.;
374 }
375 
376 static Member_func members[] = {{"state_transition", state_transition},
377  {"cond_transition", cond_transition},
378  {"set_rates", set_rates},
379  {"get_rates", get_rates},
380  {"cond", cond},
381  {"current_state", current_state},
382  {"current_cond", current_cond},
383  {"state_transitions", state_transitions},
384  {"cond_transitions", cond_transitions},
385  {"set_rand", set_rand},
386  {nullptr, nullptr}};
387 
388 static void* cons(Object*) {
389  SingleChan* s;
390  if (hoc_is_str_arg(1)) {
391  s = new SingleChan(gargstr(1));
392  } else {
393  s = new SingleChan(matrix_arg(1));
394  }
395  return (void*) s;
396 }
397 
398 static void destruct(void* v) {
399  SingleChan* s = (SingleChan*) v;
400  delete s;
401 }
402 
404  class2oc("SingleChan", cons, destruct, members, NULL, NULL, NULL);
405 }
Memb_func * memb_func
Definition: init.cpp:123
short type
Definition: cabvars.h:9
int type() const
Definition: ndatclas.cpp:119
Prop * prop() const
Definition: ndatclas.cpp:123
virtual double getval(int i, int j)
Definition: ocmatrix.h:33
virtual void resize(int, int)
Definition: ocmatrix.h:45
virtual double * mep(int i, int j)
Definition: ocmatrix.h:25
virtual void zero()
Definition: ocmatrix.h:95
virtual int nrow()
Definition: ocmatrix.h:37
Definition: random1.h:9
Random * rand
Definition: random1.h:14
Object * obj_
Definition: random1.h:17
RNG * gen
Definition: random1.h:13
int current_cond()
Definition: singlech.cpp:219
void setrand(Rand *)
Definition: singlech.cpp:245
void state_transitions(Vect *dt, Vect *state)
Definition: singlech.cpp:273
const char * name(int)
Definition: singlech.cpp:201
double(SingleChan::* erand_)()
Definition: singlech.h:38
int current_
Definition: singlech.h:46
void cond_transitions(Vect *dt, Vect *cond)
Definition: singlech.cpp:283
virtual ~SingleChan()
Definition: singlech.cpp:146
double erand1()
Definition: singlech.cpp:239
void get_rates(OcMatrix *)
Definition: singlech.cpp:293
double state_transition()
Definition: singlech.cpp:223
int current_state()
Definition: singlech.cpp:216
int index(const char *)
Definition: singlech.cpp:204
NrnProperty * nprop_
Definition: singlech.h:45
Rand * r_
Definition: singlech.h:41
void set_rates(double v)
Definition: singlech.cpp:159
double cond_transition()
Definition: singlech.cpp:264
SingleChan(const char *)
Definition: singlech.cpp:117
SingleChanState * state_
Definition: singlech.h:35
int cond(int)
Definition: singlech.cpp:207
SingleChanInfo * info_
Definition: singlech.h:44
double erand2()
Definition: singlech.cpp:242
void(* f_)(double, double *, Datum *)
Definition: singlech.cpp:46
double * tau_
Definition: singlech.cpp:38
void rate(int to_state, double value)
Definition: singlech.cpp:68
virtual ~SingleChanState()
Definition: singlech.cpp:63
double dt
Definition: netcvode.cpp:76
double t
Definition: cvodeobj.cpp:59
double chkarg(int, double low, double high)
Definition: code2.cpp:638
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
int hoc_is_object_arg(int narg)
Definition: code.cpp:756
int hoc_is_str_arg(int narg)
Definition: code.cpp:752
Vect * vector_arg(int i)
Definition: ivocvect.cpp:397
void hoc_obj_ref(Object *obj)
Definition: hoc_oop.cpp:1810
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1828
#define assert(ex)
Definition: hocassrt.h:32
#define getarg
Definition: hocdec.h:15
#define gargstr
Definition: hocdec.h:14
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
void
int nrn_istty_
Definition: hoc.cpp:882
int ifarg(int)
Definition: code.cpp:1581
#define Vect
Definition: ivocvect.h:14
Matrix * matrix_arg(int i)
Definition: matrix.cpp:45
#define v
Definition: md1redef.h:4
#define i
Definition: md1redef.h:12
char * name
Definition: init.cpp:16
#define printf
Definition: mwprefix.h:26
static List * info
int const size_t const size_t n
Definition: nrngsl.h:11
size_t j
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1560
static philox4x32_key_t k
Definition: nrnran123.cpp:11
#define e
Definition: passive0.cpp:22
static uint32_t value
Definition: scoprand.cpp:25
check_obj_type(o, "SectionList")
#define NS
Definition: singlech.cpp:54
static double current_cond(void *v)
Definition: singlech.cpp:352
void _nrn_single_react(int, int, double)
Definition: singlech.cpp:111
static SingleChan * current_chan
Definition: singlech.cpp:52
static Member_func members[]
Definition: singlech.cpp:376
static double cond_transition(void *v)
Definition: singlech.cpp:360
static void * cons(Object *)
Definition: singlech.cpp:388
static double set_rand(void *v)
Definition: singlech.cpp:328
static void destruct(void *v)
Definition: singlech.cpp:398
void hoc_reg_singlechan(int, void(*)(...))
Definition: singlech.cpp:89
std::vector< SingleChanInfo * > infolist
Definition: singlech.cpp:51
double exprand(double)
static double state_transition(void *v)
Definition: singlech.cpp:356
void _singlechan_declare(void(*)(double, double *, Datum *), int *, int)
Definition: singlech.cpp:101
static double cond(void *v)
Definition: singlech.cpp:337
static double cond_transitions(void *v)
Definition: singlech.cpp:370
static double state_transitions(void *v)
Definition: singlech.cpp:365
static double get_rates(void *v)
Definition: singlech.cpp:322
static double set_rates(void *v)
Definition: singlech.cpp:305
void SingleChan_reg()
Definition: singlech.cpp:403
static double current_state(void *v)
Definition: singlech.cpp:345
#define NULL
Definition: sptree.h:16
Symbol * sym
Definition: membfunc.h:38
Definition: hocdec.h:227
void * this_pointer
Definition: hocdec.h:232
union Object::@39 u
Datum * dparam
Definition: section.h:220
double * param
Definition: section.h:219
char * name
Definition: model.h:72
Definition: hocdec.h:177