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 CMAESOptimizer::process_readpara_settings(cmaes_t& evo) const
{
    // Termination criteria
    // ====================

    // stopMaxIter
    // -----------
    // maxIterations is a protected member variable of OptimizerRep.
    evo.sp.stopMaxIter = maxIterations;

    // stopTolFun
    // ----------
    // convergenceTolerance is a protected member variable of OptimizerRep.
    evo.sp.stopTolFun = convergenceTolerance;

    // stopMaxFunEvals
    // ---------------
    int stopMaxFunEvals;
    if (getAdvancedIntOption("stopMaxFunEvals", stopMaxFunEvals)) {
        SimTK_VALUECHECK_NONNEG_ALWAYS(stopMaxFunEvals, "stopMaxFunEvals",
                "CMAESOptimizer::processSettingsAfterCMAESInit");
        evo.sp.stopMaxFunEvals = stopMaxFunEvals;
    }

    // stopFitness
    // -----------
    double stopFitness;
    if (getAdvancedRealOption("stopFitness", stopFitness)) {
        evo.sp.stStopFitness.flg = 1;
        evo.sp.stStopFitness.val = stopFitness;
    }

    // stopTolFunHist
    // --------------
    double stopTolFunHist;
    if (getAdvancedRealOption("stopTolFunHist", stopTolFunHist)) {
        evo.sp.stopTolFunHist = stopTolFunHist;
    }

    // stopTolX
    // --------
    double stopTolX;
    if (getAdvancedRealOption("stopTolX", stopTolX)) {
        evo.sp.stopTolX = stopTolX;
    }

    // stopTolXFactor
    // --------------
    double stopTolUpXFactor;
    if (getAdvancedRealOption("stopTolUpXFactor", stopTolUpXFactor)) {
        evo.sp.stopTolUpXFactor = stopTolUpXFactor;
    }

    // maxtime
    // =======
    double maxtime;
    if (getAdvancedRealOption("maxTimeFractionForEigendecomposition", maxtime))
    {
        evo.sp.updateCmode.maxtime = maxtime;
    }
}
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;
}