void NodeMemoryAnchors::allocate_arrays(const EngineOptions& options) { deallocate_arrays(); logger_memories_ = new log::LoggerControlBlock*[options.log_.loggers_per_node_]; thread_anchors_ = new ThreadMemoryAnchors[options.thread_.thread_count_per_group_]; }
void simplex_optimization ( vfp nmodel, /* pointer to noise model */ vfp smodel, /* pointer to signal model */ int r, /* number of parameters in the noise model */ int p, /* number of parameters in the signal model */ float * min_nconstr, /* minimum parameter constraints for noise model */ float * max_nconstr, /* maximum parameter constraints for noise model */ float * min_sconstr, /* minimum parameter constraints for signal model */ float * max_sconstr, /* maximum parameter constraints for signal model */ int nabs, /* use absolute constraints for noise parameters */ int ts_length, /* length of time series array */ float ** x_array, /* independent variable matrix */ float * ts_array, /* observed time series */ float * par_rdcd, /* estimated parameters for the reduced model */ float * parameters, /* estimated parameters */ float * sse /* error sum of squares */ ) { const int MAX_ITERATIONS = 50; /* maximum number of iterations */ const int MAX_RESTARTS = 5; /* maximum number of restarts */ const float EXPANSION_COEF = 2.0; /* expansion coefficient */ const float REFLECTION_COEF = 1.0; /* reflection coefficient */ const float CONTRACTION_COEF = 0.5; /* contraction coefficient */ const float TOLERANCE = 1.0e-4; /* solution convergence tolerance */ float ** simplex = NULL; /* the simplex itself */ float * centroid = NULL; /* center of mass of the simplex */ float * response = NULL; /* error sum of squares at each vertex */ float * step_size = NULL; /* controls random placement of new vertex */ float * test1 = NULL; /* test vertex */ float * test2 = NULL; /* test vertex */ float resp1, resp2; /* error sum of squares for test vertex */ int i; /* vertex index */ int worst; /* index of worst vertex in simplex */ int best; /* index of best vertex in simplex */ int next; /* index of next-to-worst vertex in simplex */ int num_iter; /* number of simplex algorithm iterations */ int num_restarts; /* number of restarts of simplex algorithm */ int done; /* boolean for search finished */ float fit; /* array of fitted time series values */ int dimension; /* dimension of parameter space */ /*----- dimension of parameter space -----*/ dimension = r + p; /*----- allocate memory -----*/ allocate_arrays (dimension, &simplex, ¢roid, &response, &step_size, &test1, &test2); /*----- initialization for simplex algorithm -----*/ initialize_simplex (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, parameters, simplex, response, step_size, ts_length, x_array, ts_array); /* start loop to do simplex optimization */ num_iter = 0; num_restarts = 0; done = 0; while (!done) { /*----- find the worst vertex and compute centroid of remaining simplex, discarding the worst vertex -----*/ eval_vertices (dimension, response, &worst, &next, &best); calc_centroid (dimension, simplex, worst, centroid); /*----- reflect the worst point through the centroid -----*/ calc_reflection (dimension, simplex, centroid, worst, REFLECTION_COEF, test1); resp1 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test1, ts_length, x_array, ts_array); /*----- test the reflection against the best vertex and expand it if the reflection is better. if not, keep the reflection -----*/ if (resp1 < response[best]) { /*----- try expanding -----*/ calc_reflection (dimension, simplex, centroid, worst, EXPANSION_COEF, test2); resp2 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test2, ts_length, x_array, ts_array); if (resp2 <= resp1) /* keep expansion */ replace (dimension, simplex, response, worst, test2, resp2); else /* keep reflection */ replace (dimension, simplex, response, worst, test1, resp1); } else if (resp1 < response[next]) { /*----- new response is between the best and next worst so keep reflection -----*/ replace (dimension, simplex, response, worst, test1, resp1); } else { /*----- try contraction -----*/ if (resp1 >= response[worst]) calc_reflection (dimension, simplex, centroid, worst, -CONTRACTION_COEF, test2); else calc_reflection (dimension, simplex, centroid, worst, CONTRACTION_COEF, test2); resp2 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test2, ts_length, x_array, ts_array); /*---- test the contracted response against the worst response ----*/ if (resp2 > response[worst]) { /*----- new contracted response is worse, so decrease step size and restart -----*/ num_iter = 0; num_restarts += 1; restart (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, simplex, response, step_size, ts_length, x_array, ts_array); } else /*----- keep contraction -----*/ replace (dimension, simplex, response, worst, test2, resp2); } /*----- test to determine when to stop. first, check the number of iterations -----*/ num_iter += 1; /*----- increment iteration counter -----*/ if (num_iter >= MAX_ITERATIONS) { /*----- restart with smaller steps -----*/ num_iter = 0; num_restarts += 1; restart (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, simplex, response, step_size, ts_length, x_array, ts_array); } /*----- limit the number of restarts -----*/ if (num_restarts == MAX_RESTARTS) done = 1; /*----- compare relative standard deviation of vertex responses against a defined tolerance limit -----*/ fit = calc_good_fit (dimension, response); if (fit <= TOLERANCE) done = 1; /*----- if done, copy the best solution to the output array -----*/ if (done) { eval_vertices (dimension, response, &worst, &next, &best); for (i = 0; i < dimension; i++) parameters[i] = simplex[best][i]; *sse = response[best]; } } /*----- while (!done) -----*/ deallocate_arrays (dimension, &simplex, ¢roid, &response, &step_size, &test1, &test2); }
void simplex_optimization (float * parameters, float * sse) { const int MAX_ITERATIONS = 100; const int MAX_RESTARTS = 25; const float EXPANSION_COEF = 2.0; const float REFLECTION_COEF = 1.0; const float CONTRACTION_COEF = 0.5; const float TOLERANCE = 1.0e-10; float ** simplex = NULL; float * centroid = NULL; float * response = NULL; float * step_size = NULL; float * test1 = NULL; float * test2 = NULL; float resp1, resp2; int i, worst, best, next; int num_iter, num_restarts; int done; float fit; allocate_arrays (&simplex, ¢roid, &response, &step_size, &test1, &test2); simplex_initialize (parameters, simplex, response, step_size); /* start loop to do simplex optimization */ num_iter = 0; num_restarts = 0; done = 0; while (!done) { /* find the worst vertex and compute centroid of remaining simplex, discarding the worst vertex */ eval_vertices (response, &worst, &next, &best); calc_centroid (simplex, worst, centroid); /* reflect the worst point through the centroid */ calc_reflection (simplex, centroid, worst, REFLECTION_COEF, test1); resp1 = calc_error (test1); /* test the reflection against the best vertex and expand it if the reflection is better. if not, keep the reflection */ if (resp1 < response[best]) { /* try expanding */ calc_reflection (simplex, centroid, worst, EXPANSION_COEF, test2); resp2 = calc_error (test2); if (resp2 <= resp1) /* keep expansion */ replace (simplex, response, worst, test2, resp2); else /* keep reflection */ replace (simplex, response, worst, test1, resp1); } else if (resp1 < response[next]) { /* new response is between the best and next worst so keep reflection */ replace (simplex, response, worst, test1, resp1); } else { /* try contraction */ if (resp1 >= response[worst]) calc_reflection (simplex, centroid, worst, -CONTRACTION_COEF, test2); else calc_reflection (simplex, centroid, worst, CONTRACTION_COEF, test2); resp2 = calc_error (test2); /* test the contracted response against the worst response */ if (resp2 > response[worst]) { /* new contracted response is worse, so decrease step size and restart */ num_iter = 0; num_restarts += 1; restart (simplex, response, step_size); } else /* keep contraction */ replace (simplex, response, worst, test2, resp2); } /* test to determine when to stop. first, check the number of iterations */ num_iter += 1; /* increment iteration counter */ if (num_iter >= MAX_ITERATIONS) { /* restart with smaller steps */ num_iter = 0; num_restarts += 1; restart (simplex, response, step_size); } /* limit the number of restarts */ if (num_restarts == MAX_RESTARTS) done = 1; /* compare relative standard deviation of vertex responses against a defined tolerance limit */ fit = calc_good_fit (response); if (fit <= TOLERANCE) done = 1; /* if done, copy the best solution to the output array */ if (done) { eval_vertices (response, &worst, &next, &best); for (i = 0; i < DIMENSION; i++) parameters[i] = simplex[best][i]; *sse = response[best]; } } /* while (!done) */ number_restarts = num_restarts; deallocate_arrays (&simplex, ¢roid, &response, &step_size, &test1, &test2); }
void NLSSOLLeastSq::minimize_residuals() { //------------------------------------------------------------------ // Solve the problem. //------------------------------------------------------------------ // set the object instance pointers for use within the static member fns NLSSOLLeastSq* prev_nls_instance = nlssolInstance; SOLBase* prev_sol_instance = solInstance; nlssolInstance = this; solInstance = this; optLSqInstance = this; // set the constraint offset used in SOLBase::constraint_eval() constrOffset = numLeastSqTerms; fnEvalCntr = 0; // prevent current iterator from continuing previous counting // Use data structures in the NLSSOL call that are NOT updated in // constraint_eval or least_sq_eval [Using overlapping arrays causes // erroneous behavior]. int num_cv = numContinuousVars; double local_f_val = 0.; RealVector local_lsq_vals(numLeastSqTerms); RealVector local_lsq_offsets(numLeastSqTerms, true); double* local_lsq_grads = new double [numLeastSqTerms*numContinuousVars]; allocate_arrays(numContinuousVars, numNonlinearConstraints, iteratedModel.linear_ineq_constraint_coeffs(), iteratedModel.linear_eq_constraint_coeffs()); allocate_workspace(numContinuousVars, numNonlinearConstraints, numLinearConstraints, numLeastSqTerms); // NLSSOL requires a non-zero array size. Therefore, size the local // constraint arrays and matrices to a size of 1 if there are no nonlinear // constraints and to the proper size otherwise. RealVector local_c_vals(nlnConstraintArraySize); // initialize local_des_vars with DB initial point. Variables are updated // in constraint_eval/least_sq_eval RealVector local_des_vars; copy_data(iteratedModel.continuous_variables(), local_des_vars); // Augmentation of bounds appears here rather than in the constructor because // these bounds must be updated from model bounds each time an iterator is // run within the B&B strategy. RealVector augmented_l_bnds, augmented_u_bnds; copy_data(iteratedModel.continuous_lower_bounds(), augmented_l_bnds); copy_data(iteratedModel.continuous_upper_bounds(), augmented_u_bnds); augment_bounds(augmented_l_bnds, augmented_u_bnds, iteratedModel.linear_ineq_constraint_lower_bounds(), iteratedModel.linear_ineq_constraint_upper_bounds(), iteratedModel.linear_eq_constraint_targets(), iteratedModel.nonlinear_ineq_constraint_lower_bounds(), iteratedModel.nonlinear_ineq_constraint_upper_bounds(), iteratedModel.nonlinear_eq_constraint_targets()); NLSSOL_F77( numLeastSqTerms, num_cv, numLinearConstraints, numNonlinearConstraints, linConstraintArraySize, nlnConstraintArraySize, numLeastSqTerms, num_cv, linConstraintMatrixF77, augmented_l_bnds.values(), augmented_u_bnds.values(), constraint_eval, least_sq_eval, informResult, numberIterations, &constraintState[0], local_c_vals.values(), constraintJacMatrixF77, local_lsq_offsets.values(), local_lsq_vals.values(), local_lsq_grads, &cLambda[0], local_f_val, upperFactorHessianF77, local_des_vars.values(), &intWorkSpace[0], intWorkSpaceSize, &realWorkSpace[0], realWorkSpaceSize ); // NLSSOL completed. Do post-processing/output of final NLSSOL info and data: Cout << "\nNLSSOL exits with INFORM code = " << informResult << " (see \"Interpretation of output\" section of NPSOL manual)\n"; deallocate_arrays(); // SOLBase deallocate fn (shared with NPSOLOptimizer) delete [] local_lsq_grads; // Set best variables and response for use by strategy level. // local_des_vars, local_lsq_vals, & local_c_vals contain the optimal design // (not the final fn. eval) since NLSSOL performs this assignment internally // prior to exiting (see "Subroutine npsol" section of NPSOL manual). bestVariablesArray.front().continuous_variables(local_des_vars); RealVector best_fns(numFunctions); //copy_data_partial(local_lsq_vals, best_fns, 0); std::copy(local_lsq_vals.values(), local_lsq_vals.values() + numLeastSqTerms, best_fns.values()); if (numNonlinearConstraints) { //copy_data_partial(local_c_vals, best_fns, numLeastSqTerms); std::copy(local_c_vals.values(), local_c_vals.values() + nlnConstraintArraySize, best_fns.values() + numLeastSqTerms); } bestResponseArray.front().function_values(best_fns); /* // For better post-processing, could append fort.9 to dakota.out line // by line, but: THERE IS A PROBLEM WITH GETTING ALL OF THE FILE! // (FORTRAN output is lacking a final buffer flush?) Cout << "\nEcho NLSSOL's iteration output from fort.9 file:\n" << std::endl; std::ifstream npsol_fort_9( "fort.9" ); char fort_9_line[255]; while (npsol_fort_9) { npsol_fort_9.getline( fort_9_line, 255 ); Cout << fort_9_line << '\n'; } Cout << std::endl; */ Cout << "\nNOTE: see Fortran device 9 file (fort.9 or ftn09)" << "\n for complete NLSSOL iteration history." << std::endl; get_confidence_intervals(); // restore in case of recursion nlssolInstance = prev_nls_instance; solInstance = prev_sol_instance; optLSqInstance = prevMinInstance; }