// Local stuff void call(const Real& y, Real& fy) const { nCalls++; nFailures++; // assume failure unless proven otherwise int status; try { status = sf.f(y,fy); } catch (const std::exception& e) { SimTK_THROW1(Differentiator::UserFunctionThrewAnException, e.what()); } catch (...) { SimTK_THROW1(Differentiator::UserFunctionThrewAnException, "UNRECOGNIZED EXCEPTION TYPE"); } if (status != 0) SimTK_THROW1(Differentiator::UserFunctionReturnedNonzeroStatus, status); nFailures--; }
SimTK::Real InteriorPointOptimizer::optimize( Vector &results ) { int n = getOptimizerSystem().getNumParameters(); int m = getOptimizerSystem().getNumConstraints(); Index index_style = 0; /* C-style; start counting of rows and column indices at 0 */ Index nele_hess = 0; Index nele_jac = n*m; /* always assume dense */ // Parameter limits Number *x_L = NULL, *x_U = NULL; if( getOptimizerSystem().getHasLimits() ) { getOptimizerSystem().getParameterLimits( &x_L, &x_U); } else { x_U = new Number[n]; x_L = new Number[n]; for(int i=0;i<n;i++) { x_U[i] = SimTK::Real(POSITIVE_INF); x_L[i] = SimTK::Real(NEGATIVE_INF); } } SimTK::Real *x = &results[0]; IpoptProblem nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess, index_style, objectiveFuncWrapper, constraintFuncWrapper, gradientFuncWrapper, constraintJacobianWrapper, hessianWrapper); // If you want to verify which options are getting set in the optimizer, you can create a file ipopt.opt // with "print_user_options yes", and set print_level to (at least 1). It will then print the options to the screen. // sherm 100302: you have to set all of these tolerances to get IpOpt to change // its convergence criteria; see OptimalityErrorConvergenceCheck::CheckConvergence(). // We'll set acceptable tolerances to the same value to disable them. AddIpoptNumOption(nlp, "tol", convergenceTolerance); AddIpoptNumOption(nlp, "dual_inf_tol", convergenceTolerance); AddIpoptNumOption(nlp, "constr_viol_tol", constraintTolerance); AddIpoptNumOption(nlp, "compl_inf_tol", convergenceTolerance); AddIpoptNumOption(nlp, "acceptable_tol", convergenceTolerance); AddIpoptNumOption(nlp, "acceptable_dual_inf_tol", convergenceTolerance); AddIpoptNumOption(nlp, "acceptable_constr_viol_tol", constraintTolerance); AddIpoptNumOption(nlp, "acceptable_compl_inf_tol", convergenceTolerance); AddIpoptIntOption(nlp, "max_iter", maxIterations); AddIpoptStrOption(nlp, "mu_strategy", "adaptive"); AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory"); // needs to be limited-memory unless you have explicit hessians AddIpoptIntOption(nlp, "limited_memory_max_history", limitedMemoryHistory); AddIpoptIntOption(nlp, "print_level", diagnosticsLevel); // default is 4 int i; static const char *advancedRealOptions[] = { "compl_inf_tol", "dual_inf_tol", "constr_viol_tol", "acceptable_tol", "acceptable_compl_inf_tol", "acceptable_constr_viol_tol", "acceptable_dual_inf_tol", "diverging_iterates_tol", "barrier_tol_factor", "obj_scaling_factor", "nlp_scaling_max_gradient", "bounds_relax_factor", "recalc_y_feas_tol", "mu_init", "mu_max_fact", "mu_max", "mu_min", "mu_linear_decrease_factor", "mu_superlinear_decrease_factor", "bound_frac", "bound_push", "bound_mult_init_val", "constr_mult_init_max", "constr_mult_init_val", "warm_start_bound_push", "warm_start_bound_frac", "warm_start_mult_bound_push", "warm_start_mult_init_max", "recalc_y_feas_tol", "expect_infeasible_problem_ctol", "soft_resto_pderror_reduction_factor", "required_infeasibility_reduction", "bound_mult_reset_threshold", "constr_mult_reset_threshold", "max_hessian_perturbation", "min_hessian_perturbation", "first_hessian_perturbation", "perturb_inc_fact_first", "perturb_inc_fact", "perturb_dec_fact", "jacobian_reqularization_value", "derivative_test_perturbation", "derivative_test_tol", 0}; Real value; for(i=0;advancedRealOptions[i];i++) { if(getAdvancedRealOption(advancedRealOptions[i],value)) AddIpoptNumOption(nlp, advancedRealOptions[i], value); } static const std::string advancedStrOptions[] = {"nlp_scaling_method", "honor_original_bounds", "check_derivatives_for_naninf", "mu_strategy", "mu_oracle", "fixed_mu_oracle", "alpha_for_y", "recalc_y", "expect_infeasible_problem", "print_options_documentation", "print_user_options", "start_with_resto", "evaluate_orig_obj_at_resto_trial", "hessian_approximation", "derivative_test", ""}; std::string svalue; for(i=0;!advancedStrOptions[i].empty();i++) { if(getAdvancedStrOption(advancedStrOptions[i], svalue)) AddIpoptStrOption(nlp, advancedStrOptions[i].c_str(), svalue.c_str()); } static const char* advancedIntOptions[] = {"quality_function_max_section_steps", "max_soc", "watchdog_shorted_iter_trigger", "watchdog_trial_iter_max", "max_refinement_steps", "min_refinement_steps", "limited_memory_max_history", "limited_memory_max_skipping", "derivative_test_print_all", 0}; int ivalue; for(i=0;advancedIntOptions[i];i++) { if(getAdvancedIntOption(advancedIntOptions[i], ivalue)) AddIpoptIntOption(nlp, advancedIntOptions[i], ivalue); } // Only makes sense to do a warm start if this is not the first call to optimize() (since we need // reasonable starting multiplier values) bool use_warm_start=false; if(getAdvancedBoolOption("warm_start", use_warm_start) && use_warm_start && !firstOptimization) { AddIpoptStrOption(nlp, "warm_start_init_point", "yes"); AddIpoptStrOption(nlp, "warm_start_entire_iterate", "yes"); //AddIpoptStrOption(nlp, "warm_start_same_structure", "yes"); // couldn't get this one to work } SimTK::Real obj; int status = IpoptSolve(nlp, x, NULL, &obj, mult_g, mult_x_L, mult_x_U, (void *)this ); FreeIpoptProblem(nlp); // Only delete these if they aren't pointing to existing parameter limits if( !getOptimizerSystem().getHasLimits() ) { delete [] x_U; delete [] x_L; } if(status == Solved_To_Acceptable_Level) { std::cout << "Ipopt: Solved to acceptable level" << std::endl; } else if (status != Solve_Succeeded) { if( status != NonIpopt_Exception_Thrown) { char buf[1024]; sprintf(buf, "Ipopt: %s (status %d)",applicationReturnStatusToString(status).c_str(),status); SimTK_THROW1(SimTK::Exception::OptimizerFailed, SimTK::String(buf)); } } firstOptimization = false; return(obj); }
void IntegratorRep::initialize(const State& initState) { try { invalidateIntegratorInternalState(); // Copy the supplied initial state into the integrator. updAdvancedState() = initState; // Freeze the number and kinds of state variables. getSystem().realizeModel(updAdvancedState()); // Freeze problem dimensions; at this point the state represents an // instance of a physically realizable system. getSystem().realize(getAdvancedState(), Stage::Instance); // Some Systems need to get control whenever time is advanced // successfully (and irreversibly) so that they can do discrete updates. systemHasTimeAdvancedEvents = getSystem().hasTimeAdvancedEvents(); // Allocate integrator-local data structures now that we know the sizes. const int ny = getAdvancedState().getNY(); const int nc = getAdvancedState().getNYErr(); const int ne = getAdvancedState().getNEventTriggers(); timeScaleInUse = getSystem().getDefaultTimeScale(); // Set accuracy and consTol to their user-requested values or // to the appropriate defaults. setAccuracyAndTolerancesFromUserRequests(); // Now we can ask the System for information about its event triggers. // (Event trigger info is Instance stage information.) Note that the event // localization windows here are expressed in terms of the system timescale // -- be sure to multiply by timescale before using. getSystem().calcEventTriggerInfo(getAdvancedState(), eventTriggerInfo); // Realize Time stage, apply prescribed motions, and attempt to project q's // and u's onto the // position and velocity constraint manifolds to drive constraint errors // below accuracy*unitTolerance for each constraint. We'll allow project() // to throw an exception if it fails since we can't recover from here. // However, we won't set the LocalOnly option which means project() is // allowed to thrash around wildly to attempt to find *some* solution. // Also force repeated updates of iteration matrix to maximize chances of // finding a solution; we're not in a hurry here. realizeAndProjectKinematicsWithThrow(updAdvancedState(), ProjectOptions::ForceProjection, ProjectOptions::ForceFullNewton); // Inform any state-using System elements (especially Measures) that we // are starting a simulation and give them a chance to initialize their own // continuous (z) variables and discrete variables. // Handler is allowed to throw an exception if it fails since we don't // have a way to recover. HandleEventsOptions handleOpts(getConstraintToleranceInUse()); HandleEventsResults results; getSystem().handleEvents(updAdvancedState(), Event::Cause::Initialization, Array_<EventId>(), handleOpts, results); SimTK_ERRCHK_ALWAYS( results.getExitStatus()!=HandleEventsResults::ShouldTerminate, "Integrator::initialize()", "An initialization event handler requested termination."); // Now evaluate the state through the Acceleration stage to calculate // the initial state derivatives. realizeStateDerivatives(getAdvancedState()); // Now that we have valid update values for auto-update discrete variables, // use them to reinitialize the discrete state variables. This one time // only, the value swapped in from the discrete variable here is not yet // suitable for use as an update value, during time integration since it // has never been realized to Instance stage. So we'll force a // re-evaluation. updAdvancedState().autoUpdateDiscreteVariables(); getAdvancedState().invalidateAllCacheAtOrAbove(Stage::Instance); // Re-realize to fill in the swapped-in update values. realizeStateDerivatives(getAdvancedState()); // Record the continuous parts of this now-realized initial state as the // previous state as well (previous state is used when we have to back up // from a failed step attempt). saveStateAndDerivsAsPrevious(getAdvancedState()); // The initial state is set so it looks like we just *completed* a step to // get here. That way if the first reportTime is zero, this will get // reported. setStepCommunicationStatus(CompletedInternalStepNoEvent); startOfContinuousInterval = true; // This will be set to something meaningful when the simulation ends. terminationReason = Integrator::InvalidTerminationReason; // Call this virtual method in case the concrete integrator class has // additional initialization needs. Note that it gets the State as we have // adjusted it, NOT the one originally passed to initialize(). methodInitialize(getAdvancedState()); } catch (const std::exception& e) { SimTK_THROW1(Integrator::InitializationFailed, e.what()); } /* catch (...) { SimTK_THROW1(Integrator::InitializationFailed, "UNKNOWN EXCEPTION"); } */ }
Real LBFGSBOptimizer::optimize( Vector &results ) { int run_optimizer = 1; char task[61]; Real f; int *iwa; char csave[61]; bool lsave[4]; int isave[44]; Real dsave[29]; Real *wa; Real *lowerLimits, *upperLimits; const OptimizerSystem& sys = getOptimizerSystem(); int n = sys.getNumParameters(); int m = limitedMemoryHistory; Real *gradient; gradient = new Real[n]; iprint[0] = iprint[1] = iprint[2] = diagnosticsLevel; if( sys.getHasLimits() ) { sys.getParameterLimits( &lowerLimits, &upperLimits ); // Determine what kind of limits each parameter has. // nbd = 0, unbounded; 1, only lower; 2, both; 3 only upper for (int i=0; i < n; ++i) { if (lowerLimits[i] == -Infinity) nbd[i] = (upperLimits[i] == Infinity ? 0 : 3); else nbd[i] = (upperLimits[i] == Infinity ? 1 : 2); } } else { lowerLimits = 0; upperLimits = 0; for(int i=0;i<n;i++) nbd[i] = 0; // unbounded } iwa = new int[3*n]; wa = new Real[((2*m + 4)*n + 12*m*m + 12*m)]; Real factor; if( getAdvancedRealOption("factr", factor ) ) { SimTK_APIARGCHECK_ALWAYS(factor > 0,"LBFGSBOptimizer","optimize", "factr must be positive \n"); factr = factor; } strcpy( task, "START" ); while( run_optimizer ) { setulb_(&n, &m, &results[0], lowerLimits, upperLimits, nbd, &f, gradient, &factr, &convergenceTolerance, wa, iwa, task, iprint, csave, lsave, isave, dsave, 60, 60); if( strncmp( task, "FG", 2) == 0 ) { objectiveFuncWrapper( n, &results[0], true, &f, this); gradientFuncWrapper( n, &results[0], false, gradient, this); } else if( strncmp( task, "NEW_X", 5) == 0 ){ //objectiveFuncWrapper( n, &results[0], true, &f, (void*)this ); } else { run_optimizer = 0; if( strncmp( task, "CONV", 4) != 0 ){ delete[] gradient; delete[] iwa; delete[] wa; SimTK_THROW1(SimTK::Exception::OptimizerFailed , SimTK::String(task) ); } } } delete[] gradient; delete[] iwa; delete[] wa; return f; }