/*! \fn int newuoa_initialization(INIT_DATA *initData) * * This function performs initialization using the newuoa function, which is * a trust region method that forms quadratic models by interpolation. */ int newuoa_initialization(INIT_DATA *initData) { long IPRINT = ACTIVE_STREAM(LOG_INIT) ? 1000 : 0; long MAXFUN = 1000 * initData->nVars; double RHOEND = 1.0e-12; double RHOBEG = 10; /* This should be about one tenth of the greatest expected value of a variable. Perhaps the nominal value can be used for this. */ long NPT = 2*initData->nVars+1; double *W = (double*)calloc((NPT+13)*(NPT+initData->nVars)+3*initData->nVars*(initData->nVars+3)/2, sizeof(double)); ASSERT(W, "out of memory"); globalData = initData->simData; globalInitialResiduals = initData->initialResiduals; NEWUOA(&initData->nVars, &NPT, initData->vars, &RHOBEG, &RHOEND, &IPRINT, &MAXFUN, W, leastSquare); free(W); globalData = NULL; globalInitialResiduals = NULL; /* Calculate the residual to verify that equations are consistent. */ return reportResidualValue(initData); }
/*! \fn int simplex_initialization(DATA* data, INIT_DATA* initData) * * This function performs initialization by using the simplex algorithm. * This does not require a jacobian for the residuals. */ int simplex_initialization(INIT_DATA* initData) { int ind = 0; double funcValue = 0; double STOPCR = 0, SIMP = 0; long IPRINT = 0, NLOOP = 0, IQUAD = 0, IFAULT = 0, MAXF = 0; double *STEP = (double*)malloc(initData->nVars * sizeof(double)); double *VAR = (double*)malloc(initData->nVars * sizeof(double)); ASSERT(STEP, "out of memory"); ASSERT(VAR, "out of memory"); /* Start with stepping .5 in each direction. */ for(ind = 0; ind<initData->nVars; ind++) { /* some kind of scaling */ STEP[ind] = (initData->vars[ind] !=0.0 ? fabs(initData->vars[ind])/1000.0 : 1); /* 1.0 */ VAR[ind] = 0.0; } /* Set max. no. of function evaluations = 5000, print every 100. */ MAXF = 1000 * initData->nVars; IPRINT = ACTIVE_STREAM(LOG_INIT) ? MAXF/10 : -1; /* Set value for stopping criterion. Stopping occurs when the * standard deviation of the values of the objective function at * the points of the current simplex < stopcr. */ STOPCR = 1.e-12; NLOOP = initData->nVars; /* Fit a quadratic surface to be sure a minimum has been found. */ IQUAD = 0; /* As function value is being evaluated in DOUBLE PRECISION, it * should be accurate to about 15 decimals. If we set simp = 1.d-6, * we should get about 9 dec. digits accuracy in fitting the surface. */ SIMP = 1.e-12; /* Now call NELMEAD to do the work. */ funcValue = leastSquareWithLambda(initData, 1.0); if(fabs(funcValue) != 0) { globalData = initData->simData; globalInitialResiduals = initData->initialResiduals; NELMEAD(initData->vars, STEP, &initData->nVars, &funcValue, &MAXF, &IPRINT, &STOPCR, &NLOOP, &IQUAD, &SIMP, VAR, leastSquare, &IFAULT); globalData = NULL; globalInitialResiduals = NULL; } else { INFO1(LOG_INIT, "simplex_initialization | Result of leastSquare method = %g. The initial guess fits to the system", funcValue); } funcValue = leastSquareWithLambda(initData, 1.0); INFO1(LOG_INIT, "leastSquare=%g", funcValue); if(IFAULT == 1) { if(SIMP < funcValue) { WARNING1(LOG_INIT, "Error in initialization. Solver iterated %d times without finding a solution", (int)MAXF); return -1; } } else if(IFAULT == 2) { WARNING(LOG_INIT, "Error in initialization. Inconsistent initial conditions."); return -2; } else if(IFAULT == 3) { WARNING(LOG_INIT, "Error in initialization. Number of initial values to calculate < 1"); return -3; } else if(IFAULT == 4) { WARNING(LOG_INIT, "Error in initialization. Internal error, NLOOP < 1."); return -4; } return reportResidualValue(initData); }