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