/home/coin/SVN-release/OS-2.0.0/OS/CoinAllExamples/CppAD/ipopt_cppad_nlp.hpp

Go to the documentation of this file.
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

Generated on Mon Aug 3 03:02:21 2009 by  doxygen 1.4.7