NEURON
ocptrvector.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /*
3  construct a vector of pointers to variables and
4  provide fast scatter/gather between Vector and those variables.
5  p = new PtrVector(size)
6  p.pset(i, &varname)
7  val = p.getval(i)
8  p.setval(i, value)
9  p.scatter(Vector)
10  p.gather(Vector)
11 */
12 #include "classreg.h"
13 #include "oc2iv.h"
14 #include "ocptrvector.h"
15 #include "objcmd.h"
16 #include "ivocvect.h"
17 #include <OS/math.h>
18 #if HAVE_IV
19 #include "graph.h"
20 #endif
21 #include "gui-redirect.h"
22 extern Object** (*nrnpy_gui_helper_)(const char* name, Object* obj);
23 extern double (*nrnpy_object_to_double_)(Object*);
24 
25 extern int hoc_return_type_code;
26 
27 static double dummy;
28 
30 
32  label_ = NULL;
33  pd_ = new double*[sz];
34  size_ = sz;
35  update_cmd_ = NULL;
36  for (int i = 0; i < sz; ++i) {
37  pd_[i] = &dummy;
38  }
39 }
40 
42  delete[] pd_;
44  if (label_) {
45  free(label_);
46  } // allocated by strdup
47 }
48 
49 void OcPtrVector::resize(int sz) {
50  if (size_ == sz) {
51  return;
52  }
53  delete[] pd_;
54  pd_ = new double*[sz];
55  size_ = sz;
56  for (int i = 0; i < sz; ++i) {
57  pd_[i] = &dummy;
58  }
59 }
60 
62  if (update_cmd_) {
63  delete update_cmd_;
64  update_cmd_ = NULL;
65  }
66  update_cmd_ = hc;
67 }
68 
70  if (update_cmd_) {
71  update_cmd_->execute(false);
72  } else {
73  hoc_warning("PtrVector has no ptr_update callback", NULL);
74  }
75 }
76 
77 void OcPtrVector::pset(int i, double* px) {
78  assert(i < size_);
79  pd_[i] = px;
80 }
81 
82 void OcPtrVector::scatter(double* src, int sz) {
83  assert(size_ == sz);
84  for (int i = 0; i < sz; ++i) {
85  *pd_[i] = src[i];
86  }
87 }
88 
89 void OcPtrVector::gather(double* dest, int sz) {
90  assert(size_ == sz);
91  for (int i = 0; i < sz; ++i) {
92  dest[i] = *pd_[i];
93  }
94 }
95 
96 void OcPtrVector::setval(int i, double x) {
97  assert(i < size_);
98  *pd_[i] = x;
99 }
100 
101 double OcPtrVector::getval(int i) {
102  assert(i < size_);
103  return *pd_[i];
104 }
105 
106 static const char* nullstr = "";
107 
108 static const char** ptr_label(void* v) {
109  char*& s = ((OcPtrVector*) v)->label_;
110  if (ifarg(1)) {
111  if (s) {
112  free(s);
113  }
114  s = strdup(gargstr(1));
115  }
116  if (s) {
117  return (const char**) (&((OcPtrVector*) v)->label_);
118  }
119  return &nullstr;
120 }
121 
122 static double resize(void* v) {
123  hoc_return_type_code = 1; // integer
124  ((OcPtrVector*) v)->resize((int(chkarg(1, 1., 2e9))));
125  return double(((OcPtrVector*) v)->size());
126 }
127 
128 static double get_size(void* v) {
129  hoc_return_type_code = 1; // integer
130  return ((OcPtrVector*) v)->size();
131 }
132 
133 static double pset(void* v) {
134  OcPtrVector* opv = (OcPtrVector*) v;
135  int i = int(chkarg(1, 0., opv->size()));
136  opv->pset(i, hoc_pgetarg(2));
137  return opv->getval(i);
138 }
139 
140 static double getval(void* v) {
141  OcPtrVector* opv = (OcPtrVector*) v;
142  int i = int(chkarg(1, 0., opv->size()));
143  return opv->getval(i);
144 }
145 
146 static double setval(void* v) {
147  OcPtrVector* opv = (OcPtrVector*) v;
148  int i = int(chkarg(1, 0., opv->size()));
149  opv->setval(i, *hoc_getarg(2));
150  return opv->getval(i);
151 }
152 
153 static double scatter(void* v) {
154  OcPtrVector* opv = (OcPtrVector*) v;
155  Vect* src = vector_arg(1);
156  opv->scatter(vector_vec(src), vector_capacity(src));
157  return 0.;
158 }
159 
160 static double gather(void* v) {
161  OcPtrVector* opv = (OcPtrVector*) v;
162  Vect* dest = vector_arg(1);
163  opv->gather(vector_vec(dest), vector_capacity(dest));
164  return 0.;
165 }
166 
167 static double ptr_update_callback(void* v) {
168  OcPtrVector* opv = (OcPtrVector*) v;
169  HocCommand* hc = NULL;
170  if (ifarg(1) && hoc_is_object_arg(1)) {
171  hc = new HocCommand(*hoc_objgetarg(1));
172  } else if (ifarg(1)) {
173  Object* o = NULL;
174  if (ifarg(2)) {
175  o = *hoc_objgetarg(2);
176  }
177  hc = new HocCommand(hoc_gargstr(1), o);
178  }
179  opv->ptr_update_cmd(hc);
180  return 0.;
181 }
182 
183 // a copy of ivocvect::v_plot with y+i replaced by y[i]
184 static int narg() {
185  int i = 0;
186  while (ifarg(i++))
187  ;
188  return i - 2;
189 }
190 
191 static double ptr_plot(void* v) {
193  OcPtrVector* opv = (OcPtrVector*) v;
194 #if HAVE_IV
195  IFGUI
196  int i;
197  double** y = opv->pd_;
198  auto n = opv->size_;
199  char* label = opv->label_;
200 
201  Object* ob1 = *hoc_objgetarg(1);
202  check_obj_type(ob1, "Graph");
203  Graph* g = (Graph*) (ob1->u.this_pointer);
204 
205  GraphVector* gv = new GraphVector("");
206 
207  if (ifarg(5)) {
208  hoc_execerror("PtrVector.plot:", "too many arguments");
209  }
210  if (narg() == 3) {
211  gv->color((colors->color(int(*getarg(2)))));
212  gv->brush((brushes->brush(int(*getarg(3)))));
213  } else if (narg() == 4) {
214  gv->color((colors->color(int(*getarg(3)))));
215  gv->brush((brushes->brush(int(*getarg(4)))));
216  }
217 
218  if (narg() == 2 || narg() == 4) {
219  // passed a vector or xinterval and possibly line attributes
220  if (hoc_is_object_arg(2)) {
221  // passed a vector
222  Vect* vp2 = vector_arg(2);
223  n = std::min(n, vp2->size());
224  for (i = 0; i < n; ++i)
225  gv->add(vp2->elem(i), y[i]);
226  } else {
227  // passed xinterval
228  double interval = *getarg(2);
229  for (i = 0; i < n; ++i)
230  gv->add(i * interval, y[i]);
231  }
232  } else {
233  // passed line attributes or nothing
234  for (i = 0; i < n; ++i)
235  gv->add(i, y[i]);
236  }
237 
238  if (label) {
239  GLabel* glab = g->label(label);
240  gv->label(glab);
241  ((GraphItem*) g->component(g->glyph_index(glab)))->save(false);
242  }
243  g->append(new GPolyLineItem(gv));
244 
245  g->flush();
246  ENDGUI
247 #endif
248  return 0.0;
249 }
250 
251 
252 static Member_func members[] = {"size",
253  get_size,
254  "resize",
255  resize,
256  "pset",
257  pset,
258  "setval",
259  setval,
260  "getval",
261  getval,
262  "scatter",
263  scatter,
264  "gather",
265  gather,
266  "ptr_update_callback",
268  "plot",
269  ptr_plot,
270  0,
271  0};
272 
273 static Member_ret_str_func retstr_members[] = {"label", ptr_label, 0, 0};
274 
275 static void* cons(Object*) {
276  int sz;
277  sz = int(chkarg(1, 1., 2e9));
278  OcPtrVector* ocpv = new OcPtrVector(sz);
279  return (void*) ocpv;
280 }
281 
282 static void destruct(void* v) {
283  delete (OcPtrVector*) v;
284 }
285 
287  class2oc("PtrVector", cons, destruct, members, 0, 0, retstr_members);
288  pv_class_sym_ = hoc_lookup("PtrVector");
289 }
const Brush * brush(int) const
const Color * color(int) const
Definition: graph.h:424
virtual void save(std::ostream &, Coord, Coord)
void brush(const Brush *)
void color(const Color *)
GLabel * label() const
Definition: graph.h:302
Definition: graph.h:57
void add(float, double *)
int execute(bool notify=true)
Definition: objcmd.cpp:102
void resize(int)
Definition: ocptrvector.cpp:49
virtual ~OcPtrVector()
Definition: ocptrvector.cpp:41
int size()
Definition: ocptrvector.h:11
void scatter(double *, int sz)
Definition: ocptrvector.cpp:82
OcPtrVector(int sz)
Definition: ocptrvector.cpp:31
double getval(int)
void ptr_update_cmd(HocCommand *)
Definition: ocptrvector.cpp:61
size_t size_
Definition: ocptrvector.h:24
char * label_
Definition: ocptrvector.h:27
void gather(double *, int sz)
Definition: ocptrvector.cpp:89
double ** pd_
Definition: ocptrvector.h:25
void pset(int i, double *)
Definition: ocptrvector.cpp:77
void ptr_update()
Definition: ocptrvector.cpp:69
HocCommand * update_cmd_
Definition: ocptrvector.h:26
void setval(int, double)
Definition: ocptrvector.cpp:96
double chkarg(int, double low, double high)
Definition: code2.cpp:638
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:754
BrushPalette * brushes
ColorPalette * colors
int hoc_is_object_arg(int narg)
Definition: code.cpp:756
void hoc_warning(const char *, const char *)
Vect * vector_arg(int i)
Definition: ivocvect.cpp:397
Symbol * hoc_lookup(const char *)
double * hoc_pgetarg(int narg)
Definition: code.cpp:1623
#define TRY_GUI_REDIRECT_METHOD_ACTUAL_DOUBLE(name, sym, v)
Definition: gui-redirect.h:23
#define assert(ex)
Definition: hocassrt.h:32
#define IFGUI
Definition: hocdec.h:372
#define getarg
Definition: hocdec.h:15
#define gargstr
Definition: hocdec.h:14
#define ENDGUI
Definition: hocdec.h:373
Object ** hoc_objgetarg(int)
Definition: code.cpp:1587
int ifarg(int)
Definition: code.cpp:1581
int vector_capacity(Vect *v)
Definition: ivocvect.cpp:319
double * vector_vec(Vect *v)
Definition: ivocvect.cpp:328
#define Vect
Definition: ivocvect.h:14
#define min(a, b)
Definition: matrix.h:157
#define v
Definition: md1redef.h:4
#define i
Definition: md1redef.h:12
char * name
Definition: init.cpp:16
int const size_t const size_t n
Definition: nrngsl.h:11
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 const char ** ptr_label(void *v)
static Symbol * pv_class_sym_
Definition: ocptrvector.cpp:29
static double pset(void *v)
static double getval(void *v)
static Member_ret_str_func retstr_members[]
static Member_func members[]
static void * cons(Object *)
double(* nrnpy_object_to_double_)(Object *)
Definition: xmenu.cpp:14
static double gather(void *v)
static double setval(void *v)
static void destruct(void *v)
void OcPtrVector_reg()
static const char * nullstr
static int narg()
static double resize(void *v)
int hoc_return_type_code
Definition: code.cpp:42
static double get_size(void *v)
static double ptr_plot(void *v)
static double dummy
Definition: ocptrvector.cpp:27
static double ptr_update_callback(void *v)
static double scatter(void *v)
#define g
Definition: passive0.cpp:21
struct OcPtrVector_ OcPtrVector
check_obj_type(o, "SectionList")
o
Definition: seclist.cpp:175
#define NULL
Definition: sptree.h:16
Definition: hocdec.h:227
void * this_pointer
Definition: hocdec.h:232
union Object::@39 u
Definition: model.h:57