コード例 #1
0
void nimble_optim_withVarArgs(void* nimFun, OptimControl* control, OptimAns* ans,
				 	NimArr<1, double> par, optimfn objFxn,
				 	int numOtherArgs, ...){

	//Steps required:	
	//Unpack parts of control (things that are required for all optimizers)
	//Decide optimizer {
	//Based on optimizer, unpack specialized part of optimControl and call appropriate optimizer	
	//  unpack results of optimizer into ans
	//	}
	// ?return ans (depends if we want to allow return of nimble functions)

	// Generic Unpacking	
	int n = par.size();
	double* xin = &(par[0]);	//IF we want to leave par untouched by optim, we could copy these values instead of pointing at them
	double* x = &(ans->par[0]);
	double* Fmin = &(ans->Fmin);
	int* fail = &(ans->fail);
	int* fncount = &(ans->fncount);
	vector<void*>* otherArgs = new vector<void*>(numOtherArgs);
	va_list vl;
	va_start(vl, numOtherArgs);
	for(int i = 0; i < numOtherArgs; i++)
		(*otherArgs)[i] = va_arg(vl, void*);
	va_end(vl);
	vector<void*>* ex = new vector<void*> (2);
	(*ex)[0] = nimFun;
	(*ex)[1] = otherArgs;
	//Choosing and applying optimizer
	//Just using Nelder Mead as example here
	if( control->optimType == 1 ){
		NM_OptimControl* nmControl = static_cast<NM_OptimControl*>(control);	
			nmmin(n, xin, x, Fmin, objFxn, fail, nmControl->abstol, nmControl->intol,
			static_cast<void*> (ex), nmControl->alpha, nmControl->beta, nmControl->gamma, nmControl->trace,
			fncount, nmControl->maxit);
	
	}		
		delete ex;
		delete otherArgs;
	//actually, nothing else to do at this point! 
	//Could return ans if we decided to build it on the fly here instead of providing it as argument
}	
コード例 #2
0
ファイル: geod.c プロジェクト: AnneMTreasure/oce
void geod_xy_inverse(int *n,
    double *x, /* input vector of x values */
    double *y, /* input vector of y values */
    double *latr,		/* single reference latitude */
    double *lonr,		/* single reference longitude */
    double *a,		/* WGS84 major axis 6378137.00 */
    double *f,    /* WGS84 flattening parameter 1/298.257223563 */
    double *longitude, double *latitude)		/* output */
{
  //Rprintf("%3s %10s %10s %10s %10s %10s %10s [geod_xy_inverse]\n", "i", "x", "y", "lon.ref", "lat.ref", "xin[0]", "xin[1]");
  for (int i = 0; i < *n; i++) {
    double xin[2];
    double ex[4]; // x, y, lonr, latr
    ex[0] = x[i];
    ex[1] = y[i];
    ex[2] = *lonr;
    ex[3] = *latr;
    int fail=0;
    // Re the two tolerances: 1e-5 in lat or lon is 1m in space
    double abstol=1.0e-6;
    double intol=1.0e-6;
    xin[1] = y[i] / 111e3;
    xin[0] = x[i] / 111e3 / cos(xin[1]*M_PI/180.0);
    //Rprintf("%3d %10.0f %10.0f %10.2f %10.2f %10.2f %10.2f [geod_xy_inverse]\n", i, ex[0], ex[1], ex[2], ex[3], xin[0], xin[1]);
    double alpha=1.0, beta=0.5, gamma=2.0;
    double xout[2];
    double Fmin=0.0;
    int trace=0, fncount=0, maxit=500;
    int nn=2;
    nmmin(nn, xin, xout, &Fmin, 
	lonlat_misfit,
	&fail, abstol, intol, (void*)ex,
	alpha, beta, gamma, trace,
	&fncount, maxit);
    longitude[i] = xout[0];
    latitude[i] = xout[1];
    //Rprintf("  ... fncount=%d Fmin=%f\n", fncount, Fmin);
  }
}
コード例 #3
0
ファイル: MaximizeHypers.cpp プロジェクト: RGLab/pepBayes
void maximizePrecisionUnpaired(void * inputs, double * prev_val, double * x,
        bool share_nu_alpha) {
    // starting location
    precPtrsUnpaired * ex = static_cast<precPtrsUnpaired * >(inputs);
    int p = ex->p;
    int n_pep = ex->n_peptide;
    int n_trt = ex->n_trt;
    double TAU_CHECK_VAL = 1.0e-15;
    double tau_sum(0.0);
    bool orig_share = share_nu_alpha;

    for (int i = 0; i < n_trt; i++) {
        tau_sum += ex->tau[n_pep * i + p];
    }
    if ((tau_sum < TAU_CHECK_VAL) && !share_nu_alpha) {
        ex->share_nu_alpha = true;
        share_nu_alpha = true;
    }

    double par[3];
    double par_out[3];
    int n;

    par[0] = log(prev_val[0]);
    par[1] = log(prev_val[1]);
    if (share_nu_alpha) {
        par[2] = log(prev_val[1]);
        n = 2;
    } else {
        par[2] = log(prev_val[2]);
        n = 3;
    }

    // misc tuning parameters and reporting parameters
    int maxit(100), fncount, fail, trace(0);
    double Fmin, abstol(- INFINITY), intol(1.0e-4);
    double alpha(1.0), beta(.5), gamma(2.0);

    nmmin(n, par, par_out, &Fmin, precisionObjectiveFnUnpaired,
            &fail, abstol, intol, inputs, alpha, beta, gamma, trace,
            &fncount, maxit);

    if (fail > 0) {
        x[0] = prev_val[0];
        x[1] = prev_val[1];
        if (share_nu_alpha) {
            x[2] = prev_val[1];
        } else {
            x[2] = prev_val[2];
        }
        return;
    }

    x[0] = exp(par_out[0]);
    x[1] = exp(par_out[1]);
    if (share_nu_alpha) {
        x[2] = exp(par_out[1]);
    } else {
        x[2] = exp(par_out[2]);
    }

    if ((tau_sum < TAU_CHECK_VAL) && (!orig_share)) {
        x[2] = sqrt(DBL_MIN);
    }
    return;
}
コード例 #4
0
ファイル: nimOptim.cpp プロジェクト: cran/nimble
// This attempts to match the behavior of optim() defined in the documentation
//   https://stat.ethz.ch/R-manual/R-devel/library/stats/html/optim.html
// and in the reference implementation
//   https://svn.r-project.org/R/trunk/src/library/stats/R/optim.R
//   https://svn.r-project.org/R/trunk/src/library/stats/src/optim.c
//   https://svn.r-project.org/R/trunk/src/include/R_ext/Applic.h
nimSmartPtr<OptimResultNimbleList> NimOptimProblem::solve(
    NimArr<1, double>& par) {
    NIM_ASSERT1(!par.isMap(), "Internal error: failed to handle mapped NimArr");
    const int n = par.dimSize(0);

    nimSmartPtr<OptimResultNimbleList> result = new OptimResultNimbleList;
    result->par = par;
    result->counts.initialize(NA_INTEGER, true, 2);
    if (hessian_) {
        result->hessian.initialize(NA_REAL, true, n, n);
    }

    // Set context-dependent default control_ values.
    if (control_->maxit == NA_INTEGER) {
        if (method_ == "Nelder-Mead") {
            control_->maxit = 500;
        } else {
            control_->maxit = 100;
        }
    }

    // Parameters common to all methods.
    double* dpar = par.getPtr();
    double* X = result->par.getPtr();
    double* Fmin = &(result->value);
    int* fail = &(result->convergence);
    void* ex = this;
    int* fncount = &(result->counts[0]);
    int* grcount = &(result->counts[1]);

    if (method_ == "Nelder-Mead") {
        nmmin(n, dpar, X, Fmin, NimOptimProblem::fn, fail, control_->abstol,
              control_->reltol, ex, control_->alpha, control_->beta,
              control_->gamma, control_->trace, fncount, control_->maxit);
    } else if (method_ == "BFGS") {
        std::vector<int> mask(n, 1);
        vmmin(n, dpar, Fmin, NimOptimProblem::fn, NimOptimProblem::gr,
              control_->maxit, control_->trace, mask.data(), control_->abstol,
              control_->reltol, control_->REPORT, ex, fncount, grcount, fail);
        result->par = par;
    } else if (method_ == "CG") {
        cgmin(n, dpar, X, Fmin, NimOptimProblem::fn, NimOptimProblem::gr, fail,
              control_->abstol, control_->reltol, ex, control_->type,
              control_->trace, fncount, grcount, control_->maxit);
    } else if (method_ == "L-BFGS-B") {
        if (lower_.dimSize(0) == 1) lower_.initialize(lower_[0], true, n);
        if (upper_.dimSize(0) == 1) upper_.initialize(upper_[0], true, n);
        NIM_ASSERT_SIZE(lower_, n);
        NIM_ASSERT_SIZE(upper_, n);
        std::vector<int> nbd(n, 0);
        for (int i = 0; i < n; ++i) {
            if (std::isfinite(lower_[i])) nbd[i] |= 1;
            if (std::isfinite(upper_[i])) nbd[i] |= 2;
        }
        char msg[60];
        lbfgsb(n, control_->lmm, X, lower_.getPtr(), upper_.getPtr(),
               nbd.data(), Fmin, NimOptimProblem::fn, NimOptimProblem::gr, fail,
               ex, control_->factr, control_->pgtol, fncount, grcount,
               control_->maxit, msg, control_->trace, control_->REPORT);
        result->message = msg;
    } else {
        NIMERROR("Unknown method_: %s", method_.c_str());
    }
    result->value *= control_->fnscale;

    // Compute Hessian.
    if (hessian_) {
        Rf_warning("Hessian computation is not implemented");  // TODO
    }

    return result;
}
コード例 #5
0
ファイル: optim.c プロジェクト: FatManCoding/r-source
/* par fn gr method options */
SEXP optim(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP par, fn, gr, method, options, tmp, slower, supper;
    SEXP res, value, counts, conv;
    int i, npar=0, *mask, trace, maxit, fncount = 0, grcount = 0, nREPORT, tmax;
    int ifail = 0;
    double *dpar, *opar, val = 0.0, abstol, reltol, temp;
    const char *tn;
    OptStruct OS;
    PROTECT_INDEX par_index;

    args = CDR(args);
    OS = (OptStruct) R_alloc(1, sizeof(opt_struct));
    OS->usebounds = 0;
    OS->R_env = rho;
    par = CAR(args);
    OS->names = getAttrib(par, R_NamesSymbol);
    args = CDR(args); fn = CAR(args);
    if (!isFunction(fn)) error(_("'fn' is not a function"));
    args = CDR(args); gr = CAR(args);
    args = CDR(args); method = CAR(args);
    if (!isString(method)|| LENGTH(method) != 1)
	error(_("invalid '%s' argument"), "method");
    tn = CHAR(STRING_ELT(method, 0));
    args = CDR(args); options = CAR(args);
    PROTECT(OS->R_fcall = lang2(fn, R_NilValue));
    PROTECT_WITH_INDEX(par = coerceVector(par, REALSXP), &par_index);
    if (MAYBE_REFERENCED(par))
    	REPROTECT(par = duplicate(par), par_index);
    npar = LENGTH(par);
    dpar = vect(npar);
    opar = vect(npar);
    trace = asInteger(getListElement(options, "trace"));
    OS->fnscale = asReal(getListElement(options, "fnscale"));
    tmp = getListElement(options, "parscale");
    if (LENGTH(tmp) != npar)
	error(_("'parscale' is of the wrong length"));
    PROTECT(tmp = coerceVector(tmp, REALSXP));
    OS->parscale = vect(npar);
    for (i = 0; i < npar; i++) OS->parscale[i] = REAL(tmp)[i];
    UNPROTECT(1);
    for (i = 0; i < npar; i++)
	dpar[i] = REAL(par)[i] / (OS->parscale[i]);
    PROTECT(res = allocVector(VECSXP, 5));
    SEXP names;
    PROTECT(names = allocVector(STRSXP, 5));
    SET_STRING_ELT(names, 0, mkChar("par"));
    SET_STRING_ELT(names, 1, mkChar("value"));
    SET_STRING_ELT(names, 2, mkChar("counts"));
    SET_STRING_ELT(names, 3, mkChar("convergence"));
    SET_STRING_ELT(names, 4, mkChar("message"));
    setAttrib(res, R_NamesSymbol, names);
    UNPROTECT(1);
    PROTECT(value = allocVector(REALSXP, 1));
    PROTECT(counts = allocVector(INTSXP, 2));
    SEXP countnames;
    PROTECT(countnames = allocVector(STRSXP, 2));
    SET_STRING_ELT(countnames, 0, mkChar("function"));
    SET_STRING_ELT(countnames, 1, mkChar("gradient"));
    setAttrib(counts, R_NamesSymbol, countnames);
    UNPROTECT(1);
    PROTECT(conv = allocVector(INTSXP, 1));
    abstol = asReal(getListElement(options, "abstol"));
    reltol = asReal(getListElement(options, "reltol"));
    maxit = asInteger(getListElement(options, "maxit"));
    if (maxit == NA_INTEGER) error(_("'maxit' is not an integer"));

    if (strcmp(tn, "Nelder-Mead") == 0) {
	double alpha, beta, gamm;

	alpha = asReal(getListElement(options, "alpha"));
	beta = asReal(getListElement(options, "beta"));
	gamm = asReal(getListElement(options, "gamma"));
	nmmin(npar, dpar, opar, &val, fminfn, &ifail, abstol, reltol,
	      (void *)OS, alpha, beta, gamm, trace, &fncount, maxit);
	for (i = 0; i < npar; i++)
	    REAL(par)[i] = opar[i] * (OS->parscale[i]);
	grcount = NA_INTEGER;

    }
    else if (strcmp(tn, "SANN") == 0) {
	tmax = asInteger(getListElement(options, "tmax"));
	temp = asReal(getListElement(options, "temp"));
	if (trace) trace = asInteger(getListElement(options, "REPORT"));
	if (tmax == NA_INTEGER || tmax < 1) // PR#15194
	    error(_("'tmax' is not a positive integer"));
	if (!isNull(gr)) {
	    if (!isFunction(gr)) error(_("'gr' is not a function"));
		PROTECT(OS->R_gcall = lang2(gr, R_NilValue));
	} else {
	    PROTECT(OS->R_gcall = R_NilValue); /* for balance */
	}
	samin (npar, dpar, &val, fminfn, maxit, tmax, temp, trace, (void *)OS);
	for (i = 0; i < npar; i++)
	    REAL(par)[i] = dpar[i] * (OS->parscale[i]);
	fncount = npar > 0 ? maxit : 1;
	grcount = NA_INTEGER;
	UNPROTECT(1);  /* OS->R_gcall */

    } else if (strcmp(tn, "BFGS") == 0) {
	SEXP ndeps;

	nREPORT = asInteger(getListElement(options, "REPORT"));
	if (!isNull(gr)) {
	    if (!isFunction(gr)) error(_("'gr' is not a function"));
	    PROTECT(OS->R_gcall = lang2(gr, R_NilValue));
	} else {
	    PROTECT(OS->R_gcall = R_NilValue); /* for balance */
	    ndeps = getListElement(options, "ndeps");
	    if (LENGTH(ndeps) != npar)
		error(_("'ndeps' is of the wrong length"));
	    OS->ndeps = vect(npar);
	    PROTECT(ndeps = coerceVector(ndeps, REALSXP));
	    for (i = 0; i < npar; i++) OS->ndeps[i] = REAL(ndeps)[i];
	    UNPROTECT(1);
	}
	mask = (int *) R_alloc(npar, sizeof(int));
	for (i = 0; i < npar; i++) mask[i] = 1;
	vmmin(npar, dpar, &val, fminfn, fmingr, maxit, trace, mask, abstol,
	      reltol, nREPORT, (void *)OS, &fncount, &grcount, &ifail);
	for (i = 0; i < npar; i++)
	    REAL(par)[i] = dpar[i] * (OS->parscale[i]);
	UNPROTECT(1); /* OS->R_gcall */
    } else if (strcmp(tn, "CG") == 0) {
	int type;
	SEXP ndeps;

	type = asInteger(getListElement(options, "type"));
	if (!isNull(gr)) {
	    if (!isFunction(gr)) error(_("'gr' is not a function"));
	    PROTECT(OS->R_gcall = lang2(gr, R_NilValue));
	} else {
	    PROTECT(OS->R_gcall = R_NilValue); /* for balance */
	    ndeps = getListElement(options, "ndeps");
	    if (LENGTH(ndeps) != npar)
		error(_("'ndeps' is of the wrong length"));
	    OS->ndeps = vect(npar);
	    PROTECT(ndeps = coerceVector(ndeps, REALSXP));
	    for (i = 0; i < npar; i++) OS->ndeps[i] = REAL(ndeps)[i];
	    UNPROTECT(1);
	}
	cgmin(npar, dpar, opar, &val, fminfn, fmingr, &ifail, abstol,
	      reltol, (void *)OS, type, trace, &fncount, &grcount, maxit);
	for (i = 0; i < npar; i++)
	    REAL(par)[i] = opar[i] * (OS->parscale[i]);
	UNPROTECT(1); /* OS->R_gcall */

    } else if (strcmp(tn, "L-BFGS-B") == 0) {
	SEXP ndeps, smsg;
	double *lower = vect(npar), *upper = vect(npar);
	int lmm, *nbd = (int *) R_alloc(npar, sizeof(int));
	double factr, pgtol;
	char msg[60];

	nREPORT = asInteger(getListElement(options, "REPORT"));
	factr = asReal(getListElement(options, "factr"));
	pgtol = asReal(getListElement(options, "pgtol"));
	lmm = asInteger(getListElement(options, "lmm"));
	if (!isNull(gr)) {
	    if (!isFunction(gr)) error(_("'gr' is not a function"));
	    PROTECT(OS->R_gcall = lang2(gr, R_NilValue));
	} else {
	    PROTECT(OS->R_gcall = R_NilValue); /* for balance */
	    ndeps = getListElement(options, "ndeps");
	    if (LENGTH(ndeps) != npar)
		error(_("'ndeps' is of the wrong length"));
	    OS->ndeps = vect(npar);
	    PROTECT(ndeps = coerceVector(ndeps, REALSXP));
	    for (i = 0; i < npar; i++) OS->ndeps[i] = REAL(ndeps)[i];
	    UNPROTECT(1);
	}
	args = CDR(args); slower = CAR(args); /* coerce in calling code */
	args = CDR(args); supper = CAR(args);
	for (i = 0; i < npar; i++) {
	    lower[i] = REAL(slower)[i] / (OS->parscale[i]);
	    upper[i] = REAL(supper)[i] / (OS->parscale[i]);
	    if (!R_FINITE(lower[i])) {
		if (!R_FINITE(upper[i])) nbd[i] = 0; else nbd[i] = 3;
	    } else {
		if (!R_FINITE(upper[i])) nbd[i] = 1; else nbd[i] = 2;
	    }
	}
	OS->usebounds = 1;
	OS->lower = lower;
	OS->upper = upper;
	lbfgsb(npar, lmm, dpar, lower, upper, nbd, &val, fminfn, fmingr,
	       &ifail, (void *)OS, factr, pgtol, &fncount, &grcount,
	       maxit, msg, trace, nREPORT);
	for (i = 0; i < npar; i++)
	    REAL(par)[i] = dpar[i] * (OS->parscale[i]);
	UNPROTECT(1); /* OS->R_gcall */
	PROTECT(smsg = mkString(msg));
	SET_VECTOR_ELT(res, 4, smsg);
	UNPROTECT(1);
    } else
	error(_("unknown 'method'"));

    if(!isNull(OS->names)) setAttrib(par, R_NamesSymbol, OS->names);
    REAL(value)[0] = val * (OS->fnscale);
    SET_VECTOR_ELT(res, 0, par); SET_VECTOR_ELT(res, 1, value);
    INTEGER(counts)[0] = fncount; INTEGER(counts)[1] = grcount;
    SET_VECTOR_ELT(res, 2, counts);
    INTEGER(conv)[0] = ifail;
    SET_VECTOR_ELT(res, 3, conv);
    UNPROTECT(6);
    return res;
}