Example #1
0
static void* scons(Object*) {
#if HAVE_IV
	SymChooser* sc = nil;
IFGUI
	const char* caption = "Choose a Variable Name or";
	if (ifarg(1)) {
		caption = gargstr(1);
	}
	Style* style = new Style(Session::instance()->style());
	style->attribute("caption", caption);
	if (ifarg(2)) {
		Symbol* sym = hoc_lookup(gargstr(2));
		int type = RANGEVAR;
		if (sym) {
			type = sym->type;
		}
		sc = new SymChooser(new SymDirectory(type), WidgetKit::instance(), style, nil, 1);
	}else{
		sc = new SymChooser(nil, WidgetKit::instance(), style);
	}
	Resource::ref(sc);
ENDGUI
	return (void*)sc;
#else
	return (void*)0;
#endif /* HAVE_IV */
}
Example #2
0
batch_run() /* avoid interpreter overhead */
{
	double tstop, tstep, tnext;
	char* filename;
	char* comment;

	tstopunset;
	tstop = chkarg(1,0.,1e20);
	tstep = chkarg(2, 0., 1e20);
	if (ifarg(3)) {
		filename = gargstr(3);
	}else{
		filename = 0;
	}
	if (ifarg(4)) {
		comment = gargstr(4);
	}else{
		comment = "";
	}
	
	if (tree_changed) {
		setup_topology();
	}
#if VECTORIZE
	if (v_structure_change) {
		v_setup_vectors();
	}
#endif
	batch_open(filename, tstop, tstep, comment);
	batch_out();
	if (cvode_active_) {
		while (t < tstop) {
			cvode_fadvance(t+tstep);
			batch_out();
		}
	}else{
		tstep -= dt/4.;
		tstop -= dt/4.;
		tnext = t + tstep;
		while (t < tstop) {
			nrn_fixed_step();
			if (t > tnext) {
				batch_out();
				tnext = t + tstep;
			}
			if (stoprun) { tstopunset; break; }
		}
	}
	batch_close();
	ret(1.);
}
Example #3
0
static void* finithnd_cons(Object*) {
	int type = 1; // default is after INITIAL blocks are called
	int ia = 1;
	if (hoc_is_double_arg(ia)) {
		type = (int)chkarg(ia, 0, 3);
		++ia;
	}
	char* s = NULL;
	Object* pyact = NULL;
	if (hoc_is_object_arg(ia)) {
		pyact = *hoc_objgetarg(ia);
		if (!pyact) {
			hoc_execerror("arg is None", 0);
		}
	}else{
		s =gargstr(ia);
	}
	++ia;
	Object* obj = NULL;
	if (ifarg(ia)) {
		obj = *hoc_objgetarg(ia);
	}
	FInitialHandler* f = new FInitialHandler(type, s, obj, pyact);
	return f;
}
Example #4
0
static double abstol(void* v) {
	NetCvode* d = (NetCvode*)v;
	Symbol* sym;
	if (hoc_is_str_arg(1)) {
		sym = d->name2sym(gargstr(1));
	}else{
		hoc_pgetarg(1);
		sym = hoc_get_last_pointer_symbol();
		if (!sym) {
hoc_execerror("Cannot find the symbol associated with the pointer when called from Python", "Use a string instead of pointer argument");
		}
		if (nrn_vartype(sym) != STATE && sym->u.rng.type != VINDEX) {
			hoc_execerror(sym->name, "is not a STATE");
		}
	}
	if (ifarg(2)) {
		hoc_symbol_tolerance(sym, chkarg(2, 1e-30, 1e30));
		d->structure_change();
	}
	if (sym->extra && sym->extra->tolerance > 0.) {
		return sym->extra->tolerance;
	}else{
		return 1.;
	}
}
Example #5
0
static double tstop_event(void* v) {
	NetCvode* d = (NetCvode*)v;
	double x = *getarg(1);
	if (!cvode_active_) { // watch out for fixed step roundoff if x
		// close to n*dt
		double y = x/nrn_threads->_dt;
		if (y > 1 && fabs(floor(y + 1e-6) - y) < 1e-6) {
			//printf("reduce %g to avoid fixed step roundoff\n", x);
			x -= nrn_threads->_dt/4.;
		}
	}
	if (ifarg(2)) {
		Object* ppobj = nil;
		int reinit = 0;
		if (ifarg(3)) {
			ppobj = *hoc_objgetarg(3);
			if (!ppobj || ppobj->ctemplate->is_point_ <= 0
			    || nrn_is_artificial_[ob2pntproc(ppobj)->prop->type]
			){
				hoc_execerror(hoc_object_name(ppobj), "is not a POINT_PROCESS");
			}
			reinit = int(chkarg(4, 0, 1));
		}
	    if (hoc_is_object_arg(2)) {
		d->hoc_event(x, nil, ppobj, reinit, *hoc_objgetarg(2));
	    }else{		
		d->hoc_event(x, gargstr(2), ppobj, reinit);
	    }
	}else{
		//d->tstop_event(x);
		d->hoc_event(x, 0, 0, 0);
	}
	return x;
}
Example #6
0
static char* key_help() {
	static char key[50];
	if (hoc_is_str_arg(1)) {
		return gargstr(1);
	}else{
		sprintf(key, "%g", *getarg(1));
		return key;
	}
}
Example #7
0
static void* cons(Object*) {
	double* p;
	const char* s;
	if (hoc_is_pdouble_arg(1)) {
		p = hoc_pgetarg(1);
		s = "unknown";
	}else{
		s = gargstr(1);
		ParseTopLevel ptl;
		p = hoc_val_pointer(s);
	}
	if (!p) { hoc_execerror("Pointer constructor failed", 0); }
	OcPointer* ocp = new OcPointer(s, p);
	if (ifarg(2)) {
		ocp->sti_ = new StmtInfo(gargstr(2));
	}
	return (void*)ocp;
}
Example #8
0
void make_mechanism() {
	char buf[256];
	int i, cnt;
	Symbol* sp;
	char* mname = gargstr(1);
//printf("mname=%s\n", mname);
	check(mname);
	char* classname = gargstr(2);
//printf("classname=%s\n", classname);
	char* parnames = nil;
	if (ifarg(3)) {
		parnames = new char[strlen(gargstr(3)) + 1];
		strcpy(parnames, gargstr(3));
	}
//if(parnames) printf("parnames=%s\n", parnames);
	Symbol* classsym = hoc_lookup(classname);
	if (classsym->type != TEMPLATE) {
		hoc_execerror(classname, "not a template");
	}
	cTemplate* tp = classsym->u.ctemplate;
	Symlist* slist = tp->symtable;
	char** m = make_m(true, cnt, slist, mname, parnames);

	common_register(m, classsym, slist, alloc_mech, i);
		
	for (sp = slist->first; sp; sp = sp->next) {
		if (sp->type == VAR && sp->cpublic) {
			sprintf(buf, "%s_%s", sp->name, m[1]);
			Symbol* sp1 = hoc_lookup(buf);
			sp1->u.rng.index = sp->u.oboff;
		}
	}
	for (i=0; i < cnt; ++i) {
		if (m[i]) {
			delete [] m[i];
		}
	}
	delete [] m;
	delete [] parnames;
	ret(1.);
}
Example #9
0
static double post(void* v) {
	OcBBS* bbs = (OcBBS*)v;
	pack_help(2, bbs);
	posting_ = false;
	if (hoc_is_str_arg(1)) {
		bbs->post(gargstr(1));
	}else{
		char key[50];
		sprintf(key, "%g", *getarg(1));
		bbs->post(key);
	}
	return 1.;
}
Example #10
0
static double ste_transition(void* v) {
	StateTransitionEvent* ste = (StateTransitionEvent*)v;
	int src = (int)chkarg(1, 0, ste->nstate()-1);
	int dest = (int)chkarg(2, 0, ste->nstate()-1);
	if (src == dest) {
		hoc_execerror("source and destination are the same", 0);
	}
	double* var1 = hoc_pgetarg(3);
	double* var2 = hoc_pgetarg(4);
	char* stmt = gargstr(5);
	Object* obj = nil;
	if (ifarg(6)) {
		obj = hoc_obj_get(6);
	}
	ste->transition(src, dest, var1, var2, 1, stmt, obj);
	return 1.;
}
Example #11
0
JNIEXPORT jstring JNICALL Java_neuron_Neuron_getHocStringArg(
    JNIEnv *env, jclass cls, jint idx) {    
	char *str="";
	if (!ifarg(idx)) {
		printf("error - missing string as arg %d\n", idx);
		illegalArg(env, "missing string");
		return nil;
	}
	if (hoc_is_str_arg( idx )) {
		str =  gargstr( idx );
	} else {
		printf("error - expecting string as arg %d\n", idx);
		illegalArg(env, "expecting string");
		return nil;
	}
	jstring ret = env->NewStringUTF( str );
	return ret;
}
Example #12
0
void hoc_Lw(void)
{
    char *s;
    static int dev=2;
#ifndef WIN32
    if (ifarg(1)) {
        s = gargstr(1);
        if (ifarg(2)) {
            dev = *getarg(2);
        }
        if (s[0] != '\0') {
            Fig_file(s, dev);
        } else {
            Fig_file((char *)0, dev);
        }
    } else {
        Fig_file((char *) 0, dev);
    }
#endif
    ret();
    pushx(0.);
}
Example #13
0
JNIEXPORT jobject JNICALL Java_neuron_Neuron_getHocObjectArg
  (JNIEnv *env, jclass cl, jint i, jthrowable e) {
	jobject ret;
//printf("getHocObjArg %s  %ld\n", hoc_object_name(o), (long)o);
	if (!ifarg(i)) {
		printf("error - missing Object as arg %d\n", i);
		illegalArg(env, "missing Object");
		return e;
	}
	if (hoc_is_object_arg(i)) {
		Object* o = *hoc_objgetarg(i);
		ret = h2jObject(o);
	}else if (hoc_is_str_arg(i)) { //encapsulate in String
		char* s = gargstr(i);
		ret = Java_neuron_Neuron_getHocStringArg(env, cl, i);
	}else{
		printf("error - expecting Object or strdef as arg %d\n", i);
		illegalArg(env, "expecting Object or strdef");
		ret = e;
	}
	return ret;
}
Example #14
0
static void pack_help(int i, OcBBS* bbs) {
	if (!posting_) {
		bbs->pkbegin();
		posting_ = true;
	}
	for (; ifarg(i); ++i) {
		if (hoc_is_double_arg(i)) {
			bbs->pkdouble(*getarg(i));
		}else if (hoc_is_str_arg(i)) {
			bbs->pkstr(gargstr(i));
		}else if (is_vector_arg(i)){
			int n; double* px;
			n = vector_arg_px(i, &px);
			bbs->pkint(n);
			bbs->pkvec(n, px);
		}else{ // must be a PythonObject
			size_t size;
			char* s = nrnpy_po2pickle(*hoc_objgetarg(i), &size);
			bbs->pkpickle(s, size);
			delete [] s;
		}
	}
}
Example #15
0
static double ste_transition(void* v) {
	StateTransitionEvent* ste = (StateTransitionEvent*)v;
	int src = (int)chkarg(1, 0, ste->nstate()-1);
	int dest = (int)chkarg(2, 0, ste->nstate()-1);
	double* var1 = hoc_pgetarg(3);
	double* var2 = hoc_pgetarg(4);
	HocCommand* hc = NULL;
	if (ifarg(5)) {
		Object* obj = NULL;
		if (hoc_is_str_arg(5)) {
			char* stmt = NULL;
			stmt = gargstr(5);
			if (ifarg(6)) {
				obj = *hoc_objgetarg(6);
			}
			hc = new HocCommand(stmt, obj);
		}else{
			obj = *hoc_objgetarg(5);
			hc = new HocCommand(obj);
		}
	}
	ste->transition(src, dest, var1, var2, hc);
	return 1.;
}
Example #16
0
static double A_f1(void* v) {
	((A*)v)->f1(gargstr(1));
	return(0.);
}
Example #17
0
static int submit_help(OcBBS* bbs) {
	int id, i, firstarg, style;
	char* pname = 0; // if using Python callable
	posting_ = true;
	bbs->pkbegin();
	i = 1;
	if (hoc_is_double_arg(i)) {
		bbs->pkint((id = (int)chkarg(i++, 0, 1e7)));
	}else{
		bbs->pkint((id = --bbs->next_local_));
	}
	if (ifarg(i+1)) {
#if 1
		int argtypes = 0;
		int ii = 1;
		if (hoc_is_str_arg(i)) {
			style = 1;
			bbs->pkint(style); // "fname", arg1, ... style
			bbs->pkstr(gargstr(i++));
		}else{
			Object* ob = *hoc_objgetarg(i++);
			size_t size;
			if (nrnpy_po2pickle) {
				pname = (*nrnpy_po2pickle)(ob, &size);
			}
			if (pname) {
				style = 3;
				bbs->pkint(style); // pyfun, arg1, ... style
				bbs->pkpickle(pname, size);
				delete [] pname;
			}else{
				style = 2;
				bbs->pkint(style); // [object],"fname", arg1, ... style
				bbs->pkstr(ob->ctemplate->sym->name);
				bbs->pkint(ob->index);
//printf("ob=%s\n", hoc_object_name(ob));
				bbs->pkstr(gargstr(i++));

			}
		}
		firstarg = i;
		for (; ifarg(i); ++i) { // first is least significant
			if (hoc_is_double_arg(i)) {
				argtypes += 1*ii;
			}else if (hoc_is_str_arg(i)) {
				argtypes += 2*ii;
			}else if (is_vector_arg(i)) { //hoc Vector
				argtypes += 3*ii;
			}else{ // must be a PythonObject
				argtypes += 4*ii;
			}
			ii *= 5;
		}
//printf("submit style %d %s argtypes=%o\n", style, gargstr(firstarg-1), argtypes);
		bbs->pkint(argtypes);
		pack_help(firstarg, bbs);
#endif
	}else{
		if (hoc_is_str_arg(i)) {
			bbs->pkint(0); // hoc statement style
			bbs->pkstr(gargstr(i));
		}else if (nrnpy_po2pickle) {
			size_t size;
			pname = (*nrnpy_po2pickle)(*hoc_objgetarg(i), &size);
			bbs->pkint(3); // pyfun with no arg style
			bbs->pkpickle(pname, size);
			bbs->pkint(0); // argtypes
			delete [] pname;
		}
	}
	posting_ = false;
	return id;
}
Example #18
0
File: fmenu.c Project: nrnhines/nrn
void hoc_fmenu(void){
	int imenu, flag, i, narg;
#ifdef WIN32
	hoc_execerror("fmenu not available under mswindows.", "Use xpanel series");
#endif
	imenu = *getarg(1);
	if (!ifarg(2)) { /* navigate the menu */
		chk(imenu);
		menu_manager(imenu);
		Ret(0.);
		return ;
	}
	flag = *getarg(2);
	narg = 2;
	switch(flag)
	{
		case -1:
			if (current_menu != -1) {
				diag("can't destroy current menu");
			}
			if (maxmenus) {
				for (i = 0; i<maxmenus; i++) {
					destroy(i);
				}
				free((char *)menusfirst);
				free((char *)menuslast);
			}
			maxmenus = 0;
menusfirst = (Menuitem **)emalloc((unsigned)(imenu*sizeof(Menuitem *)));
menuslast = (Menuitem **)emalloc((unsigned)(imenu*sizeof(Menuitem *)));
menuscurrent = (Menuitem **)emalloc((unsigned)(imenu*sizeof(Menuitem *)));

			maxmenus = imenu;
			for (i=0; i<maxmenus; i++) {
				menusfirst[i] = menuslast[i] = menuscurrent[i]
				 = (Menuitem *)0;
			}
			break;
		case 0:
			chk(imenu);
			if (current_menu == imenu) {
				diag(" can't destroy current menu");
			}
			destroy(imenu);
			appendaction(imenu, "Exit", "stop");
			break;
		case 1:
			while (ifarg(narg=narg+1)) {
				appendvar(imenu, gargstr(narg), (char *)0);
				menuslast[imenu]->symmin = *getarg(narg=narg+1);
				menuslast[imenu]->symmax = *getarg(narg=narg+1);
			}
			break;
		case 2:
			while (ifarg(narg=narg+1)) {
				char *prompt, *command;
				prompt = gargstr(narg);
				command = gargstr(narg=narg+1);
				appendaction(imenu, prompt, command);
			}
			break;
		case 3:
			while (ifarg(narg=narg+1)) {
				appendvar(imenu, gargstr(narg), gargstr(narg+1));
				menuslast[imenu]->symmin = *getarg(narg=narg+2);
				menuslast[imenu]->symmax = *getarg(narg=narg+1);
			}
			break;
		default:
			diag("illegal argument flag");
			break;
	}
	Ret (0.);
}
Example #19
0
void make_pointprocess() {
	char buf[256];
	int i, cnt, type, ptype;
	Symbol* sp, *s2;
	char* classname = gargstr(1);
//printf("classname=%s\n", classname);
	char* parnames = nil;
	if (ifarg(2)) {
		parnames = new char[strlen(gargstr(2)) + 1];
		strcpy(parnames, gargstr(2));
	}
//if(parnames) printf("parnames=%s\n", parnames);
	Symbol* classsym = hoc_lookup(classname);
	if (classsym->type != TEMPLATE) {
		hoc_execerror(classname, "not a template");
	}
	cTemplate* tp = classsym->u.ctemplate;
	Symlist* slist = tp->symtable;
	// increase the dataspace by 1 void pointer. The last element
	// is where the Point_process pointer can be found and when
	// the object dataspace is freed, so is the Point_process.
	if (tp->count > 0) {
fprintf(stderr, "%d object(s) of type %s already exist.\n", tp->count, classsym->name);
hoc_execerror("Can't make a template into a PointProcess when instances already exist", 0);
	}
	++tp->dataspace_size;
	char** m = make_m(false, cnt, slist, classsym->name, parnames);
	
	check_list("loc", slist);
	check_list("get_loc", slist);
	check_list("has_loc", slist);
	//so far we need only the name and type
	sp = hoc_install("loc", FUNCTION, 0., &slist); sp->cpublic = 1;
	sp = hoc_install("get_loc", FUNCTION, 0., &slist); sp->cpublic = 1;
	sp = hoc_install("has_loc", FUNCTION, 0., &slist); sp->cpublic = 1;

	Symlist* slsav = hoc_symlist;
	hoc_symlist = nil;
	HocMech* hm = common_register(m, classsym, slist, alloc_pnt, type);
	hm->slist = hoc_symlist;
	hoc_symlist = slsav;
	s2 = hoc_table_lookup(m[1], hm->slist);
	assert(s2->subtype == type);
//	type = s2->subtype;
	ptype = point_reg_helper(s2);
//printf("type=%d pointtype=%d %s %lx\n", type, ptype, s2->name, (long)s2);
	classsym->u.ctemplate->is_point_ = ptype;

	// classsym->name is already in slist as an undef, Remove it and
	// move s2 out of HocMech->slist and into slist.
	// That is the one with the u.ppsym.
	// The only reason it needs to be in slist is to find the
	// mechanims type. And it needs to be LAST in that list.
	// The only reason for the u.ppsym is for ndatclas.c and we
	// need to fill those symbols with oboff.
	sp = hoc_table_lookup(classsym->name, slist);
	hoc_unlink_symbol(sp, slist);
	hoc_unlink_symbol(s2, hm->slist);
	hoc_link_symbol(s2, slist);
	hoc_link_symbol(sp, hm->slist); // just so it isn't counted as leakage
	for (i=0; i < s2->s_varn; ++i) {
		Symbol* sp = hoc_table_lookup(s2->u.ppsym[i]->name, slist);
		s2->u.ppsym[i]->cpublic = 2;
		s2->u.ppsym[1]->u.oboff = sp->u.oboff;
	}
	for (i=0; i < cnt; ++i) {
		if (m[i]) {
			delete [] m[i];
		}
	}
	delete [] m;
	if (parnames) {
		delete [] parnames;
	}
	ret(1.);
}
Example #20
0
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);
			}
		}
	}
}
Example #21
0
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);
}