예제 #1
0
void
VR_dovm(Sint *ntr, Sdata *train, Sdata *weights,
		Sint *Nw, double *wts, double *Fmin,
		Sint *maxit, Sint *trace, Sint *mask,
		double *abstol, double *reltol, int *ifail)
{
    int fncount, grcount;
    NTrain = *ntr;
    TrainIn = train;
    TrainOut = train + Ninputs * NTrain;
    Weights = weights;
    vmmin((int) *Nw, wts, Fmin, fminfn, fmingr, 
		  (int) *maxit, (int) *trace, mask,
		  *abstol, *reltol, REPORT, NULL, &fncount, &grcount, ifail);
}
예제 #2
0
void maximizeTnormHypers(const double * data, int data_len, const double m_mean,
        const double m_prec, const double nu_rate, const double nu_shape,
        double * x) {
    // inside betaHyperObjectiveFn:
    // const double beta1_sum(input[0]);
    // const double beta1_sqr_sum(input[1]);
    // const double P(input[2]);
    // const double l1(input[3]);
    // const double s1(input[4]);
    // const double m_bar(input[5]);
    // const double nu_m(input[6]);

    double input[7];
    input[0] = 0.0;
    input[1] = 0.0;
    for (int j = 0; j < data_len; j++) {
        input[0] += data[j];
        input[1] += data[j] * data[j];
    }
    input[2] = (double) data_len;
    input[3] = nu_rate;
    input[4] = nu_shape;
    input[5] = m_mean;
    input[6] = m_prec;

    // initial guess for location and (log) inverse-scale;
    double par[2];
    par[0] = input[0] / input[2];
    par[1] = - log(1.0 + input[1] / input[2] - par[0] * par[0]);

    // misc BFGS tuning parameters and reporting parameters
    int n(2), report(10), maxit(100), fncount, grcount, fail, trace(0);
    int mask[2] = {1, 1};
    double Fmin, abstol(- INFINITY), reltol(1.0e-8);

    vmmin(n, par, &Fmin, betaHyperObjectiveFn, betaHyperObjectiveGr,
            maxit, trace, mask, abstol, reltol, report, (void *) input,
            &fncount, &grcount, &fail);

    if (fail > 0)
        return;

    x[0] = par[0];
    x[1] = exp(par[1]);
}
예제 #3
0
void maximizeGammaHypers(const double * data, int data_len, const double l_s,
        const double l_lambda, double * x) {
    // inside gammaHyperObjectiveFn:
    // const double sum_log_x(input[0]);
    // const double sum_x(input[1]);
    // const double P(input[2]);
    // const double l_s(input[3]);
    // const double l_l(input[4]);

    double input[5];
    input[0] = 0.0;
    input[1] = 0.0;
    for(int j = 0; j < data_len; j++) {
        input[0] += log(data[j]);
        input[1] += data[j];
    }
    input[2] = (double) data_len;
    input[3] = l_s;
    input[4] = l_lambda;

    // initial guess for max of shape (pretty good, actually)
    double par, s = log(input[1] / input[2]) - input[0] / input[2];
    s = ((3 - s) + sqrt((s - 3) * (s - 3) + 24.0 * s)) / (12 * s);
    par = s;

    // misc BFGS tuning parameters and reporting parameters
    int n(1), mask(1), report(10), maxit(100), fncount, grcount, fail, trace(0);
    double Fmin, abstol(- INFINITY), reltol(1.0e-8);

    vmmin(n, &par, &Fmin, gammaHyperObjectiveFn, gammaHyperObjectiveGr,
            maxit, trace, &mask, abstol, reltol, report, (void *) input,
            &fncount, &grcount, &fail);

    // optimization failed for some reason; return good guess
    if (fail > 0)
        par = s;

    x[0] = par;
    x[1] = input[2] * par / (l_lambda + input[1]);
    return;
}
예제 #4
0
파일: expreg.c 프로젝트: cran/eha
void expsup(int *iter, double *eps, int *printlevel,
	    int *nn, int *ncov, int *bdim,
	    double *time0, double *time, int * ind,
	    double *covar, double *offset, double *shape,
	    double *init, double *beta, double *lambda, double *lambda_sd,
	    double *loglik, double *dloglik, double *variance, double *sctest,
	    int *conver, int *fail){

    Exts *ex;
    int ord, i, j;
    int iok;
    int maxiter;
    int trace;
    int *mask;
    int events;
    int nREPORT = 1;
    int fncount, grcount;
    int ipfixed = 1;
    double Fmin;
    double zb, s, d, ap, bdz;

    ex = (Exts *)R_alloc(1, sizeof(Exts));
    mask = (int *)R_alloc(*bdim, sizeof(int));

    for (i = 0; i < *bdim; i++){
	mask[i] = 1;
    }

    maxiter = 1000;
    trace = *printlevel;

    iok = 0;

/* Fill in 'ex': */
    ex->pfix = shape;
    ex->mb = ncov;
    ex->nn = nn;
    ex->z = covar;
    ex->time0 = time0;
    ex->time = time;
    ex->ind = ind;
    ex->offset = offset;
    ex->iok = &iok;

    for (i = 0; i < *ncov; i++) beta[i] = init[i];
    *lambda = 0.0;
    events = 0;
    for (i = 0; i < *nn; i++){
	zb = offset[i];
	for (j = 0; j < *ncov; j++){
	    zb += beta[j] * covar[j + i * (*ncov)];
	}
	*lambda += exp(zb) * (time[i] - time0[i]);
	events += ind[i];
    }
    if (events <= 0) error("No events\n");
    if (*lambda <= 0.0) error("No (or negative) exposure time!\n");
    *lambda = (double)events / *lambda;
    beta[*ncov] = log(*lambda);

    Fmin = 0.0;
    s = 0.0;
    d = 0.0;
    bdz = 0.0;
    ap = log(*lambda);
    for (i = 0; i < *nn; i++){
	zb = offset[i];
	for (j = 0; j < *ncov; j++){
	    if (ind[i])
		bdz += beta[j] * covar[j + i * (*ncov)];
	    zb += beta[j] * covar[j + i * (*ncov)];
	}
	s += *lambda * exp(zb) * (time[i] - time0[i]);
	d += ind[i];
	Fmin += ind[i] * (ap + zb);
	Fmin -= *lambda * exp(zb) * (time[i] - time0[i]);
    }

    ord = 0; /* get initial loglik value in 'loglik[0]' */

    F77_CALL(wfunc)(&ord, &ipfixed, ex->pfix, bdim, ex->mb, beta,
		    ex->nn, ex->z, ex->time0, ex->time, ex->ind, ex->offset,
		    &Fmin, dloglik, variance, ex->iok);
    loglik[0] = -Fmin; /* NOTE! */

    vmmin(*bdim, beta, &Fmin,   
	  e_fun, ge_fun, maxiter, trace,  
	  mask, *eps, *eps, nREPORT,
	  ex, &fncount, &grcount, fail);

    loglik[1] = -Fmin;
    ord = 2;
    F77_CALL(wfunc)(&ord, &ipfixed, ex->pfix, bdim, ex->mb, beta,
		    ex->nn, ex->z, ex->time0, ex->time, ex->ind, ex->offset,
		    &Fmin, dloglik, variance, ex->iok);
 
    F77_CALL(expnr)(iter, eps, printlevel, nn, ncov, bdim,
		    time0, time, ind, covar, offset, shape,
		    beta, lambda, lambda_sd, &Fmin, dloglik,
		    variance,
		    conver, fail);
    loglik[1] = Fmin;
}
예제 #5
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;
}
예제 #6
0
/* 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;
}