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