void LinearMechanism::create() { int i; lmfree(); i = 0; Object* o = *hoc_objgetarg(++i); if (strcmp(o->ctemplate->sym->name, "PythonObject") == 0) { f_callable_ = o; hoc_obj_ref(o); c_ = matrix_arg(++i); } else { f_callable_ = NULL; c_ = matrix_arg(1); } g_ = matrix_arg(++i); y_ = vector_arg(++i); if (ifarg(i + 2) && hoc_is_object_arg(i + 2) && is_vector_arg(i + 2)) { y0_ = vector_arg(++i); } b_ = vector_arg(++i); if (ifarg(++i)) { #if HAVE_IV Oc oc; #endif if (hoc_is_double_arg(i)) { nnode_ = 1; nodes_ = new Node*[1]; double x = chkarg(i, 0., 1.); Section* sec = chk_access(); nodes_[0] = node_exact(sec, x); nrn_notify_when_double_freed(&NODEV(nodes_[0]), this); }else{ Object* o = *hoc_objgetarg(i); check_obj_type(o, "SectionList"); SectionList* sl = new SectionList(o); sl->ref(); Vect* x = vector_arg(i+1); Section* sec; nnode_ = 0; nodes_ = new Node*[x->capacity()]; for (sec = sl->begin(); sec; sec = sl->next()) { nodes_[nnode_] = node_exact(sec, x->elem(nnode_)); nrn_notify_when_double_freed(&NODEV(nodes_[nnode_]), this); ++nnode_; } if (ifarg(i+2)) { elayer_ = vector_arg(i+2); } sl->unref(); } } model_ = new LinearModelAddition(c_, g_, y_, y0_, b_, nnode_, nodes_, elayer_, f_callable_); }
static void unpack_help(int i, OcBBS* bbs) { for (; ifarg(i); ++i) { if (hoc_is_pdouble_arg(i)) { *hoc_pgetarg(i) = bbs->upkdouble(); }else if (hoc_is_str_arg(i)) { char* s = bbs->upkstr(); char** ps = hoc_pgargstr(i); hoc_assign_str(ps, s); delete [] s; }else if (is_vector_arg(i)){ Vect* vec = vector_arg(i); int n = bbs->upkint(); vec->resize(n); bbs->upkvec(n, vec->vec()); }else{ hoc_execerror("pc.unpack can only unpack str, scalar, or Vector.", "use pc.upkpyobj to unpack a Python Object"); } } }
void nrn_vecsim_add(void* v, boolean record) { IvocVect* yvec, *tvec, *dvec; extern short* nrn_is_artificial_; double* pvar = nil; char* s = nil; double ddt; Object* ppobj = nil; int iarg = 0; yvec = (IvocVect*)v; if (hoc_is_object_arg(1)) { iarg = 1; ppobj = *hoc_objgetarg(1); if (!ppobj || ppobj->ctemplate->is_point_ <= 0 || nrn_is_artificial_[ob2pntproc(ppobj)->prop->type] ) { hoc_execerror("Optional first arg is not a POINT_PROCESS", 0); } } if (record == false && hoc_is_str_arg(iarg+1)) {//statement involving $1 // Vector.play("proced($1)", ...) s = gargstr(iarg+1); }else if (record == false && hoc_is_double_arg(iarg+1)) {// play that element // Vector.play(index) // must be a VecPlayStep and nothing else VecPlayStep* vps = (VecPlayStep*)net_cvode_instance->playrec_uses(v); if (vps) { int j = (int)chkarg(iarg+1, 0., yvec->capacity()-1); if (vps->si_) { vps->si_->play_one(yvec->elem(j)); } } return; }else{ // Vector.play(&SEClamp[0].amp1, ...) // Vector.record(&SEClamp[0].i, ...) pvar = hoc_pgetarg(iarg+1); } tvec = nil; dvec = nil; ddt = -1.; int con = 0; if (ifarg(iarg+2)) { if (hoc_is_object_arg(iarg+2)) { // Vector...(..., tvec) tvec = vector_arg(iarg+2); }else{ // Vector...(..., Dt) ddt = chkarg(iarg+2, 1e-9, 1e10); } if (ifarg(iarg+3)) { if (hoc_is_double_arg(iarg+3)) { con = (int)chkarg(iarg+3, 0., 1.); }else{ dvec = vector_arg(iarg+3); con = 1; } } } // tvec can be used for many record/play items // if (tvec) { nrn_vecsim_remove(tvec); } if (record) { // yvec can be used only for one record (but many play) if (yvec) { nrn_vecsim_remove(yvec); } if (tvec) { new VecRecordDiscrete(pvar, yvec, tvec, ppobj); } else if (ddt > 0.) { new VecRecordDt(pvar, yvec, ddt, ppobj); } else if (pvar == &t) { new TvecRecord(chk_access(), yvec, ppobj); } else { new YvecRecord(pvar, yvec, ppobj); } }else{ if (con) { if (s) { new VecPlayContinuous(s, yvec, tvec, dvec, ppobj); }else{ new VecPlayContinuous(pvar, yvec, tvec, dvec, ppobj); } }else{ if (!tvec && ddt == -1.) { chkarg(iarg+2, 1e-9, 1e10); } if (s) { new VecPlayStep(s, yvec, tvec, ddt, ppobj); }else{ new VecPlayStep(pvar, yvec, tvec, ddt, ppobj); } } } }
void fit_praxis(void) { extern Symbol* hoc_lookup(); extern char* gargstr(); char* after_quad; int i; double err, fmin; double* px; /* allow nested calls to fit_praxis. I.e. store all the needed statics specific to this invocation with proper reference counting and then unref/destoy on exit from this invocation. Before the prax call save the statics from earlier invocation without increasing the ref count and on exit restore without decreasing the ref count. */ /* save before setting statics, restore after prax */ double minerrsav, *minargsav, maxstepsizesav, tolerancesav; long int printmodesav, nvarsav; Symbol* efun_sym_sav; Object* efun_py_save, *efun_py_arg_save; void* vec_py_save_save; /* store statics specified by this invocation */ /* will be copied just before calling prax */ double minerr_, *minarg_; long int nvar_; Symbol* efun_sym_; Object* efun_py_, *efun_py_arg_; void* vec_py_save_; minerr_ = 0.0; nvar_ = 0; minarg_ = NULL; efun_sym_ = NULL; efun_py_ = NULL; efun_py_arg_ = NULL; vec_py_save_ = NULL; fmin = 0.; if (hoc_is_object_arg(1)) { assert(nrnpy_praxis_efun); efun_py_ = *hoc_objgetarg(1); hoc_obj_ref(efun_py_); efun_py_arg_ = *vector_pobj(vector_arg(2)); hoc_obj_ref(efun_py_arg_); vec_py_save_ = vector_new2(efun_py_arg_->u.this_pointer); nvar_ = vector_capacity(vec_py_save_); px = vector_vec(vec_py_save_); }else{ nvar_ = (int)chkarg(1, 0., 1e6); efun_sym_ = hoc_lookup(gargstr(2)); if (!efun_sym_ || (efun_sym_->type != FUNCTION && efun_sym_->type != FUN_BLTIN)) { hoc_execerror(gargstr(2), "not a function name"); } if (!hoc_is_pdouble_arg(3)) { void* vec = vector_arg(3); if (vector_capacity(vec) != nvar_) { hoc_execerror("first arg not equal to size of Vector",0); } px = vector_vec(vec); }else{ px = hoc_pgetarg(3); } } minarg_ = (double*)ecalloc(nvar_, sizeof(double)); if (maxstepsize == 0.) { hoc_execerror("call attr_praxis first to set attributes", 0); } machep = 1e-15; if (ifarg(4)) { after_quad = gargstr(4); }else{ after_quad = (char*)0; } /* save the values set by earlier invocation */ minerrsav = minerr; minargsav = minarg; tolerancesav = tolerance; maxstepsizesav = maxstepsize; printmodesav = printmode; nvarsav = nvar; efun_sym_sav = hoc_efun_sym; efun_py_save = efun_py; efun_py_arg_save = efun_py_arg; vec_py_save_save = vec_py_save; /* copy this invocation values to the statics */ minerr = minerr_; minarg = minarg_; nvar = nvar_; hoc_efun_sym = efun_sym_; efun_py = efun_py_; efun_py_arg = efun_py_arg_; vec_py_save = vec_py_save_; minerr=1e9; err = praxis(&tolerance, &machep, &maxstepsize, nvar, &printmode, px, efun, &fmin, after_quad); err = minerr; if (minerr < 1e9) { for (i=0; i<nvar; ++i) { px[i] = minarg[i]; } } /* restore the values set by earlier invocation */ minerr = minerrsav; minarg = minargsav; tolerance = tolerancesav; maxstepsize = maxstepsizesav; printmode = printmodesav; nvar = nvar_; /* in case one calls prax_pval */ hoc_efun_sym = efun_sym_sav; efun_py = efun_py_save; efun_py_arg = efun_py_arg_save; vec_py_save = vec_py_save_save; if (efun_py_) { double* px = vector_vec(efun_py_arg_->u.this_pointer); for (i=0; i < nvar_; ++i) { px[i] = minarg_[i]; } hoc_obj_unref(efun_py_); hoc_obj_unref(efun_py_arg_); vector_delete(vec_py_save_); } if (minarg_) { free(minarg_); } hoc_retpushx(err); }