Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <ifopt_snopt/snopt_adapter.h>
00028
00029 namespace ifopt {
00030
00031 SnoptAdapter::NLPPtr SnoptAdapter::nlp_;
00032
00033 void
00034 SnoptAdapter::Solve (Problem& ref)
00035 {
00036 SnoptAdapter snopt(ref);
00037 snopt.Init();
00038 SetOptions(snopt);
00039
00040
00041 int Cold = 0;
00042 int INFO = snopt.solve(Cold);
00043 int EXIT = INFO - INFO%10;
00044
00045 if (EXIT != 0) {
00046 std::string msg = "Snopt failed to find a solution. EXIT:" + std::to_string(EXIT) + ", INFO:" + std::to_string(INFO);
00047 throw std::runtime_error(msg);
00048 }
00049
00050 snopt.SetVariables();
00051 }
00052
00053 void SnoptAdapter::SetOptions(SnoptAdapter& solver)
00054 {
00055
00056
00057
00058 solver.setProbName( "snopt" );
00059 solver.setIntParameter( "Major Print level", 1 );
00060 solver.setIntParameter( "Minor Print level", 1 );
00061 solver.setParameter( "Solution");
00062 solver.setIntParameter( "Derivative option", 1 );
00063 solver.setIntParameter( "Verify level ", 3 );
00064 solver.setIntParameter("Iterations limit", 200000);
00065 solver.setRealParameter( "Major feasibility tolerance", 1.0e-3);
00066 solver.setRealParameter( "Minor feasibility tolerance", 1.0e-3);
00067 solver.setRealParameter( "Major optimality tolerance", 1.0e-2);
00068 }
00069
00070 SnoptAdapter::SnoptAdapter (Problem& ref)
00071 {
00072 nlp_ = &ref;
00073 }
00074
00075 void
00076 SnoptAdapter::Init ()
00077 {
00078 int obj_count = nlp_->HasCostTerms()? 1 : 0;
00079 n = nlp_->GetNumberOfOptimizationVariables();
00080 neF = nlp_->GetNumberOfConstraints() + obj_count;
00081
00082 x = new double[n];
00083 xlow = new double[n];
00084 xupp = new double[n];
00085 xmul = new double[n];
00086 xstate = new int[n];
00087
00088 F = new double[neF];
00089 Flow = new double[neF];
00090 Fupp = new double[neF];
00091 Fmul = new double[neF];
00092 Fstate = new int[neF];
00093
00094
00095
00096 auto bounds_x = nlp_->GetBoundsOnOptimizationVariables();
00097 for (uint _n=0; _n<bounds_x.size(); ++_n) {
00098 xlow[_n] = bounds_x.at(_n).lower_;
00099 xupp[_n] = bounds_x.at(_n).upper_;
00100 xstate[_n] = 0;
00101 }
00102
00103
00104 int c = 0;
00105 if (nlp_->HasCostTerms()) {
00106 Flow[c] = -1e20; Fupp[c] = 1e20; Fmul[c] = 0.0;
00107 c++;
00108 }
00109
00110
00111 auto bounds_g = nlp_->GetBoundsOnConstraints();
00112 for (const auto& b : bounds_g) {
00113 Flow[c] = b.lower_; Fupp[c] = b.upper_; Fmul[c] = 0.0;
00114 c++;
00115 }
00116
00117
00118 VectorXd x_all = nlp_->GetVariableValues();
00119 Eigen::Map<VectorXd>(&x[0], x_all.rows()) = x_all;
00120
00121 ObjRow = nlp_->HasCostTerms()? 0 : -1;
00122 ObjAdd = 0.0;
00123
00124
00125 lenA = 0;
00126 neA = 0;
00127 iAfun = nullptr;
00128 jAvar = nullptr;
00129 A = nullptr;
00130
00131
00132 lenG = obj_count*n + nlp_->GetJacobianOfConstraints().nonZeros();
00133 iGfun = new int[lenG];
00134 jGvar = new int[lenG];
00135
00136
00137 neG=0;
00138
00139
00140 if(nlp_->HasCostTerms()) {
00141 for (int var=0; var<n; ++var) {
00142 iGfun[neG] = 0;
00143 jGvar[neG] = var;
00144 neG++;
00145 }
00146 }
00147
00148
00149 auto jac = nlp_->GetJacobianOfConstraints();
00150 for (int k=0; k<jac.outerSize(); ++k) {
00151 for (Jacobian::InnerIterator it(jac,k); it; ++it) {
00152 iGfun[neG] = it.row() + obj_count;
00153 jGvar[neG] = it.col();
00154 neG++;
00155 }
00156 }
00157
00158 setUserFun(&SnoptAdapter::ObjectiveAndConstraintFct);
00159 }
00160
00161 void
00162 SnoptAdapter::ObjectiveAndConstraintFct (int* Status, int* n, double x[],
00163 int* needF, int* neF, double F[],
00164 int* needG, int* neG, double G[],
00165 char* cu, int* lencu, int iu[],
00166 int* leniu, double ru[], int* lenru)
00167 {
00168 if ( *needF > 0 ) {
00169 int i=0;
00170
00171
00172 if (nlp_->HasCostTerms())
00173 F[i++] = nlp_->EvaluateCostFunction(x);
00174
00175
00176 VectorXd g_eig = nlp_->EvaluateConstraints(x);
00177 Eigen::Map<VectorXd>(F+i, g_eig.rows()) = g_eig;
00178 }
00179
00180
00181 if ( *needG > 0 ) {
00182 int i=0;
00183
00184
00185 if (nlp_->HasCostTerms()) {
00186 Eigen::VectorXd grad = nlp_->EvaluateCostFunctionGradient(x);
00187 i = grad.rows();
00188 Eigen::Map<VectorXd>(G, i) = grad;
00189 }
00190
00191
00192 nlp_->EvalNonzerosOfJacobian(x, G+i);
00193 nlp_->SaveCurrent();
00194 }
00195 }
00196
00197 void
00198 SnoptAdapter::SetVariables ()
00199 {
00200 nlp_->SetVariables(x);
00201 }
00202
00203 }