PageRenderTime 85ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 1ms

/src/ivoc/ivocvect.cpp

https://bitbucket.org/nrnhines/nrn
C++ | 3981 lines | 3136 code | 601 blank | 244 comment | 799 complexity | 790bb93b23d5071ac599cc16a9b59d00 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. #include <../../nrnconf.h>
  2. #if defined(__GO32__)
  3. #define HAVE_IV 0
  4. #endif
  5. //#include <string.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <ivstream.h>
  9. #include <math.h>
  10. #include <errno.h>
  11. #include <OS/math.h>
  12. #include "fourier.h"
  13. #if HAVE_IV
  14. #include <InterViews/glyph.h>
  15. #include <InterViews/hit.h>
  16. #include <InterViews/event.h>
  17. #include <InterViews/color.h>
  18. #include <InterViews/brush.h>
  19. #include <InterViews/window.h>
  20. #include <InterViews/printer.h>
  21. #include <InterViews/label.h>
  22. #include <InterViews/font.h>
  23. #include <InterViews/background.h>
  24. #include <InterViews/style.h>
  25. //#include <OS/string.h>
  26. #include <IV-look/kit.h>
  27. #else
  28. #include <InterViews/resource.h>
  29. #include <OS/list.h>
  30. #endif
  31. #if defined(SVR4)
  32. extern "C" {extern void exit(int status);};
  33. #endif
  34. #include "classreg.h"
  35. #if HAVE_IV
  36. #include "apwindow.h"
  37. #include "ivoc.h"
  38. #include "graph.h"
  39. #endif
  40. #ifndef PI
  41. #ifndef M_PI
  42. #define M_PI 3.14159265358979323846
  43. #endif
  44. #define PI M_PI
  45. #endif
  46. #define BrainDamaged 0 //The Sun CC compiler but it doesn't hurt to leave it in
  47. #if BrainDamaged
  48. #define FWrite(arg1,arg2,arg3,arg4) if (fwrite((char*)(arg1),arg2,arg3,arg4) != arg3) { hoc_execerror("fwrite error", 0); }
  49. #define FRead(arg1,arg2,arg3,arg4) if (fread((char*)(arg1),arg2,arg3,arg4) != arg3) { hoc_execerror("fread error", 0); }
  50. #else
  51. #define FWrite(arg1,arg2,arg3,arg4) if (fwrite(arg1,arg2,arg3,arg4) != arg3){}
  52. #define FRead(arg1,arg2,arg3,arg4) if (fread(arg1,arg2,arg3,arg4) != arg3) {}
  53. #endif
  54. static double dmaxint_;
  55. // Definitions allow machine independent write and read
  56. // note that must include BYTEHEADER at head of routine
  57. // The policy is that each machine vwrite binary information in
  58. // without swapping, ie. native endian.
  59. // On reading, the type is checked to decide whether
  60. // byteswapping should be performed
  61. #define BYTEHEADER int _II__; char *_IN__; char _OUT__[16]; int BYTESWAP_FLAG=0;
  62. #define BYTESWAP(_X__,_TYPE__) \
  63. if (BYTESWAP_FLAG == 1) { \
  64. _IN__ = (char *) &(_X__); \
  65. for (_II__=0;_II__<sizeof(_TYPE__);_II__++) { \
  66. _OUT__[_II__] = _IN__[sizeof(_TYPE__)-_II__-1]; } \
  67. (_X__) = *((_TYPE__ *) &_OUT__); \
  68. }
  69. #include "ivocvect.h"
  70. // definition of SampleHistogram from the gnu c++ class library
  71. #include <SmplHist.h>
  72. // definition of random numer generator
  73. #include "random1.h"
  74. #include <Uniform.h>
  75. // definition of comparison functions
  76. #include <d_defs.h>
  77. #if HAVE_IV
  78. #include "utility.h"
  79. #endif
  80. #include "oc2iv.h"
  81. #include "parse.h"
  82. #include "ocfile.h"
  83. extern "C" {
  84. extern Object* hoc_thisobject;
  85. extern Symlist* hoc_top_level_symlist;
  86. extern void nrn_exit(int);
  87. IvocVect* (*nrnpy_vec_from_python_p_)(void*);
  88. Object** (*nrnpy_vec_to_python_p_)(void*);
  89. Object** (*nrnpy_vec_as_numpy_helper_)(int, double*);
  90. };
  91. int cmpfcn(double a, double b) { return ((a) <= (b))? (((a) == (b))? 0 : -1) : 1; }
  92. // math functions with error checking defined in oc/SRC/math.c
  93. extern "C" {
  94. extern double hoc_Log(double x), hoc_Log10(double x), hoc_Exp(double x), hoc_Sqrt(double x);
  95. extern double hoc_scan(FILE*);
  96. }
  97. static int narg() {
  98. int i=0;
  99. while (ifarg(i++));
  100. return i-2;
  101. }
  102. #define MAX_FIT_PARAMS 20
  103. #define TWO_BYTE_HIGH 65535.
  104. #define ONE_BYTE_HIGH 255.
  105. #define ONE_BYTE_HALF 128.
  106. #define EPSILON 1e-9
  107. extern "C" {
  108. extern void notify_freed_val_array(double*, size_t);
  109. extern void install_vector_method(const char* name, Pfrd_vp);
  110. extern int vector_instance_px(void*, double**);
  111. extern int vector_arg_px(int, double**);
  112. extern int nrn_mlh_gsort (double* vec, int *base_ptr, int total_elems, doubleComparator cmp);
  113. };
  114. IvocVect::IvocVect(Object* o) : ParentVect(){obj_ = o; label_ = NULL; MUTCONSTRUCT(0)}
  115. IvocVect::IvocVect(int l, Object* o) : ParentVect(l){obj_ = o; label_ = NULL; MUTCONSTRUCT(0)}
  116. IvocVect::IvocVect(int l, double fill_value, Object* o) : ParentVect(l, fill_value){obj_ = o; label_ = NULL; MUTCONSTRUCT(0)}
  117. IvocVect::IvocVect(IvocVect& v, Object* o) : ParentVect(v) {obj_ = o; label_ = NULL; MUTCONSTRUCT(0)}
  118. IvocVect::~IvocVect(){
  119. MUTDESTRUCT
  120. if (label_) {
  121. delete [] label_;
  122. }
  123. notify_freed_val_array(vec(), capacity());
  124. }
  125. void IvocVect::label(const char* label) {
  126. if (label_) {
  127. delete [] label_;
  128. label_ = NULL;
  129. }
  130. if (label) {
  131. label_ = new char[strlen(label) + 1];
  132. strcpy(label_, label);
  133. }
  134. }
  135. static const char* nullstr = "";
  136. static const char** v_label(void* v) {
  137. Vect* x = (Vect*)v;
  138. if (ifarg(1)) {
  139. x->label(gargstr(1));
  140. }
  141. if (x->label_) {
  142. return (const char**)&x->label_;
  143. }
  144. return &nullstr;
  145. }
  146. static void same_err(const char* s, Vect* x, Vect* y) {
  147. if (x == y) {
  148. hoc_execerror(s, " argument needs to be copied first");
  149. }
  150. }
  151. /* the Vect->at(start, end) function was used in about a dozen places
  152. for the purpose of dealing with a subrange of elements. However that
  153. function clones the subrange and returns a new Vect. This caused a
  154. memory leak and was needlessly inefficient for those functions.
  155. To fix both problems for these specific functions
  156. we use a special vector which does not have
  157. it's own space but merely a pointer and capacity to the right space of
  158. the original vector. The usage is restricted to only once at a time, i.e.
  159. can't use two subvecs at once and never do anything which affects the
  160. memory space.
  161. */
  162. static IvocVect* subvec_; // allocated when registered.
  163. IvocVect* IvocVect::subvec(int start, int end) {
  164. subvec_->len = end - start + 1;
  165. subvec_->s = s + start;
  166. return subvec_;
  167. }
  168. void IvocVect::resize(int newlen) { // all that for this
  169. long oldcap = capacity();
  170. if (newlen > space) {
  171. notify_freed_val_array(vec(), capacity());
  172. }
  173. ParentVect::resize(newlen);
  174. for (;oldcap < newlen; ++oldcap) {
  175. elem(oldcap) = 0.;
  176. }
  177. }
  178. void IvocVect::resize_chunk(int newlen, int extra) {
  179. if (newlen > space) {
  180. long x = newlen + extra;
  181. if (extra == 0) {
  182. x = ListImpl_best_new_count(newlen, sizeof(double));
  183. }
  184. // printf("resize_chunk %d\n", x);
  185. resize(x);
  186. }
  187. resize(newlen);
  188. }
  189. #if HAVE_IV
  190. /*static*/ class GraphMarkItem : public GraphItem {
  191. public:
  192. GraphMarkItem(Glyph* g) : GraphItem(g){}
  193. virtual ~GraphMarkItem(){};
  194. virtual void erase(Scene* s, GlyphIndex i, int type) {
  195. if (type & GraphItem::ERASE_LINE) {
  196. s->remove(i);
  197. }
  198. }
  199. };
  200. #endif
  201. static void* v_cons(Object* o) {
  202. double fill_value = 0.;
  203. int n = 0;
  204. Vect* vec;
  205. if (ifarg(1)) {
  206. if (hoc_is_double_arg(1)) {
  207. n = int(chkarg(1,0,1e10));
  208. if (ifarg(2)) fill_value = *getarg(2);
  209. vec = new Vect(n,fill_value, o);
  210. }else{
  211. if (!nrnpy_vec_from_python_p_) {
  212. hoc_execerror("Python not available", 0);
  213. }
  214. vec = (*nrnpy_vec_from_python_p_)(new Vect(0, 0, o));
  215. }
  216. }else{
  217. vec = new Vect(0, 0, o);
  218. }
  219. return vec;
  220. }
  221. static void v_destruct(void* v) {
  222. delete (Vect*)v;
  223. }
  224. static Symbol* svec_;
  225. // extern "C" vector functions used by ocmatrix.dll
  226. // can also be used in mod files
  227. Vect* vector_new(int n, Object* o){return new Vect(n, o);}
  228. Vect* vector_new0(){return new Vect();}
  229. Vect* vector_new1(int n){return new Vect(n);}
  230. Vect* vector_new2(Vect* v){return new Vect(*v);}
  231. void vector_delete(Vect* v){delete v;}
  232. int vector_buffer_size(Vect* v){return v->buffer_size();}
  233. int vector_capacity(Vect* v){return v->capacity();}
  234. void vector_resize(Vect* v, int n){v->resize(n);}
  235. Object** vector_temp_objvar(Vect* v){return v->temp_objvar();}
  236. double* vector_vec(Vect* v){return v->vec();}
  237. Object** vector_pobj(Vect* v){return &v->obj_;}
  238. char* vector_get_label(Vect* v) { return v->label_; }
  239. void vector_set_label(Vect* v, char* s) { v->label(s); }
  240. void vector_append(Vect* v, double x){
  241. long n = v->capacity();
  242. v->resize_chunk(n+1);
  243. v->elem(n) = x;
  244. }
  245. #ifdef WIN32
  246. #if !defined(USEMATRIX) || USEMATRIX == 0
  247. #include "../windll/dll.h"
  248. extern "C" {extern char* neuron_home;}
  249. void load_ocmatrix() {
  250. struct DLL* dll = NULL;
  251. char buf[256];
  252. sprintf(buf, "%s\\lib\\ocmatrix.dll", neuron_home);
  253. dll = dll_load(buf);
  254. if (dll) {
  255. Pfri mreg = (Pfri)dll_lookup(dll, "_Matrix_reg");
  256. if (mreg) {
  257. (*mreg)();
  258. }
  259. }else{
  260. printf("No Matrix class.\n");
  261. }
  262. }
  263. #endif
  264. #endif
  265. Object** IvocVect::temp_objvar() {
  266. IvocVect* v = (IvocVect*)this;
  267. Object** po;
  268. if (v->obj_) {
  269. po = hoc_temp_objptr(v->obj_);
  270. }else{
  271. po = hoc_temp_objvar(svec_, (void*)v);
  272. obj_ = *po;
  273. }
  274. return po;
  275. }
  276. extern "C" { // bug in cray compiler requires this
  277. void install_vector_method(const char* name, double (*f)(void*)) {
  278. Symbol* s_meth;
  279. if (hoc_table_lookup(name, svec_->u.ctemplate->symtable)) {
  280. hoc_execerror(name, " already a method in the Vector class");
  281. }
  282. s_meth = hoc_install(name, FUNCTION, 0.0, &svec_->u.ctemplate->symtable);
  283. s_meth->u.u_proc->defn.pfd = (Pfrd)f;
  284. #define PUBLIC_TYPE 1
  285. s_meth->cpublic = PUBLIC_TYPE;
  286. }
  287. }
  288. int vector_instance_px(void* v, double** px) {
  289. Vect* x = (Vect*)v;
  290. *px = x->vec();
  291. return x->capacity();
  292. }
  293. Vect* vector_arg(int i) {
  294. Object* ob = *hoc_objgetarg(i);
  295. if (!ob || ob->ctemplate != svec_->u.ctemplate) {
  296. check_obj_type(ob, "Vector");
  297. }
  298. return (Vect*)(ob->u.this_pointer);
  299. }
  300. int is_vector_arg(int i) {
  301. Object* ob = *hoc_objgetarg(i);
  302. if (!ob || ob->ctemplate != svec_->u.ctemplate) {
  303. return 0;
  304. }
  305. return 1;
  306. }
  307. int vector_arg_px(int i, double** px) {
  308. Vect* x = vector_arg(i);
  309. *px = x->vec();
  310. return x->capacity();
  311. }
  312. extern void nrn_vecsim_add(void*, bool);
  313. extern void nrn_vecsim_remove(void*);
  314. static int possible_destvec(int arg, Vect*& dest) {
  315. if (ifarg(arg) && hoc_is_object_arg(arg)) {
  316. dest = vector_arg(arg);
  317. return arg+1;
  318. }else{
  319. dest = new Vect();
  320. return arg;
  321. }
  322. }
  323. static double v_record(void* v) {
  324. nrn_vecsim_add(v, true);
  325. return 1.;
  326. }
  327. static double v_play_remove(void* v) {
  328. nrn_vecsim_remove(v);
  329. return 1.;
  330. }
  331. static double v_play(void* v) {
  332. nrn_vecsim_add(v, false);
  333. return 1.;
  334. }
  335. static double v_fwrite(void* v) {
  336. Vect* vp = (Vect*)v;
  337. void* s;
  338. int x_max = vp->capacity()-1;
  339. int start = 0;
  340. int end = x_max;
  341. if (ifarg(2)) {
  342. start = int(chkarg(2,0,x_max));
  343. end = int(chkarg(3,0,x_max));
  344. }
  345. s = (void*)(&vp->elem(start));
  346. const char* x = (const char*)s;
  347. Object* ob = *hoc_objgetarg(1);
  348. check_obj_type(ob, "File");
  349. OcFile* f = (OcFile*)(ob->u.this_pointer);
  350. FILE* fp = f->file();
  351. if (!fp) {
  352. return 0.;
  353. }
  354. int n = end-start+1;
  355. BinaryMode(f);
  356. return (double)fwrite(x,sizeof(double),n,fp);
  357. }
  358. static double v_fread(void* v) {
  359. Vect* vp = (Vect*)v;
  360. void* s = (void*)(vp->vec());
  361. Object* ob = *hoc_objgetarg(1);
  362. check_obj_type(ob, "File");
  363. OcFile* f = (OcFile*)(ob->u.this_pointer);
  364. if (ifarg(2)) vp->resize(int(chkarg(2,0,1e10)));
  365. int n = vp->capacity();
  366. int type = 4;
  367. if (ifarg(3)) {
  368. type = int(chkarg(3,1,5));
  369. }
  370. FILE* fp = f->file();
  371. if (!fp) {
  372. return 0.;
  373. }
  374. int i;
  375. BinaryMode(f)
  376. if (n > 0) switch (type) {
  377. case 5: // short ints
  378. {
  379. short *xs = (short *)malloc(n * (unsigned)sizeof(short));
  380. FRead(xs,sizeof(short),n,fp);
  381. for (i=0;i<n;++i) {
  382. vp->elem(i) = double(xs[i]);
  383. }
  384. free((char *)xs);
  385. break;
  386. }
  387. case 4: // doubles
  388. FRead(&(vp->elem(0)),sizeof(double),n,fp);
  389. break;
  390. case 3: // floats
  391. {
  392. float *xf = (float *)malloc(n * (unsigned)sizeof(float));
  393. FRead(xf,sizeof(float),n,fp);
  394. for (i=0;i<n;++i) {
  395. vp->elem(i) = double(xf[i]);
  396. }
  397. free((char *)xf);
  398. break;
  399. }
  400. case 2: // unsigned short ints
  401. {
  402. unsigned short *xi = (unsigned short *)malloc(n * (unsigned)sizeof(unsigned short));
  403. FRead(xi,sizeof(unsigned short),n,fp);
  404. for (i=0;i<n;++i) {
  405. vp->elem(i) = double(xi[i]);
  406. }
  407. free((char *)xi);
  408. break;
  409. }
  410. case 1: // char
  411. {
  412. char *xc = (char *)malloc(n * (unsigned)sizeof(char));
  413. FRead(xc,sizeof(char),n,fp);
  414. for (i=0;i<n;++i) {
  415. vp->elem(i) = double(xc[i]);
  416. }
  417. free(xc);
  418. break;
  419. }
  420. }
  421. return 1;
  422. }
  423. static double v_vwrite(void* v) {
  424. Vect* vp = (Vect*)v;
  425. Object* ob = *hoc_objgetarg(1);
  426. check_obj_type(ob, "File");
  427. OcFile* f = (OcFile*)(ob->u.this_pointer);
  428. FILE* fp = f->file();
  429. if (!fp) {
  430. return 0.;
  431. }
  432. BinaryMode(f)
  433. // first, write the size of the vector
  434. int n = vp->capacity();
  435. FWrite(&n,sizeof(int),1,fp);
  436. // next, write the type of elements
  437. int type = 4;
  438. if (ifarg(2)) {
  439. type = int(chkarg(2,1,5));
  440. }
  441. FWrite(&type,sizeof(int),1,fp);
  442. // convert the data if necessary
  443. int i;
  444. void *s;
  445. const char* x;
  446. double min,r,sf,sub,intermed;
  447. switch (type) {
  448. case 5: // integers as ints (no scaling)
  449. {
  450. int* xi = (int *)malloc(n * sizeof(int));
  451. for (i=0;i<n;++i) {
  452. xi[i] = (int)(vp->elem(i));
  453. }
  454. FWrite(xi,sizeof(int),n,fp);
  455. free((char *)xi);
  456. break;
  457. }
  458. case 4: // doubles (no conversion unless BYTESWAP used and needed)
  459. {
  460. s = (void*)(&(vp->elem(0)));
  461. x = (const char*)s;
  462. FWrite(x,sizeof(double),n,fp);
  463. break;
  464. }
  465. case 3: // float (simple automatic type conversion)
  466. {
  467. float* xf = (float *)malloc(n * (unsigned)sizeof(float));
  468. for (i=0;i<n;++i) {
  469. xf[i] = float(vp->elem(i));
  470. }
  471. FWrite(xf,sizeof(float),n,fp);
  472. free((char *)xf);
  473. break;
  474. }
  475. case 2: // short ints (scale to 16 bits with compression)
  476. {
  477. min = vp->min();
  478. r = vp->max()- min;
  479. if (r > 0) {
  480. sf = TWO_BYTE_HIGH/r;
  481. } else {
  482. sf = 1.;
  483. }
  484. unsigned short* xi = (unsigned short *)malloc(n * (unsigned)sizeof(unsigned short));
  485. for (i=0;i<n;++i) {
  486. intermed = (vp->elem(i)-min)*sf;
  487. xi[i] = (unsigned short)intermed;
  488. }
  489. s = (void*)xi;
  490. x = (const char*)s;
  491. // store the info needed to reconvert
  492. FWrite(&sf,sizeof(double),1,fp);
  493. FWrite(&min,sizeof(double),1,fp);
  494. // store the actual data
  495. FWrite(x,sizeof(unsigned short),n,fp);
  496. free((char *)xi);
  497. break;
  498. }
  499. case 1: // char (scale to 8 bits with compression)
  500. {
  501. sub = ONE_BYTE_HALF;
  502. min = vp->min();
  503. r = vp->max()- min;
  504. if (r > 0) {
  505. sf = ONE_BYTE_HIGH/r;
  506. } else {
  507. sf = 1.;
  508. }
  509. char* xc = (char *)malloc(n * (unsigned)sizeof(char));
  510. for (i=0;i<n;++i) {
  511. xc[i] = char(((vp->elem(i)-min)*sf)-sub);
  512. }
  513. s = (void*)xc;
  514. x = (const char*)s;
  515. // store the info needed to reconvert
  516. FWrite(&sf,sizeof(double),1,fp);
  517. FWrite(&min,sizeof(double),1,fp);
  518. FWrite(x,sizeof(char),n,fp);
  519. free(xc);
  520. break;
  521. }
  522. }
  523. return 1;
  524. }
  525. static double v_vread(void* v) {
  526. Vect* vp = (Vect*)v;
  527. void* s = (void*)(vp->vec());
  528. Object* ob = *hoc_objgetarg(1);
  529. check_obj_type(ob, "File");
  530. OcFile* f = (OcFile*)(ob->u.this_pointer);
  531. BYTEHEADER
  532. FILE* fp = f->file();
  533. if (!fp) {
  534. return 0.;
  535. }
  536. BinaryMode(f)
  537. int n;
  538. FRead(&n,sizeof(int),1,fp);
  539. int type = 0;
  540. FRead(&type,sizeof(int),1,fp);
  541. // since the type ranges from 1 to 5 (very important that it not be 0)
  542. // we can check the type and decide if it needs to be byteswapped
  543. if (type < 1 || type > 5) {
  544. BYTESWAP_FLAG = 1;
  545. }else{
  546. BYTESWAP_FLAG = 0;
  547. }
  548. BYTESWAP(n,int)
  549. BYTESWAP(type,int)
  550. if (type < 1 || type > 5) { return 0.;}
  551. if (vp->capacity() != n) vp->resize(n);
  552. // read as appropriate type and convert to doubles
  553. int i;
  554. double sf = 1.;
  555. double min = 0.;
  556. double add;
  557. switch (type) {
  558. case 5: // ints; no conversion
  559. {
  560. int *xi = (int *)malloc(n * sizeof(int));
  561. FRead(xi,sizeof(int),n,fp);
  562. for (i=0;i<n;++i) {
  563. BYTESWAP(xi[i],int)
  564. vp->elem(i) = double(xi[i]);
  565. }
  566. free((char *)xi);
  567. break;
  568. }
  569. case 4: // doubles
  570. FRead(&(vp->elem(0)),sizeof(double),n,fp);
  571. if (BYTESWAP_FLAG == 1) {
  572. for (i=0;i<n;++i) { BYTESWAP(vp->elem(i),double) }
  573. }
  574. break;
  575. case 3: // floats
  576. {
  577. float *xf = (float *)malloc(n * (unsigned)sizeof(float));
  578. FRead(xf,sizeof(float),n,fp);
  579. for (i=0;i<n;++i) {
  580. BYTESWAP(xf[i],float)
  581. vp->elem(i) = double(xf[i]);
  582. }
  583. free((char *)xf);
  584. break;
  585. }
  586. case 2: // unsigned short ints
  587. { // convert back to double
  588. FRead(&sf,sizeof(double),1,fp);
  589. FRead(&min,sizeof(double),1,fp);
  590. BYTESWAP(sf,double)
  591. BYTESWAP(min,double)
  592. unsigned short *xi = (unsigned short *)malloc(n * (unsigned)sizeof(unsigned short));
  593. FRead(xi,sizeof(unsigned short),n,fp);
  594. for (i=0;i<n;++i) {
  595. BYTESWAP(xi[i],short)
  596. vp->elem(i) = double(xi[i]/sf +min);
  597. }
  598. free((char *)xi);
  599. break;
  600. }
  601. case 1: // char
  602. { // convert back to double
  603. FRead(&sf,sizeof(double),1,fp);
  604. FRead(&min,sizeof(double),1,fp);
  605. BYTESWAP(sf,double)
  606. BYTESWAP(min,double)
  607. char *xc = (char *)malloc(n * (unsigned)sizeof(char));
  608. FRead(xc,sizeof(char),n,fp);
  609. add = ONE_BYTE_HALF;
  610. for (i=0;i<n;++i) {
  611. vp->elem(i) = double((xc[i]+add)/sf +min);
  612. }
  613. free(xc);
  614. break;
  615. }
  616. }
  617. return 1;
  618. }
  619. static double v_printf(void *v) {
  620. Vect* x = (Vect*)v;
  621. int top = x->capacity()-1;
  622. int start = 0;
  623. int end = top;
  624. int next_arg = 1;
  625. const char *format = "%g\t";
  626. int print_file = 0;
  627. int extra_newline = 1; // when no File
  628. OcFile *f;
  629. if (ifarg(next_arg) && (hoc_is_object_arg(next_arg))) {
  630. Object* ob = *hoc_objgetarg(1);
  631. check_obj_type(ob, "File");
  632. f = (OcFile*)(ob->u.this_pointer);
  633. format = "%g\n";
  634. next_arg++;
  635. print_file = 1;
  636. }
  637. if (ifarg(next_arg) && (hoc_argtype(next_arg) == STRING)) {
  638. format = gargstr(next_arg);
  639. next_arg++;
  640. extra_newline = 0;
  641. }
  642. if (ifarg(next_arg)) {
  643. start = int(chkarg(next_arg,0,top));
  644. end = int(chkarg(next_arg+1,start,top));
  645. }
  646. if (print_file) {
  647. for (int i=start;i<=end;i++) {
  648. fprintf(f->file(),format,x->elem(i));
  649. }
  650. fprintf(f->file(),"\n");
  651. } else {
  652. for (int i=start;i<=end;i++) {
  653. printf(format,x->elem(i));
  654. if (extra_newline && !((i-start+1)%5)){ printf("\n");}
  655. }
  656. if(extra_newline) {printf("\n");}
  657. }
  658. return double(end-start+1);
  659. }
  660. static double v_scanf(void *v) {
  661. Vect* x = (Vect*)v;
  662. int n = -1;
  663. int c = 1;
  664. int nc = 1;
  665. Object* ob = *hoc_objgetarg(1);
  666. check_obj_type(ob, "File");
  667. OcFile* f = (OcFile*)(ob->u.this_pointer);
  668. if (ifarg(4)) {
  669. n = int(*getarg(2));
  670. c = int(*getarg(3));
  671. nc = int(*getarg(4));
  672. } else if (ifarg(3)) {
  673. c = int(*getarg(2));
  674. nc = int(*getarg(3));
  675. } else if (ifarg(2)) {
  676. n = int(*getarg(2));
  677. }
  678. if (n >= 0) {
  679. x->resize(n);
  680. }
  681. // start at the right column
  682. int i=0;
  683. while((n < 0 || i<n) && ! f->eof()) {
  684. // skip unwanted columns before
  685. int j;
  686. for (j=1;j<c;j++) {
  687. if (!f->eof()) hoc_scan(f->file());
  688. }
  689. // read data
  690. if (!f->eof()) {
  691. x->resize_chunk(i+1);
  692. x->elem(i) = hoc_scan(f->file());
  693. }
  694. // skip unwanted columns after
  695. for (j=c;j<nc;j++) {
  696. if (!f->eof()) hoc_scan(f->file());
  697. }
  698. i++;
  699. }
  700. if (x->capacity() != i) x->resize(i);
  701. return double(i);
  702. }
  703. static double v_scantil(void *v) {
  704. Vect* x = (Vect*)v;
  705. double val, til;
  706. int c = 1;
  707. int nc = 1;
  708. Object* ob = *hoc_objgetarg(1);
  709. check_obj_type(ob, "File");
  710. OcFile* f = (OcFile*)(ob->u.this_pointer);
  711. til = *getarg(2);
  712. if (ifarg(4)) {
  713. c = int(*getarg(3));
  714. nc = int(*getarg(4));
  715. }
  716. // start at the right column
  717. int i=0;
  718. for(;;) {
  719. // skip unwanted columns before
  720. int j;
  721. for (j=1;j<c;j++) {
  722. if (hoc_scan(f->file()) == til) {
  723. return double(i);
  724. }
  725. }
  726. // read data
  727. val = hoc_scan(f->file());
  728. if (val == til) {
  729. break;
  730. }
  731. x->resize_chunk(i+1);
  732. x->elem(i) = val;
  733. // skip unwanted columns after
  734. for (j=c;j<nc;j++) {
  735. hoc_scan(f->file());
  736. }
  737. i++;
  738. }
  739. return double(i);
  740. }
  741. /*ARGSUSED*/
  742. static Object** v_plot(void* v) {
  743. Vect* vp = (Vect*)v;
  744. #if HAVE_IV
  745. IFGUI
  746. int i;
  747. double* y = vp->vec();
  748. int n = vp->capacity();
  749. Object* ob1 = *hoc_objgetarg(1);
  750. check_obj_type(ob1, "Graph");
  751. Graph* g = (Graph*)(ob1->u.this_pointer);
  752. GraphVector* gv = new GraphVector("");
  753. if (ifarg(5)) {
  754. hoc_execerror("Vector.line:", "too many arguments");
  755. }
  756. if (narg() == 3) {
  757. gv->color((colors->color(int(*getarg(2)))));
  758. gv->brush((brushes->brush(int(*getarg(3)))));
  759. } else if (narg() == 4) {
  760. gv->color((colors->color(int(*getarg(3)))));
  761. gv->brush((brushes->brush(int(*getarg(4)))));
  762. }
  763. if (narg() == 2 || narg() == 4) {
  764. // passed a vector or xinterval and possibly line attributes
  765. if (hoc_is_object_arg(2)) {
  766. // passed a vector
  767. Vect* vp2 = vector_arg(2);
  768. n = Math::min(n, vp2->capacity());
  769. for (i=0; i < n; ++i) gv->add(vp2->elem(i), y + i);
  770. } else {
  771. // passed xinterval
  772. double interval = *getarg(2);
  773. for (i=0; i < n; ++i) gv->add(i * interval, y + i);
  774. }
  775. } else {
  776. // passed line attributes or nothing
  777. for (i=0; i < n; ++i) gv->add(i, y + i);
  778. }
  779. if (vp->label_) {
  780. GLabel* glab = g->label(vp->label_);
  781. gv->label(glab);
  782. ((GraphItem*)g->component(g->glyph_index(glab)))->save(false);
  783. }
  784. g->append(new GPolyLineItem(gv));
  785. g->flush();
  786. ENDGUI
  787. #endif
  788. return vp->temp_objvar();
  789. }
  790. static Object** v_ploterr(void* v) {
  791. Vect* vp = (Vect*)v;
  792. #if HAVE_IV
  793. IFGUI
  794. int n = vp->capacity();
  795. Object* ob1 = *hoc_objgetarg(1);
  796. check_obj_type(ob1, "Graph");
  797. Graph* g = (Graph*)(ob1->u.this_pointer);
  798. char style = '-';
  799. double size = 4;
  800. if (ifarg(4)) size = chkarg(4,0.1,100.);
  801. const ivColor * color = g->color();
  802. const ivBrush * brush = g->brush();
  803. if (ifarg(5)) {
  804. color = colors->color(int(*getarg(5)));
  805. brush = brushes->brush(int(*getarg(6)));
  806. }
  807. Vect* vp2 = vector_arg(2);
  808. if (vp2->capacity() < n) n = vp2->capacity();
  809. Vect* vp3 = vector_arg(3);
  810. if (vp3->capacity() < n) n = vp3->capacity();
  811. for (int i=0; i < n; ++i) {
  812. g->begin_line();
  813. g->line(vp2->elem(i),vp->elem(i) - vp3->elem(i));
  814. g->line(vp2->elem(i),vp->elem(i) + vp3->elem(i));
  815. g->mark(vp2->elem(i), vp->elem(i) - vp3->elem(i), style, size, color, brush);
  816. g->mark(vp2->elem(i), vp->elem(i) + vp3->elem(i), style, size, color, brush);
  817. }
  818. g->flush();
  819. ENDGUI
  820. #endif
  821. return vp->temp_objvar();
  822. }
  823. static Object** v_line(void* v) {
  824. Vect* vp = (Vect*)v;
  825. #if HAVE_IV
  826. IFGUI
  827. int i;
  828. int n = vp->capacity();
  829. Object* ob1 = *hoc_objgetarg(1);
  830. check_obj_type(ob1, "Graph");
  831. Graph* g = (Graph*)(ob1->u.this_pointer);
  832. char* s = vp->label_;
  833. if (ifarg(5)) {
  834. hoc_execerror("Vector.line:", "too many arguments");
  835. }
  836. if (narg() == 3) {
  837. g->begin_line(colors->color(int(*getarg(2))),
  838. brushes->brush(int(*getarg(3))), s);
  839. } else if (narg() == 4) {
  840. g->begin_line(colors->color(int(*getarg(3))),
  841. brushes->brush(int(*getarg(4))), s);
  842. } else {
  843. g->begin_line(s);
  844. }
  845. if (narg() == 2 || narg() == 4) {
  846. // passed a vector or xinterval and possibly line attributes
  847. if (hoc_is_object_arg(2)) {
  848. // passed a vector
  849. Vect* vp2 = vector_arg(2);
  850. n = Math::min(n, vp2->capacity());
  851. for (i=0; i < n; ++i) g->line(vp2->elem(i), vp->elem(i));
  852. } else {
  853. // passed xinterval
  854. double interval = *getarg(2);
  855. for (i=0; i < n; ++i) g->line(i * interval, vp->elem(i));
  856. }
  857. } else {
  858. // passed line attributes or nothing
  859. for (i=0; i < n; ++i) g->line(i, vp->elem(i));
  860. }
  861. g->flush();
  862. ENDGUI
  863. #endif
  864. return vp->temp_objvar();
  865. }
  866. static Object** v_mark(void* v) {
  867. Vect* vp = (Vect*)v;
  868. #if HAVE_IV
  869. IFGUI
  870. int i;
  871. int n = vp->capacity();
  872. Object* ob1 = *hoc_objgetarg(1);
  873. check_obj_type(ob1, "Graph");
  874. Graph* g = (Graph*)(ob1->u.this_pointer);
  875. char style = '+';
  876. if (ifarg(3)) {
  877. if (hoc_is_str_arg(3)) {
  878. style = *gargstr(3);
  879. } else {
  880. style = char(chkarg(3,0,10));
  881. }
  882. }
  883. double size = 12;
  884. if (ifarg(4)) size = chkarg(4,0.1,100.);
  885. const ivColor * color = g->color();
  886. if (ifarg(5)) color = colors->color(int(*getarg(5)));
  887. const ivBrush * brush = g->brush();
  888. if (ifarg(6)) brush = brushes->brush(int(*getarg(6)));
  889. if (hoc_is_object_arg(2)) {
  890. // passed a vector
  891. Vect* vp2 = vector_arg(2);
  892. for (i=0; i < n; ++i) {
  893. g->mark(vp2->elem(i), vp->elem(i), style, size, color, brush);
  894. }
  895. } else {
  896. // passed xinterval
  897. double interval = *getarg(2);
  898. for (i=0; i < n; ++i) {
  899. g->mark(i*interval, vp->elem(i), style, size, color, brush);
  900. }
  901. }
  902. ENDGUI
  903. #endif
  904. return vp->temp_objvar();
  905. }
  906. static Object** v_histogram(void* v) {
  907. Vect* x = (Vect*)v;
  908. double low = *getarg(1);
  909. double high = chkarg(2,low,1e99);
  910. double width = chkarg(3,0,high-low);
  911. // SampleHistogram h(low,high,width);
  912. int i;
  913. // for (i=0; i< x->capacity(); i++) h += x->elem(i);
  914. // int n = h.buckets();
  915. // analogous to howManyBuckets in gnu/SamplHist.cpp
  916. int n = int(floor((high - low)/width)) + 2;
  917. Vect* y = new Vect(n);
  918. y->fill(0.);
  919. // for (i=0; i< n; i++) y->elem(i) = h.inBucket(i);
  920. for (i=0; i < x->capacity(); ++i) {
  921. int ind = int(floor((x->elem(i) - low)/width)) + 1;
  922. if (ind >= 0 && ind < y->capacity()) {
  923. y->elem(ind) += 1.0;
  924. }
  925. }
  926. return y->temp_objvar();
  927. }
  928. static Object** v_hist(void* v) {
  929. Vect* hv = (Vect*)v;
  930. Vect* data = vector_arg(1);
  931. same_err("hist", hv, data);
  932. double start = *getarg(2);
  933. int size = int(*getarg(3));
  934. double step = chkarg(4,1.e-99,1.e99);
  935. double high = start+step*size;
  936. // SampleHistogram h(start,high,step);
  937. // for (int i=0; i< data->capacity(); i++) h += data->elem(i);
  938. if (hv->capacity() != size) hv->resize(size);
  939. hv->fill(0.);
  940. for (int i=0; i< data->capacity(); i++) {
  941. int ind = int(floor((data->elem(i)-start)/step));
  942. if (ind >=0 && ind < hv->capacity()) hv->elem(ind) += 1;
  943. }
  944. // for (i=0; i< size; i++) hv->elem(i) = h.inBucket(i);
  945. return hv->temp_objvar();
  946. }
  947. static Object** v_sumgauss(void* v) {
  948. Vect* x = (Vect*)v;
  949. double low = *getarg(1);
  950. double high = chkarg(2,low,1e99);
  951. double step = chkarg(3,1.e-99,1.e99);
  952. double var = chkarg(4,0,1.e99);
  953. Vect* w;
  954. bool d = false;
  955. if (ifarg(5)) {
  956. w = vector_arg(5);
  957. } else {
  958. w = new Vect(x->capacity());
  959. w->fill(1);
  960. d = true;
  961. }
  962. int points = int((high-low)/step + .5);
  963. Vect* sum = new Vect(points,0.);
  964. double svar = var/(step*step);
  965. // 4/28/93 ZFM: corrected bug: replaced svar w/ var in line below
  966. double scale = 1./hoc_Sqrt(2.*PI*var);
  967. for (int i=0;i<x->capacity();i++) {
  968. double xv = int((x->elem(i)-low)/step);
  969. for (int j=0; j<points;j++) {
  970. double arg = -(j-xv)*(j-xv)/(2.*svar);
  971. if (arg > -20.) sum->elem(j) += hoc_Exp(arg) * scale * w->elem(i);
  972. }
  973. }
  974. if (d) {
  975. delete w;
  976. }
  977. return sum->temp_objvar();
  978. }
  979. static Object** v_smhist(void* v) {
  980. Vect* v1 = (Vect*)v;
  981. Vect* data = vector_arg(1);
  982. double start = *getarg(2);
  983. int size = int(*getarg(3));
  984. double step = chkarg(4,1.e-99,1.e99);
  985. double var = chkarg(5,0,1.e99);
  986. int weight,i;
  987. Vect *w;
  988. if (ifarg(6)) {
  989. w = vector_arg(6);
  990. weight = 1;
  991. } else {
  992. weight = 0;
  993. }
  994. // ready a gaussian to convolve
  995. double svar = 2*var/(step*step);
  996. double scale = 1/hoc_Sqrt(2.*PI*var);
  997. int g2 = int(sqrt(10*svar));
  998. int g = g2*2+1;
  999. int n = 1;
  1000. while(n<size+g) n*=2;
  1001. double *gauss = (double *)calloc(n,(unsigned)sizeof(double));
  1002. for (i=0;i<= g2;i++) gauss[i] = scale * hoc_Exp(-i*i/svar);
  1003. for (i=1;i<= g2;i++) gauss[g-i] = scale * hoc_Exp(-i*i/svar);
  1004. // put the data into a time series
  1005. double *series = (double *)calloc(n,(unsigned)sizeof(double));
  1006. double high = start + n*step;
  1007. if (weight) {
  1008. for (i=0;i<data->capacity();i++) {
  1009. if (data->elem(i) >= start && data->elem(i) < high) {
  1010. series[int((data->elem(i)-start)/step)] += w->elem(i);
  1011. }
  1012. }
  1013. } else {
  1014. for (i=0;i<data->capacity();i++) {
  1015. if (data->elem(i) >= start && data->elem(i) < high) {
  1016. series[int((data->elem(i)-start)/step)] += 1.;
  1017. }
  1018. }
  1019. }
  1020. // ready the answer vector
  1021. double *ans = (double *)calloc(2*n,(unsigned)sizeof(double));
  1022. // convolve
  1023. nrn_convlv(series,n,gauss,g,1,ans);
  1024. // put the answer in the vector
  1025. if (v1->capacity() != size) v1->resize(size);
  1026. v1->fill(0.,0,size);
  1027. for (i=0;i<size;i++) if (ans[i] > EPSILON) v1->elem(i) = ans[i];
  1028. free((char*) series);
  1029. free((char*) gauss);
  1030. free((char*) ans);
  1031. return v1->temp_objvar();
  1032. }
  1033. static Object** v_ind(void* v) {
  1034. Vect* x = (Vect*)v;
  1035. Vect* y = vector_arg(1);
  1036. Vect* z = new Vect();
  1037. int yv;
  1038. int ztop = 0;
  1039. int top = x->capacity();
  1040. z->resize(y->capacity()); z->resize(0);
  1041. for (int i=0;i<y->capacity();i++) {
  1042. yv = int(y->elem(i));
  1043. if ((yv < top) && (yv >= 0)) {
  1044. z->resize(++ztop);
  1045. z->elem(ztop-1) = x->elem(yv);
  1046. }
  1047. }
  1048. return z->temp_objvar();
  1049. }
  1050. static double v_size(void* v) {
  1051. Vect* x = (Vect*)v;
  1052. return double(x->capacity());
  1053. }
  1054. static double v_buffer_size(void* v) {
  1055. Vect* x = (Vect*)v;
  1056. if (ifarg(1)) {
  1057. int n = (int)chkarg(1, (double)x->capacity(), dmaxint_);
  1058. x->buffer_size(n);
  1059. }
  1060. return x->buffer_size();
  1061. }
  1062. int IvocVect::buffer_size() {
  1063. return space;
  1064. }
  1065. void IvocVect::buffer_size(int n) {
  1066. double* y = new double[n];
  1067. if (len > n) {
  1068. len = n;
  1069. }
  1070. for (int i=0; i < len; ++i) {
  1071. y[i] = s[i];
  1072. }
  1073. space = n;
  1074. delete [] s;
  1075. s = y;
  1076. }
  1077. static Object** v_resize(void* v) {
  1078. Vect* x = (Vect*)v;
  1079. x->resize(int(chkarg(1,0,dmaxint_)));
  1080. return x->temp_objvar();
  1081. }
  1082. static Object** v_clear(void* v) {
  1083. Vect* x = (Vect*)v;
  1084. x->resize(0);
  1085. return x->temp_objvar();
  1086. }
  1087. static double v_get(void* v) {
  1088. Vect* x = (Vect*)v;
  1089. return x->elem(int(chkarg(1,0,x->capacity()-1)));
  1090. }
  1091. static Object** v_set(void* v) {
  1092. Vect* x = (Vect*)v;
  1093. x->elem(int(chkarg(1,0,x->capacity()-1))) = *getarg(2);
  1094. return x->temp_objvar();
  1095. }
  1096. static Object** v_append(void* v) {
  1097. Vect* x = (Vect*)v;
  1098. int n,j,i=1;
  1099. while (ifarg(i)) {
  1100. if (hoc_argtype(i) == NUMBER) {
  1101. x->resize_chunk(x->capacity()+1);
  1102. x->elem(x->capacity()-1) = *getarg(i);
  1103. } else if (hoc_is_object_arg(i)) {
  1104. Vect* y = vector_arg(i);
  1105. same_err("append", x, y);
  1106. n = x->capacity();
  1107. x->resize_chunk(n+y->capacity());
  1108. for (j=0;j<y->capacity();j++) {
  1109. x->elem(n+j) = y->elem(j);
  1110. }
  1111. }
  1112. i++;
  1113. }
  1114. return x->temp_objvar();
  1115. }
  1116. static Object** v_insert(void* v) {
  1117. // insert all before indx (first arg)
  1118. Vect* x = (Vect*)v;
  1119. int n,j,m,i=2;
  1120. int indx = (int)chkarg(1, 0, x->capacity());
  1121. m = x->capacity() - indx;
  1122. double* z;
  1123. if (m) {
  1124. z = new double[m];
  1125. for (j=0; j < m; ++j) {
  1126. z[j] = x->elem(indx + j);
  1127. }
  1128. }
  1129. x->resize(indx);
  1130. while (ifarg(i)) {
  1131. if (hoc_argtype(i) == NUMBER) {
  1132. x->resize_chunk(x->capacity()+1);
  1133. x->elem(x->capacity()-1) = *getarg(i);
  1134. } else if (hoc_is_object_arg(i)) {
  1135. Vect* y = vector_arg(i);
  1136. same_err("insrt", x, y);
  1137. n = x->capacity();
  1138. x->resize_chunk(n+y->capacity());
  1139. for (j=0;j<y->capacity();j++) {
  1140. x->elem(n+j) = y->elem(j);
  1141. }
  1142. }
  1143. i++;
  1144. }
  1145. if (m) {
  1146. n = x->capacity();
  1147. x->resize(n + m);
  1148. for (j=0; j < m; ++j) {
  1149. x->elem(n + j) = z[j];
  1150. }
  1151. delete [] z;
  1152. }
  1153. return x->temp_objvar();
  1154. }
  1155. static Object** v_remove(void* v) {
  1156. Vect* x = (Vect*)v;
  1157. int i, j, n, start, end;
  1158. start = (int)chkarg(1, 0, x->capacity()-1);
  1159. if (ifarg(2)) {
  1160. end = (int)chkarg(2, start, x->capacity()-1);
  1161. }else{
  1162. end = start;
  1163. }
  1164. n = x->capacity();
  1165. for (i=start, j=end+1; j < n; ++i, ++j) {
  1166. x->elem(i) = x->elem(j);
  1167. }
  1168. x->resize(i);
  1169. return x->temp_objvar();
  1170. }
  1171. static double v_contains(void* v) {
  1172. Vect* x = (Vect*)v;
  1173. double g = *getarg(1);
  1174. for (int i=0;i<x->capacity();i++) {
  1175. if (Math::equal(x->elem(i), g, hoc_epsilon)) return 1.;
  1176. }
  1177. return 0.;
  1178. }
  1179. static Object** v_copy(void* v) {
  1180. Vect* y = (Vect*)v;
  1181. Vect* x = vector_arg(1);
  1182. int top = x->capacity()-1;
  1183. int srcstart = 0;
  1184. int srcend = top;
  1185. int srcinc = 1;
  1186. int deststart = 0;
  1187. int destinc = 1;
  1188. if (ifarg(2) && hoc_is_object_arg(2)) {
  1189. Vect* srcind = vector_arg(2);
  1190. int ns = srcind->capacity();
  1191. int nx = x->capacity();
  1192. if (ifarg(3)) {
  1193. Vect* destind = vector_arg(3);
  1194. if (destind->capacity() < ns) {
  1195. ns = destind->capacity();
  1196. }
  1197. int ny = y->capacity();
  1198. for (int i=0; i < ns; ++i) {
  1199. int ix = (int) (srcind->elem(i) + hoc_epsilon);
  1200. int iy = (int) (destind->elem(i) + hoc_epsilon);
  1201. if (ix >= 0 && iy >= 0 && ix < nx && iy < ny) {
  1202. y->elem(iy) = x->elem(ix);
  1203. }
  1204. }
  1205. }else{
  1206. if (y->capacity() < nx) {
  1207. nx = y->capacity();
  1208. }
  1209. for (int i=0; i < ns; ++i) {
  1210. int ii = (int)(srcind->elem(i) + hoc_epsilon);
  1211. if (ii >= 0 && ii < nx) {
  1212. y->elem(ii) = x->elem(ii);
  1213. }
  1214. }
  1215. }
  1216. return y->temp_objvar();
  1217. }
  1218. if (ifarg(2) && !(ifarg(3))) {
  1219. deststart = int(*getarg(2));
  1220. } else {
  1221. if (ifarg(4)) {
  1222. deststart = int(*getarg(2));
  1223. srcstart = int(chkarg(3,0,top));
  1224. srcend = int(chkarg(4,-1,top));
  1225. if (ifarg(5)) {
  1226. destinc = int(chkarg(5, 1, dmaxint_));
  1227. srcinc = int(chkarg(6, 1, dmaxint_));
  1228. }
  1229. } else if (ifarg(3)) {
  1230. srcstart = int(chkarg(2,0,top));
  1231. srcend = int(chkarg(3,-1,top));
  1232. }
  1233. }
  1234. if (srcend == -1) {
  1235. srcend = top;
  1236. }else if (srcend < srcstart) {
  1237. hoc_execerror("Vector.copy: src_end arg smaller than src_start", 0);
  1238. }
  1239. int size = (srcend-srcstart)/srcinc;
  1240. size *= destinc;
  1241. size += deststart+1;
  1242. if (y->capacity() < size) {
  1243. y->resize(size);
  1244. }else if (y->capacity() > size && !ifarg(2)) {
  1245. y->resize(size);
  1246. }
  1247. int i, j;
  1248. for (i=srcstart, j=deststart; i<=srcend; i+=srcinc, j+=destinc) {
  1249. y->elem(j) = x->elem(i);
  1250. }
  1251. return y->temp_objvar();
  1252. }
  1253. static Object** v_at(void* v) {
  1254. Vect* x = (Vect*)v;
  1255. int top = x->capacity()-1;
  1256. int start = 0;
  1257. int end = top;
  1258. if (ifarg(1)) {
  1259. start = int(chkarg(1,0,top));
  1260. }
  1261. if (ifarg(2)) {
  1262. end = int(chkarg(2,start,top));
  1263. }
  1264. int size = end-start+1;
  1265. Vect* y = new Vect(size);
  1266. // ZFM: fixed bug -- i<size, not i<=size
  1267. for (int i=0; i<size; i++) y->elem(i) = x->elem(i+start);
  1268. return y->temp_objvar();
  1269. }
  1270. #define USE_MLH_GSORT 0
  1271. #if !USE_MLH_GSORT
  1272. typedef struct {double x; int i;} SortIndex;
  1273. static int sort_index_cmp(const void* a, const void* b) {
  1274. double x = ((SortIndex*)a)->x;
  1275. double y = ((SortIndex*)b)->x;
  1276. if (x > y) return (1);
  1277. if (x < y) return (-1);
  1278. return (0);
  1279. }
  1280. static Object** v_sortindex(void* v) {
  1281. // v.index(vsrc, vsrc.sortindex) sorts vsrc into v
  1282. int i, n;
  1283. Vect* x = (Vect*)v;
  1284. n = x->capacity();
  1285. Vect* y;
  1286. possible_destvec(1, y);
  1287. y->resize(n);
  1288. SortIndex* si = new SortIndex[n];
  1289. for (i=0; i < n; ++i) {
  1290. si[i].i = i;
  1291. si[i].x = x->elem(i);
  1292. }
  1293. // On BlueGene
  1294. // qsort apparently can generate errno 38 "Function not implemented"
  1295. qsort((void*)si, n, sizeof(SortIndex), sort_index_cmp);
  1296. errno = 0;
  1297. for (i=0; i<n; i++) y->elem(i) = (double)si[i].i;
  1298. delete [] si;
  1299. return y->temp_objvar();
  1300. }
  1301. #else
  1302. static Object** v_sortindex(void* v) {
  1303. // v.index(vsrc, vsrc.sortindex) sorts vsrc into v
  1304. int i, n;
  1305. Vect* x = (Vect*)v;
  1306. n = x->capacity();
  1307. Vect* y;
  1308. possible_destvec(1, y);
  1309. y->resize(n);
  1310. int* si = new int[n];
  1311. for (i=0; i < n; ++i) {
  1312. si[i] = i;
  1313. }
  1314. nrn_mlh_gsort(vector_vec(x), si, n, cmpfcn);
  1315. for (i=0; i<n; i++) y->elem(i) = (double)si[i];
  1316. delete [] si;
  1317. return y->temp_objvar();
  1318. }
  1319. #endif // USE_MLH_GSORT
  1320. static Object** v_c(void* v) {
  1321. return v_at(v);
  1322. }
  1323. static Object** v_cl(void* v) {
  1324. Object** r = v_at(v);
  1325. ((Vect*)((*r)->u.this_pointer))->label(((Vect*)v)->label_);
  1326. return r;
  1327. }
  1328. static Object** v_interpolate(void* v) {
  1329. Vect* yd = (Vect*)v;
  1330. Vect* xd = vector_arg(1);
  1331. Vect* xs = vector_arg(2);
  1332. Vect* ys;
  1333. int flag, is, id, nd, ns;
  1334. double thet;
  1335. ns = xs->capacity();
  1336. nd = xd->capacity();
  1337. if (ifarg(3)) {
  1338. ys = vector_arg(3);
  1339. flag = 0;
  1340. }else{
  1341. ys = new Vect(*yd);
  1342. flag = 1;
  1343. }
  1344. yd->resize(nd);
  1345. // before domain
  1346. for (id = 0; id < nd && xd->elem(id) <= xs->elem(0); ++id) {
  1347. yd->elem(id) = ys->elem(0);
  1348. }
  1349. // in domain
  1350. for (is = 1; is < ns && id < nd; ++is) {
  1351. if (xs->elem(is) <= xs->elem(is-1)) {
  1352. continue;
  1353. }
  1354. while (xd->elem(id) <= xs->elem(is)) {
  1355. thet = (xd->elem(id) - xs->elem(is-1))/(xs->elem(is) - xs->elem(is-1));
  1356. yd->elem(id) = (1.-thet)*(ys->elem(is-1)) + thet*(ys->elem(is));
  1357. ++id;
  1358. if (id >= nd) {
  1359. break;
  1360. }
  1361. }
  1362. }
  1363. // after domain
  1364. for (; id < nd; ++id) {
  1365. yd->elem(id) = ys->elem(ns-1);
  1366. }
  1367. if (flag) {
  1368. delete ys;
  1369. }
  1370. return yd->temp_objvar();
  1371. }
  1372. static int possible_srcvec(ParentVect*& src, Vect* dest, int& flag) {
  1373. if (ifarg(1) && hoc_is_object_arg(1)) {
  1374. src = vector_arg(1);
  1375. flag = 0;
  1376. return 2;
  1377. }else{
  1378. src = new ParentVect(*dest);
  1379. flag = 1;
  1380. return 1;
  1381. }
  1382. }
  1383. static Object** v_where(void* v) {
  1384. Vect* y = (Vect*)v;
  1385. ParentVect* x;
  1386. int iarg, flag;
  1387. iarg = possible_srcvec(x, y, flag);
  1388. int n = x->capacity();
  1389. int m = 0;
  1390. int i;
  1391. char* op = gargstr(iarg++);
  1392. double value = *getarg(iarg++);
  1393. double value2;
  1394. y->resize(0);
  1395. if (!strcmp(op,"==")) {
  1396. for (i=0; i<n; i++) {
  1397. if (Math::equal(x->elem(i), value, hoc_epsilon)) {
  1398. y->resize_chunk(++m);
  1399. y->elem(m-1) = x->elem(i);
  1400. }
  1401. }
  1402. } else if (!strcmp(op,"!=")) {
  1403. for (i=0; i<n; i++) {
  1404. if (!Math::equal(x->elem(i), value, hoc_epsilon)) {
  1405. y->resize_chunk(++m);
  1406. y->elem(m-1) = x->elem(i);
  1407. }
  1408. }
  1409. } else if (!strcmp(op,">")) {
  1410. for (i=0; i<n; i++) {
  1411. if (x->elem(i) > value + hoc_epsilon) {
  1412. y->resize_chunk(++m);
  1413. y->elem(m-1) = x->elem(i);
  1414. }
  1415. }
  1416. } else if (!strcmp(op,"<")) {
  1417. for (i=0; i<n; i++) {
  1418. if (x->elem(i) < value - hoc_epsilon) {
  1419. y->resize_chunk(++m);
  1420. y->elem(m-1) = x->elem(i);
  1421. }
  1422. }
  1423. } else if (!strcmp(op,">=")) {
  1424. for (i=0; i<n; i++) {
  1425. if (x->elem(i) >= value - hoc_epsilon) {
  1426. y->resize_chunk(++m);
  1427. y->elem(m-1) = x->elem(i);
  1428. }
  1429. }
  1430. } else if (!strcmp(op,"<=")) {
  1431. for (i=0; i<n; i++) {
  1432. if (x->elem(i) <= value + hoc_epsilon) {
  1433. y->resize_chunk(++m);
  1434. y->elem(m-1) = x->elem(i);
  1435. }
  1436. }
  1437. } else if (!strcmp(op,"()")) {
  1438. value2 = *getarg(iarg);
  1439. for (i=0; i<n; i++) {
  1440. if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
  1441. y->resize_chunk(++m);
  1442. y->elem(m-1) = x->elem(i);
  1443. }
  1444. }
  1445. } else if (!strcmp(op,"[]")) {
  1446. value2 = *getarg(iarg);
  1447. for (i=0; i<n; i++) {
  1448. if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
  1449. y->resize_chunk(++m);
  1450. y->elem(m-1) = x->elem(i);
  1451. }
  1452. }
  1453. } else if (!strcmp(op,"[)")) {
  1454. value2 = *getarg(iarg);
  1455. for (i=0; i<n; i++) {
  1456. if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
  1457. y->resize_chunk(++m);
  1458. y->elem(m-1) = x->elem(i);
  1459. }
  1460. }
  1461. } else if (!strcmp(op,"(]")) {
  1462. value2 = *getarg(iarg);
  1463. for (i=0; i<n; i++) {
  1464. if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
  1465. y->resize_chunk(++m);
  1466. y->elem(m-1) = x->elem(i);
  1467. }
  1468. }
  1469. } else {
  1470. hoc_execerror("Vector","Invalid comparator in .where()\n");
  1471. }
  1472. if (flag) {
  1473. delete x;
  1474. }
  1475. return y->temp_objvar();
  1476. }
  1477. static double v_indwhere(void* v) {
  1478. Vect* x = (Vect*)v;
  1479. int i, iarg, m=0;
  1480. char* op;
  1481. double value,value2;
  1482. op = gargstr(1);
  1483. value = *getarg(2);
  1484. iarg = 3;
  1485. int n = x->capacity();
  1486. if (!strcmp(op,"==")) {
  1487. for (i=0; i<n; i++) {
  1488. if (Math::equal(x->elem(i), value, hoc_epsilon)) {
  1489. return i;
  1490. }
  1491. }
  1492. } else if (!strcmp(op,"!=")) {
  1493. for (i=0; i<n; i++) {
  1494. if (!Math::equal(x->elem(i), value, hoc_epsilon)) {
  1495. return i;
  1496. }
  1497. }
  1498. } else if (!strcmp(op,">")) {
  1499. for (i=0; i<n; i++) {
  1500. if (x->elem(i) > value + hoc_epsilon) {
  1501. return i;
  1502. }
  1503. }
  1504. } else if (!strcmp(op,"<")) {
  1505. for (i=0; i<n; i++) {
  1506. if (x->elem(i) < value - hoc_epsilon) {
  1507. return i;
  1508. }
  1509. }
  1510. } else if (!strcmp(op,">=")) {
  1511. for (i=0; i<n; i++) {
  1512. if (x->elem(i) >= value - hoc_epsilon) {
  1513. return i;
  1514. }
  1515. }
  1516. } else if (!strcmp(op,"<=")) {
  1517. for (i=0; i<n; i++) {
  1518. if (x->elem(i) <= value + hoc_epsilon) {
  1519. return i;
  1520. }
  1521. }
  1522. } else if (!strcmp(op,"()")) {
  1523. value2 = *getarg(iarg);
  1524. for (i=0; i<n; i++) {
  1525. if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
  1526. return i;
  1527. }
  1528. }
  1529. } else if (!strcmp(op,"[]")) {
  1530. value2 = *getarg(iarg);
  1531. for (i=0; i<n; i++) {
  1532. if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
  1533. return i;
  1534. }
  1535. }
  1536. } else if (!strcmp(op,"[)")) {
  1537. value2 = *getarg(iarg);
  1538. for (i=0; i<n; i++) {
  1539. if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
  1540. return i;
  1541. }
  1542. }
  1543. } else if (!strcmp(op,"(]")) {
  1544. value2 = *getarg(iarg);
  1545. for (i=0; i<n; i++) {
  1546. if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
  1547. return i;
  1548. }
  1549. }
  1550. } else {
  1551. hoc_execerror("Vector","Invalid comparator in .indwhere()\n");
  1552. }
  1553. return -1.;
  1554. }
  1555. static Object** v_indvwhere(void* v) {
  1556. Vect* y = (Vect*)v;
  1557. ParentVect* x;
  1558. int i, iarg, m=0, flag;
  1559. char* op;
  1560. double value,value2;
  1561. iarg = possible_srcvec(x, y, flag);
  1562. op = gargstr(iarg++);
  1563. value = *getarg(iarg++);
  1564. y->resize(0);
  1565. int n = x->capacity();
  1566. if (!strcmp(op,"==")) {
  1567. for (i=0; i<n; i++) {
  1568. if (Math::equal(x->elem(i), value, hoc_epsilon)) {
  1569. y->resize_chunk(++m);
  1570. y->elem(m-1) = i;
  1571. }
  1572. }
  1573. } else if (!strcmp(op,"!=")) {
  1574. for (i=0; i<n; i++) {
  1575. if (!Math::equal(x->elem(i), value, hoc_epsilon)) {
  1576. y->resize_chunk(++m);
  1577. y->elem(m-1) = i;
  1578. }
  1579. }
  1580. } else if (!strcmp(op,">")) {
  1581. for (i=0; i<n; i++) {
  1582. if (x->elem(i) > value + hoc_epsilon) {
  1583. y->resize_chunk(++m);
  1584. y->elem(m-1) = i;
  1585. }
  1586. }
  1587. } else if (!strcmp(op,"<")) {
  1588. for (i=0; i<n; i++) {
  1589. if (x->elem(i) < value - hoc_epsilon) {
  1590. y->resize_chunk(++m);
  1591. y->elem(m-1) = i;
  1592. }
  1593. }
  1594. } else if (!strcmp(op,">=")) {
  1595. for (i=0; i<n; i++) {
  1596. if (x->elem(i) >= value - hoc_epsilon) {
  1597. y->resize_chunk(++m);
  1598. y->elem(m-1) = i;
  1599. }
  1600. }
  1601. } else if (!strcmp(op,"<=")) {
  1602. for (i=0; i<n; i++) {
  1603. if (x->elem(i) <= value + hoc_epsilon) {
  1604. y->resize_chunk(++m);
  1605. y->elem(m-1) = i;
  1606. }
  1607. }
  1608. } else if (!strcmp(op,"()")) {
  1609. value2 = *getarg(iarg);
  1610. for (i=0; i<n; i++) {
  1611. if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
  1612. y->resize_chunk(++m);
  1613. y->elem(m-1) = i;
  1614. }
  1615. }
  1616. } else if (!strcmp(op,"[]")) {
  1617. value2 = *getarg(iarg);
  1618. for (i=0; i<n; i++) {
  1619. if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
  1620. y->resize_chunk(++m);
  1621. y->elem(m-1) = i;
  1622. }
  1623. }
  1624. } else if (!strcmp(op,"[)")) {
  1625. value2 = *getarg(iarg);
  1626. for (i=0; i<n; i++) {
  1627. if ((x->elem(i) >= value - hoc_epsilon) && (x->elem(i) < value2 - hoc_epsilon)) {
  1628. y->resize_chunk(++m);
  1629. y->elem(m-1) = i;
  1630. }
  1631. }
  1632. } else if (!strcmp(op,"(]")) {
  1633. value2 = *getarg(iarg);
  1634. for (i=0; i<n; i++) {
  1635. if ((x->elem(i) > value + hoc_epsilon) && (x->elem(i) <= value2 + hoc_epsilon)) {
  1636. y->resize_chunk(++m);
  1637. y->elem(m-1) = i;
  1638. }
  1639. }
  1640. } else {
  1641. hoc_execerror("Vector","Invalid comparator in .indvwhere()\n");
  1642. }
  1643. if (flag) {
  1644. delete x;
  1645. }
  1646. return y->temp_objvar();
  1647. }
  1648. static Object** v_fill(void* v)
  1649. {
  1650. Vect* x = (Vect*)v;
  1651. int top = x->capacity()-1;
  1652. int start = 0;
  1653. int end = top;
  1654. if (ifarg(2)) {
  1655. start = int(chkarg(2,0,top));
  1656. end = int(chkarg(3,start,top));
  1657. }
  1658. x->fill(*getarg(1),start,end-start+1);
  1659. return x->temp_objvar();
  1660. }
  1661. static Object** v_indgen(void* v)
  1662. {
  1663. Vect* x = (Vect*)v;
  1664. int n = x->capacity();
  1665. double start = 0.;
  1666. double step = 1.;
  1667. double end = double(n-1);
  1668. if (ifarg(1)) {
  1669. if (ifarg(3)) {
  1670. start = *getarg(1);
  1671. end = *getarg(2);
  1672. step = chkarg(3,Math::min(start-end,end-start),Math::max(start-end,end-start));
  1673. double xn = floor((end-start)/step + EPSILON)+1.;
  1674. if (xn > dmaxint_) {
  1675. hoc_execerror("size too large", 0);
  1676. } else if (xn < 0) {
  1677. hoc_execerror("empty set", 0);
  1678. }
  1679. n = int(xn);
  1680. if (n != x->capacity()) x->resize(n);
  1681. } else if (ifarg(2)) {
  1682. start = *getarg(1);
  1683. step = chkarg(2,-dmaxint_,dmaxint_);
  1684. } else {
  1685. step = chkarg(1,-dmaxint_,dmaxint_);
  1686. }
  1687. }
  1688. for (int i=0;i<n;i++) {
  1689. x->elem(i) = double(i)*step+start;
  1690. }
  1691. return x->temp_objvar();
  1692. }
  1693. static Object** v_addrand(void* v)
  1694. {
  1695. Vect* x = (Vect*)v;
  1696. Object* ob = *hoc_objgetarg(1);
  1697. check_obj_type(ob, "Random");
  1698. Rand* r = (Rand*)(ob->u.this_pointer);
  1699. int top = x->capacity()-1;
  1700. int start = 0;
  1701. int end = top;
  1702. if (ifarg(2)) {
  1703. start = int(chkarg(2,0,top));
  1704. end = int(chkarg(3,start,top));
  1705. }
  1706. for (int i=start;i<=end;i++) x->elem(i) += (*(r->rand))();
  1707. return x->temp_objvar();
  1708. }
  1709. static Object** v_setrand(void* v)
  1710. {
  1711. Vect* x = (Vect*)v;
  1712. Object* ob = *hoc_objgetarg(1);
  1713. check_obj_type(ob, "Random");
  1714. Rand* r = (Rand*)(ob->u.this_pointer);
  1715. int top = x->capacity()-1;
  1716. int start = 0;
  1717. int end = top;
  1718. if (ifarg(2)) {
  1719. start = int(chkarg(2,0,top));
  1720. end = int(chkarg(3,start,top));
  1721. }
  1722. for (int i=start;i<=end;i++) x->elem(i) = (*(r->rand))();
  1723. return x->temp_objvar();
  1724. }
  1725. static Object** v_apply(void* v)
  1726. {
  1727. Vect* x = (Vect*)v;
  1728. char* func = gargstr(1);
  1729. int top = x->capacity()-1;
  1730. int start = 0;
  1731. int end = top;
  1732. Object* ob;
  1733. if (ifarg(2)) {
  1734. start = int(chkarg(2,0,top));
  1735. end = int(chkarg(3,start,top));
  1736. }
  1737. Symbol* s = hoc_lookup(func);
  1738. ob = hoc_thisobject;
  1739. if (!s) {
  1740. ob = NULL;
  1741. s = hoc_table_lookup(func, hoc_top_level_symlist);
  1742. if (!s) {
  1743. hoc_execerror(func, " is undefined");
  1744. }
  1745. }
  1746. for (int i=start; i<=end; i++) {
  1747. hoc_pushx(x->elem(i));
  1748. x->elem(i) = hoc_call_objfunc(s, 1, ob);
  1749. }
  1750. return x->temp_objvar();
  1751. }
  1752. static double v_reduce(void* v)
  1753. {
  1754. Vect* x = (Vect*)v;
  1755. double base = 0;
  1756. int top = x->capacity()-1;
  1757. int start = 0;
  1758. int end = top;
  1759. if (ifarg(3)) {
  1760. start = int(chkarg(3,0,top));
  1761. end = int(chkarg(4,start,top));
  1762. }
  1763. char* func = gargstr(1);
  1764. if (ifarg(2)) base = *getarg(2);
  1765. Symbol* s = hoc_lookup(func);
  1766. if (!s) {
  1767. hoc_execerror(func, " is undefined");
  1768. }
  1769. for (int i=start; i<=end; i++) {
  1770. hoc_pushx(x->elem(i));
  1771. base += hoc_call_func(s, 1);
  1772. }
  1773. return base;
  1774. }
  1775. static double v_min(void* v)
  1776. {
  1777. Vect* x = (Vect*)v;
  1778. int x_max = x->capacity()-1;
  1779. if (ifarg(1)) {
  1780. int start = int(chkarg(1,0,x_max));
  1781. int end = int(chkarg(2,0,x_max));
  1782. return x->subvec(start, end)->min();
  1783. } else {
  1784. return x->min();
  1785. }
  1786. }
  1787. static double v_min_ind(void* v)
  1788. {
  1789. Vect* x = (Vect*)v;
  1790. int x_max = x->capacity()-1;
  1791. if (ifarg(1)) {
  1792. int start = int(chkarg(1,0,x_max));
  1793. int end = int(chkarg(2,0,x_max));
  1794. return x->subvec(start, end)->min_index()+start;
  1795. } else {
  1796. return x->min_index();
  1797. }
  1798. }
  1799. static double v_max(void* v)
  1800. {
  1801. Vect* x = (Vect*)v;
  1802. int x_max = x->capacity()-1;
  1803. if (ifarg(1)) {
  1804. int start = int(chkarg(1,0,x_max));
  1805. int end = int(chkarg(2,0,x_max));
  1806. return x->subvec(start, end)->max();
  1807. } else {
  1808. return x->max();
  1809. }
  1810. }
  1811. static double v_max_ind(void* v)
  1812. {
  1813. Vect* x = (Vect*)v;
  1814. int x_max = x->capacity()-1;
  1815. if (ifarg(1)) {
  1816. int start = int(chkarg(1,0,x_max));
  1817. int end = int(chkarg(2,0,x_max));
  1818. return (x->subvec(start,end))->max_index()+start;
  1819. } else {
  1820. return x->max_index();
  1821. }
  1822. }
  1823. static double v_sum(void* v)
  1824. {
  1825. Vect* x = (Vect*)v;
  1826. int x_max = x->capacity()-1;
  1827. if (ifarg(1)) {
  1828. int start = int(chkarg(1,0,x_max));
  1829. int end = int(chkarg(2,0,x_max));
  1830. return (x->subvec(start,end))->sum();
  1831. } else {
  1832. return x->sum();
  1833. }
  1834. }
  1835. static double v_sumsq(void* v)
  1836. {
  1837. Vect* x = (Vect*)v;
  1838. int x_max = x->capacity()-1;
  1839. if (ifarg(1)) {
  1840. int start = int(chkarg(1,0,x_max));
  1841. int end = int(chkarg(2,0,x_max));
  1842. return (x->subvec(start,end))->sumsq();
  1843. } else {
  1844. return x->sumsq();
  1845. }
  1846. }
  1847. static double v_mean(void* v)
  1848. {
  1849. Vect* x = (Vect*)v;
  1850. int x_max = x->capacity()-1;
  1851. if (ifarg(1)) {
  1852. int start = int(chkarg(1,0,x_max));
  1853. int end = int(chkarg(2,0,x_max));
  1854. if (end - start < 1) {
  1855. hoc_execerror("end - start", "must be > 0");
  1856. }
  1857. return (x->subvec(start,end))->mean();
  1858. } else {
  1859. if (x->ca

Large files files are truncated, but you can click here to view the full file