00001 # ifndef CPPAD_IPOPT_CPPAD_NLP_INCLUDED 00002 # define CPPAD_IPOPT_CPPAD_NLP_INCLUDED 00003 /* -------------------------------------------------------------------------- 00004 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-08 Bradley M. Bell 00005 00006 CppAD is distributed under multiple licenses. This distribution is under 00007 the terms of the 00008 Common Public License Version 1.0. 00009 00010 A copy of this license is included in the COPYING file of this distribution. 00011 Please visit http://www.coin-or.org/CppAD/ for information on other licenses. 00012 -------------------------------------------------------------------------- */ 00013 /* 00014 $begin ipopt_cppad_nlp$$ 00015 $spell 00016 bool 00017 doesn't 00018 nan 00019 inf 00020 naninf 00021 std 00022 maxiter 00023 infeasibility 00024 obj 00025 const 00026 optimizer 00027 ipopt_cppad_nlp.hpp 00028 fg_info.eval 00029 retape 00030 CppAD 00031 00032 $$ 00033 $section Nonlinear Programming Using Ipopt and CppAD$$ 00034 00035 $index nonlinear, programming$$ 00036 $index programming, nonlinear$$ 00037 $index AD, nonlinear programming$$ 00038 $index CppAD, nonlinear programming$$ 00039 $index Ipopt, with AD$$ 00040 00041 $head Syntax$$ 00042 $codei%# include "ipopt_cppad_nlp.hpp" 00043 %$$ 00044 $codei%# ipopt_cppad_solution %solution%; 00045 %$$ 00046 $codei%ipopt_cppad_nlp %cppad_nlp%( 00047 %n%, %m%, %x_i%, %x_l%, %x_u%, %g_l%, %g_u%, %fg_info%, &%solution% 00048 )%$$ 00049 00050 $head Purpose$$ 00051 The class $code ipopt_cppad_nlp$$ is used to solve nonlinear programming 00052 problems of the form 00053 $latex \[ 00054 \begin{array}{rll} 00055 {\rm minimize} & f(x) 00056 \\ 00057 {\rm subject \; to} & g^l \leq g(x) \leq g^u 00058 \\ 00059 & x^l \leq x \leq x^u 00060 \end{array} 00061 \] $$ 00062 This is done using 00063 $href% 00064 https://www.coin-or.org/projects/Ipopt% 00065 Ipopt 00066 %$$ 00067 optimizer and 00068 $href% 00069 http://www.coin-or.org/CppAD/% 00070 CppAD 00071 %$$ 00072 Algorithmic Differentiation package. 00073 00074 $head Warning$$ 00075 This is only an example use of CppAD. 00076 It is expected that this class will be improved and that 00077 its user interface may change in ways that are not backward compatible. 00078 00079 $head fg(x)$$ 00080 The function $latex fg : \R^n \rightarrow \R^{m+1}$$ is defined by 00081 $latex \[ 00082 \begin{array}{rcl} 00083 fg_0 (x) & = & f(x) \\ 00084 fg_1 (x) & = & g_0 (x) \\ 00085 & \vdots & \\ 00086 fg_m (x) & = & g_{m-1} (x) 00087 \end{array} 00088 \] $$ 00089 00090 $subhead Index Vector$$ 00091 We define an $italic index vector$$ as a vector of non-negative integers 00092 for which none of the values are equal; i.e., 00093 it is both a vector and a set. 00094 If $latex I$$ is an index vector $latex |I|$$ is used to denote the 00095 number of elements in $latex I$$ and $latex \| I \|$$ is used 00096 to denote the value of the maximum element in $latex I$$. 00097 00098 $subhead Projection$$ 00099 Given an index vector $latex J$$ and a positive integer $latex n$$ 00100 where $latex n > \| J \|$$, we use $latex J \otimes n$$ for 00101 the mapping $latex J \otimes n : \R^n \rightarrow \R^{|J|}$$ defined by 00102 $latex \[ 00103 J \otimes n (x)_j = x_{J(j)} 00104 \] $$ 00105 for $latex j = 0 , \ldots |J| - 1$$. 00106 00107 $subhead Injection$$ 00108 Given an index vector $latex I$$ and a positive integer $latex m$$ 00109 where $latex m > \| I \|$$, we use $latex m \otimes I$$ for 00110 the mapping $latex m \otimes I: \R^{|I|} \rightarrow \R^m$$ defined by 00111 $latex \[ 00112 m \otimes I (y)_i = \left\{ \begin{array}{ll} 00113 y_k & {\rm if} \; i = I(k) \; {\rm for \; some} \; 00114 k \in \{ 0 , \cdots, |I|-1 \} 00115 \\ 00116 0 & {\rm otherwise} 00117 \end{array} \right. 00118 \] $$ 00119 00120 $subhead Representation$$ 00121 In many applications, each of the component functions of $latex fg(x)$$ 00122 only depend on a few of the components of $latex x$$. 00123 In this case, expressing $latex fg(x)$$ in terms of simpler functions 00124 with fewer arguments can greatly reduce the amount of work required 00125 to compute its derivatives. 00126 $pre 00127 00128 $$ 00129 We use the functions 00130 $latex r_k : \R^{q(k)} \rightarrow \R^{p(k)}$$ 00131 for $latex k = 0 , \ldots , K$$ to express our 00132 representation of $latex fg(x)$$ in terms of simpler functions 00133 as follows 00134 $latex \[ 00135 fg(x) = \sum_{k=0}^{K-1} \; \sum_{\ell=0}^{L(k) - 1} 00136 (m+1) \otimes I_{k,\ell} \; 00137 \{ \; r_k \; [ \; J_{k,\ell} \otimes n \; (x) \; ] \} 00138 \] $$ 00139 where for $latex k = 0 , \ldots , K - 1$$, 00140 and $latex \ell = 0 , \ldots , L(k)$$, 00141 $latex I_{k,\ell}$$, and $latex J_{k,\ell}$$ are index vectors with 00142 $latex | J_{k,\ell} | = q(k)$$ and $latex | I_{k,\ell} | = p(k)$$. 00143 00144 $head Simple Representation$$ 00145 In the simple representation, 00146 $latex r_0 (x) = fg(x)$$, 00147 $latex K = 1$$, 00148 $latex q(0) = n$$, 00149 $latex p(0) = m$$, 00150 $latex L(0) = 1$$, 00151 $latex I_{0,0} = (0 , \ldots , m)$$, 00152 and $latex J_{0,0} = (0 , \ldots , n-1)$$. 00153 00154 $head SizeVector$$ 00155 The type $codei SizeVector$$ is defined by the 00156 $codei ipopt_cppad_nlp.hpp$$ include file to be a 00157 $cref/SimpleVector/$$ class with elements of type 00158 $code size_t$$. 00159 00160 $head NumberVector$$ 00161 The type $codei NumberVector$$ is defined by the 00162 $codei ipopt_cppad_nlp.hpp$$ include file to be a 00163 $cref/SimpleVector/$$ class with elements of type 00164 $code Ipopt::Number$$. 00165 00166 $head ADNumber$$ 00167 The type $codei ADNumber$$ is defined by the 00168 $codei ipopt_cppad_nlp.hpp$$ include file to be a 00169 an AD type that can be used to compute derivatives. 00170 00171 $head ADVector$$ 00172 The type $codei ADVector$$ is defined by the 00173 $codei ipopt_cppad_nlp.hpp$$ include file to be a 00174 $cref/SimpleVector/$$ class with elements of type 00175 $code ADNumber$$. 00176 00177 $head n$$ 00178 The argument $icode n$$ has prototype 00179 $codei% 00180 size_t %n% 00181 %$$ 00182 It specifies the dimension of the argument space; 00183 i.e., $latex x \in \R^n$$. 00184 00185 $head m$$ 00186 The argument $icode m$$ has prototype 00187 $codei% 00188 size_t %m% 00189 %$$ 00190 It specifies the dimension of the range space for $latex g$$; 00191 i.e., $latex g : \R^n \rightarrow \R^m$$. 00192 00193 $head x_i$$ 00194 The argument $icode x_i$$ has prototype 00195 $codei% 00196 const NumberVector& %x_i% 00197 %$$ 00198 and its size is equal to $latex n$$. 00199 It specifies the initial point where Ipopt starts the optimization process. 00200 00201 $head x_l$$ 00202 The argument $icode x_l$$ has prototype 00203 $codei% 00204 const NumberVector& %x_l% 00205 %$$ 00206 and its size is equal to $latex n$$. 00207 It specifies the lower limits for the argument in the optimization problem; 00208 i.e., $latex x^l$$. 00209 00210 $head x_u$$ 00211 The argument $icode x_u$$ has prototype 00212 $codei% 00213 const NumberVector& %x_u% 00214 %$$ 00215 and its size is equal to $latex n$$. 00216 It specifies the upper limits for the argument in the optimization problem; 00217 i.e., $latex x^u$$. 00218 00219 $head g_l$$ 00220 The argument $icode g_l$$ has prototype 00221 $codei% 00222 const NumberVector& %g_l% 00223 %$$ 00224 and its size is equal to $latex m$$. 00225 It specifies the lower limits for the constraints in the optimization problem; 00226 i.e., $latex g^l$$. 00227 00228 $head g_u$$ 00229 The argument $icode g_u$$ has prototype 00230 $codei% 00231 const NumberVector& %g_u% 00232 %$$ 00233 and its size is equal to $latex n$$. 00234 It specifies the upper limits for the constraints in the optimization problem; 00235 i.e., $latex g^u$$. 00236 00237 $head fg_info$$ 00238 The argument $icode fg_info$$ has prototype 00239 $codei% 00240 ipopt_cppad_fg_info* %fg_info% 00241 %$$ 00242 where the object $codei%*%fg_info%$$ is a member of 00243 a class (referred to as $icode FG_info$$) 00244 that is derived from the base class $code ipopt_cppad_fg_info$$. 00245 Certain virtual member functions of $code ipopt_cppad_fg_info$$ are used to 00246 compute the value of $latex fg(x)$$. 00247 The specifications for these member functions are given below: 00248 00249 $subhead fg_info->number_functions$$ 00250 This member function has prototype 00251 $codei% 00252 virtual size_t ipopt_cppad_fg_info::number_functions(void) 00253 %$$ 00254 If $icode K$$ has type $code size_t$$, the syntax 00255 $codei% 00256 %K% = %fg_info%->number_functions() 00257 %$$ 00258 sets $icode K$$ to the number of functions used in the 00259 representation of $latex fg(x)$$; i.e., $latex K$$ in 00260 the $cref/representation/ipopt_cppad_nlp/fg(x)/Representation/$$ above. 00261 $pre 00262 00263 $$ 00264 The $code ipopt_cppad_fg_info$$ implementation of this function 00265 corresponds to the simple representation mentioned above; i.e. 00266 $icode%K% = 1%$$. 00267 00268 $subhead fg_info->eval_r$$ 00269 This member function has the prototype 00270 $codei% 00271 virtual ADVector ipopt_cppad_fg_info::eval_r(size_t %k%, const ADVector& %u%) = 0; 00272 %$$ 00273 This prototype is pure virtual and hence it must be defined in the 00274 derived class $icode FG_info$$. 00275 $pre 00276 00277 $$ 00278 This function computes the value of $latex r_k (u)$$ 00279 used in the $cref/representation/ipopt_cppad_nlp/fg(x)/Representation/$$ 00280 for $latex fg(x)$$. 00281 If $icode k$$ is in $latex \{0 , \ldots , K-1 \}$$ has type $code size_t$$, 00282 $icode u$$ is an $code ADVector$$ of size $icode q(k)$$ 00283 and $icode r$$ is an $code ADVector$$ of size $icode p(k)$$ 00284 the syntax 00285 $codei% 00286 %r% = %fg_info%->eval_r(%k%, %u%) 00287 %$$ 00288 set $icode r$$ to the vector $latex r_k (u)$$. 00289 00290 $subhead fg_info->retape$$ 00291 This member function has the prototype 00292 $codei% 00293 virtual bool ipopt_cppad_fg_info::retape(size_t %k%) 00294 %$$ 00295 If $icode k$$ is in $latex \{0 , \ldots , K-1 \}$$ has type $code size_t$$, 00296 and $icode retape$$ has type $code bool$$, 00297 the syntax 00298 $codei% 00299 %retape% = %fg_info%->retape(%k%) 00300 %$$ 00301 sets $icode retape$$ to true or false. 00302 If $icode retape$$ is true, 00303 $code ipopt_cppad_nlp$$ will retape the operation sequence 00304 corresponding to $latex r_k (u)$$ for 00305 every value of $icode u$$. 00306 An $code ipopt_cppad_nlp$$ object 00307 should use much less memory and run faster if $icode retape$$ is false. 00308 You can test both the true and false cases to make sure 00309 the operation sequence does not depend on $icode u$$. 00310 $pre 00311 00312 $$ 00313 The $code ipopt_cppad_fg_info$$ implementation of this function 00314 sets $icode retape$$ to true. 00315 00316 $subhead fg_info->domain_size$$ 00317 This member function has prototype 00318 $codei% 00319 virtual size_t ipopt_cppad_fg_info::domain_size(size_t %k%) 00320 %$$ 00321 If $icode k$$ is in $latex \{0 , \ldots , K-1 \}$$ has type $code size_t$$, 00322 and $icode q$$ has type $code size_t$$, the syntax 00323 $codei% 00324 %q% = %fg_info%->domain_size(%k%) 00325 %$$ 00326 sets $icode q$$ to the dimension of the domain space for $latex r_k (u)$$; 00327 i.e., $latex q(k)$$ in 00328 the $cref/representation/ipopt_cppad_nlp/fg(x)/Representation/$$ above. 00329 00330 $pre 00331 00332 $$ 00333 The $code ipopt_cppad_h_base$$ implementation of this function 00334 corresponds to the simple representation mentioned above; i.e., 00335 $latex q = n$$. 00336 00337 $subhead fg_info->range_size$$ 00338 This member function has prototype 00339 $codei% 00340 virtual size_t ipopt_cppad_fg_info::range_size(size_t %k%) 00341 %$$ 00342 If $icode k$$ is in $latex \{0 , \ldots , K-1 \}$$ has type $code size_t$$, 00343 and $icode p$$ has type $code size_t$$, the syntax 00344 $codei% 00345 %p% = %fg_info%->range_size(%k%) 00346 %$$ 00347 sets $icode p$$ to the dimension of the range space for $latex r_k (u)$$; 00348 i.e., $latex p(k)$$ in 00349 the $cref/representation/ipopt_cppad_nlp/fg(x)/Representation/$$ above. 00350 $pre 00351 00352 $$ 00353 The $code ipopt_cppad_h_base$$ implementation of this function 00354 corresponds to the simple representation mentioned above; i.e., 00355 $latex p = m+1$$. 00356 00357 $subhead fg_info->number_terms$$ 00358 This member function has prototype 00359 $codei% 00360 virtual size_t ipopt_cppad_fg_info::number_terms(size_t %k%) 00361 %$$ 00362 If $icode k$$ is in $latex \{0 , \ldots , K-1 \}$$ has type $code size_t$$, 00363 and $icode L$$ has type $code size_t$$, the syntax 00364 $codei% 00365 %L% = %fg_info%->range_sum(%k%) 00366 %$$ 00367 sets $icode L$$ to the number of terms in representation 00368 for this value of $icode k$$; 00369 i.e., $latex L(k)$$ in 00370 the $cref/representation/ipopt_cppad_nlp/fg(x)/Representation/$$ above. 00371 $pre 00372 00373 $$ 00374 The $code ipopt_cppad_h_base$$ implementation of this function 00375 corresponds to the simple representation mentioned above; i.e., 00376 $latex L = 1$$. 00377 00378 $subhead fg_info->index$$ 00379 This member function has prototype 00380 $codei% 00381 virtual void ipopt_cppad_fg_info::index( 00382 size_t %k%, size_t %ell%, SizeVector& %I%, SizeVector& %J% 00383 ) 00384 %$$ 00385 The argument 00386 $icode% 00387 k 00388 %$$ 00389 has type $codei size_t$$ 00390 and is a value between zero and $latex K-1$$ inclusive. 00391 The argument 00392 $icode% 00393 ell 00394 %$$ 00395 has type $codei size_t$$ 00396 and is a value between zero and $latex L(k)-1$$ inclusive. 00397 The argument 00398 $icode% 00399 I 00400 %$$ is a $cref/SimpleVector/$$ with elements 00401 of type $code size_t$$ and size greater than or equal to $latex p(k)$$. 00402 The input value of the elements of $icode I$$ does not matter. 00403 The output value of 00404 the first $latex p(k)$$ elements of $icode I$$ 00405 must be the corresponding elements of $latex I_{k,ell}$$ 00406 in the $cref/representation/ipopt_cppad_nlp/fg(x)/Representation/$$ above. 00407 The argument 00408 $icode% 00409 J 00410 %$$ is a $cref/SimpleVector/$$ with elements 00411 of type $code size_t$$ and size greater than or equal to $latex q(k)$$. 00412 The input value of the elements of $icode J$$ does not matter. 00413 The output value of 00414 the first $latex q(k)$$ elements of $icode J$$ 00415 must be the corresponding elements of $latex J_{k,ell}$$ 00416 in the $cref/representation/ipopt_cppad_nlp/fg(x)/Representation/$$ above. 00417 $pre 00418 00419 $$ 00420 The $code ipopt_cppad_h_base$$ implementation of this function 00421 corresponds to the simple representation mentioned above; i.e., 00422 for $latex i = 0 , \ldots , m$$, 00423 $icode%I%[%i%] = %i%$$, 00424 and for $latex j = 0 , \ldots , n-1$$, 00425 $icode%J%[%j%] = %j%$$. 00426 00427 $head solution$$ 00428 After the optimization process is completed, $icode solution$$ contains 00429 the following information: 00430 00431 $subhead status$$ 00432 The $icode status$$ field of $icode solution$$ has prototype 00433 $codei% 00434 ipopt_cppad_solution::solution_status %solution%.status 00435 %$$ 00436 It is the final Ipopt status for the optimizer. 00437 Here is a list of the possible values for the status: 00438 00439 $table 00440 $icode status$$ $cnext Meaning 00441 $rnext 00442 not_defined $cnext 00443 The optimizer did not return a final status to this $code ipopt_cppad_nlp$$ 00444 object. 00445 $rnext 00446 unknown $cnext 00447 The status returned by the optimizer is not defined in the Ipopt 00448 documentation for $code finalize_solution$$. 00449 $rnext 00450 success $cnext 00451 Algorithm terminated successfully at a point satisfying the convergence 00452 tolerances (see Ipopt options). 00453 $rnext 00454 maxiter_exceeded $cnext 00455 The maximum number of iterations was exceeded (see Ipopt options). 00456 $rnext 00457 stop_at_tiny_step $cnext 00458 Algorithm terminated because progress was very slow. 00459 $rnext 00460 stop_at_acceptable_point $cnext 00461 Algorithm stopped at a point that was converged, 00462 not to the 'desired' tolerances, but to 'acceptable' tolerances 00463 (see Ipopt options). 00464 $rnext 00465 local_infeasibility $cnext 00466 Algorithm converged to a non-feasible point 00467 (problem may have no solution). 00468 $rnext 00469 user_requested_stop $cnext 00470 This return value should not happen. 00471 $rnext 00472 diverging_iterates $cnext 00473 It the iterates are diverging. 00474 $rnext 00475 restoration_failure $cnext 00476 Restoration phase failed, algorithm doesn't know how to proceed. 00477 $rnext 00478 error_in_step_computation $cnext 00479 An unrecoverable error occurred while Ipopt tried to 00480 compute the search direction. 00481 $rnext 00482 invalid_number_detected $cnext 00483 Algorithm received an invalid number (such as $code nan$$ or $code inf$$) 00484 from the users function $icode%fg_info%.eval%$$ or from the CppAD evaluations 00485 of its derivatives 00486 (see the Ipopt option $code check_derivatives_for_naninf$$). 00487 $rnext 00488 internal_error $cnext 00489 An unknown Ipopt internal error occurred. 00490 Contact the Ipopt authors through the mailing list. 00491 $tend 00492 00493 $subhead x$$ 00494 The $code x$$ field of $icode solution$$ has prototype 00495 $codei% 00496 NumberVector %solution%.x 00497 %$$ 00498 and its size is equal to $latex n$$. 00499 It is the final $latex x$$ value for the optimizer. 00500 00501 $subhead z_l$$ 00502 The $code z_l$$ field of $icode solution$$ has prototype 00503 $codei% 00504 NumberVector %solution%.z_l 00505 %$$ 00506 and its size is equal to $latex n$$. 00507 It is the final Lagrange multipliers for the 00508 lower bounds on $latex x$$. 00509 00510 $subhead z_u$$ 00511 The $code z_u$$ field of $icode solution$$ has prototype 00512 $codei% 00513 NumberVector %solution%.z_u 00514 %$$ 00515 and its size is equal to $latex n$$. 00516 It is the final Lagrange multipliers for the 00517 upper bounds on $latex x$$. 00518 00519 $subhead g$$ 00520 The $code g$$ field of $icode solution$$ has prototype 00521 $codei% 00522 NumberVector %solution%.g 00523 %$$ 00524 and its size is equal to $latex m$$. 00525 It is the final value for the constraint function $latex g(x)$$. 00526 00527 $subhead lambda$$ 00528 The $code lambda$$ field of $icode solution$$ has prototype 00529 $codei% 00530 NumberVector %solution%.lambda 00531 %$$ 00532 and its size is equal to $latex m$$. 00533 It is the final value for the 00534 Lagrange multipliers corresponding to the constraint function. 00535 00536 $subhead obj_value$$ 00537 The $code obj_value$$ field of $icode solution$$ has prototype 00538 $codei% 00539 Number %solution%.obj_value 00540 %$$ 00541 It is the final value of the objective function $latex f(x)$$. 00542 00543 00544 $children% 00545 example/ipopt_cppad.cpp% 00546 example/ipopt_cppad_ode.cpp 00547 %$$ 00548 00549 $head Example$$ 00550 The file 00551 $cref/ipopt_cppad.cpp/$$ is an example and test of $code ipopt_cppad_nlp$$. 00552 that uses the 00553 $cref/simple representation/ipopt_cppad_nlp/Simple Representation/$$. 00554 The file 00555 $cref/ipopt_cppad_ode.cpp/$$ is a more complex example that optimizes 00556 the solution of an ordinary differential equation. 00557 They return true if they succeed and false otherwise. 00558 00559 $end 00560 ----------------------------------------------------------------------------- 00561 */ 00562 00563 00564 # include <cppad/cppad.hpp> 00565 # include <coin/IpIpoptApplication.hpp> 00566 # include <coin/IpTNLP.hpp> 00567 00568 typedef CppAD::AD<Ipopt::Number> ADNumber; 00569 typedef CppAD::vector<size_t> SizeVector; 00570 typedef CppAD::vector<Ipopt::Number> NumberVector; 00571 typedef CppAD::vector<ADNumber> ADVector; 00572 00573 /* 00574 Class for return solution values. 00575 */ 00576 class ipopt_cppad_fg_info 00577 { 00578 friend class ipopt_cppad_nlp; 00579 private: 00580 size_t n_; 00581 size_t m_; 00582 00583 void set_n(size_t n) 00584 { n_ = n; } 00585 void set_m(size_t m) 00586 { m_ = m; } 00587 00588 public: 00589 // make destructor virtual so that derived class destructor gets called 00590 virtual ~ipopt_cppad_fg_info(void) 00591 { } 00592 // number_functions: for simple representation 00593 virtual size_t number_functions(void) 00594 { return 1; } 00595 // eval_r: pure virtual so that it must be defined by derived class 00596 virtual ADVector eval_r(size_t k, const ADVector& u) = 0; 00597 // retape: default definition 00598 virtual bool retape(size_t k) 00599 { return true; } 00600 // domain_size: for simple representation 00601 virtual size_t domain_size(size_t k) 00602 { return n_; } 00603 // range_size: for simple representation 00604 virtual size_t range_size(size_t k) 00605 { return m_ + 1; } 00606 // number_terms: for simple representation 00607 virtual size_t number_terms(size_t k) 00608 { return 1; } 00609 // index: for simple representation 00610 virtual void index(size_t k, size_t ell, SizeVector& I, SizeVector& J) 00611 { assert( I.size() >= m_ + 1 ); 00612 assert( J.size() >= n_ ); 00613 for(size_t i = 0; i <= m_; i++) 00614 I[i] = i; 00615 for(size_t j = 0; j < n_; j++) 00616 J[j] = j; 00617 } 00618 }; 00619 00620 class ipopt_cppad_solution 00621 { 00622 public: 00623 enum solution_status { 00624 not_defined, 00625 success, 00626 maxiter_exceeded, 00627 stop_at_tiny_step, 00628 stop_at_acceptable_point, 00629 local_infeasibility, 00630 user_requested_stop, 00631 feasible_point_found, 00632 diverging_iterates, 00633 restoration_failure, 00634 error_in_step_computation, 00635 invalid_number_detected, 00636 too_few_degrees_of_freedom, 00637 internal_error, 00638 unknown 00639 } status; 00640 NumberVector x; 00641 NumberVector z_l; 00642 NumberVector z_u; 00643 NumberVector g; 00644 NumberVector lambda; 00645 Ipopt::Number obj_value; 00646 00647 ipopt_cppad_solution(void) 00648 { status = not_defined; } 00649 }; 00650 00651 /* 00652 Class for interfacing a problem to IPOPT and using CppAD for derivative 00653 and sparsity pattern calculations. 00654 */ 00655 class ipopt_cppad_nlp : public Ipopt::TNLP 00656 { 00657 typedef Ipopt::Number Number; 00658 typedef Ipopt::Index Index; 00659 typedef Ipopt::TNLP::IndexStyleEnum IndexStyleEnum; 00660 typedef CppAD::vectorBool BoolVector; 00661 typedef CppAD::vector< CppAD::ADFun<Number> > ADFunVector; 00662 typedef CppAD::vector<BoolVector> BoolVectorVector; 00663 00664 typedef CppAD::vector< std::map<size_t,size_t> > IndexMap; 00665 public: 00666 // constructor 00667 ipopt_cppad_nlp( 00668 size_t n , 00669 size_t m , 00670 const NumberVector &x_i , 00671 const NumberVector &x_l , 00672 const NumberVector &x_u , 00673 const NumberVector &g_l , 00674 const NumberVector &g_u , 00675 ipopt_cppad_fg_info* fg_info , 00676 ipopt_cppad_solution* solution 00677 ); 00678 00679 00680 // default destructor 00681 virtual ~ipopt_cppad_nlp(); 00682 00683 // return info about the nlp 00684 virtual bool get_nlp_info( 00685 Index& n , 00686 Index& m , 00687 Index& nnz_jac_g , 00688 Index& nnz_h_lag , 00689 IndexStyleEnum& index_style 00690 ); 00691 00692 // return bounds for my problem 00693 virtual bool get_bounds_info( 00694 Index n , 00695 Number* x_l , 00696 Number* x_u , 00697 Index m , 00698 Number* g_l , 00699 Number* g_u 00700 ); 00701 00702 // return the starting point for the algorithm 00703 virtual bool get_starting_point( 00704 Index n , 00705 bool init_x , 00706 Number* x , 00707 bool init_z , 00708 Number* z_L , 00709 Number* z_U , 00710 Index m , 00711 bool init_lambda , 00712 Number* lambda 00713 ); 00714 00715 // return the objective value 00716 virtual bool eval_f( 00717 Index n , 00718 const Number* x , 00719 bool new_x , 00720 Number& obj_value 00721 ); 00722 00723 // Method to return the gradient of the objective 00724 virtual bool eval_grad_f( 00725 Index n , 00726 const Number* x , 00727 bool new_x , 00728 Number* grad_f 00729 ); 00730 00731 // return the constraint residuals 00732 virtual bool eval_g( 00733 Index n , 00734 const Number* x , 00735 bool new_x , 00736 Index m , 00737 Number* g 00738 ); 00739 00740 // Method to return: 00741 // 1) The structure of the jacobian (if "values" is NULL) 00742 // 2) The values of the jacobian (if "values" is not NULL) 00743 virtual bool eval_jac_g( 00744 Index n , 00745 const Number* x , 00746 bool new_x , 00747 Index m , 00748 Index nele_jac , 00749 Index* iRow , 00750 Index* jCol , 00751 Number* values 00752 ); 00753 00754 // Method to return: 00755 // 1) structure of hessian of the lagrangian (if "values" is NULL) 00756 // 2) values of hessian of the lagrangian (if "values" is not NULL) 00757 virtual bool eval_h( 00758 Index n , 00759 const Number* x , 00760 bool new_x , 00761 Number obj_factor , 00762 Index m , 00763 const Number* lambda , 00764 bool new_lambda , 00765 Index nele_hess , 00766 Index* iRow , 00767 Index* jCol , 00768 Number* values 00769 ); 00770 00771 // called when the algorithm is completed so the TNLP can 00772 // store/write the solution 00773 virtual void finalize_solution( 00774 Ipopt::SolverReturn status , 00775 Index n , 00776 const Number* x , 00777 const Number* z_L , 00778 const Number* z_U , 00779 Index m , 00780 const Number* g , 00781 const Number* lambda , 00782 Number obj_value , 00783 const Ipopt::IpoptData* ip_data , 00784 Ipopt::IpoptCalculatedQuantities* ip_cq 00785 ); 00786 private: 00787 /* 00788 Values passed in by user 00789 */ 00790 // dimension of the domain space 00791 const size_t n_; 00792 // number of components in g 00793 const size_t m_; 00794 // initial x 00795 const NumberVector x_i_; 00796 // limits for x and g 00797 const NumberVector x_l_; 00798 const NumberVector x_u_; 00799 const NumberVector g_l_; 00800 const NumberVector g_u_; 00801 // Users function that evaluates f and g 00802 ipopt_cppad_fg_info* const fg_info_; 00803 // object for storing final solution results 00804 ipopt_cppad_solution* const solution_; 00805 // values determined by fg_info 00806 size_t K_; // number terms in summation 00807 BoolVector retape_; // for operations sequence of r_k (u) 00808 SizeVector q_; // dimension of domain for r_k (u) 00809 SizeVector p_; // dimension of range for r_k (u) 00810 SizeVector L_; // number of r_k (u) terms 00811 SizeVector J_; // index vector for domain 00812 SizeVector I_; // index vector for range 00813 /* 00814 Computed values 00815 */ 00816 // CppAD sparsity patterns 00817 BoolVectorVector pattern_jac_r_; 00818 BoolVectorVector pattern_r_lag_; 00819 // Ipopt sparsity structure for Jacobian of g 00820 size_t nnz_jac_g_; 00821 SizeVector iRow_jac_g_; 00822 SizeVector jCol_jac_g_; 00823 // mapping from array indices to Ipopt sparsity structure 00824 IndexMap index_jac_fg_; 00825 IndexMap index_h_lag_; 00826 // Ipopt sparsity structure for Hessian of Lagragian 00827 size_t nnz_h_lag_; 00828 SizeVector iRow_h_lag_; 00829 SizeVector jCol_h_lag_; 00830 // CppAD function object for both f and g as one function 00831 ADFunVector r_fun_; 00832 /* 00833 Methods 00834 */ 00835 // Methods to block default compiler methods. 00836 ipopt_cppad_nlp(const ipopt_cppad_nlp&); 00837 ipopt_cppad_nlp& operator=(const ipopt_cppad_nlp&); 00838 00839 // Methods used by public methods 00840 static void record_r_fun( 00841 ipopt_cppad_fg_info *fg_info , 00842 size_t k , 00843 SizeVector& p , 00844 SizeVector& q , 00845 ADVector& u_ad , 00846 ADFunVector& r_fun 00847 ); 00848 static void compute_index_jac_fg( 00849 ipopt_cppad_fg_info *fg_info , 00850 SizeVector& I , 00851 SizeVector& J , 00852 size_t K , 00853 SizeVector& L , 00854 size_t m , 00855 size_t n , 00856 SizeVector& p , 00857 SizeVector& q , 00858 ADFunVector& r_fun , 00859 BoolVectorVector& pattern_jac_r , 00860 IndexMap& index_jac_fg 00861 ); 00862 static void compute_index_h_lag( 00863 ipopt_cppad_fg_info *fg_info , 00864 SizeVector& I , 00865 SizeVector& J , 00866 size_t K , 00867 SizeVector& L , 00868 size_t m , 00869 size_t n , 00870 SizeVector& p , 00871 SizeVector& q , 00872 ADFunVector& r_fun , 00873 BoolVectorVector& pattern_r_lag , 00874 IndexMap& index_h_hag 00875 ); 00876 static void compute_structure_jac_g( 00877 IndexMap& index_jac_fg , // const does not work 00878 size_t m , 00879 size_t n , 00880 size_t& nnz_jac_g , 00881 SizeVector& iRow_jac_g , 00882 SizeVector& jCol_jac_g 00883 ); 00884 static void compute_structure_h_lag( 00885 IndexMap& index_h_lag , // const does not work 00886 size_t m , 00887 size_t n , 00888 size_t& nnz_h_lag , 00889 SizeVector& iRow_h_lag , 00890 SizeVector& jCol_h_lag 00891 ); 00892 static void compute_index_jac_fg( 00893 size_t m , 00894 size_t n , 00895 const BoolVector& pattern_jac_fg , 00896 IndexMap& index_jac_fg 00897 ); 00898 static void compute_index_h_lag( 00899 size_t m , 00900 size_t n , 00901 const BoolVector& pattern_h_lag , 00902 IndexMap& index_h_lag 00903 ); 00904 00905 }; 00906 00907 00908 00909 # endif