NEURON
ivocvect.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 #if defined(__GO32__)
4 #define HAVE_IV 0
5 #endif
6 
7 //#include <string.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <ivstream.h>
11 #include <math.h>
12 #include <errno.h>
13 #include <numeric>
14 #include <functional>
15 
16 #include <OS/math.h>
17 #include "fourier.h"
18 
19 #if HAVE_IV
20 #include <InterViews/glyph.h>
21 #include <InterViews/hit.h>
22 #include <InterViews/event.h>
23 #include <InterViews/color.h>
24 #include <InterViews/brush.h>
25 #include <InterViews/window.h>
26 #include <InterViews/printer.h>
27 #include <InterViews/label.h>
28 #include <InterViews/font.h>
29 #include <InterViews/background.h>
30 #include <InterViews/style.h>
31 //#include <OS/string.h>
32 
33 #include <IV-look/kit.h>
34 #else
35 #include <InterViews/resource.h>
36 #include <OS/list.h>
37 #endif
38 
39 #if defined(SVR4)
40 extern void exit(int status);
41 #endif
42 
43 #include "classreg.h"
44 #if HAVE_IV
45 #include "apwindow.h"
46 #include "ivoc.h"
47 #include "graph.h"
48 #endif
49 
50 #include "gui-redirect.h"
51 
52 extern Object** (*nrnpy_gui_helper_)(const char* name, Object* obj);
53 extern double (*nrnpy_object_to_double_)(Object*);
54 
55 #ifndef PI
56 #ifndef M_PI
57  #define M_PI 3.14159265358979323846
58 #endif
59 #define PI M_PI
60 #endif
61 #define BrainDamaged 0 //The Sun CC compiler but it doesn't hurt to leave it in
62 #if BrainDamaged
63 #define FWrite(arg1,arg2,arg3,arg4) if (fwrite((arg1),arg2,arg3,arg4) != arg3) { hoc_execerror("fwrite error", 0); }
64 #define FRead(arg1,arg2,arg3,arg4) if (fread((arg1),arg2,arg3,arg4) != arg3) { hoc_execerror("fread error", 0); }
65 #else
66 #define FWrite(arg1,arg2,arg3,arg4) if (fwrite(arg1,arg2,arg3,arg4) != arg3){}
67 #define FRead(arg1,arg2,arg3,arg4) if (fread(arg1,arg2,arg3,arg4) != arg3) {}
68 #endif
69 
70 /**
71  * As all parameters are passed from hoc as double, we need
72  * to calculate max integer that can fit into double variable.
73  *
74  * With IEEE 64-bit double has 52 bits of mantissa, so it's 2^53.
75  * calculating it with approach `while (dbl + 1 != dbl) dbl++;`
76  * has issues with SSE and other 32 bits platform. So we are using
77  * direct value here.
78  *
79  * The maximum mantissa 0xFFFFFFFFFFFFF which is 52 bits all 1.
80  * In Python it's:
81  *
82  * >>> (2.**53).hex()
83  * '0x1.0000000000000p+53'
84  * >>> (2.**53)
85  * 9007199254740992.0
86  *
87  * See https://stackoverflow.com/questions/1848700/biggest-integer-that-can-be-stored-in-a-double
88  */
89 static double dmaxint_ = 9007199254740992;
90 
91 // Definitions allow machine independent write and read
92 // note that must include BYTEHEADER at head of routine
93 // The policy is that each machine vwrite binary information in
94 // without swapping, ie. native endian.
95 // On reading, the type is checked to decide whether
96 // byteswapping should be performed
97 
98 #define BYTEHEADER int _II__; char *_IN__; char _OUT__[16]; int BYTESWAP_FLAG=0;
99 #define BYTESWAP(_X__,_TYPE__) \
100  if (BYTESWAP_FLAG == 1) { \
101  _IN__ = (char *) &(_X__); \
102  for (_II__=0;_II__<sizeof(_TYPE__);_II__++) { \
103  _OUT__[_II__] = _IN__[sizeof(_TYPE__)-_II__-1]; } \
104  (_X__) = *((_TYPE__ *) &_OUT__); \
105  }
106 
107 #include "ivocvect.h"
108 
109 // definition of random numer generator
110 #include "random1.h"
111 #include <Uniform.h>
112 
113 #if HAVE_IV
114 #include "utility.h"
115 #endif
116 #include "oc2iv.h"
117 #include "parse.hpp"
118 #include "ocfile.h"
119 
120 extern Object* hoc_thisobject;
122 extern "C" void nrn_exit(int);
123 IvocVect* (*nrnpy_vec_from_python_p_)(void*);
124 Object** (*nrnpy_vec_to_python_p_)(void*);
125 Object** (*nrnpy_vec_as_numpy_helper_)(int, double*);
126 
127 // math functions with error checking defined in oc/SRC/math.cpp
128 extern double hoc_Log(double x), hoc_Log10(double x), /*hoc_Exp(double x), */hoc_Sqrt(double x);
129 extern double hoc_scan(FILE*);
130 
131 extern "C" {
132  extern double hoc_Exp(double);
133 } // extern "C"
134 
135 static int narg() {
136  int i=0;
137  while (ifarg(i++));
138  return i-2;
139 }
140 
141 #define MAX_FIT_PARAMS 20
142 
143 #define TWO_BYTE_HIGH 65535.
144 #define ONE_BYTE_HIGH 255.
145 #define ONE_BYTE_HALF 128.
146 
147 #define EPSILON 1e-9
148 
149 
150 int cmpfcn(double a, double b) { return ((a) <= (b))? (((a) == (b))? 0 : -1) : 1; }
151 typedef int (*doubleComparator)(double, double);
152 
153 extern "C" {
154 extern void install_vector_method(const char* name, Pfrd_vp);
155 extern int vector_instance_px(void*, double**);
156 extern int nrn_mlh_gsort (double* vec, int *base_ptr, int total_elems, doubleComparator cmp);
157 } // extern "C"
158 
159 extern int vector_arg_px(int, double**);
160 extern void notify_freed_val_array(double*, size_t);
161 
162 extern int hoc_return_type_code;
163 
166 IvocVect::IvocVect(int l, double fill_value, Object* o) : vec_(l, fill_value){obj_ = o; label_ = NULL; MUTCONSTRUCT(0)}
168 
171  if (label_) {
172  delete [] label_;
173  }
174  notify_freed_val_array(vec_.data(), vec_.capacity());
175 }
176 
177 void IvocVect::label(const char* label) {
178  if (label_) {
179  delete [] label_;
180  label_ = NULL;
181  }
182  if (label) {
183  label_ = new char[strlen(label) + 1];
184  strcpy(label_, label);
185  }
186 }
187 
188 static const char* nullstr = "";
189 
190 static const char** v_label(void* v) {
191  Vect* x = (Vect*)v;
192  if (ifarg(1)) {
193  x->label(gargstr(1));
194  }
195  if (x->label_) {
196  return (const char**)&x->label_;
197  }
198  return &nullstr;
199 }
200 
201 static void same_err(const char* s, Vect* x, Vect* y) {
202  if (x == y) {
203  hoc_execerror(s, " argument needs to be copied first");
204  }
205 }
206 
207 /* the Vect->elem(start, end) function was used in about a dozen places
208 for the purpose of dealing with a subrange of elements. However that
209 function clones the subrange and returns a new Vect. This caused a
210 memory leak and was needlessly inefficient for those functions.
211 To fix both problems for these specific functions
212 we use a special vector which does not have
213 it's own space but merely a pointer and capacity to the right space of
214 the original vector. The usage is restricted to only once at a time, i.e.
215 can't use two subvecs at once and never do anything which affects the
216 memory space.
217 */
218 
219 #if HAVE_IV
220 /*static*/ class GraphMarkItem : public GraphItem {
221 public:
222  GraphMarkItem(Glyph* g) : GraphItem(g){}
223  virtual ~GraphMarkItem(){};
224  virtual void erase(Scene* s, GlyphIndex i, int type) {
225  if (type & GraphItem::ERASE_LINE) {
226  s->remove(i);
227  }
228  }
229 };
230 #endif
231 
232 static void* v_cons(Object* o) {
233  double fill_value = 0.;
234  int n = 0;
235  Vect* vec;
236  if (ifarg(1)) {
237  if (hoc_is_double_arg(1)) {
238  n = int(chkarg(1,0,1e10));
239  if (ifarg(2)) fill_value = *getarg(2);
240  vec = new Vect(n,fill_value, o);
241  }else{
243  hoc_execerror("Python not available", 0);
244  }
245  vec = (*nrnpy_vec_from_python_p_)(new Vect(0, 0, o));
246  }
247  }else{
248  vec = new Vect(0, 0, o);
249  }
250  return vec;
251 }
252 
253 
254 static void v_destruct(void* v) {
255  delete (Vect*)v;
256 }
257 
258 static Symbol* svec_;
259 
260 // extern "C" vector functions used by ocmatrix.dll
261 // can also be used in mod files
262 Vect* vector_new(int n, Object* o){return new Vect(n, o);}
263 Vect* vector_new0(){return new Vect();}
264 Vect* vector_new1(int n){return new Vect(n);}
265 Vect* vector_new2(Vect* v){return new Vect(*v);}
266 void vector_delete(Vect* v){delete v;}
267 int vector_buffer_size(Vect* v){return v->buffer_size();}
268 int vector_capacity(Vect* v){return v->size();}
269 void vector_resize(Vect* v, int n){v->resize(n);}
270 Object** vector_temp_objvar(Vect* v){return v->temp_objvar();}
271 double* vector_vec(Vect* v){return v->data();}
272 Object** vector_pobj(Vect* v){return &v->obj_;}
273 char* vector_get_label(Vect* v) { return v->label_; }
274 void vector_set_label(Vect* v, char* s) { v->label(s); }
275 void vector_append(Vect* v, double x){
276  v->push_back(x);
277 }
278 
279 #ifdef WIN32
280 #if !defined(USEMATRIX) || USEMATRIX == 0
281 #include "../windll/dll.h"
282 extern char* neuron_home;
283 
284 void load_ocmatrix() {
285  struct DLL* dll = NULL;
286  char buf[256];
287  sprintf(buf, "%s\\lib\\ocmatrix.dll", neuron_home);
288  dll = dll_load(buf);
289  if (dll) {
290  Pfri mreg = (Pfri)dll_lookup(dll, "_Matrix_reg");
291  if (mreg) {
292  (*mreg)();
293  }
294  }else{
295  printf("No Matrix class.\n");
296  }
297 }
298 #endif
299 #endif
300 
302  IvocVect* v = (IvocVect*)this;
303  Object** po;
304  if (v->obj_) {
305  po = hoc_temp_objptr(v->obj_);
306  }else{
307  po = hoc_temp_objvar(svec_, (void*)v);
308  obj_ = *po;
309  }
310  return po;
311 }
312 
313 extern "C" { // bug in cray compiler requires this
314 void install_vector_method(const char* name, double (*f)(void*)) {
315  Symbol* s_meth;
316  if (hoc_table_lookup(name, svec_->u.ctemplate->symtable)) {
317  hoc_execerror(name, " already a method in the Vector class");
318  }
319  s_meth = hoc_install(name, FUNCTION, 0.0, &svec_->u.ctemplate->symtable);
320  s_meth->u.u_proc->defn.pfd = (Pfrd)f;
321 #define PUBLIC_TYPE 1
322  s_meth->cpublic = PUBLIC_TYPE;
323 }
324 } // extern "C"
325 
326 extern "C" int vector_instance_px(void* v, double** px) {
327  Vect* x = (Vect*)v;
328  *px = x->data();
329  return x->size();
330 }
331 
332 extern "C" Vect* vector_arg(int i) {
333  Object* ob = *hoc_objgetarg(i);
334  if (!ob || ob->ctemplate != svec_->u.ctemplate) {
335  check_obj_type(ob, "Vector");
336  }
337  return (Vect*)(ob->u.this_pointer);
338 }
339 
340 int is_vector_arg(int i) {
341  Object* ob = *hoc_objgetarg(i);
342  if (!ob || ob->ctemplate != svec_->u.ctemplate) {
343  return 0;
344  }
345  return 1;
346 }
347 
348 int vector_arg_px(int i, double** px) {
349  Vect* x = vector_arg(i);
350  *px = x->data();
351  return x->size();
352 }
353 
354 extern void nrn_vecsim_add(void*, bool);
355 extern void nrn_vecsim_remove(void*);
356 
357 static int possible_destvec(int arg, Vect*& dest) {
358  if (ifarg(arg) && hoc_is_object_arg(arg)) {
359  dest = vector_arg(arg);
360  return arg+1;
361  }else{
362  dest = new Vect();
363  return arg;
364  }
365 }
366 
367 static double v_play_remove(void* v) {
369  return 1.;
370 }
371 
372 static double v_fwrite(void* v) {
373  Vect* vp = (Vect*)v;
374  void* s;
375  int x_max = vp->size()-1;
376  int start = 0;
377  int end = x_max;
378  hoc_return_type_code = 1; // integer
379  if (ifarg(2)) {
380  start = int(chkarg(2,0,x_max));
381  end = int(chkarg(3,start,x_max));
382  }
383  s = (void*)(&vp->elem(start));
384  const char* x = (const char*)s;
385 
386  Object* ob = *hoc_objgetarg(1);
387  check_obj_type(ob, "File");
388  OcFile* f = (OcFile*)(ob->u.this_pointer);
389  FILE* fp = f->file();
390  if (!fp) {
391  return 0.;
392  }
393  int n = end-start+1;
394  BinaryMode(f);
395  return (double)fwrite(x,sizeof(double),n,fp);
396 }
397 
398 static double v_fread(void* v) {
399  Vect* vp = (Vect*)v;
400 
401  Object* ob = *hoc_objgetarg(1);
402 
403  check_obj_type(ob, "File");
404  OcFile* f = (OcFile*)(ob->u.this_pointer);
405 
406  if (ifarg(2)) vp->resize(int(chkarg(2,0,1e10)));
407  int n = vp->size();
408 
409  int type = 4;
410  if (ifarg(3)) {
411  type = int(chkarg(3,1,5));
412  }
413 
414  FILE* fp = f->file();
415  if (!fp) {
416  return 0.;
417  }
418 
419  int i;
420  BinaryMode(f)
421  if (n > 0) switch (type) {
422 
423  case 5: // short ints
424  {
425  short *xs = (short *)malloc(n * (unsigned)sizeof(short));
426  FRead(xs,sizeof(short),n,fp);
427  for (i=0;i<n;++i) {
428  vp->elem(i) = double(xs[i]);
429  }
430  free((char *)xs);
431  break;
432  }
433 
434  case 4: // doubles
435  FRead(&(vp->elem(0)),sizeof(double),n,fp);
436  break;
437 
438  case 3: // floats
439  {
440  float *xf = (float *)malloc(n * (unsigned)sizeof(float));
441  FRead(xf,sizeof(float),n,fp);
442  for (i=0;i<n;++i) {
443  vp->elem(i) = double(xf[i]);
444  }
445  free((char *)xf);
446  break;
447  }
448 
449  case 2: // unsigned short ints
450  {
451 
452  unsigned short *xi = (unsigned short *)malloc(n * (unsigned)sizeof(unsigned short));
453  FRead(xi,sizeof(unsigned short),n,fp);
454  for (i=0;i<n;++i) {
455  vp->elem(i) = double(xi[i]);
456  }
457  free((char *)xi);
458  break;
459  }
460 
461  case 1: // char
462  {
463  char *xc = (char *)malloc(n * (unsigned)sizeof(char));
464  FRead(xc,sizeof(char),n,fp);
465  for (i=0;i<n;++i) {
466  vp->elem(i) = double(xc[i]);
467  }
468  free(xc);
469  break;
470  }
471  }
472  return 1;
473 }
474 
475 static double v_vwrite(void* v) {
476  Vect* vp = (Vect*)v;
477 
478  Object* ob = *hoc_objgetarg(1);
479  check_obj_type(ob, "File");
480  OcFile* f = (OcFile*)(ob->u.this_pointer);
481 
482  FILE* fp = f->file();
483  if (!fp) {
484  return 0.;
485  }
486 
487  BinaryMode(f)
488  // first, write the size of the vector
489  int n = vp->size();
490  FWrite(&n,sizeof(int),1,fp);
491 
492 // next, write the type of elements
493  int type = 4;
494  if (ifarg(2)) {
495  type = int(chkarg(2,1,5));
496  }
497  FWrite(&type,sizeof(int),1,fp);
498 
499 // convert the data if necessary
500  int i;
501  void *s;
502  const char* x;
503 
504  double min, max, r,sf,sub,intermed;
505  switch (type) {
506 
507  case 5: // integers as ints (no scaling)
508  {
509  int* xi = (int *)malloc(n * sizeof(int));
510  for (i=0;i<n;++i) {
511  xi[i] = (int)(vp->elem(i));
512  }
513  FWrite(xi,sizeof(int),n,fp);
514  free((char *)xi);
515  break;
516  }
517 
518  case 4: // doubles (no conversion unless BYTESWAP used and needed)
519  {
520  s = (void*)(&(vp->elem(0)));
521  x = (const char*)s;
522  FWrite(x,sizeof(double),n,fp);
523  break;
524  }
525 
526  case 3: // float (simple automatic type conversion)
527  {
528  float* xf = (float *)malloc(n * (unsigned)sizeof(float));
529  for (i=0;i<n;++i) {
530  xf[i] = float(vp->elem(i));
531  }
532  FWrite(xf,sizeof(float),n,fp);
533  free((char *)xf);
534  break;
535  }
536 
537 
538  case 2: // short ints (scale to 16 bits with compression)
539  {
540  auto minmax = std::minmax_element(vp->begin(), vp->end());
541  min = *minmax.first;
542  max = *minmax.second;
543  r = max - min;
544  if (r > 0) {
545  sf = TWO_BYTE_HIGH/r;
546  } else {
547  sf = 1.;
548  }
549  unsigned short* xi = (unsigned short *)malloc(n * (unsigned)sizeof(unsigned short));
550  for (i=0;i<n;++i) {
551  intermed = (vp->elem(i)-min)*sf;
552  xi[i] = (unsigned short)intermed;
553  }
554  s = (void*)xi;
555  x = (const char*)s;
556  // store the info needed to reconvert
557  FWrite(&sf,sizeof(double),1,fp);
558  FWrite(&min,sizeof(double),1,fp);
559  // store the actual data
560  FWrite(x,sizeof(unsigned short),n,fp);
561  free((char *)xi);
562  break;
563  }
564 
565  case 1: // char (scale to 8 bits with compression)
566  {
567  sub = ONE_BYTE_HALF;
568  auto minmax = std::minmax_element(vp->begin(), vp->end());
569  min = *minmax.first;
570  max = *minmax.second;
571  r = max - min;
572  if (r > 0) {
573  sf = ONE_BYTE_HIGH/r;
574  } else {
575  sf = 1.;
576  }
577 
578  char* xc = (char *)malloc(n * (unsigned)sizeof(char));
579  for (i=0;i<n;++i) {
580  xc[i] = char(((vp->elem(i)-min)*sf)-sub);
581  }
582  s = (void*)xc;
583  x = (const char*)s;
584  // store the info needed to reconvert
585  FWrite(&sf,sizeof(double),1,fp);
586  FWrite(&min,sizeof(double),1,fp);
587  FWrite(x,sizeof(char),n,fp);
588  free(xc);
589  break;
590  }
591 
592  }
593  return 1;
594 }
595 
596 
597 static double v_vread(void* v) {
598  Vect* vp = (Vect*)v;
599  void* s = (void*)(vp->data());
600 
601  Object* ob = *hoc_objgetarg(1);
602  check_obj_type(ob, "File");
603  OcFile* f = (OcFile*)(ob->u.this_pointer);
604  BYTEHEADER
605 
606  FILE* fp = f->file();
607  if (!fp) {
608  return 0.;
609  }
610 
611  BinaryMode(f)
612  int n;
613  FRead(&n,sizeof(int),1,fp);
614 
615  int type = 0;
616  FRead(&type,sizeof(int),1,fp);
617 
618  // since the type ranges from 1 to 5 (very important that it not be 0)
619  // we can check the type and decide if it needs to be byteswapped
620  if (type < 1 || type > 5) {
621  BYTESWAP_FLAG = 1;
622  }else{
623  BYTESWAP_FLAG = 0;
624  }
625 
626  BYTESWAP(n,int)
627  BYTESWAP(type,int)
628  if (type < 1 || type > 5) { return 0.;}
629  if (vp->size() != n) vp->resize(n);
630 
631 // read as appropriate type and convert to doubles
632 
633  int i;
634  double sf = 1.;
635  double min = 0.;
636  double add;
637 
638  switch (type) {
639 
640  case 5: // ints; no conversion
641  {
642  int *xi = (int *)malloc(n * sizeof(int));
643  FRead(xi,sizeof(int),n,fp);
644  for (i=0;i<n;++i) {
645  BYTESWAP(xi[i],int)
646  vp->elem(i) = double(xi[i]);
647  }
648  free((char *)xi);
649  break;
650  }
651 
652  case 4: // doubles
653  FRead(&(vp->elem(0)),sizeof(double),n,fp);
654  if (BYTESWAP_FLAG == 1) {
655  for (i=0;i<n;++i) { BYTESWAP(vp->elem(i),double) }
656  }
657  break;
658 
659  case 3: // floats
660  {
661  float *xf = (float *)malloc(n * (unsigned)sizeof(float));
662  FRead(xf,sizeof(float),n,fp);
663  for (i=0;i<n;++i) {
664  BYTESWAP(xf[i],float)
665  vp->elem(i) = double(xf[i]);
666  }
667  free((char *)xf);
668  break;
669  }
670 
671  case 2: // unsigned short ints
672  { // convert back to double
673  FRead(&sf,sizeof(double),1,fp);
674  FRead(&min,sizeof(double),1,fp);
675  BYTESWAP(sf,double)
676  BYTESWAP(min,double)
677 
678  unsigned short *xi = (unsigned short *)malloc(n * (unsigned)sizeof(unsigned short));
679  FRead(xi,sizeof(unsigned short),n,fp);
680  for (i=0;i<n;++i) {
681  BYTESWAP(xi[i],short)
682  vp->elem(i) = double(xi[i]/sf +min);
683  }
684  free((char *)xi);
685  break;
686  }
687 
688  case 1: // char
689  { // convert back to double
690  FRead(&sf,sizeof(double),1,fp);
691  FRead(&min,sizeof(double),1,fp);
692  BYTESWAP(sf,double)
693  BYTESWAP(min,double)
694  char *xc = (char *)malloc(n * (unsigned)sizeof(char));
695  FRead(xc,sizeof(char),n,fp);
696  add = ONE_BYTE_HALF;
697  for (i=0;i<n;++i) {
698  vp->elem(i) = double((xc[i]+add)/sf +min);
699  }
700  free(xc);
701  break;
702  }
703  }
704  return 1;
705 }
706 
707 
708 static double v_printf(void *v) {
709  Vect* x = (Vect*)v;
710 
711  int top = x->size()-1;
712  int start = 0;
713  int end = top;
714  int next_arg = 1;
715  const char *format = "%g\t";
716  int print_file = 0;
717  int extra_newline = 1; // when no File
718  OcFile *f;
719 
720  if (ifarg(next_arg) && (hoc_is_object_arg(next_arg))) {
721  Object* ob = *hoc_objgetarg(1);
722  check_obj_type(ob, "File");
723  f = (OcFile*)(ob->u.this_pointer);
724  format = "%g\n";
725  next_arg++;
726  print_file = 1;
727  }
728  if (ifarg(next_arg) && (hoc_argtype(next_arg) == STRING)) {
729  format = gargstr(next_arg);
730  next_arg++;
731  extra_newline = 0;
732  }
733  if (ifarg(next_arg)) {
734  start = int(chkarg(next_arg,0,top));
735  end = int(chkarg(next_arg+1,start,top));
736  }
737 
738  if (print_file) {
739  for (int i=start;i<=end;i++) {
740  fprintf(f->file(),format,x->elem(i));
741  }
742  fprintf(f->file(),"\n");
743  } else {
744  for (int i=start;i<=end;i++) {
745  Printf(format,x->elem(i));
746  if (extra_newline && !((i-start+1)%5)){ Printf("\n");}
747  }
748  if(extra_newline) {Printf("\n");}
749  }
750  hoc_return_type_code = 1; // integer
751  return double(end-start+1);
752 }
753 
754 
755 static double v_scanf(void *v) {
756  Vect* x = (Vect*)v;
757 
758  int n = -1;
759  int c = 1;
760  int nc = 1;
761  Object* ob = *hoc_objgetarg(1);
762  check_obj_type(ob, "File");
763  OcFile* f = (OcFile*)(ob->u.this_pointer);
764 
765  hoc_return_type_code = 1; // integer
766 
767  if (ifarg(4)) {
768  n = int(*getarg(2));
769  c = int(*getarg(3));
770  nc = int(*getarg(4));
771  } else if (ifarg(3)) {
772  c = int(*getarg(2));
773  nc = int(*getarg(3));
774  } else if (ifarg(2)) {
775  n = int(*getarg(2));
776  }
777 
778  if (n >= 0 ) {
779  x->resize(n);
780  }
781  else if(x->size()) { // gnuvec legacy handling
782  x->resize(0);
783  }
784 
785  // start at the right column
786 
787  int i=0;
788 
789  while((n < 0 || i<n) && ! f->eof()) {
790 
791  // skip unwanted columns before
792  int j;
793  for (j=1;j<c;j++) {
794  if (!f->eof()) hoc_scan(f->file());
795  }
796 
797  // read data
798  if (!f->eof()) {
799  if(n >= 0)
800  x->elem(i) = hoc_scan(f->file());
801  else
802  x->push_back(hoc_scan(f->file()));
803  }
804 
805  // skip unwanted columns after
806  for (j=c;j<nc;j++) {
807  if (!f->eof()) hoc_scan(f->file());
808  }
809 
810  i++;
811  }
812 
813  if (x->size() != i) x->resize(i);
814 
815  return double(i);
816 }
817 
818 static double v_scantil(void *v) {
819  Vect* x = (Vect*)v;
820  double val, til;
821 
822  int c = 1;
823  int nc = 1;
824  Object* ob = *hoc_objgetarg(1);
825  check_obj_type(ob, "File");
826  OcFile* f = (OcFile*)(ob->u.this_pointer);
827  // old gnuvec compatibility: clear vector if not empty()
828  if(x->size() > 0) {
829  x->resize(0);
830  }
831 
832  hoc_return_type_code = 1; // integer
833  til = *getarg(2);
834  if (ifarg(4)) {
835  c = int(*getarg(3));
836  nc = int(*getarg(4));
837  }
838 
839  // start at the right column
840 
841  int i=0;
842 
843  for(;;) {
844 
845  // skip unwanted columns before
846  int j;
847  for (j=1;j<c;j++) {
848  if (hoc_scan(f->file()) == til) {
849  return double(i);
850  }
851  }
852 
853  // read data
854  val = hoc_scan(f->file());
855  if (val == til) {
856  break;
857  }
858  x->push_back(val);
859 
860  // skip unwanted columns after
861  for (j=c;j<nc;j++) {
862  hoc_scan(f->file());
863  }
864 
865  i++;
866  }
867  return double(i);
868 }
869 
870 
871 
872 static Object** v_record(void* v) {
873  if (hoc_is_double_arg(1)) {
874  hoc_execerror("Vector.record:", "A number was provided instead of a pointer.\nDid you forget an _ref_ (Python) or an & (HOC)?");
875  }
876  Vect* vp = (Vect*)v;
877  nrn_vecsim_add(v, true);
878  return vp->temp_objvar();
879 }
880 
881 static Object** v_play(void* v) {
882  Vect* vp = (Vect*)v;
883  nrn_vecsim_add(v, false);
884  return vp->temp_objvar();
885 }
886 
887 /*ARGSUSED*/
888 static Object** v_plot(void* v) {
889  TRY_GUI_REDIRECT_METHOD_ACTUAL_OBJ("Vector.plot", svec_, v);
890  Vect* vp = (Vect*)v;
891 #if HAVE_IV
892 IFGUI
893  int i;
894  double* y = vp->data();
895  auto n = vp->size();
896 
897  Object* ob1 = *hoc_objgetarg(1);
898  check_obj_type(ob1, "Graph");
899  Graph* g = (Graph*)(ob1->u.this_pointer);
900 
901  GraphVector* gv = new GraphVector("");
902 
903  if (ifarg(5)) {
904  hoc_execerror("Vector.line:", "too many arguments");
905  }
906  if (narg() == 3) {
907  gv->color((colors->color(int(*getarg(2)))));
908  gv->brush((brushes->brush(int(*getarg(3)))));
909  } else if (narg() == 4) {
910  gv->color((colors->color(int(*getarg(3)))));
911  gv->brush((brushes->brush(int(*getarg(4)))));
912  }
913 
914  if (narg() == 2 || narg() == 4) {
915  // passed a vector or xinterval and possibly line attributes
916  if (hoc_is_object_arg(2)) {
917  // passed a vector
918  Vect* vp2 = vector_arg(2);
919  n = std::min(n, vp2->size());
920  for (i=0; i < n; ++i) gv->add(vp2->elem(i), y + i);
921  } else {
922  // passed xinterval
923  double interval = *getarg(2);
924  for (i=0; i < n; ++i) gv->add(i * interval, y + i);
925  }
926  } else {
927  // passed line attributes or nothing
928  for (i=0; i < n; ++i) gv->add(i, y + i);
929  }
930 
931  if (vp->label_) {
932  GLabel* glab = g->label(vp->label_);
933  gv->label(glab);
934  ((GraphItem*)g->component(g->glyph_index(glab)))->save(false);
935  }
936  g->append(new GPolyLineItem(gv));
937 
938  g->flush();
939 ENDGUI
940 #endif
941  return vp->temp_objvar();
942 }
943 
944 static Object** v_ploterr(void* v) {
945  TRY_GUI_REDIRECT_METHOD_ACTUAL_OBJ("Vector.ploterr", svec_, v);
946  Vect* vp = (Vect*)v;
947 #if HAVE_IV
948 IFGUI
949  int n = vp->size();
950 
951  Object* ob1 = *hoc_objgetarg(1);
952  check_obj_type(ob1, "Graph");
953  Graph* g = (Graph*)(ob1->u.this_pointer);
954 
955  char style = '-';
956  double size = 4;
957  if (ifarg(4)) size = chkarg(4,0.1,100.);
958  const ivColor * color = g->color();
959  const ivBrush * brush = g->brush();
960  if (ifarg(5)) {
961  color = colors->color(int(*getarg(5)));
962  brush = brushes->brush(int(*getarg(6)));
963  }
964 
965  Vect* vp2 = vector_arg(2);
966  if (vp2->size() < n) n = vp2->size();
967 
968  Vect* vp3 = vector_arg(3);
969  if (vp3->size() < n) n = vp3->size();
970 
971  for (int i=0; i < n; ++i) {
972  g->begin_line();
973 
974  g->line(vp2->elem(i),vp->elem(i) - vp3->elem(i));
975  g->line(vp2->elem(i),vp->elem(i) + vp3->elem(i));
976  g->mark(vp2->elem(i), vp->elem(i) - vp3->elem(i), style, size, color, brush);
977  g->mark(vp2->elem(i), vp->elem(i) + vp3->elem(i), style, size, color, brush);
978  }
979 
980  g->flush();
981 ENDGUI
982 #endif
983  return vp->temp_objvar();
984 }
985 
986 static Object** v_line(void* v) {
987  TRY_GUI_REDIRECT_METHOD_ACTUAL_OBJ("Vector.line", svec_, v);
988  Vect* vp = (Vect*)v;
989 #if HAVE_IV
990 IFGUI
991  int i;
992  auto n = vp->size();
993 
994  Object* ob1 = *hoc_objgetarg(1);
995  check_obj_type(ob1, "Graph");
996  Graph* g = (Graph*)(ob1->u.this_pointer);
997  char* s = vp->label_;
998 
999  if (ifarg(5)) {
1000  hoc_execerror("Vector.line:", "too many arguments");
1001  }
1002  if (narg() == 3) {
1003  g->begin_line(colors->color(int(*getarg(2))),
1004  brushes->brush(int(*getarg(3))), s);
1005  } else if (narg() == 4) {
1006  g->begin_line(colors->color(int(*getarg(3))),
1007  brushes->brush(int(*getarg(4))), s);
1008  } else {
1009  g->begin_line(s);
1010  }
1011 
1012  if (narg() == 2 || narg() == 4) {
1013  // passed a vector or xinterval and possibly line attributes
1014  if (hoc_is_object_arg(2)) {
1015  // passed a vector
1016  Vect* vp2 = vector_arg(2);
1017  n = std::min(n, vp2->size());
1018  for (i=0; i < n; ++i) g->line(vp2->elem(i), vp->elem(i));
1019  } else {
1020  // passed xinterval
1021  double interval = *getarg(2);
1022  for (i=0; i < n; ++i) g->line(i * interval, vp->elem(i));
1023  }
1024  } else {
1025  // passed line attributes or nothing
1026  for (i=0; i < n; ++i) g->line(i, vp->elem(i));
1027  }
1028 
1029  g->flush();
1030 ENDGUI
1031 #endif
1032  return vp->temp_objvar();
1033 }
1034 
1035 
1036 static Object** v_mark(void* v) {
1037  TRY_GUI_REDIRECT_METHOD_ACTUAL_OBJ("Vector.mark", svec_, v);
1038  Vect* vp = (Vect*)v;
1039 #if HAVE_IV
1040 IFGUI
1041  int i;
1042  int n = vp->size();
1043 
1044  Object* ob1 = *hoc_objgetarg(1);
1045  check_obj_type(ob1, "Graph");
1046  Graph* g = (Graph*)(ob1->u.this_pointer);
1047 
1048  char style = '+';
1049  if (ifarg(3)) {
1050  if (hoc_is_str_arg(3)) {
1051  style = *gargstr(3);
1052  } else {
1053  style = char(chkarg(3,0,10));
1054  }
1055  }
1056  double size = 12;
1057  if (ifarg(4)) size = chkarg(4,0.1,100.);
1058  const ivColor * color = g->color();
1059  if (ifarg(5)) color = colors->color(int(*getarg(5)));
1060  const ivBrush * brush = g->brush();
1061  if (ifarg(6)) brush = brushes->brush(int(*getarg(6)));
1062 
1063  if (hoc_is_object_arg(2)) {
1064  // passed a vector
1065  Vect* vp2 = vector_arg(2);
1066 
1067  for (i=0; i < n; ++i) {
1068  g->mark(vp2->elem(i), vp->elem(i), style, size, color, brush);
1069  }
1070 
1071  } else {
1072  // passed xinterval
1073  double interval = *getarg(2);
1074  for (i=0; i < n; ++i) {
1075  g->mark(i*interval, vp->elem(i), style, size, color, brush);
1076  }
1077 
1078  }
1079 ENDGUI
1080 #endif
1081  return vp->temp_objvar();
1082 }
1083 
1084 static Object** v_histogram(void* v) {
1085  Vect* x = (Vect*)v;
1086 
1087  double low = *getarg(1);
1088  double high = chkarg(2,low,1e99);
1089  double width = chkarg(3,0,high-low);
1090 
1091 // SampleHistogram h(low,high,width);
1092  int i;
1093 // for (i=0; i< x->size(); i++) h += x->elem(i);
1094 
1095 // int n = h.buckets();
1096  // analogous to howManyBuckets in gnu/SamplHist.cpp
1097  int n = int(floor((high - low)/width)) + 2;
1098  Vect* y = new Vect(n);
1099  std::fill(y->begin(), y->end(), 0.);
1100 // for (i=0; i< n; i++) y->elem(i) = h.inBucket(i);
1101 
1102  for (i=0; i < x->size(); ++i) {
1103  int ind = int(floor((x->elem(i) - low)/width)) + 1;
1104  if (ind >= 0 && ind < y->size()) {
1105  y->elem(ind) += 1.0;
1106  }
1107  }
1108  return y->temp_objvar();
1109 }
1110 
1111 static Object** v_hist(void* v) {
1112 
1113  Vect* hv = (Vect*)v;
1114 
1115  Vect* data = vector_arg(1);
1116  same_err("hist", hv, data);
1117  double start = *getarg(2);
1118  int size = int(*getarg(3));
1119  double step = chkarg(4,1.e-99,1.e99);
1120  double high = start+step*size;
1121 
1122 // SampleHistogram h(start,high,step);
1123 // for (int i=0; i< data->size(); i++) h += data->elem(i);
1124 
1125  if (hv->size() != size) hv->resize(size);
1126  std::fill(hv->begin(), hv->end(), 0.);
1127  for (int i=0; i< data->size(); i++) {
1128  int ind = int(floor((data->elem(i)-start)/step));
1129  if (ind >=0 && ind < hv->size()) hv->elem(ind) += 1;
1130  }
1131 
1132 // for (i=0; i< size; i++) hv->elem(i) = h.inBucket(i);
1133 
1134  return hv->temp_objvar();
1135 }
1136 
1137 
1138 
1139 static Object** v_sumgauss(void* v) {
1140  Vect* x = (Vect*)v;
1141 
1142  double low = *getarg(1);
1143  double high = chkarg(2,low,1e99);
1144  double step = chkarg(3,1.e-99,1.e99);
1145  double var = chkarg(4,0,1.e99);
1146  Vect* w;
1147  bool d = false;
1148  if (ifarg(5)) {
1149  w = vector_arg(5);
1150  } else {
1151  w = new Vect(x->size());
1152  std::fill(w->begin(), w->end(), 1);
1153  d = true;
1154  }
1155 
1156  int points = int((high-low)/step + .5);
1157  Vect* sum = new Vect(points,0.);
1158 
1159  double svar = var/(step*step);
1160 
1161 // 4/28/93 ZFM: corrected bug: replaced svar w/ var in line below
1162  double scale = 1./hoc_Sqrt(2.*PI*var);
1163 
1164  for (int i=0;i<x->size();i++) {
1165  double xv = int((x->elem(i)-low)/step);
1166  for (int j=0; j<points;j++) {
1167  double arg = -(j-xv)*(j-xv)/(2.*svar);
1168  if (arg > -20.) sum->elem(j) += hoc_Exp(arg) * scale * w->elem(i);
1169  }
1170  }
1171  if (d) {
1172  delete w;
1173  }
1174  return sum->temp_objvar();
1175 }
1176 
1177 static Object** v_smhist(void* v) {
1178  Vect* v1 = (Vect*)v;
1179 
1180  Vect* data = vector_arg(1);
1181 
1182  double start = *getarg(2);
1183  int size = int(*getarg(3));
1184  double step = chkarg(4,1.e-99,1.e99);
1185  double var = chkarg(5,0,1.e99);
1186 
1187  int weight,i;
1188  Vect *w;
1189 
1190  if (ifarg(6)) {
1191  w = vector_arg(6);
1192  if (w->size() != data->size()) {
1193  hoc_execerror("Vector.smhist: weight Vector must be same size as source Vector.", 0);
1194  }
1195  weight = 1;
1196  } else {
1197  weight = 0;
1198  }
1199 
1200 
1201  // ready a gaussian to convolve
1202  double svar = 2*var/(step*step);
1203  double scale = 1/hoc_Sqrt(2.*PI*var);
1204 
1205  int g2 = int(sqrt(10*svar));
1206  int g = g2*2+1;
1207 
1208  int n = 1;
1209  while(n<size+g) n*=2;
1210 
1211  double *gauss = (double *)calloc(n,(unsigned)sizeof(double));
1212 
1213  for (i=0;i<= g2;i++) gauss[i] = scale * hoc_Exp(-i*i/svar);
1214  for (i=1;i<= g2;i++) gauss[g-i] = scale * hoc_Exp(-i*i/svar);
1215 
1216  // put the data into a time series
1217  double *series = (double *)calloc(n,(unsigned)sizeof(double));
1218 
1219  double high = start + n*step;
1220  if (weight) {
1221  for (i=0;i<data->size();i++) {
1222  if (data->elem(i) >= start && data->elem(i) < high) {
1223  series[int((data->elem(i)-start)/step)] += w->elem(i);
1224  }
1225  }
1226  } else {
1227  for (i=0;i<data->size();i++) {
1228  if (data->elem(i) >= start && data->elem(i) < high) {
1229  series[int((data->elem(i)-start)/step)] += 1.;
1230  }
1231  }
1232  }
1233 
1234  // ready the answer vector
1235  double *ans = (double *)calloc(2*n,(unsigned)sizeof(double));
1236 
1237  // convolve
1238  nrn_convlv(series,n,gauss,g,1,ans);
1239 
1240  // put the answer in the vector
1241  if (v1->size() != size) v1->resize(size);
1242  std::fill(v1->begin(), v1->end(), 0.);
1243  for (i=0;i<size;i++) if (ans[i] > EPSILON) v1->elem(i) = ans[i];
1244 
1245  free(series);
1246  free(gauss);
1247  free(ans);
1248 
1249  return v1->temp_objvar();
1250 }
1251 
1252 
1253 static Object** v_ind(void* v) {
1254  Vect* x = (Vect*)v;
1255  Vect* y = vector_arg(1);
1256  Vect* z = new Vect();
1257 
1258  int yv;
1259  int ztop = 0;
1260  int top = x->size();
1261  z->resize(y->size()); z->resize(0);
1262  for (int i=0;i<y->size();i++) {
1263  yv = int(y->elem(i));
1264  if ((yv < top) && (yv >= 0)) {
1265  z->resize(++ztop);
1266  z->elem(ztop-1) = x->elem(yv);
1267  }
1268  }
1269  return z->temp_objvar();
1270 }
1271 
1272 
1273 static double v_size(void* v) {
1274  Vect* x = (Vect*)v;
1276  return double(x->size());
1277 }
1278 
1279 static double v_buffer_size(void* v) {
1280  Vect* x = (Vect*)v;
1281  if (ifarg(1)) {
1282  int n = (int)chkarg(1, (double)x->size(), dmaxint_);
1283  x->buffer_size(n);
1284  }
1286  return x->buffer_size();
1287 }
1288 
1290  return vec_.capacity();
1291 }
1292 
1294  vec_.reserve(n);
1295 }
1296 
1297 static Object** v_resize(void* v) {
1298  Vect* x = (Vect*)v;
1299  x->resize(int(chkarg(1,0,dmaxint_)));
1300  return x->temp_objvar();
1301 }
1302 
1303 static Object** v_clear(void* v) {
1304  Vect* x = (Vect*)v;
1305  x->resize(0);
1306  return x->temp_objvar();
1307 }
1308 
1309 static double v_get(void* v) {
1310  Vect* x = (Vect*)v;
1311  return x->elem(int(chkarg(1,0,x->size()-1)));
1312 }
1313 
1314 static Object** v_set(void* v) {
1315  Vect* x = (Vect*)v;
1316  x->elem(int(chkarg(1,0,x->size()-1))) = *getarg(2);
1317  return x->temp_objvar();
1318 }
1319 
1320 
1321 static Object** v_append(void* v) {
1322  Vect* x = (Vect*)v;
1323  int j,i=1;
1324  while (ifarg(i)) {
1325  if (hoc_argtype(i) == NUMBER) {
1326  x->push_back(*getarg(i));
1327  } else if (hoc_is_object_arg(i)) {
1328  Vect* y = vector_arg(i);
1329  same_err("append", x, y);
1330  x->buffer_size(x->size() + y->size());
1331  x->vec().insert(x->end(), y->begin(), y->end());
1332  }
1333  i++;
1334  }
1335  return x->temp_objvar();
1336 }
1337 
1338 static Object** v_insert(void* v) {
1339  // insert all before indx (first arg)
1340  Vect* x = (Vect*)v;
1341  int n,j,m,i=2;
1342  int indx = (int)chkarg(1, 0, x->size());
1343  m = x->size() - indx;
1344  double* z;
1345  if (m) {
1346  z = new double[m];
1347  for (j=0; j < m; ++j) {
1348  z[j] = x->elem(indx + j);
1349  }
1350  }
1351  x->resize(indx);
1352  while (ifarg(i)) {
1353  if (hoc_argtype(i) == NUMBER) {
1354  x->push_back(*getarg(i));
1355  } else if (hoc_is_object_arg(i)) {
1356  Vect* y = vector_arg(i);
1357  same_err("insrt", x, y);
1358  n = x->size();
1359  x->buffer_size(n+y->size());
1360  x->vec().insert(x->end(), y->begin(), y->end());
1361  }
1362  i++;
1363  }
1364  if (m) {
1365  n = x->size();
1366  x->resize(n + m);
1367  for (j=0; j < m; ++j) {
1368  x->elem(n + j) = z[j];
1369  }
1370  delete [] z;
1371  }
1372  return x->temp_objvar();
1373 }
1374 
1375 static Object** v_remove(void* v) {
1376  Vect* x = (Vect*)v;
1377  int i, j, n, start, end;
1378  start = (int)chkarg(1, 0, x->size()-1);
1379  if (ifarg(2)) {
1380  end = (int)chkarg(2, start, x->size()-1);
1381  }else{
1382  end = start;
1383  }
1384  n = x->size();
1385  for (i=start, j=end+1; j < n; ++i, ++j) {
1386  x->elem(i) = x->elem(j);
1387  }
1388  x->resize(i);
1389  return x->temp_objvar();
1390 }
1391 
1392 static double v_contains(void* v) {
1393  Vect* x = (Vect*)v;
1394  double g = *getarg(1);
1396  for (int i=0;i<x->size();i++) {
1397  if (Math::equal(x->elem(i), g, hoc_epsilon)) return 1.;
1398  }
1399  return 0.;
1400 }
1401 
1402 
1403 static Object** v_copy(void* v) {
1404  Vect* y = (Vect*)v;
1405 
1406  Vect* x = vector_arg(1);
1407 
1408  int top = x->size()-1;
1409  int srcstart = 0;
1410  int srcend = top;
1411  int srcinc = 1;
1412 
1413  int deststart = 0;
1414  int destinc = 1;
1415 
1416  if (ifarg(2) && hoc_is_object_arg(2)) {
1417  Vect* srcind = vector_arg(2);
1418  int ns = srcind->size();
1419  int nx = x->size();
1420  if (ifarg(3)) {
1421  Vect* destind = vector_arg(3);
1422  if (destind->size() < ns) {
1423  ns = destind->size();
1424  }
1425  int ny = y->size();
1426  for (int i=0; i < ns; ++i) {
1427  int ix = (int) (srcind->elem(i) + hoc_epsilon);
1428  int iy = (int) (destind->elem(i) + hoc_epsilon);
1429  if (ix >= 0 && iy >= 0 && ix < nx && iy < ny) {
1430  y->elem(iy) = x->elem(ix);
1431  }
1432  }
1433  }else{
1434  if (y->size() < nx) {
1435  nx = y->size();
1436  }
1437  for (int i=0; i < ns; ++i) {
1438  int ii = (int)(srcind->elem(i) + hoc_epsilon);
1439  if (ii >= 0 && ii < nx) {
1440  y->elem(ii) = x->elem(ii);
1441  }
1442  }
1443  }
1444  return y->temp_objvar();
1445  }
1446 
1447  if (ifarg(2) && !(ifarg(3))) {
1448  deststart = int(*getarg(2));
1449  } else {
1450  if (ifarg(4)) {
1451  deststart = int(*getarg(2));
1452  srcstart = int(chkarg(3,0,top));
1453  srcend = int(chkarg(4,-1,top));
1454  if (ifarg(5)) {
1455  destinc = int(chkarg(5, 1, dmaxint_));
1456  srcinc = int(chkarg(6, 1, dmaxint_));
1457  }
1458  } else if (ifarg(3)) {
1459  srcstart = int(chkarg(2,0,top));
1460  srcend = int(chkarg(3,-1,top));
1461  }
1462  }
1463  if (srcend == -1) {
1464  srcend = top;
1465  }else if (srcend < srcstart) {
1466  hoc_execerror("Vector.copy: src_end arg smaller than src_start", 0);
1467  }
1468  int size = (srcend-srcstart)/srcinc;
1469  size *= destinc;
1470  size += deststart+1;
1471  if (y->size() < size) {
1472  y->resize(size);
1473  }else if (y->size() > size && !ifarg(2)) {
1474  y->resize(size);
1475  }
1476  int i, j;
1477  for (i=srcstart, j=deststart; i<=srcend; i+=srcinc, j+=destinc) {
1478  y->elem(j) = x->elem(i);
1479  }
1480 
1481  return y->temp_objvar();
1482 }
1483 
1484 
1485 static Object** v_at(void* v) {
1486  Vect* x = (Vect*)v;
1487 
1488  int top = x->size()-1;
1489  int start = 0;
1490  int end = top;
1491  if (ifarg(1)) {
1492  start = int(chkarg(1,0,top));
1493  }
1494  if (ifarg(2)) {
1495  end = int(chkarg(2,start,top));
1496  }
1497  int size = end-start+1;
1498  Vect* y = new Vect(size);
1499 // ZFM: fixed bug -- i<size, not i<=size
1500  for (int i=0; i<size; i++) y->elem(i) = x->elem(i+start);
1501 
1502  return y->temp_objvar();
1503 }
1504 
1505 typedef struct {double x; int i;} SortIndex;
1506 
1507 static int sort_index_cmp(const void* a, const void* b) {
1508  double x = ((SortIndex*)a)->x;
1509  double y = ((SortIndex*)b)->x;
1510  if (x > y) return (1);
1511  if (x < y) return (-1);
1512  return (0);
1513 }
1514 
1515 static Object** v_sortindex(void* v) {
1516  // v.index(vsrc, vsrc.sortindex) sorts vsrc into v
1517  int i, n;
1518  Vect* x = (Vect*)v;
1519  n = x->size();
1520  Vect* y;
1521  possible_destvec(1, y);
1522  y->resize(n);
1523 
1524  SortIndex* si = new SortIndex[n];
1525  for (i=0; i < n; ++i) {
1526  si[i].i = i;
1527  si[i].x = x->elem(i);
1528  }
1529 
1530 // On BlueGene
1531 // qsort apparently can generate errno 38 "Function not implemented"
1532  qsort((void*)si, n, sizeof(SortIndex), sort_index_cmp);
1533  errno = 0;
1534  for (i=0; i<n; i++) y->elem(i) = (double)si[i].i;
1535 
1536  delete [] si;
1537  return y->temp_objvar();
1538 }
1539 
1540 static Object** v_c(void* v) {
1541  return v_at(v);
1542 }
1543 
1544 static Object** v_cl(void* v) {
1545  Object** r = v_at(v);
1546  ((Vect*)((*r)->u.this_pointer))->label(((Vect*)v)->label_);
1547  return r;
1548 }
1549 
1550 static Object** v_interpolate(void* v) {
1551  Vect* yd = (Vect*)v;
1552  Vect* xd = vector_arg(1);
1553  Vect* xs = vector_arg(2);
1554  Vect* ys;
1555  int flag, is, id, nd, ns;
1556  double thet;
1557  ns = xs->size();
1558  nd = xd->size();
1559  if (ifarg(3)) {
1560  ys = vector_arg(3);
1561  flag = 0;
1562  }else{
1563  ys = new Vect(*yd);
1564  flag = 1;
1565  }
1566  yd->resize(nd);
1567  // before domain
1568  for (id = 0; id < nd && xd->elem(id) <= xs->elem(0); ++id) {
1569  yd->elem(id) = ys->elem(0);
1570  }
1571  // in domain
1572  for (is = 1; is < ns && id < nd; ++is) {
1573  if (xs->elem(is) <= xs->elem(is-1)) {
1574  continue;
1575  }
1576  while (xd->elem(id) <= xs->elem(is)) {
1577 thet = (xd->elem(id) - xs->elem(is-1))/(xs->elem(is) - xs->elem(is-1));
1578  yd->elem(id) = (1.-thet)*(ys->elem(is-1)) + thet*(ys->elem(is));
1579  ++id;
1580  if (id >= nd) {
1581  break;
1582  }
1583  }
1584  }
1585  // after domain
1586  for (; id < nd; ++id) {
1587  yd->elem(id) = ys->elem(ns-1);
1588  }
1589 
1590  if (flag) {
1591  delete ys;
1592  }
1593 
1594  return yd->temp_objvar();
1595 }
1596 
1597 static int possible_srcvec(Vect*& src, Vect* dest, int& flag) {
1598  if (ifarg(1) && hoc_is_object_arg(1)) {
1599  src = vector_arg(1);
1600  flag = 0;
1601  return 2;
1602  }else{
1603  src = new Vect(*dest);
1604  flag = 1;
1605  return 1;
1606  }
1607 }
1608 
1609 static Object** v_where(void* v) {
1610  Vect* y = (Vect*)v;
1611  Vect* x;
1612  int iarg, flag;
1613 
1614  iarg = possible_srcvec(x, y, flag);
1615 
1616  int n = x->size();
1617  int m = 0;
1618  int i;
1619 
1620  char* op = gargstr(iarg++);
1621  double value = *getarg(iarg++);
1622  double value2;
1623 
1624  y->resize(0);
1625 
1626  if (!strcmp(op,"==")) {
1627  for (i=0; i<n; i++) {
1628  if (Math::equal(x->elem(i), value, hoc_epsilon)) {
1629 // y->resize_chunk(++m);
1630 // y->elem(m-1) = x->elem(i);
1631  y->push_back(x->elem(i));
1632  }
1633  }
1634  } else if (!strcmp(op,"!=")) {
1635  for (i=0; i<n; i++) {
1636  if (!Math::equal(x->elem(i), value, hoc_epsilon)) {
1637  y->push_back(x->elem(i));
1638  }
1639  }
1640  } else if (!strcmp(op,">")) {
1641  for (i=0; i<n; i++) {
1642  if (x->elem(i) > value + hoc_epsilon) {
1643  y->push_back(x->elem(i));
1644  }
1645  }
1646  } else if (!strcmp(op,"<")) {
1647  for (i=0; i<n; i++) {
1648  if (x->elem(i) < value - hoc_epsilon) {
1649  y->push_back(x->elem(i));
1650  }
1651  }
1652  } else if (!strcmp(op,">=")) {
1653  for (i=0; i<n; i++) {
1654  if (x->elem(i) >= value - hoc_epsilon) {
1655  y->push_back(x->elem(i));
1656  }
1657  }
1658  } else if (!strcmp(op,"<=")) {
1659  for (i=0; i<n; i++) {
1660  if (x->elem(i) <= value + hoc_epsilon) {
1661  y->push_back(x->elem(i));
1662  }
1663  }
1664  } else if (!strcmp(op,"()")) {
1665  value2 = *getarg(iarg);
1666  for (i=0; i<n; i++) {
1667  if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
1668  y->push_back(x->elem(i));
1669  }
1670  }
1671  } else if (!strcmp(op,"[]")) {
1672  value2 = *getarg(iarg);
1673  for (i=0; i<n; i++) {
1674  if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
1675  y->push_back(x->elem(i));
1676  }
1677  }
1678  } else if (!strcmp(op,"[)")) {
1679  value2 = *getarg(iarg);
1680  for (i=0; i<n; i++) {
1681  if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
1682  y->push_back(x->elem(i));
1683  }
1684  }
1685  } else if (!strcmp(op,"(]")) {
1686  value2 = *getarg(iarg);
1687  for (i=0; i<n; i++) {
1688  if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
1689  y->push_back(x->elem(i));
1690  }
1691  }
1692  } else {
1693  hoc_execerror("Vector","Invalid comparator in .where()\n");
1694  }
1695  if (flag) {
1696  delete x;
1697  }
1698  return y->temp_objvar();
1699 }
1700 
1701 static double v_indwhere(void* v) {
1702 
1703  Vect* x = (Vect*)v;
1704  int i, iarg, m=0;
1705  char* op;
1706  double value,value2;
1708  op = gargstr(1);
1709  value = *getarg(2);
1710  iarg = 3;
1711 
1712  int n = x->size();
1713 
1714 
1715  if (!strcmp(op,"==")) {
1716  for (i=0; i<n; i++) {
1717  if (Math::equal(x->elem(i), value, hoc_epsilon)) {
1718  return i;
1719  }
1720  }
1721  } else if (!strcmp(op,"!=")) {
1722  for (i=0; i<n; i++) {
1723  if (!Math::equal(x->elem(i), value, hoc_epsilon)) {
1724  return i;
1725  }
1726  }
1727  } else if (!strcmp(op,">")) {
1728  for (i=0; i<n; i++) {
1729  if (x->elem(i) > value + hoc_epsilon) {
1730  return i;
1731  }
1732  }
1733  } else if (!strcmp(op,"<")) {
1734  for (i=0; i<n; i++) {
1735  if (x->elem(i) < value - hoc_epsilon) {
1736  return i;
1737  }
1738  }
1739  } else if (!strcmp(op,">=")) {
1740  for (i=0; i<n; i++) {
1741  if (x->elem(i) >= value - hoc_epsilon) {
1742  return i;
1743  }
1744  }
1745  } else if (!strcmp(op,"<=")) {
1746  for (i=0; i<n; i++) {
1747  if (x->elem(i) <= value + hoc_epsilon) {
1748  return i;
1749  }
1750  }
1751  } else if (!strcmp(op,"()")) {
1752  value2 = *getarg(iarg);
1753  for (i=0; i<n; i++) {
1754  if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
1755  return i;
1756  }
1757  }
1758  } else if (!strcmp(op,"[]")) {
1759  value2 = *getarg(iarg);
1760  for (i=0; i<n; i++) {
1761  if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
1762  return i;
1763  }
1764  }
1765  } else if (!strcmp(op,"[)")) {
1766  value2 = *getarg(iarg);
1767  for (i=0; i<n; i++) {
1768  if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
1769  return i;
1770  }
1771  }
1772  } else if (!strcmp(op,"(]")) {
1773  value2 = *getarg(iarg);
1774  for (i=0; i<n; i++) {
1775  if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
1776  return i;
1777  }
1778  }
1779  } else {
1780  hoc_execerror("Vector","Invalid comparator in .indwhere()\n");
1781  }
1782 
1783  return -1.;
1784 }
1785 
1786 static Object** v_indvwhere(void* v) {
1787 
1788  Vect* y = (Vect*)v;
1789  Vect* x;
1790  int i, iarg, m=0, flag;
1791  char* op;
1792  double value,value2;
1793 
1794  iarg = possible_srcvec(x, y, flag);
1795  op = gargstr(iarg++);
1796  value = *getarg(iarg++);
1797  y->resize(0);
1798 
1799  int n = x->size();
1800 
1801 
1802  if (!strcmp(op,"==")) {
1803  for (i=0; i<n; i++) {
1804  if (Math::equal(x->elem(i), value, hoc_epsilon)) {
1805  y->push_back(i);
1806  }
1807  }
1808  } else if (!strcmp(op,"!=")) {
1809  for (i=0; i<n; i++) {
1810  if (!Math::equal(x->elem(i), value, hoc_epsilon)) {
1811  y->push_back(i);
1812  }
1813  }
1814  } else if (!strcmp(op,">")) {
1815  for (i=0; i<n; i++) {
1816  if (x->elem(i) > value + hoc_epsilon) {
1817  y->push_back(i);
1818  }
1819  }
1820  } else if (!strcmp(op,"<")) {
1821  for (i=0; i<n; i++) {
1822  if (x->elem(i) < value - hoc_epsilon) {
1823  y->push_back(i);
1824  }
1825  }
1826  } else if (!strcmp(op,">=")) {
1827  for (i=0; i<n; i++) {
1828  if (x->elem(i) >= value - hoc_epsilon) {
1829  y->push_back(i);
1830  }
1831  }
1832  } else if (!strcmp(op,"<=")) {
1833  for (i=0; i<n; i++) {
1834  if (x->elem(i) <= value + hoc_epsilon) {
1835  y->push_back(i);
1836  }
1837  }
1838  } else if (!strcmp(op,"()")) {
1839  value2 = *getarg(iarg);
1840  for (i=0; i<n; i++) {
1841  if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
1842  y->push_back(i);
1843  }
1844  }
1845  } else if (!strcmp(op,"[]")) {
1846  value2 = *getarg(iarg);
1847  for (i=0; i<n; i++) {
1848  if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
1849  y->push_back(i);
1850  }
1851  }
1852  } else if (!strcmp(op,"[)")) {
1853  value2 = *getarg(iarg);
1854  for (i=0; i<n; i++) {
1855  if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
1856  y->push_back(i);
1857  }
1858  }
1859  } else if (!strcmp(op,"(]")) {
1860  value2 = *getarg(iarg);
1861  for (i=0; i<n; i++) {
1862  if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
1863  y->push_back(i);
1864  }
1865  }
1866  } else {
1867  hoc_execerror("Vector","Invalid comparator in .indvwhere()\n");
1868  }
1869 
1870  if (flag) {
1871  delete x;
1872  }
1873  return y->temp_objvar();
1874 }
1875 
1876 static Object** v_fill(void* v)
1877 {
1878  Vect* x = (Vect*)v;
1879  int top = x->size()-1;
1880  int start = 0;
1881  int end = top;
1882  if (ifarg(2)) {
1883  start = int(chkarg(2,0,top));
1884  end = int(chkarg(3,start,top));
1885  }
1886  std::fill(x->begin()+start,x->begin()+end+1, *getarg(1));
1887  return x->temp_objvar();
1888 }
1889 
1890 static Object** v_indgen(void* v)
1891 {
1892  Vect* x = (Vect*)v;
1893 
1894  int n = x->size();
1895 
1896  double start = 0.;
1897  double step = 1.;
1898  double end = double(n-1);
1899 
1900  if (ifarg(1)) {
1901  if (ifarg(3)) {
1902  start = *getarg(1);
1903  end = *getarg(2);
1904  step = chkarg(3,Math::min(start-end,end-start),Math::max(start-end,end-start));
1905  double xn = floor((end-start)/step + EPSILON)+1.;
1906  if (xn > dmaxint_) {
1907  hoc_execerror("size too large", 0);
1908  } else if (xn < 0) {
1909  hoc_execerror("empty set", 0);
1910  }
1911  n = int(xn);
1912  if (n != x->size()) x->resize(n);
1913  } else if (ifarg(2)) {
1914  start = *getarg(1);
1915  step = chkarg(2,-dmaxint_,dmaxint_);
1916  } else {
1917  step = chkarg(1,-dmaxint_,dmaxint_);
1918  }
1919  }
1920  for (int i=0;i<n;i++) {
1921  x->elem(i) = double(i)*step+start;
1922  }
1923  return x->temp_objvar();
1924 }
1925 
1926 static Object** v_addrand(void* v)
1927 {
1928  Vect* x = (Vect*)v;
1929  Object* ob = *hoc_objgetarg(1);
1930  check_obj_type(ob, "Random");
1931  Rand* r = (Rand*)(ob->u.this_pointer);
1932  int top = x->size()-1;
1933  int start = 0;
1934  int end = top;
1935  if (ifarg(2)) {
1936  start = int(chkarg(2,0,top));
1937  end = int(chkarg(3,start,top));
1938  }
1939  for (int i=start;i<=end;i++) x->elem(i) += (*(r->rand))();
1940  return x->temp_objvar();
1941 }
1942 
1943 static Object** v_setrand(void* v)
1944 {
1945  Vect* x = (Vect*)v;
1946  Object* ob = *hoc_objgetarg(1);
1947  check_obj_type(ob, "Random");
1948  Rand* r = (Rand*)(ob->u.this_pointer);
1949  int top = x->size()-1;
1950  int start = 0;
1951  int end = top;
1952  if (ifarg(2)) {
1953  start = int(chkarg(2,0,top));
1954  end = int(chkarg(3,start,top));
1955  }
1956  for (int i=start;i<=end;i++) x->elem(i) = (*(r->rand))();
1957  return x->temp_objvar();
1958 }
1959 
1960 
1961 
1962 
1963 
1964 static Object** v_apply(void* v)
1965 {
1966  Vect* x = (Vect*)v;
1967  char* func = gargstr(1);
1968  int top = x->size()-1;
1969  int start = 0;
1970  int end = top;
1971  Object* ob;
1972  if (ifarg(2)) {
1973  start = int(chkarg(2,0,top));
1974  end = int(chkarg(3,start,top));
1975  }
1976  Symbol* s = hoc_lookup(func);
1977  ob = hoc_thisobject;
1978  if (!s) {
1979  ob = NULL;
1980  s = hoc_table_lookup(func, hoc_top_level_symlist);
1981  if (!s) {
1982  hoc_execerror(func, " is undefined");
1983  }
1984  }
1985  for (int i=start; i<=end; i++) {
1986  hoc_pushx(x->elem(i));
1987  x->elem(i) = hoc_call_objfunc(s, 1, ob);
1988  }
1989  return x->temp_objvar();
1990 }
1991 
1992 static double v_reduce(void* v)
1993 {
1994  Vect* x = (Vect*)v;
1995  double base = 0;
1996  int top = x->size()-1;
1997  int start = 0;
1998  int end = top;
1999  if (ifarg(3)) {
2000  start = int(chkarg(3,0,top));
2001  end = int(chkarg(4,start,top));
2002  }
2003  char* func = gargstr(1);
2004  if (ifarg(2)) base = *getarg(2);
2005  Symbol* s = hoc_lookup(func);
2006  if (!s) {
2007  hoc_execerror(func, " is undefined");
2008  }
2009  for (int i=start; i<=end; i++) {
2010  hoc_pushx(x->elem(i));
2011  base += hoc_call_func(s, 1);
2012  }
2013  return base;
2014 }
2015 
2016 
2017 static double v_min(void* v)
2018 {
2019  Vect* x = (Vect*)v;
2020  if (x->size() == 0) {
2021  return 0.0;
2022  }
2023  int x_max = x->size()-1;
2024  if (ifarg(1)) {
2025  int start = int(chkarg(1,0,x_max));
2026  int end = int(chkarg(2,start,x_max));
2027  return *std::min_element(x->begin()+start, x->begin()+end+1);
2028  } else {
2029  return *std::min_element(x->begin(), x->end());
2030  }
2031 }
2032 
2033 static double v_min_ind(void* v)
2034 {
2035  Vect* x = (Vect*)v;
2036  if (x->size() == 0) {
2037  return -1.0;
2038  }
2039  int x_max = x->size()-1;
2040  hoc_return_type_code = 1; // integer
2041  if (ifarg(1)) {
2042  int start = int(chkarg(1,0,x_max));
2043  int end = int(chkarg(2,start,x_max));
2044  return std::min_element(x->begin()+start, x->begin()+end+1) - x->begin()+start;
2045  } else {
2046  return std::min_element(x->begin(), x->end()) - x->begin();
2047  }
2048 }
2049 
2050 static double v_max(void* v)
2051 {
2052  Vect* x = (Vect*)v;
2053  if(x->size() == 0) {
2054  return 0.0;
2055  }
2056  int x_max = x->size()-1;
2057  if (ifarg(1)) {
2058  int start = int(chkarg(1,0,x_max));
2059  int end = int(chkarg(2,start,x_max));
2060  return *std::max_element(x->begin()+start, x->begin()+end+1);
2061  } else {
2062  return *std::max_element(x->begin(), x->end());
2063  }
2064 }
2065 
2066 static double v_max_ind(void* v)
2067 {
2068  Vect* x = (Vect*)v;
2069  if(x->size() == 0) {
2070  return -1.0;
2071  }
2072  int x_max = x->size()-1;
2073  hoc_return_type_code = 1; // integer
2074  if (ifarg(1)) {
2075  int start = int(chkarg(1,0,x_max));
2076  int end = int(chkarg(2,start,x_max));
2077  return std::max_element(x->begin()+start,x->begin()+end+1) - x->begin()+start;
2078  } else {
2079  return std::max_element(x->begin(),x->end()) - x->begin();
2080  }
2081 }
2082 
2083 static double v_sum(void* v)
2084 {
2085  Vect* x = (Vect*)v;
2086  int x_max = x->size()-1;
2087  if (ifarg(1)) {
2088  int start = int(chkarg(1,0,x_max));
2089  int end = int(chkarg(2,start,x_max));
2090  return std::accumulate(x->begin()+start, x->begin()+end+1,0.);
2091  } else {
2092  return std::accumulate(x->begin(), x->end(),0.);
2093  }
2094 }
2095 
2096 static double v_sumsq(void* v)
2097 {
2098  Vect* x = (Vect*)v;
2099  int x_max = x->size()-1;
2100  if (ifarg(1)) {
2101  int start = int(chkarg(1,0,x_max));
2102  int end = int(chkarg(2,start,x_max));
2103  return std::inner_product( x->begin()+start, x->begin()+end+1, x->begin()+start, 0. );
2104  } else {
2105  return std::inner_product( x->begin(), x->end(), x->begin(), 0.);
2106  }
2107 }
2108 
2109 static double v_mean(void* v)
2110 {
2111  Vect* x = (Vect*)v;
2112  int x_max = x->size()-1;
2113  if (ifarg(1)) {
2114  int start = int(chkarg(1,0,x_max));
2115  int end = int(chkarg(2,start,x_max));
2116  if (end - start < 1) {
2117  hoc_execerror("end - start", "must be > 0");
2118  }
2119  const double sum = std::accumulate(x->begin()+start, x->begin()+end+1, 0.0);
2120  return sum / end-start+1;
2121  } else {
2122  if (x->size() < 1) {
2123  hoc_execerror("Vector", "must have size > 0");
2124  }
2125  const double sum = std::accumulate(x->begin(), x->end(), 0.0);
2126  return sum / x->size();
2127  }
2128 }
2129 
2130 static double v_var(void* v)
2131 {
2132  Vect* x = (Vect*)v;
2133  int x_max = x->size()-1;
2134  if (ifarg(1)) {
2135  int start = int(chkarg(1,0,x_max));
2136  int end = int(chkarg(2,start,x_max));
2137  if (end - start < 1) {
2138  hoc_execerror("end - start", "must be > 1");
2139  }
2140  return var(x->begin()+start, x->begin()+end+1);
2141  } else {
2142  if (x->size() < 2) {
2143  hoc_execerror("Vector", "must have size > 1");
2144  }
2145  return var(x->begin(), x->end());
2146  }
2147 }
2148 
2149 static double v_stdev(void* v)
2150 {
2151  Vect* x = (Vect*)v;
2152  int x_max = x->size()-1;
2153  if (ifarg(1)) {
2154  int start = int(chkarg(1,0,x_max));
2155  int end = int(chkarg(2,start,x_max));
2156  if (end - start < 1) {
2157  hoc_execerror("end - start", "must be > 1");
2158  }
2159  return stdDev(x->begin()+start, x->begin()+end+1);
2160  } else {
2161  if (x->size() < 2) {
2162  hoc_execerror("Vector", "must have size > 1");
2163  }
2164  return stdDev(x->begin(), x->end());
2165  }
2166 }
2167 
2168 static double v_stderr(void* v)
2169 {
2170  Vect* x = (Vect*)v;
2171  int x_max = x->size()-1;
2172  if (ifarg(1)) {
2173  int start = int(chkarg(1,0,x_max));
2174  int end = int(chkarg(2,start,x_max));
2175  if (end - start < 1) {
2176  hoc_execerror("end - start", "must be > 1");
2177  }
2178  return stdDev(x->begin()+start, x->begin()+end+1)/hoc_Sqrt(double(end-start+1));
2179  } else {
2180  if (x->size() < 2) {
2181  hoc_execerror("Vector", "must have size > 1");
2182  }
2183  return stdDev(x->begin(), x->end())/hoc_Sqrt((double)x_max+1.);
2184  }
2185 }
2186 
2187 static double v_meansqerr(void* v1)
2188 {
2189  Vect* x = (Vect*)v1;
2190 
2191  Vect* y = vector_arg(1);
2192  Vect* w = NULL;
2193 
2194  if (ifarg(2)) {
2195  w = vector_arg(2);
2196  }
2197  double err = 0.;
2198  int size = x->size();
2199  if (size > y->size() || !size) {
2200  hoc_execerror("Vector","Vector argument too small\n");
2201  } else {
2202  if (w) {
2203  if (size > w->size()) {
2204  hoc_execerror("Vector","second Vector size too small\n");
2205  }
2206  for (int i=0;i<size;i++) {
2207  double diff = x->elem(i) - y->elem(i);
2208  err += diff*diff*w->elem(i);
2209  }
2210  }else{
2211  for (int i=0;i<size;i++) {
2212  double diff = x->elem(i) - y->elem(i);
2213  err += diff*diff;
2214  }
2215  }
2216  }
2217  return err/size;
2218 }
2219 
2220 static double v_dot(void* v1)
2221 {
2222  Vect* x = (Vect*)v1;
2223  Vect* y = vector_arg(1);
2224  return std::inner_product( x->begin(), x->end(), y->begin(), 0.);
2225 }
2226 
2227 static double v_mag(void* v1)
2228 {
2229  Vect* x = (Vect*)v1;
2230  return hoc_Sqrt(std::inner_product( x->begin(), x->end(), x->begin(), 0.));
2231 }
2232 
2233 static Object** v_from_double(void* v) {
2234  Vect* x = (Vect*)v;
2235  int i;
2236  int n = (int)*getarg(1);
2237  double* px = hoc_pgetarg(2);
2238  x->resize(n);
2239  for (i=0; i < n; ++i) {
2240  x->elem(i) = px[i];
2241  }
2242  return x->temp_objvar();
2243 }
2244 
2245 static Object** v_add(void* v1)
2246 {
2247  Vect* x = (Vect*)v1;
2248  if (hoc_argtype(1) == NUMBER) {
2249  std::for_each(x->begin(), x->end(), [](double& d) { d += *getarg(1); } );
2250  }
2251  if (hoc_is_object_arg(1)) {
2252  Vect* y = vector_arg(1);
2253  if (x->size() != y->size()) {
2254  hoc_execerror("Vector","Vector argument to .add() wrong size\n");
2255  } else {
2256  std::transform(x->begin(), x->end(), y->begin(), x->begin(), std::plus<double>());
2257  }
2258  }
2259  return x->temp_objvar();
2260 }
2261 
2262 
2263 static Object** v_sub(void* v1)
2264 {
2265  Vect* x = (Vect*)v1;
2266  if (hoc_argtype(1) == NUMBER) {
2267  std::for_each(x->begin(), x->end(), [](double& d) { d -= *getarg(1); } );
2268  }
2269  if (hoc_is_object_arg(1)) {
2270  Vect* y = vector_arg(1);
2271  if (x->size() != y->size()) {
2272  hoc_execerror("Vector","Vector argument to .sub() wrong size\n");
2273  } else {
2274  std::transform(x->begin(), x->end(), y->begin(), x->begin(), std::minus<double>());
2275  }
2276  }
2277  return x->temp_objvar();
2278 }
2279 
2280 static Object** v_mul(void* v1)
2281 {
2282  Vect* x = (Vect*)v1;
2283  if (hoc_argtype(1) == NUMBER) {
2284  std::for_each(x->begin(), x->end(), [](double& d) { d *= *getarg(1); } );
2285  }
2286  if (hoc_is_object_arg(1)) {
2287  Vect* y = vector_arg(1);
2288  if (x->size() != y->size()) {
2289  hoc_execerror("Vector","Vector argument to .mult() wrong size\n");
2290  } else {
2291  std::transform(x->begin(), x->end(), y->begin(), x->begin(), std::multiplies<double>());
2292  }
2293  }
2294  return x->temp_objvar();
2295 }
2296 
2297 
2298 static Object** v_div(void* v1)
2299 {
2300  Vect* x = (Vect*)v1;
2301  if (hoc_argtype(1) == NUMBER) {
2302  std::for_each(x->begin(), x->end(), [](double& d) { d /= *getarg(1); } );
2303  }
2304  if (hoc_is_object_arg(1)) {
2305  Vect* y = vector_arg(1);
2306  if (x->size() != y->size()) {
2307  hoc_execerror("Vector","Vector argument to .div() wrong size\n");
2308  } else {
2309  std::transform(x->begin(), x->end(), y->begin(), x->begin(), std::divides<double>());
2310  }
2311  }
2312  return x->temp_objvar();
2313 }
2314 
2315 static double v_scale(void* v1)
2316 {
2317  Vect* x = (Vect*)v1;
2318 
2319  double a = *getarg(1);
2320  double b = *getarg(2);
2321  double sf;
2322  auto minmax = std::minmax_element(x->begin(), x->end());
2323  double min = *minmax.first;
2324  double max = *minmax.second;
2325  double r = max - min;
2326  if (r > 0) {
2327  sf = (b-a)/r;
2328  std::for_each(x->begin(), x->end(), [&](double& d) {
2329  d -= min;
2330  d *= sf;
2331  d += a;
2332  });
2333  } else {
2334  sf = 0.;
2335  }
2336  return sf;
2337 }
2338 
2339 static double v_eq(void* v1)
2340 {
2341  Vect* x = (Vect*)v1;
2342  Vect* y = vector_arg(1);
2343  int i, n = x->size();
2344  if (n != y->size()) {
2345  return false;
2346  }
2347  for (i=0; i < n; ++i) {
2348  if (!Math::equal(x->elem(i), y->elem(i), hoc_epsilon)) {
2349  return false;
2350  }
2351  }
2352  return true;
2353 }
2354 
2355 
2356 /*=============================================================================
2357 
2358  FITTING A MULTIVARIABLE FUNCTION FROM DATA -- SIMPLEX METHOD
2359 
2360  double simplex( p,n,trial,a,b,c,d )
2361  double *p;
2362  vector of dimension n, containing variables
2363  int n;
2364  number of variables of the function to fit
2365  int trial;
2366  number of trials of simplex loop
2367  trial = 0: do simplex until the minimum pole has found
2368  trial > 0: do simplex [trial] times.
2369  double a,b,c,d
2370  values of contraction/expansion of the simplex;
2371  control the rate of the search in multidim variable space
2372  must be chosen by trial and error
2373  2.0, 1.4, 0.7, 0.3 -> standard values
2374 
2375  return most optimized eval value
2376  (negative if error occured)
2377 
2378  A function must be supplied by the user:
2379 
2380  external function DOUBLE EVAL(double *p);
2381 
2382  This function evaluates the mean square error between the
2383  the data and the multivariable function with the values of
2384  variables in vector p.
2385 
2386 =============================================================================*/
2387 
2388 
2389 #define SIMPLEX_MAXN 1e+300
2390 #define SIMPLEX_INORM 1.2
2391 
2392 /* 1.2: normal,
2393  1.3: extensive search,
2394  1.1: final adjustments
2395 */
2396 
2397 
2398 #define SIMPLEX_ALPHA 2.0
2399 #define SIMPLEX_BETA 1.4
2400 #define SIMPLEX_GAMMA 0.7
2401 #define SIMPLEX_DELTA 0.3
2402 
2403 /*
2404  values of contraction/expansion of the simplex;
2405  control the rate of the search in multidim variable space
2406  must be chosen by trial and error
2407  2.0, 1.4, 0.7, 0.3 -> standard values
2408 */
2409 
2410 static double splx_evl_;
2411 static int renew_;
2412 
2413 
2414 
2415 static double eval(double *p, int n, Vect *x, Vect *y, char *fcn)
2416 {
2417 
2418  double sq_err = 0.;
2419  double guess;
2420  int i;
2421  double dexp,t,amp1,tau1,amp2,tau2;
2422 
2423  if (!strcmp(fcn,"exp2")) {
2424  if (n < 4) hoc_execerror("Vector",".fit(\"exp2\") requires amp1,tau1,amp2,tau2");
2425  amp1 = p[0];
2426  tau1 = p[1];
2427  amp2 = p[2];
2428  tau2 = p[3];
2429 
2430  for (i=0;i<x->size();i++) {
2431  t = x->elem(i);
2432  dexp = amp1*hoc_Exp(-t/tau1) + amp2*hoc_Exp(-t/tau2);
2433  guess = dexp - y->elem(i);
2434  sq_err += guess * guess;
2435  }
2436  } else if (!strcmp(fcn,"charging")) {
2437  if (n < 4) hoc_execerror("Vector",".fit(\"charging\") requires amp1,tau1,amp2,tau2");
2438  amp1 = p[0];
2439  tau1 = p[1];
2440  amp2 = p[2];
2441  tau2 = p[3];
2442 
2443  for (i=0;i<x->size();i++) {
2444  t = x->elem(i);
2445  dexp = amp1*(1-hoc_Exp(-t/tau1)) + amp2*(1-hoc_Exp(-t/tau2));
2446  guess = dexp - y->elem(i);
2447  sq_err += guess * guess;
2448  }
2449  } else if (!strcmp(fcn,"exp1")) {
2450  if (n < 2) hoc_execerror("Vector",".fit(\"exp1\") requires amp,tau");
2451  amp1 = p[0];
2452  tau1 = p[1];
2453 
2454 
2455  for (i=0;i<x->size();i++) {
2456  t = x->elem(i);
2457  dexp = amp1*hoc_Exp(-t/tau1);
2458  guess = dexp - y->elem(i);
2459  sq_err += guess * guess;
2460  }
2461  } else if (!strcmp(fcn,"line")) {
2462  if (n < 2) hoc_execerror("Vector",".fit(\"line\") requires slope,intercept");
2463 
2464  for (i=0;i<x->size();i++) {
2465  guess = (p[0]*x->elem(i) + p[1]) - y->elem(i);
2466  sq_err += guess * guess;
2467  }
2468  } else if (!strcmp(fcn,"quad")) {
2469  if (n < 3) hoc_execerror("Vector",".fit(\"quad\") requires ax^2+bx+c");
2470 
2471  for (i=0;i<x->size();i++) {
2472  guess = (p[0]*x->elem(i)*x->elem(i) + p[1]*x->elem(i) + p[2]) - y->elem(i);
2473  sq_err += guess * guess;
2474  }
2475  } else {
2476  for (i=0;i<x->size();i++) {
2477 
2478 // first the independent variable
2479  hoc_pushx(x->elem(i));
2480 // then other parameters
2481  for (int j=0;j<n;j++) hoc_pushx(p[j]);
2482 
2483  guess = hoc_call_func(hoc_lookup(fcn), n+1) - y->elem(i);
2484  sq_err += guess * guess;
2485  }
2486  }
2487  return sq_err/x->size();
2488 }
2489 
2490 
2491 static double eval_error(double *p, int n, Vect *x, Vect *y, char *fcn)
2492 {
2493  double retval;
2494 
2495  if (renew_ > 3*(n+1)) {
2496  retval = eval(p,n,x,y,fcn);
2497  if (retval == splx_evl_) return(splx_evl_); else return( SIMPLEX_MAXN );
2498  } else{
2499  retval = eval(p,n,x,y,fcn);
2500  if (splx_evl_ > retval) splx_evl_ = retval;
2501  return(retval);
2502  }
2503 }
2504 
2505 static double simplex(double *p, int n, Vect *x, Vect *y, char* fcn)
2506 {
2507  int i,j;
2508  int emaxp; /* max position */
2509  int eminp;
2510  int ptr;
2511 
2512  double *evortex; /* eval value of votexes */
2513  double *gvortex; /* the vector of gravity */
2514  double *vortex; /* parameter matrix */
2515  double *nvortex; /* new vortex */
2516  double emax;
2517  double emin;
2518  double fv1;
2519 
2520  evortex = (double *)calloc(n+1,(unsigned)sizeof(double));
2521  gvortex = (double *)calloc(n, (unsigned)sizeof(double));
2522  vortex = (double *)calloc(n*(n+1),(unsigned)sizeof(double));
2523  nvortex = (double *)calloc(n*4,(unsigned)sizeof(double));
2524 
2525  if( 0==evortex || 0==gvortex || 0==vortex || 0==nvortex ){
2526  Printf("allocation error in simplex()\n");
2527  nrn_exit(1);
2528  }
2529 
2530 
2531 // NEXT:;
2532  /* make the initial vortex matrix */
2533  for(i=0;i<n+1;i++){
2534  for(j=0;j<n;j++){
2535  vortex[i*n+j]=p[j];
2536  if(i==j) vortex[i*n+j] *=SIMPLEX_INORM;
2537  }
2538  }
2539 
2540  /* evaluate the n+1 of vortexes and make the maximal one
2541  to be pointed out by emaxp */
2542  for(i=0;i<n+1;i++) evortex[i]=eval_error( &vortex[i*n],n,x,y,fcn);
2543 
2544 Label2:;
2545  emin = emax = evortex[0];
2546  emaxp = eminp =0;
2547  for(i=0;i<n+1;i++){
2548  fv1=evortex[i];
2549  if( fv1>emax ){
2550  emax=fv1;
2551  emaxp=i;
2552  }
2553  if( fv1<emin ){
2554  emin = fv1;
2555  eminp=i;
2556  }
2557  }
2558  /* calculate the center of gravity */
2559  for(i=0;i<n;i++) gvortex[i]=0.0;
2560  for(i=0;i<n+1;i++)
2561  for(j=0;j<n;j++) gvortex[j] += vortex[i*n+j];
2562  for(i=0;i<n;i++)
2563  gvortex[i] = ( gvortex[i] - vortex[emaxp*n+i] ) / n;
2564 
2565  /* calculate the new vortexes */
2566 
2567  for(i=0;i<n;i++)
2568  nvortex[i]=(1.0-SIMPLEX_ALPHA)*vortex[emaxp*n+i]+SIMPLEX_ALPHA*gvortex[i];
2569  fv1=eval_error( &nvortex[0],n,x,y,fcn);
2570  if( fv1 < evortex[emaxp] ){
2571  ptr = 0;
2572  goto UPDATE;
2573  }
2574 
2575  for(i=0;i<n;i++)
2576  nvortex[1*n+i]=(1.0-SIMPLEX_BETA)*vortex[emaxp*n+i]+SIMPLEX_BETA*gvortex[i];
2577  fv1=eval_error( &nvortex[1*n],n,x,y,fcn );
2578  if( fv1 < evortex[emaxp] ){
2579  ptr = 1;
2580  goto UPDATE;
2581  }
2582 
2583  for(i=0;i<n;i++)
2584  nvortex[2*n+i]=(1.0-SIMPLEX_GAMMA)*vortex[emaxp*n+i]+SIMPLEX_GAMMA*gvortex[i];
2585  fv1=eval_error( &nvortex[2*n],n,x,y,fcn );
2586  if( fv1 < evortex[emaxp] ){
2587  ptr = 2;
2588  goto UPDATE;
2589  }
2590 
2591  for(i=0;i<n;i++)
2592  nvortex[3*n+i]=(1.0-SIMPLEX_DELTA)*vortex[emaxp*n+i]+SIMPLEX_DELTA*gvortex[i];
2593  fv1=eval_error( &nvortex[3*n],n,x,y,fcn );
2594  if( fv1 < evortex[emaxp] ){
2595  ptr = 3;
2596  goto UPDATE;
2597  }
2598 
2599  goto Label3;
2600 
2601 
2602 
2603 UPDATE:;
2604  /* update the vortex matrix */
2605  if( splx_evl_ == fv1 ) renew_++;
2606  for(i=0;i<n;i++) vortex[emaxp*n+i]=nvortex[ptr*n+i];
2607  evortex[emaxp]=fv1;
2608  goto Label2;
2609 
2610 
2611 Label3:;
2612  /*
2613  ** search for the vortex that represents smallest eval vaule
2614  */
2615  emin=evortex[0];
2616  eminp=0;
2617  for(i=0;i<n+1;i++){
2618  if( evortex[i]<emin ){
2619  emin=evortex[i];
2620  eminp=i;
2621  }
2622  }
2623 
2624  for(i=0;i<n;i++) p[i]=vortex[eminp*n+i];
2625  free(gvortex);
2626  free(evortex);
2627  free(vortex);
2628  free(nvortex);
2629  return(emin);
2630 }
2631 
2632 
2633 double call_simplex(double *p, int n, Vect *x, Vect *y, char *fcn, int trial)
2634 {
2635  double retval;
2636 
2637  if (!trial) {
2638  while (1) {
2639  renew_ = 0;
2640  splx_evl_ = SIMPLEX_MAXN;
2641  retval = simplex(p,n,x,y,fcn);
2642  if (!renew_ || splx_evl_ <= retval) break;
2643  }
2644  } else {
2645  for (int i=0;i<trial;i++) {
2646  renew_ = 0;
2647  splx_evl_ = SIMPLEX_MAXN;
2648  retval = simplex(p,n,x,y,fcn);
2649  if (!renew_ || splx_evl_ <= retval) break;
2650  }
2651  }
2652  return (retval);
2653 }
2654 
2655 static double v_fit(void* v) {
2656 
2657  int trial = 0;
2658 /* number of trials of simplex loop
2659  trial = 0: do simplex until the minimum pole has found
2660  trial > 0: do simplex [trial] times.
2661 */
2662 
2663 
2664 // get the data vector
2665  Vect* y = (Vect*)v;
2666 
2667 // get a vector to place the fitted function
2668  Vect* fitted = vector_arg(1);
2669  if (fitted->size() != y->size()) fitted->resize(y->size());
2670 
2671 // get a function to fit
2672  char *fcn;
2673  fcn = gargstr(2);
2674 
2675 // get the independent variable
2676 
2677  Vect* x = vector_arg(3);
2678  if (x->size() != y->size()) {
2679  hoc_execerror("Vector","Indep argument to .fit() wrong size\n");
2680  }
2681 
2682 // get the parameters of the function
2683 
2684  double * p_ptr[MAX_FIT_PARAMS];
2685  double p[MAX_FIT_PARAMS];
2686 
2687  if (ifarg(MAX_FIT_PARAMS)) {
2688  hoc_execerror("Vector","Too many parameters to fit()\n");
2689  }
2690  int n = 0;
2691  while(ifarg(4+n)) {
2692  // pointer to parameter
2693  p_ptr[n] = hoc_pgetarg(4+n);
2694  // parameter value
2695  p[n] = *(p_ptr[n]);
2696  n++;
2697  }
2698 
2699  double meansqerr = call_simplex(p,n,x,y,fcn,trial);
2700 
2701 // assign data to pointers where they came from;
2702  int i;
2703  for(i=0;i<n;i++) {
2704  *(p_ptr[i]) = p[i];
2705  }
2706 
2707  if (!strcmp(fcn,"exp2")) {
2708  for(i=0;i<x->size();i++) {
2709  fitted->elem(i) = p[0]*hoc_Exp(-(x->elem(i)/p[1])) +
2710  p[2]*hoc_Exp(-(x->elem(i)/p[3]));
2711  }
2712  } else if (!strcmp(fcn,"charging")) {
2713  for(i=0;i<x->size();i++) {
2714  fitted->elem(i) = p[0]*(1-hoc_Exp(-(x->elem(i)/p[1]))) +
2715  p[2]*(1-hoc_Exp(-(x->elem(i)/p[3])));
2716  }
2717  } else if (!strcmp(fcn,"exp1")) {
2718  for(i=0;i<x->size();i++) {
2719  fitted->elem(i) = p[0]*hoc_Exp(-(x->elem(i)/p[1]));
2720  }
2721  } else if (!strcmp(fcn,"line")) {
2722  for(i=0;i<x->size();i++) {
2723  fitted->elem(i) = p[0]*x->elem(i)+p[1];
2724  }
2725  } else if (!strcmp(fcn,"quad")) {
2726  for(i=0;i<x->size();i++) {
2727  fitted->elem(i) = p[0]*x->elem(i)*x->elem(i) + p[1]*x->elem(i) + p[2];
2728  }
2729  } else {
2730  for(i=0;i<x->size();i++) {
2731  hoc_pushx(x->elem(i));
2732  for (int j=0;j<n;j++) hoc_pushx(p[j]);
2733  fitted->elem(i) = hoc_call_func(hoc_lookup(fcn), n+1);
2734  }
2735  }
2736 
2737  return meansqerr;
2738 }
2739 
2740 
2741 // FOURIER analysis
2742 
2743 
2744 static Object** v_correl(void* v) {
2745  Vect* v3 = (Vect*)v;
2746 
2747  Vect* v1;
2748  Vect* v2;
2749 
2750  // first data set
2751  v1 = vector_arg(1);
2752 
2753  // second data set
2754  if (ifarg(2)) {
2755  v2 = vector_arg(2);
2756  } else {
2757  v2 = v1;
2758  }
2759 
2760  // make both data sets equal integer power of 2
2761  int v1n = v1->size();
2762  int v2n = v2->size();
2763  int m = (v1n > v2n) ? v1n : v2n;
2764  int n = 1;
2765  while(n < m) n*=2;
2766 
2767  double *d1 = (double *)calloc(n,(unsigned)sizeof(double));
2768  int i;
2769  for (i=0;i<v1n;++i) d1[i] = v1->elem(i);
2770  double *d2 = (double *)calloc(n,(unsigned)sizeof(double));
2771  for (i=0;i<v2n;++i) d2[i] = v2->elem(i);
2772  double *ans = (double *)calloc(n,(unsigned)sizeof(double));
2773 
2774  nrn_correl(d1, d2, n, ans);
2775 
2776  if (v3->size() != n) v3->resize(n);
2777  for (i=0;i<n;++i) v3->elem(i)=ans[i];
2778  free((char *)d1);
2779  free((char *)d2);
2780  free((char *)ans);
2781 
2782  return v3->temp_objvar();
2783 }
2784 
2785 static Object** v_convlv(void* v) {
2786  Vect* v3 = (Vect*)v;
2787 
2788  Vect* v1, *v2;
2789 
2790  // data set
2791  v1 = vector_arg(1);
2792 
2793 
2794  // filter
2795  v2 = vector_arg(2);
2796 
2797  // convolve unless isign is -1, then deconvolve!
2798  int isign;
2799  if (ifarg(3)) isign = (int)(*getarg(3)); else isign = 1;
2800 
2801  // make both data sets equal integer power of 2
2802  int v1n = v1->size();
2803  int v2n = v2->size();
2804  int m = (v1n > v2n) ? v1n : v2n;
2805  int n = 1;
2806  while(n < m) n*=2;
2807 
2808  double *data = (double *)calloc(n,(unsigned)sizeof(double));
2809  int i;
2810  for (i=0;i<v1n;++i) data[i] = v1->elem(i);
2811 
2812  // assume respns is given in "wrap-around" order,
2813  // with countup t=0..t=n/2 followed by countdown t=n..t=n/2
2814  // v2n should be an odd <= n
2815 
2816  double *respns = (double *)calloc(n,(unsigned)sizeof(double));
2817  for (i=0;i<v2n;i++) respns[i] = v2->elem(i);
2818 
2819  double *ans = (double *)calloc(2*n,(unsigned)sizeof(double));
2820 
2821  nrn_convlv(data,n,respns,v2n,isign,ans);
2822 
2823  if (v3->size() != n) v3->resize(n);
2824  for (i=0;i<n;++i) v3->elem(i)=ans[i];
2825 
2826  free((char *)data);
2827  free((char *)respns);
2828  free((char *)ans);
2829 
2830  return v3->temp_objvar();
2831 }
2832 
2833 
2834 static Object** v_spctrm(void* v) {
2835  Vect* ans = (Vect*)v;
2836 
2837  // n data pts will be divided into k partitions of size m
2838  // the spectrum will have m values from 0 to m/2 cycles/dt.
2839  // n = (2*k+1)*m
2840 
2841  // data set
2842  Vect* v1 = vector_arg(1);
2843 
2844  int dc = v1->size();
2845  int mr;
2846  if (ifarg(2)) mr = (int)(*getarg(2)); else mr = dc/8;
2847 
2848  // make sure the length of partitions is integer power of 2
2849  int m = 1;
2850  while(m<mr) m*=2;
2851 
2852  int k = int(ceil((double(dc)/m-1.)/2.));
2853  int n = (2*k+1)*m;
2854 
2855  double *data = (double *)calloc(n,(unsigned)sizeof(double));
2856  for (int i=0;i<dc;++i) data[i] = v1->elem(i);
2857 
2858  if (ans->size() < m) ans->resize(m);
2859  nrn_spctrm(data, &ans->elem(0), m, k);
2860 
2861  free((char *)data);
2862 
2863  return ans->temp_objvar();
2864 }
2865 
2866 static Object** v_filter(void* v) {
2867  Vect* v3 = (Vect*)v;
2868  Vect* v1;
2869  Vect *v2;
2870  int iarg = 1;
2871 
2872  // data set
2873  if (hoc_is_object_arg(iarg)) {
2874  v1 = vector_arg(iarg++);
2875  }else{
2876  v1 = v3;
2877  }
2878 
2879  // filter
2880  v2 = vector_arg(iarg);
2881 
2882  // make both data sets equal integer power of 2
2883  int v1n = v1->size();
2884  int v2n = v2->size();
2885  int m = (v1n > v2n) ? v1n : v2n;
2886  int n = 1;
2887  while(n < m) n*=2;
2888 
2889  double *data = (double *)calloc(n,(unsigned)sizeof(double));
2890  int i;
2891  for (i=0;i<v1n;++i) data[i] = v1->elem(i);
2892 
2893  double *filter = (double *)calloc(n,(unsigned)sizeof(double));
2894  for (i=0;i<v2n;i++) filter[i] = v2->elem(i);
2895 
2896  double *ans = (double *)calloc(2*n,(unsigned)sizeof(double));
2897 
2898  nrngsl_realft(filter,n,1);
2899 
2900  nrn_convlv(data,n,filter,v2n,1,ans);
2901 
2902  if (v3->size() != n) v3->resize(n);
2903  for (i=0;i<n;++i) v3->elem(i)=ans[i];
2904 
2905  free((char *)data);
2906  free((char *)filter);
2907  free((char *)ans);
2908 
2909  return v3->temp_objvar();
2910 }
2911 
2912 
2913 static Object** v_fft(void* v) {
2914  Vect* v3 = (Vect*)v;
2915  Vect* v1;
2916  int iarg = 1;
2917 
2918  // data set
2919  if (hoc_is_object_arg(iarg)) {
2920  v1 = vector_arg(iarg++);
2921  }else{
2922  v1 = v3;
2923  }
2924 
2925  // inverse = -1, regular = 1
2926 
2927  int inv = 1;
2928  if (ifarg(iarg)) inv = int(chkarg(iarg,-1,1));
2929 
2930  // make data set integer power of 2
2931  int v1n = v1->size();
2932  int n = 1;
2933  while(n < v1n) n*=2;
2934 
2935  double *data = (double *)calloc(n,(unsigned)sizeof(double));
2936  int i;
2937  for (i=0;i<v1n;++i) data[i] = v1->elem(i);
2938  if (v3->size() != n) v3->resize(n);
2939 
2940  if (inv == -1) {
2941  nrn_nrc2gsl(data, &v3->elem(0), n);
2942  nrngsl_realft(&v3->elem(0), n, -1);
2943  }else{
2944  nrngsl_realft(data, n, 1);
2945  nrn_gsl2nrc(data, &v3->elem(0), n);
2946  }
2947  free((char *)data);
2948 
2949  return v3->temp_objvar();
2950 }
2951 
2952 static Object** v_spikebin(void* v) {
2953  Vect* ans = (Vect*)v;
2954 
2955  // data set
2956  Vect* v1 = vector_arg(1);
2957 
2958  double thresh = *getarg(2);
2959 
2960  int bin = 1;
2961  if (ifarg(3)) bin = int(chkarg(3,0,1e6));
2962 
2963  int n = v1->size()/bin;
2964  if (ans->size() != n) ans->resize(n);
2965  std::fill(ans->begin(), ans->end(), 0.);
2966 
2967  int firing = 0;
2968  int k;
2969 
2970  for (int i=0; i<n;i++) {
2971  for (int j=0; j<bin;j++) {
2972  k = i*bin+j;
2973  if (v1->elem(k) >= thresh && !firing) {
2974  firing = 1;
2975  ans->elem(i)=1;
2976  } else if (firing && v1->elem(k) < thresh) {
2977  firing = 0;
2978  }
2979  }
2980  }
2981 
2982  return ans->temp_objvar();
2983 }
2984 
2985 static Object** v_rotate(void* v)
2986 {
2987  Vect* a = (Vect*)v;
2988 
2989  int wrap = 1;
2990  int rev = 0;
2991 
2992  int n = a->size();
2993  int r = int(*getarg(1));
2994  if (ifarg(2)) wrap = 0;
2995 
2996  if (r>n) r = r%n;
2997  if (r<0) { r = n-(Math::abs(r)%n); rev = 1; }
2998 
2999  if (r > 0) {
3000  int rc = n-r;
3001 
3002  double *hold = (double *)calloc(n,(unsigned)sizeof(double));
3003 
3004  int i;
3005  if (wrap) {
3006  for (i=0;i<rc;i++) hold[i+r] = a->elem(i);
3007  for (i=0;i<r;i++) hold[i] = a->elem(i+rc);
3008  } else {
3009  if (rev==0) {
3010  for (i=0;i<rc;i++) hold[i+r] = a->elem(i);
3011  for (i=0;i<r;i++) hold[i] = 0.;
3012  } else {
3013  for (i=0;i<r;i++) hold[i] = a->elem(i+rc);
3014  for (i=r;i<n;i++) hold[i] = 0.;
3015  }
3016  }
3017  for (i=0;i<n;i++) a->elem(i) = hold[i];
3018 
3019 
3020  free((char *)hold);
3021  }
3022 
3023  return a->temp_objvar();
3024 }
3025 
3026 static Object** v_deriv(void* v)
3027 {
3028  Vect* ans = (Vect*)v;
3029  Vect* v1;
3030  int flag, iarg = 1;
3031 
3032  // data set
3033  iarg = possible_srcvec(v1, ans, flag);
3034 
3035  int n = v1->size();
3036  if (n < 2) {
3037 hoc_execerror("Can't take derivative of Vector with less than two points", 0);
3038  }
3039  if (ans->size() != n) ans->resize(n);
3040 
3041  double dx = 1;
3042  if(ifarg(iarg)) dx = *getarg(iarg++);
3043 
3044  int sym = 2;
3045  if(ifarg(iarg)) sym = int(chkarg(iarg++,1,2));
3046 
3047 
3048  if (sym == 2) {
3049  // use symmetrical form -- see NumRcpC p. 187.
3050  // at boundaries use single-sided form
3051 
3052  ans->elem(0) = (v1->elem(1) - v1->elem(0))/dx;
3053  ans->elem(n-1) = (v1->elem(n-1) - v1->elem(n-2))/dx;
3054  dx = dx*2;
3055  for (int i=1;i<n-1;i++) {
3056  ans->elem(i) = (v1->elem(i+1) - v1->elem(i-1))/dx;
3057  }
3058  } else {
3059  // use single-sided form
3060  ans->resize(n-1);
3061  for (int i=0;i<n-1;i++) {
3062  ans->elem(i) = (v1->elem(i+1) - v1->elem(i))/dx;
3063  }
3064  }
3065  if (flag) {
3066  delete v1;
3067  }
3068  return ans->temp_objvar();
3069 }
3070 
3071 static Object** v_integral(void* v)
3072 {
3073  Vect* ans = (Vect*)v;
3074  Vect* v1;
3075  int iarg = 1;
3076 
3077  // data set
3078  if (ifarg(iarg) && hoc_is_object_arg(iarg)) {
3079  v1 = vector_arg(iarg++);
3080  }else{
3081  v1 = ans;
3082  }
3083 
3084  int n = v1->size();
3085  if (ans->size() != n) ans->resize(n);
3086 
3087  double dx = 1.;
3088  if(ifarg(iarg)) dx = *getarg(iarg++);
3089 
3090  ans->elem(0) = v1->elem(0);
3091  for (int i=1;i<n;i++) {
3092  ans->elem(i) = ans->elem(i-1) + v1->elem(i) * dx;
3093  }
3094  return ans->temp_objvar();
3095 }
3096 
3097 static double v_trigavg(void* v)
3098 {
3099  Vect* avg = (Vect*)v;
3100 
3101  // continuous data(t)
3102  Vect* data = vector_arg(1);
3103 
3104  // trigger times
3105  Vect* trig = vector_arg(2);
3106 
3107  int n = data->size();
3108  int pre = int(chkarg(3,0,n-1));
3109  int post = int(chkarg(4,0,n-1));
3110  int m = pre+post;
3111  if (avg->size() != m) avg->resize(m);
3112  int l = trig->size();
3113  int trcount = 0;
3114 
3115  std::fill(avg->begin(), avg->end(), 0.);
3116 
3117  for (int i=0;i<l;i++) {
3118  int tr = int(trig->elem(i));
3119 
3120  // throw out events within the window size of the edges
3121  if (tr >= pre && tr < n-post) {
3122  trcount++;
3123  for (int j=-pre;j<post;j++) {
3124  avg->elem(j+pre) += data->elem(tr+j);
3125  }
3126  }
3127  }
3128  std::for_each(avg->begin(), avg->end(),[&](double& d) { d /= trcount; } );
3129 
3130  return trcount;
3131 }
3132 
3133 
3134 static Object** v_medfltr(void* v)
3135 {
3136  Vect* ans = (Vect*)v;
3137  Vect* v1;
3138  int w0, w1, wlen, i, flag, iarg = 1;
3139 
3140  // data set
3141  iarg = possible_srcvec(v1, ans, flag);
3142 
3143  int n = v1->size();
3144  if (ans->size() != n) ans->resize(n);
3145 
3146  int points = 3;
3147  if (ifarg(iarg)) points = int(chkarg(iarg,1,n/2));
3148 
3149  double *res = (double *)calloc(n,(unsigned)sizeof(double));
3150  for (i=0; i<n; i++) {
3151  w0 = (i >= points) ? i-points : 0;
3152  w1 = (i < n-points) ? i+points : n-1;
3153  wlen = w1-w0;
3154 
3155  std::vector<double> window (v1->begin() + w0, v1->begin() + wlen);
3156  std::sort(window.begin(), window.end());
3157  res[i] = window[wlen/2];
3158  }
3159 
3160  if (ans->size() != n) ans->resize(n);
3161  for (i=0;i <n; i++) {
3162  ans->elem(i) = res[i];
3163  }
3164  free(res);
3165  if (flag) {
3166  delete v1;
3167  }
3168  return ans->temp_objvar();
3169 }
3170 
3171 static double v_median(void* v)
3172 {
3173  Vect* ans = (Vect*)v;
3174 
3175  int n = ans->size();
3176  if (n == 0) {
3177  hoc_execerror("Vector", "must have size > 0");
3178  }
3179 
3180  Vect* sorted = new Vect(*ans);
3181  std::sort(sorted->begin(), sorted->end());
3182 
3183  int n2 = n/2;
3184 
3185  double median;
3186  if (2*n2 == n) {
3187  median = (sorted->elem(n2-1) + sorted->elem(n2))/2.;
3188  }else{
3189  median = sorted->elem(n2);
3190  }
3191  delete sorted;
3192 
3193  return median;
3194 }
3195 
3196 static Object** v_sort(void* v)
3197 {
3198  Vect* ans = (Vect*)v;
3199  std::sort(ans->begin(), ans->end());
3200  return ans->temp_objvar();
3201 }
3202 
3203 static Object** v_reverse(void* v)
3204 {
3205  Vect* ans = (Vect*)v;
3206  std::reverse(ans->begin(), ans->end());
3207  return ans->temp_objvar();
3208 }
3209 
3210 
3211 static Object** v_sin(void* v)
3212 {
3213  Vect* ans = (Vect*)v;
3214 
3215  int n = ans->size();
3216  double freq = *getarg(1);
3217  double phase = *getarg(2);
3218  double dx = 1;
3219  if(ifarg(3)) dx = *getarg(3);
3220 
3221  double period = 2*PI/1000*freq*dx;
3222 
3223  for (int i=0; i<n;i++) {
3224  ans->elem(i) = sin(period*i+phase);
3225  }
3226  return ans->temp_objvar();
3227 }
3228 
3229 static Object** v_log(void* v)
3230 {
3231  Vect* ans = (Vect*)v;
3232  Vect* v1;
3233  // data set
3234  if (ifarg(1)) {
3235  v1 = vector_arg(1);
3236  }else{
3237  v1 = ans;
3238  }
3239 
3240  int n = v1->size();
3241  if (ans->size() != n) ans->resize(n);
3242 
3243  for (int i=0; i<n;i++) {
3244  ans->elem(i) = log(v1->elem(i));
3245  }
3246  return ans->temp_objvar();
3247 }
3248 
3249 static Object** v_log10(void* v)
3250 {
3251  Vect* ans = (Vect*)v;
3252  Vect* v1;
3253  // data set
3254  if (ifarg(1)) {
3255  v1 = vector_arg(1);
3256  }else{
3257  v1 = ans;
3258  }
3259 
3260  int n = v1->size();
3261  if (ans->size() != n) ans->resize(n);
3262 
3263  for (int i=0; i<n;i++) {
3264  ans->elem(i) = log10(v1->elem(i));
3265  }
3266  return ans->temp_objvar();
3267 }
3268 
3269 static Object** v_rebin(void* v)
3270 {
3271  Vect* ans = (Vect*)v;
3272  Vect* v1;
3273  int flag, iarg = 1;
3274 
3275  // data set
3276  iarg = possible_srcvec(v1, ans, flag);
3277 
3278  int f = int(*getarg(iarg));
3279  int n = v1->size()/f;
3280  if (ans->size() != n) ans->resize(n);
3281 
3282  for (int i=0; i<n;i++) {
3283  ans->elem(i) = 0.;
3284  for (int j=0; j<f; j++) {
3285  ans->elem(i) += v1->elem(i*f+j);
3286  }
3287  }
3288 
3289  if (flag) {
3290  delete v1;
3291  }
3292  return ans->temp_objvar();
3293 }
3294 
3295 static Object** v_resample(void* v)
3296 {
3297  Vect* ans = (Vect*)v;
3298 
3299  // data set
3300  Vect* v1 = vector_arg(1);
3301 
3302  double f = chkarg(2,0,v1->size()/2);
3303  int n = int(v1->size()*f);
3304 
3305  Vect* temp = new Vect(n);
3306 
3307  for (int i=0; i<n; i++) temp->elem(i) = v1->elem(int(i/f));
3308  ans->vec().swap(temp->vec());
3309 
3310  delete temp;
3311 
3312  return ans->temp_objvar();
3313 }
3314 
3315 static Object** v_psth(void* v)
3316 {
3317  Vect* ans = (Vect*)v;
3318 
3319  // data set
3320  Vect* v1 = vector_arg(1);
3321 
3322  double dt = chkarg(2,0,9e99);
3323  double trials = chkarg(3,0,9e99);
3324  double size = chkarg(4,0,v1->size()/2); int n = int(v1->size());
3325 
3326  Vect* temp = new Vect(n);
3327 
3328  for (int i=0; i<n; i++) {
3329  int fj=0;
3330  int bj=0;
3331  double integral = v1->elem(i);
3332  while (integral < size) {
3333  if (i+fj < n-1) { fj++; integral += v1->elem(i+fj); }
3334  if (i-bj > 0 && integral < size) { bj++; integral += v1->elem(i-bj); }
3335  }
3336  temp->elem(i) = integral/trials*1000./((fj+bj+1)*dt);
3337  }
3338 
3339  ans->vec().swap(temp->vec());
3340 
3341  delete temp;
3342 
3343  return ans->temp_objvar();
3344 }
3345 
3346 static Object** v_inf(void* x)
3347 {
3348  Vect* V = (Vect*)x;
3349 
3350  // data set
3351  Vect* stim = vector_arg(1);
3352  int n = stim->size();
3353 
3354  double dt = chkarg(2,1e-99,9e99);
3355  double gl = *getarg(3);
3356  double el = *getarg(4);
3357  double cm = *getarg(5)/dt;
3358  double th = *getarg(6);
3359  double res = *getarg(7);
3360  double refp = 0;
3361  if (ifarg(8)) refp = *getarg(8);
3362 
3363  if (V->size() != n) V->resize(n);
3364 
3365  double i=0,v,ref=0;
3366 
3367  V->elem(0) = el;
3368 
3369  for (int t=0;t<n-1;t++) {
3370  i = -gl*(V->elem(t)-el) + stim->elem(t);
3371  v = V->elem(t) + i/cm;
3372  if (v >= th && ref <= 0) {
3373  V->elem(t+1) = 0;
3374  t = t + 1;
3375  V->elem(t+1) = res;
3376  ref = refp;
3377  } else {
3378  ref = ref-dt;
3379  V->elem(t+1) = v;
3380  }
3381  }
3382  return V->temp_objvar();
3383 }
3384 
3385 static Object** v_pow(void* v)
3386 {
3387  Vect* ans = (Vect*)v;
3388  Vect* v1;
3389  int iarg = 1;
3390 
3391  // data set
3392  if (hoc_is_object_arg(iarg)) {
3393  v1 = vector_arg(iarg++);
3394  }else{
3395  v1 = ans;
3396  }
3397 
3398  double p = *getarg(iarg);
3399  int n = v1->size();
3400  if (ans->size() != n) ans->resize(n);
3401 
3402  if (p == -1) {
3403  for (int i=0; i<n;i++) {
3404  if (ans->elem(i) == 0) {
3405  hoc_execerror("Vector","Invalid comparator in .where()\n");
3406  } else {
3407  ans->elem(i) = 1/v1->elem(i);
3408  }
3409  }
3410  } else if (p == 0) {
3411  for (int i=0; i<n;i++) {
3412  ans->elem(i) = 1;
3413  }
3414  } else if (p == 0.5) {
3415  for (int i=0; i<n;i++) {
3416  ans->elem(i) = hoc_Sqrt(v1->elem(i));
3417  }
3418  } else if (p == 1) {
3419  for (int i=0; i<n;i++) {
3420  ans->elem(i) = v1->elem(i);
3421  }
3422  } else if (p == 2) {
3423  for (int i=0; i<n;i++) {
3424  ans->elem(i) = v1->elem(i)*v1->elem(i);
3425  }
3426  } else {
3427  for (int i=0; i<n;i++) {
3428  ans->elem(i) = pow(v1->elem(i),p);
3429  }
3430  }
3431  return ans->temp_objvar();
3432 }
3433 
3434 static Object** v_sqrt(void* v)
3435 {
3436  Vect* ans = (Vect*)v;
3437  Vect* v1;
3438  // data set
3439  if (ifarg(1)) {
3440  v1 = vector_arg(1);
3441  }else{
3442  v1 = ans;
3443  }
3444 
3445  int n = v1->size();
3446  if (ans->size() != n) ans->resize(n);
3447 
3448  for (int i=0; i<n;i++) {
3449  ans->elem(i) = hoc_Sqrt(v1->elem(i));
3450  }
3451  return ans->temp_objvar();
3452 }
3453 
3454 static Object** v_abs(void* v)
3455 {
3456  Vect* ans = (Vect*)v;
3457  Vect* v1;
3458  // data set
3459  if (ifarg(1)) {
3460  v1 = vector_arg(1);
3461  }else{
3462  v1 = ans;
3463  }
3464 
3465  int n = v1->size();
3466  if (ans->size() != n) ans->resize(n);
3467 
3468  for (int i=0; i<n;i++) {
3469  ans->elem(i) = Math::abs(v1->elem(i));
3470  }
3471  return ans->temp_objvar();
3472 }
3473 
3474 static Object** v_floor(void* v)
3475 {
3476  Vect* ans = (Vect*)v;
3477  Vect* v1;
3478  // data set
3479  if (ifarg(1)) {
3480  v1 = vector_arg(1);
3481  }else{
3482  v1 = ans;
3483  }
3484 
3485  int n = v1->size();
3486  if (ans->size() != n) ans->resize(n);
3487 
3488  for (int i=0; i<n;i++) {
3489  ans->elem(i) = floor(v1->elem(i));
3490  }
3491  return ans->temp_objvar();
3492 }
3493 
3494 static Object** v_tanh(void* v)
3495 {
3496  Vect* ans = (Vect*)v;
3497  Vect* v1;
3498  // data set
3499  if (ifarg(1)) {
3500  v1 = vector_arg(1);
3501  }else{
3502  v1 = ans;
3503  }
3504 
3505  int n = v1->size();
3506  if (ans->size() != n) ans->resize(n);
3507 
3508  for (int i=0; i<n;i++) {
3509  ans->elem(i) = tanh(v1->elem(i));
3510  }
3511  return ans->temp_objvar();
3512 }
3513 
3514 static Object** v_index(void* v)
3515 {
3516  Vect* ans = (Vect*)v;
3517  Vect* data;
3518  Vect* index;
3519  bool del = false;
3520 
3521  if (ifarg(2)) {
3522  data = vector_arg(1);
3523  index = vector_arg(2);
3524  }else{
3525  data = ans;
3526  index = vector_arg(1);
3527  }
3528  if (data == ans) {
3529  data = new Vect(*data);
3530  del = true;
3531  }
3532 
3533  int n = data->size();
3534  int m = index->size();
3535  if (ans->size() != m) ans->resize(m);
3536 
3537  for (int i=0; i<m;i++) {
3538  int j = int(index->elem(i));
3539  if (j >= 0 && j < n) {
3540  ans->elem(i) = data->elem(j);
3541  } else {
3542  ans->elem(i) = 0.;
3543  }
3544  }
3545 
3546  if (del) {
3547  delete data;
3548  }
3549 
3550  return ans->temp_objvar();
3551 }
3552 
3554  if (!nrnpy_vec_from_python_p_) {
3555  hoc_execerror("Python not available", 0);
3556  }
3557  Vect* vec = (*nrnpy_vec_from_python_p_)(v);
3558  return vec->temp_objvar();
3559 }
3560 
3562  if (!nrnpy_vec_to_python_p_) {
3563  hoc_execerror("Python not available", 0);
3564  }
3565  return (*nrnpy_vec_to_python_p_)(v);
3566 }
3567 
3568 Object** v_as_numpy(void* v) {
3570  hoc_execerror("Python not available", 0);
3571  }
3572  Vect* vec = (Vect*)v;
3573  // not a copy, shares the data! So do not change the size while
3574  // the python numpy array is in use.
3575  return (*nrnpy_vec_as_numpy_helper_)(vec->size(), vec->data());
3576 }
3577 
3578 
3579 
3580 
3581 
3583 
3584  "x", v_size, // will be changed below
3585  "size", v_size,
3586  "buffer_size", v_buffer_size,
3587  "get", v_get,
3588  "reduce", v_reduce,
3589  "min", v_min,
3590  "max", v_max,
3591  "min_ind", v_min_ind,
3592  "max_ind", v_max_ind,
3593  "sum", v_sum,
3594  "sumsq", v_sumsq,
3595  "mean", v_mean,
3596  "var", v_var,
3597  "stdev", v_stdev,
3598  "stderr", v_stderr,
3599  "meansqerr", v_meansqerr,
3600  "mag", v_mag,
3601  "contains", v_contains,
3602  "median", v_median,
3603 
3604  "dot", v_dot,
3605  "eq", v_eq,
3606 
3607  "play_remove", v_play_remove,
3608 
3609  "fwrite", v_fwrite,
3610  "fread", v_fread,
3611  "vwrite", v_vwrite,
3612  "vread", v_vread,
3613  "printf", v_printf,
3614  "scanf", v_scanf,
3615  "scantil", v_scantil,
3616 
3617  "fit", v_fit,
3618  "trigavg", v_trigavg,
3619  "indwhere", v_indwhere,
3620 
3621  "scale", v_scale,
3622 
3623  0, 0
3624 };
3625 
3627  "c", v_c,
3628  "cl", v_cl,
3629  "at", v_at,
3630  "ind", v_ind,
3631  "histogram", v_histogram,
3632  "sumgauss", v_sumgauss,
3633 
3634  "resize", v_resize,
3635  "clear", v_clear,
3636  "set", v_set,
3637  "append", v_append,
3638  "copy", v_copy,
3639  "insrt", v_insert,
3640  "remove", v_remove,
3641  "interpolate", v_interpolate,
3642  "from_double", v_from_double,
3643 
3644  "index", v_index,
3645  "apply", v_apply,
3646  "add", v_add,
3647  "sub", v_sub,
3648  "mul", v_mul,
3649  "div", v_div,
3650  "fill", v_fill,
3651  "indgen", v_indgen,
3652  "addrand", v_addrand,
3653  "setrand", v_setrand,
3654  "deriv", v_deriv,
3655  "integral", v_integral,
3656 
3657  "sqrt", v_sqrt,
3658  "abs", v_abs,
3659  "floor", v_floor,
3660  "sin", v_sin,
3661  "pow", v_pow,
3662  "log", v_log,
3663  "log10", v_log10,
3664  "tanh", v_tanh,
3665 
3666  "correl", v_correl,
3667  "convlv", v_convlv,
3668  "spctrm", v_spctrm,
3669  "filter", v_filter,
3670  "fft", v_fft,
3671  "rotate", v_rotate,
3672  "smhist", v_smhist,
3673  "hist", v_hist,
3674  "spikebin", v_spikebin,
3675  "rebin", v_rebin,
3676  "medfltr", v_medfltr,
3677  "sort", v_sort,
3678  "sortindex", v_sortindex,
3679  "reverse", v_reverse,
3680  "resample", v_resample,
3681  "psth", v_psth,
3682  "inf", v_inf,
3683 
3684  "index", v_index,
3685  "indvwhere", v_indvwhere,
3686 
3687  "where", v_where,
3688 
3689  "plot", v_plot,
3690  "line", v_line,
3691  "mark", v_mark,
3692  "ploterr", v_ploterr,
3693 
3694  "record", v_record,
3695  "play", v_play,
3696 
3697  "from_python", v_from_python,
3698  "to_python", v_to_python,
3699  "as_numpy", v_as_numpy,
3700 
3701  0,0
3702 };
3703 
3705  "label", v_label,
3706 
3707  0,0
3708 };
3709 
3710 extern int hoc_araypt(Symbol*, int);
3711 
3713  Vect* vp = (Vect*)o->u.this_pointer;
3714  return vp->size();
3715 }
3716 
3717 double* ivoc_vector_ptr(Object* o, int index) {
3718  check_obj_type(o, "Vector");
3719  Vect* vp = (Vect*)o->u.this_pointer;
3720  return vp->data() + index;
3721 }
3722 
3723 static void steer_x(void* v) {
3724  Vect* vp = (Vect*)v;
3725  int index;
3726  Symbol* s = hoc_spop();
3727  // if you don't want to test then you could get the index off the stack
3728  s->arayinfo->sub[0] = vp->size();
3729  index = hoc_araypt(s, SYMBOL);
3730  hoc_pushpx(vp->data() + index);
3731 }
3732 
3733 void Vector_reg() {
3734  class2oc("Vector", v_cons, v_destruct, v_members, NULL, v_retobj_members, v_retstr_members);
3735  svec_ = hoc_lookup("Vector");
3736  // now make the x variable an actual double
3737  Symbol* sv = hoc_lookup("Vector");
3738  Symbol* sx = hoc_table_lookup("x", sv->u.ctemplate->symtable);
3739  sx->type = VAR;
3740  sx->arayinfo = new Arrayinfo;
3741  sx->arayinfo->refcount = 1;
3742  sx->arayinfo->a_varn = NULL;
3743  sx->arayinfo->nsub = 1;
3744  sx->arayinfo->sub[0] = 1;
3745  sv->u.ctemplate->steer = steer_x;
3746 #if defined(WIN32) && !defined(USEMATRIX)
3747  load_ocmatrix();
3748 #endif
3749 }
3750 
3751 // hacked version of gsort from ../gnu/d_vec.cpp
3752 // the transformation is that everything that used to be a double* becomes
3753 // an int* and cmp(*arg1, *arg2) becomes cmp(vec[*arg1], vec[*arg2])
3754 // I am not sure what to do about the BYTES_PER_WORD
3755 
3756 // An adaptation of Schmidt's new quicksort
3757 
3758 static inline void SWAP(int* A, int* B)
3759 {
3760  int tmp = *A; *A = *B; *B = tmp;
3761 }
3762 
3763 /* This should be replaced by a standard ANSI macro. */
3764 #define BYTES_PER_WORD 8
3765 #define BYTES_PER_LONG 4
3766 
3767 /* The next 4 #defines implement a very fast in-line stack abstraction. */
3768 
3769 #define STACK_SIZE (BYTES_PER_WORD * BYTES_PER_LONG)
3770 #define PUSH(LOW,HIGH) do {top->lo = LOW;top++->hi = HIGH;} while (0)
3771 #define POP(LOW,HIGH) do {LOW = (--top)->lo;HIGH = top->hi;} while (0)
3772 #define STACK_NOT_EMPTY (stack < top)
3773 
3774 /* Discontinue quicksort algorithm when partition gets below this size.
3775  This particular magic number was chosen to work best on a Sun 4/260. */
3776 #define MAX_THRESH 4
3777 
3778 
3779 /* Order size using quicksort. This implementation incorporates
3780  four optimizations discussed in Sedgewick:
3781 
3782  1. Non-recursive, using an explicit stack of pointer that
3783  store the next array partition to sort. To save time, this
3784  maximum amount of space required to store an array of
3785  MAX_INT is allocated on the stack. Assuming a 32-bit integer,
3786  this needs only 32 * sizeof (stack_node) == 136 bits. Pretty
3787  cheap, actually.
3788 
3789  2. Chose the pivot element using a median-of-three decision tree.
3790  This reduces the probability of selecting a bad pivot value and
3791  eliminates certain extraneous comparisons.
3792 
3793  3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
3794  insertion sort to order the MAX_THRESH items within each partition.
3795  This is a big win, since insertion sort is faster for small, mostly
3796  sorted array segements.
3797 
3798  4. The larger of the two sub-partitions is always pushed onto the
3799  stack first, with the algorithm then concentrating on the
3800  smaller partition. This *guarantees* no more than log (n)
3801  stack size is needed! */
3802 
3803 extern "C" int nrn_mlh_gsort (double* vec, int *base_ptr, int total_elems, doubleComparator cmp)
3804 {
3805 /* Stack node declarations used to store unfulfilled partition obligations. */
3806  struct stack_node { int *lo; int *hi; };
3807  int pivot_buffer;
3808  int max_thresh = MAX_THRESH;
3809 
3810  if (total_elems > MAX_THRESH)
3811  {
3812  int *lo = base_ptr;
3813  int *hi = lo + (total_elems - 1);
3814  int *left_ptr;
3815  int *right_ptr;
3816  stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */
3817  stack_node *top = stack + 1;
3818 
3819  while (STACK_NOT_EMPTY)
3820  {
3821  {
3822  int *pivot = &pivot_buffer;
3823  {
3824  /* Select median value from among LO, MID, and HI. Rearrange
3825  LO and HI so the three values are sorted. This lowers the
3826  probability of picking a pathological pivot value and
3827  skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
3828 
3829  int *mid = lo + ((hi - lo) >> 1);
3830 
3831  if ( cmp(vec[*mid], vec[*lo]) < 0)
3832  SWAP (mid, lo);
3833  if ( cmp(vec[*hi], vec[*mid]) < 0)
3834  {
3835  SWAP (mid, hi);
3836  if ( cmp(vec[*mid], vec[*lo]) < 0)
3837  SWAP (mid, lo);
3838  }
3839  *pivot = *mid;
3840  pivot = &pivot_buffer;
3841  }
3842  left_ptr = lo + 1;
3843  right_ptr = hi - 1;
3844 
3845  /* Here's the famous ``collapse the walls'' section of quicksort.
3846  Gotta like those tight inner loops! They are the main reason
3847  that this algorithm runs much faster than others. */
3848  do
3849  {
3850  while ( cmp(vec[*left_ptr], vec[*pivot]) < 0)
3851  left_ptr += 1;
3852 
3853  while ( cmp(vec[*pivot], vec[*right_ptr]) < 0)
3854  right_ptr -= 1;
3855 
3856  if (left_ptr < right_ptr)
3857  {
3858  SWAP (left_ptr, right_ptr);
3859  left_ptr += 1;
3860  right_ptr -= 1;
3861  }
3862  else if (left_ptr == right_ptr)
3863  {
3864  left_ptr += 1;
3865  right_ptr -= 1;
3866  break;
3867  }
3868  }
3869  while (left_ptr <= right_ptr);
3870 
3871  }
3872 
3873  /* Set up pointers for next iteration. First determine whether
3874  left and right partitions are below the threshold size. If so,
3875  ignore one or both. Otherwise, push the larger partition's
3876  bounds on the stack and continue sorting the smaller one. */
3877 
3878  if ((right_ptr - lo) <= max_thresh)
3879  {
3880  if ((hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */
3881  POP (lo, hi);
3882  else /* Ignore small left partition. */
3883  lo = left_ptr;
3884  }
3885  else if ((hi - left_ptr) <= max_thresh) /* Ignore small right partition. */
3886  hi = right_ptr;
3887  else if ((right_ptr - lo) > (hi - left_ptr)) /* Push larger left partition indices. */
3888  {
3889  PUSH (lo, right_ptr);
3890  lo = left_ptr;
3891  }
3892  else /* Push larger right partition indices. */
3893  {
3894  PUSH (left_ptr, hi);
3895  hi = right_ptr;
3896  }
3897  }
3898  }
3899 
3900  /* Once the BASE_PTR array is partially sorted by quicksort the rest
3901  is completely sorted using insertion sort, since this is efficient
3902  for partitions below MAX_THRESH size. BASE_PTR points to the beginning
3903  of the array to sort, and END_PTR points at the very last element in
3904  the array (*not* one beyond it!). */
3905 
3906 
3907  {
3908  int *end_ptr = base_ptr + 1 * (total_elems - 1);
3909  int *run_ptr;
3910  int *tmp_ptr = base_ptr;
3911  int *thresh = (end_ptr < (base_ptr + max_thresh))?
3912  end_ptr : (base_ptr + max_thresh);
3913 
3914  /* Find smallest element in first threshold and place it at the
3915  array's beginning. This is the smallest array element,
3916  and the operation speeds up insertion sort's inner loop. */
3917 
3918  for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr += 1)
3919  if ( cmp(vec[*run_ptr], vec[*tmp_ptr]) < 0)
3920  tmp_ptr = run_ptr;
3921 
3922  if (tmp_ptr != base_ptr)
3923  SWAP (tmp_ptr, base_ptr);
3924 
3925  /* Insertion sort, running from left-hand-side up to `right-hand-side.'
3926  Pretty much straight out of the original GNU qsort routine. */
3927 
3928  for (run_ptr = base_ptr + 1; (tmp_ptr = run_ptr += 1) <= end_ptr; )
3929  {
3930 
3931  while ( cmp(vec[*run_ptr], vec[*(tmp_ptr -= 1)]) < 0)
3932  ;
3933 
3934  if ((tmp_ptr += 1) != run_ptr)
3935  {
3936  int *trav;
3937 
3938  for (trav = run_ptr + 1; --trav >= run_ptr;)
3939  {
3940  int c = *trav;
3941  int *hi, *lo;
3942 
3943  for (hi = lo = trav; (lo -= 1) >= tmp_ptr; hi = lo)
3944  *hi = *lo;
3945  *hi = c;
3946  }
3947  }
3948 
3949  }
3950  }
3951  return 1;
3952 }
step
Definition: extdef.h:3
static Object ** v_correl(void *v)
Definition: ivocvect.cpp:2744
struct DLL * dll_load(char *filename)
Definition: dll.cpp:330
static Object ** v_tanh(void *v)
Definition: ivocvect.cpp:3494
o
Definition: seclist.cpp:180
static Object ** v_floor(void *v)
Definition: ivocvect.cpp:3474
static Object ** v_at(void *v)
Definition: ivocvect.cpp:1485
char * label_
Definition: ivocvect.h:87
static Object ** v_interpolate(void *v)
Definition: ivocvect.cpp:1550
Definition: hocdec.h:84
static Object ** v_log(void *v)
Definition: ivocvect.cpp:3229
static Object ** v_plot(void *v)
Definition: ivocvect.cpp:888
#define Printf
Definition: model.h:252
void flush()
double max(double a, double b)
Definition: geometry3d.cpp:22
virtual Glyph * component(GlyphIndex) const
#define B(i)
Definition: multisplit.cpp:62
struct Arrayinfo Arrayinfo
short type
Definition: cabvars.h:10
int hoc_is_str_arg(int narg)
Definition: code.cpp:741
Vect * vector_new1(int n)
Definition: ivocvect.cpp:264
static void steer_x(void *v)
Definition: ivocvect.cpp:3723
static Object ** v_hist(void *v)
Definition: ivocvect.cpp:1111
double points
static double v_mag(void *v1)
Definition: ivocvect.cpp:2227
#define Vect
Definition: ivocvect.h:14
#define dc
static realtype retval
short type
Definition: model.h:58
Object ** v_from_python(void *v)
Definition: ivocvect.cpp:3553
#define EPSILON
Definition: ivocvect.cpp:147
tanh
Definition: extdef.h:3
static Object ** v_where(void *v)
Definition: ivocvect.cpp:1609
static double v_var(void *v)
Definition: ivocvect.cpp:2130
#define STACK_NOT_EMPTY
Definition: ivocvect.cpp:3772
IvocVect(Object *obj=NULL)
Definition: ivocvect.cpp:164
int nsub
Definition: hocdec.h:70
void nrn_spctrm(double *data, double *psd, int setsize, int numsegpairs)
Definition: fourier.cpp:146
int hoc_argtype(int narg)
Definition: code.cpp:727
#define ind(mm, x)
Definition: isaac64.cpp:18
virtual void append(Glyph *)
#define min(a, b)
Definition: matrix.h:157
static double v_indwhere(void *v)
Definition: ivocvect.cpp:1701
#define g
Definition: passive0.cpp:23
size_t size() const
Definition: ivocvect.h:43
int hoc_is_double_arg(int narg)
Definition: code.cpp:733
static double v_scantil(void *v)
Definition: ivocvect.cpp:818
static void SWAP(int *A, int *B)
Definition: ivocvect.cpp:3758
static Object ** v_resize(void *v)
Definition: ivocvect.cpp:1297
#define Glyph
Definition: _defines.h:132
ceil
Definition: extdef.h:3
Symbol * hoc_lookup(const char *)
Symlist * symtable
Definition: hocdec.h:196
static bool equal(float x, float y, float e)
Definition: math.h:108
void * this_pointer
Definition: hocdec.h:231
void nrn_gsl2nrc(double *x, double *y, unsigned long n)
Definition: fourier.cpp:55
size_t p
log
Definition: extdef.h:3
#define POP(LOW, HIGH)
Definition: ivocvect.cpp:3771
static Object ** v_append(void *v)
Definition: ivocvect.cpp:1321
static Object ** v_psth(void *v)
Definition: ivocvect.cpp:3315
Vect * vector_new0()
Definition: ivocvect.cpp:263
static double v_eq(void *v1)
Definition: ivocvect.cpp:2339
static double simplex(double *p, int n, Vect *x, Vect *y, char *fcn)
Definition: ivocvect.cpp:2505
double hoc_Log10(double x)
static Object ** v_sqrt(void *v)
Definition: ivocvect.cpp:3434
static Object ** v_record(void *v)
Definition: ivocvect.cpp:872
static const char * nullstr
Definition: ivocvect.cpp:188
check_obj_type(o, "SectionList")
static double v_median(void *v)
Definition: ivocvect.cpp:3171
static Object ** v_cl(void *v)
Definition: ivocvect.cpp:1544
nd
Definition: treeset.cpp:893
GLabel * label(float x, float y, const char *s, int fixtype, float scale, float x_align, float y_align, const Color *)
double hoc_epsilon
Definition: hoc_init.cpp:260
static int narg()
Definition: ivocvect.cpp:135
void nrngsl_realft(double *data, unsigned long n, int direction)
Definition: fourier.cpp:41
Object * hoc_thisobject
Definition: hoc_oop.cpp:132
#define v
Definition: md1redef.h:4
static double v_contains(void *v)
Definition: ivocvect.cpp:1392
static double v_stdev(void *v)
Definition: ivocvect.cpp:2149
static Symbol * svec_
Definition: ivocvect.cpp:258
static Object ** v_reverse(void *v)
Definition: ivocvect.cpp:3203
static int possible_destvec(int arg, Vect *&dest)
Definition: ivocvect.cpp:357
static double v_dot(void *v1)
Definition: ivocvect.cpp:2220
auto end() -> std::vector< double >::iterator
Definition: ivocvect.h:69
#define SYMBOL
Definition: model.h:102
#define BinaryMode(ocfile)
Definition: ocfile.h:48
static int abs(int)
Definition: math.cpp:43
static void v_destruct(void *v)
Definition: ivocvect.cpp:254
Object * obj_
Definition: ivocvect.h:86
static philox4x32_key_t k
Definition: nrnran123.cpp:11
static double v_fit(void *v)
Definition: ivocvect.cpp:2655
sin
Definition: extdef.h:3
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
static Object ** v_rebin(void *v)
Definition: ivocvect.cpp:3269
gauss
Definition: extdef.h:3
int nrn_mlh_gsort(double *vec, int *base_ptr, int total_elems, doubleComparator cmp)
Definition: ivocvect.cpp:3803
ColorPalette * colors
#define SIMPLEX_ALPHA
Definition: ivocvect.cpp:2398
static Object ** v_indvwhere(void *v)
Definition: ivocvect.cpp:1786
#define SIMPLEX_BETA
Definition: ivocvect.cpp:2399
static Object ** v_abs(void *v)
Definition: ivocvect.cpp:3454
static Object ** v_resample(void *v)
Definition: ivocvect.cpp:3295
static Object ** v_index(void *v)
Definition: ivocvect.cpp:3514
virtual GlyphIndex glyph_index(const Glyph *)
#define e
Definition: passive0.cpp:24
Symbol * hoc_install(const char *, int, double, Symlist **)
#define gargstr
Definition: hocdec.h:14
int is_vector_arg(int i)
Definition: ivocvect.cpp:340
double hoc_Exp(double)
Definition: math.cpp:44
int refcount
Definition: hocdec.h:71
#define TRY_GUI_REDIRECT_METHOD_ACTUAL_OBJ(name, sym, v)
Definition: gui-redirect.h:33
Object ** vector_pobj(Vect *v)
Definition: ivocvect.cpp:272
return status
#define stack
Definition: code.cpp:128
static double eval(double *p, int n, Vect *x, Vect *y, char *fcn)
Definition: ivocvect.cpp:2415
void start()
Definition: hel2mos.cpp:205
double * hoc_pgetarg(int narg)
Definition: code.cpp:1604
static double eval_error(double *p, int n, Vect *x, Vect *y, char *fcn)
Definition: ivocvect.cpp:2491
Definition: graph.h:48
static double v_printf(void *v)
Definition: ivocvect.cpp:708
static Object ** v_fill(void *v)
Definition: ivocvect.cpp:1876
double dt
Definition: init.cpp:123
int hoc_return_type_code
Definition: code.cpp:41
double hoc_call_func(Symbol *s, int narg)
Definition: code.cpp:1445
void(* steer)(void *)
Definition: hocdec.h:208
void brush(const Brush *)
int ivoc_vector_size(Object *o)
Definition: ivocvect.cpp:3712
Vect * vector_new2(Vect *v)
Definition: ivocvect.cpp:265
#define MAX_FIT_PARAMS
Definition: ivocvect.cpp:141
static Object ** v_copy(void *v)
Definition: ivocvect.cpp:1403
void vector_delete(Vect *v)
Definition: ivocvect.cpp:266
static Object ** v_sub(void *v1)
Definition: ivocvect.cpp:2263
static Object ** v_div(void *v1)
Definition: ivocvect.cpp:2298
void nrn_exit(int)
Definition: hoc.cpp:219
Object ** hoc_temp_objvar(Symbol *symtemp, void *v)
Definition: hoc_oop.cpp:503
#define SIMPLEX_DELTA
Definition: ivocvect.cpp:2401
static double v_sumsq(void *v)
Definition: ivocvect.cpp:2096
static double v_trigavg(void *v)
Definition: ivocvect.cpp:3097
Vect * vector_new(int n, Object *o)
Definition: ivocvect.cpp:262
static Frame * fp
Definition: code.cpp:154
Object ** v_to_python(void *v)
Definition: ivocvect.cpp:3561
void install_vector_method(const char *name, Pfrd_vp)
Definition: ivocvect.cpp:314
double(* Pfrd)(void)
Definition: hocdec.h:41
std::vector< double > & vec()
Definition: ivocvect.h:35
Symlist * hoc_top_level_symlist
Definition: symbol.cpp:41
int sub[1]
Definition: hocdec.h:72
log10
Definition: extdef.h:3
static double ref(void *v)
Definition: ocbox.cpp:377
int const size_t const size_t n
Definition: nrngsl.h:12
#define color
Definition: rbtqueue.cpp:50
int(* Pfri)(void)
Definition: hocdec.h:39
#define STACK_SIZE
Definition: ivocvect.cpp:3769
Symbol * hoc_spop(void)
static void same_err(const char *s, Vect *x, Vect *y)
Definition: ivocvect.cpp:201
_CONST char * s
Definition: system.cpp:74
int cmpfcn(double a, double b)
Definition: ivocvect.cpp:150
static double splx_evl_
Definition: ivocvect.cpp:2410
double cm
static Object ** v_medfltr(void *v)
Definition: ivocvect.cpp:3134
static Object ** v_set(void *v)
Definition: ivocvect.cpp:1314
void line(Coord x, Coord y)
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
static int possible_srcvec(Vect *&src, Vect *dest, int &flag)
Definition: ivocvect.cpp:1597
double(* nrnpy_object_to_double_)(Object *)
Definition: xmenu.cpp:14
static int indx
Definition: deriv.cpp:240
static Object ** v_log10(void *v)
Definition: ivocvect.cpp:3249
int val
Definition: dll.cpp:167
static Object ** v_ploterr(void *v)
Definition: ivocvect.cpp:944
double hoc_Log(double x)
Arrayinfo * arayinfo
Definition: hocdec.h:158
#define FWrite(arg1, arg2, arg3, arg4)
Definition: ivocvect.cpp:66
#define printf
Definition: mwprefix.h:26
void Vector_reg()
Definition: ivocvect.cpp:3733
double(* Pfrd_vp)(void *)
Definition: hocdec.h:47
static void * v_cons(Object *o)
Definition: ivocvect.cpp:232
int
Definition: nrnmusic.cpp:71
virtual void save(std::ostream &, Coord, Coord)
#define STRING
Definition: bbslsrv.cpp:9
double x
Definition: ivocvect.cpp:1505
#define xc
Definition: extcelln.cpp:83
double hoc_scan(FILE *)
Definition: fileio.cpp:363
#define PUSH(LOW, HIGH)
Definition: ivocvect.cpp:3770
static double v_min(void *v)
Definition: ivocvect.cpp:2017
static Object ** v_addrand(void *v)
Definition: ivocvect.cpp:1926
#define ENDGUI
Definition: hocdec.h:352
#define GlyphIndex
Definition: _defines.h:23
static void del(int *a)
Definition: bgpdmasetup.cpp:97
#define TWO_BYTE_HIGH
Definition: ivocvect.cpp:143
static Object ** v_insert(void *v)
Definition: ivocvect.cpp:1338
void vector_set_label(Vect *v, char *s)
Definition: ivocvect.cpp:274
void hoc_execerror(const char *, const char *)
Definition: hoc.cpp:741
static int renew_
Definition: ivocvect.cpp:2411
static double v_play_remove(void *v)
Definition: ivocvect.cpp:367
static double v_vwrite(void *v)
Definition: ivocvect.cpp:475
static double v_mean(void *v)
Definition: ivocvect.cpp:2109
#define BYTESWAP(_X__, _TYPE__)
Definition: ivocvect.cpp:99
static Object ** v_apply(void *v)
Definition: ivocvect.cpp:1964
#define SIMPLEX_INORM
Definition: ivocvect.cpp:2390
errno
Definition: system.cpp:98
void nrn_vecsim_remove(void *)
Definition: datapath.cpp:19
Proc * u_proc
Definition: hocdec.h:144
const Brush * brush(int) const
Inst defn
Definition: hocdec.h:76
pow
Definition: extdef.h:3
const char * neuron_home
Definition: hoc_init.cpp:268
static Member_ret_obj_func v_retobj_members[]
Definition: ivocvect.cpp:3626
size_t j
static double v_scale(void *v1)
Definition: ivocvect.cpp:2315
fprintf(stderr, "Don't know the location of params at %p\, pp)
Definition: model.h:57
void nrn_convlv(double *data, unsigned long n, double *respns, unsigned long m, int isign, double *ans)
Definition: fourier.cpp:81
static Object ** v_mul(void *v1)
Definition: ivocvect.cpp:2280
char * name
Definition: init.cpp:16
int(* doubleComparator)(double, double)
Definition: ivocvect.cpp:151
static Object ** v_pow(void *v)
Definition: ivocvect.cpp:3385
std::vector< double > vec_
Definition: ivocvect.h:88
BrushPalette * brushes
static int sort_index_cmp(const void *a, const void *b)
Definition: ivocvect.cpp:1507
static Object ** v_spikebin(void *v)
Definition: ivocvect.cpp:2952
void * dll_lookup(struct DLL *Pdll, char *name)
Definition: dll.cpp:733
void color(const Color *)
static double v_max(void *v)
Definition: ivocvect.cpp:2050
#define ONE_BYTE_HALF
Definition: ivocvect.cpp:145
void nrn_nrc2gsl(double *x, double *y, unsigned long n)
Definition: fourier.cpp:66
static const char ** v_label(void *v)
Definition: ivocvect.cpp:190
static char * format
Definition: matrixio.c:386
static double v_get(void *v)
Definition: ivocvect.cpp:1309
double hoc_Sqrt(double x)
static double v_size(void *v)
Definition: ivocvect.cpp:1273
IvocVect *(* nrnpy_vec_from_python_p_)(void *)
Definition: ivocvect.cpp:123
static double v_sum(void *v)
Definition: ivocvect.cpp:2083
double(* func)(double)
Definition: hoc_init.cpp:111
static uint32_t value
Definition: scoprand.cpp:26
int ifarg(int)
Definition: code.cpp:1562
void vector_resize(Vect *v, int n)
Definition: ivocvect.cpp:269
static double dmaxint_
As all parameters are passed from hoc as double, we need to calculate max integer that can fit into d...
Definition: ivocvect.cpp:89
static Object ** v_inf(void *x)
Definition: ivocvect.cpp:3346
static Object ** v_filter(void *v)
Definition: ivocvect.cpp:2866
static Object ** v_sortindex(void *v)
Definition: ivocvect.cpp:1515
void hoc_pushx(double)
char * vector_get_label(Vect *v)
Definition: ivocvect.cpp:273
static Object ** v_integral(void *v)
Definition: ivocvect.cpp:3071
static double v_vread(void *v)
Definition: ivocvect.cpp:597
static Object ** v_deriv(void *v)
Definition: ivocvect.cpp:3026
Object ** temp_objvar()
Definition: ivocvect.cpp:301
#define MUTCONSTRUCT(mkmut)
Definition: nrnmutdec.h:30
Definition: random1.h:9
#define PUBLIC_TYPE
static Object ** v_rotate(void *v)
Definition: ivocvect.cpp:2985
int vector_instance_px(void *, double **)
Definition: ivocvect.cpp:326
Vect * vector_arg(int i)
Definition: ivocvect.cpp:332
#define SIMPLEX_GAMMA
Definition: ivocvect.cpp:2400
int vector_capacity(Vect *v)
Definition: ivocvect.cpp:268
short cpublic
Note: public is a reserved keyword.
Definition: hocdec.h:125
Pfrd pfd
Definition: hocdec.h:53
int vector_buffer_size(Vect *v)
Definition: ivocvect.cpp:267
sqrt
Definition: extdef.h:3
#define BYTEHEADER
Definition: ivocvect.cpp:98
Object **(* nrnpy_vec_to_python_p_)(void *)
Definition: ivocvect.cpp:124
#define FUNCTION(a, b)
Definition: nrngsl.h:6
static Object ** v_clear(void *v)
Definition: ivocvect.cpp:1303
#define ONE_BYTE_HIGH
Definition: ivocvect.cpp:144
void mark(Coord x, Coord y, char style='+', float size=12, const Color *=NULL, const Brush *=NULL)
void vector_append(Vect *v, double x)
Definition: ivocvect.cpp:275
static double v_fread(void *v)
Definition: ivocvect.cpp:398
static Object ** v_add(void *v1)
Definition: ivocvect.cpp:2245
Definition: hocdec.h:226
HocStruct cTemplate * ctemplate
Definition: hocdec.h:151
static Object ** v_sort(void *v)
Definition: ivocvect.cpp:3196
static double v_min_ind(void *v)
Definition: ivocvect.cpp:2033
#define getarg
Definition: hocdec.h:15
virtual void remove(GlyphIndex)
static Object ** v_spctrm(void *v)
Definition: ivocvect.cpp:2834
Symbol * hoc_table_lookup(const char *, Symlist *)
Definition: symbol.cpp:60
static double v_buffer_size(void *v)
Definition: ivocvect.cpp:1279
Random * rand
Definition: random1.h:14
void add(float, double *)
static Object ** v_sin(void *v)
Definition: ivocvect.cpp:3211
static Object ** v_mark(void *v)
Definition: ivocvect.cpp:1036
static Object ** v_smhist(void *v)
Definition: ivocvect.cpp:1177
#define i
Definition: md1redef.h:12
#define PI
Definition: ivocvect.cpp:59
#define MUTDESTRUCT
Definition: nrnmutdec.h:31
#define id
Definition: md1redef.h:33
#define A(i)
Definition: multisplit.cpp:61
#define c
double * vector_vec(Vect *v)
Definition: ivocvect.cpp:271
static Member_func v_members[]
Definition: ivocvect.cpp:3582
Object **(* nrnpy_vec_as_numpy_helper_)(int, double *)
Definition: ivocvect.cpp:125
static Object ** v_remove(void *v)
Definition: ivocvect.cpp:1375
#define arg
Definition: redef.h:28
Definition: graph.h:329
floor
Definition: extdef.h:3
char buf[512]
Definition: init.cpp:13
Definition: ocfile.h:9
void brush(int)
GLabel * label() const
Definition: graph.h:233
static Member_ret_str_func v_retstr_members[]
Definition: ivocvect.cpp:3704
void hoc_pushpx(double *d)
Definition: code.cpp:702
#define MAX_THRESH
Definition: ivocvect.cpp:3776
#define add
Definition: redef.h:24
int hoc_is_object_arg(int narg)
Definition: code.cpp:745
#define FRead(arg1, arg2, arg3, arg4)
Definition: ivocvect.cpp:67
static Object ** v_setrand(void *v)
Definition: ivocvect.cpp:1943
void begin_line(const char *s=NULL)
static Object ** v_play(void *v)
Definition: ivocvect.cpp:881
void color(int)
Object ** vector_temp_objvar(Vect *v)
Definition: ivocvect.cpp:270
double hoc_call_objfunc(Symbol *s, int narg, Object *ob)
Definition: hoc_oop.cpp:390
static Object ** v_histogram(void *v)
Definition: ivocvect.cpp:1084
union Symbol::@18 u
static double v_scanf(void *v)
Definition: ivocvect.cpp:755
double stdDev(InputIterator begin, InputIterator end)
Definition: ivocvect.h:108
static double v_reduce(void *v)
Definition: ivocvect.cpp:1992
bool eof()
Definition: ocfile.cpp:390
union Object::@54 u
static double v_stderr(void *v)
Definition: ivocvect.cpp:2168
Object ** hoc_temp_objptr(Object *)
Definition: code.cpp:209
#define IFGUI
Definition: hocdec.h:351
double t
Definition: init.cpp:123
void label(const char *)
Definition: ivocvect.cpp:177
#define SIMPLEX_MAXN
Definition: ivocvect.cpp:2389
Object ** v_as_numpy(void *v)
Definition: ivocvect.cpp:3568
int buffer_size()
Definition: ivocvect.cpp:1289
static void post(HCONV hc, const char *name)
Definition: ddeclnt.cpp:166
Object ** hoc_objgetarg(int)
Definition: code.cpp:1568
static Object ** v_from_double(void *v)
Definition: ivocvect.cpp:2233
const Color * color(int) const
unsigned * a_varn
Definition: hocdec.h:69
double var(InputIterator begin, InputIterator end)
Definition: ivocvect.h:93
static Object ** v_c(void *v)
Definition: ivocvect.cpp:1540
static Object ** v_sumgauss(void *v)
Definition: ivocvect.cpp:1139
return NULL
Definition: cabcode.cpp:461
int hoc_araypt(Symbol *, int)
double chkarg(int, double low, double high)
Definition: code2.cpp:608
static Object ** v_fft(void *v)
Definition: ivocvect.cpp:2913
FILE * file()
Definition: ocfile.cpp:383
void notify_freed_val_array(double *, size_t)
Definition: ivoc.cpp:104
double * data()
Definition: ivocvect.h:39
short index
Definition: cabvars.h:11
double call_simplex(double *p, int n, Vect *x, Vect *y, char *fcn, int trial)
Definition: ivocvect.cpp:2633
void nrn_correl(double *x, double *y, unsigned long n, double *z)
Definition: fourier.cpp:122
double * ivoc_vector_ptr(Object *o, int index)
Definition: ivocvect.cpp:3717
static Object ** v_ind(void *v)
Definition: ivocvect.cpp:1253
void nrn_vecsim_add(void *, bool)
Definition: datapath.cpp:18
static double v_max_ind(void *v)
Definition: ivocvect.cpp:2066
static Object ** v_indgen(void *v)
Definition: ivocvect.cpp:1890
static Object ** v_convlv(void *v)
Definition: ivocvect.cpp:2785
int vector_arg_px(int, double **)
Definition: ivocvect.cpp:348
static double v_fwrite(void *v)
Definition: ivocvect.cpp:372
static Object ** v_line(void *v)
Definition: ivocvect.cpp:986
static double v_meansqerr(void *v1)
Definition: ivocvect.cpp:2187