1 // Copyright (C) 2004, 2006 International Business Machines and others.
2 // All Rights Reserved.
3 // This code is published under the Common Public License.
4 //
5 // $Id: IpTNLP.hpp 759 2006-07-07 03:07:08Z andreasw $
6 //
7 // Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
8 
9 #ifndef __IPTNLP_HPP__
10 #define __IPTNLP_HPP__
11 
12 #include "IpUtils.hpp"
13 #include "IpReferenced.hpp"
14 #include "IpException.hpp"
15 #include "IpAlgTypes.hpp"
16 #include "IpReturnCodes.hpp"
17 
18 namespace SimTKIpopt
19 {
20   // forward declarations
21   class IpoptData;
22   class IpoptCalculatedQuantities;
23   class IteratesVector;
24 
25   /** Base class for all NLP's that use standard triplet matrix form
26    *  and dense vectors.  This is the standard base class for all
27    *  NLP's that use the standard triplet matrix form (as for Harwell
28    *  routines) and dense vectors. The class TNLPAdapter then converts
29    *  this interface to an interface that can be used directly by
30    *  ipopt.
31    *
32    *  This interface presents the problem form:
33    *
34    *     min f(x)
35    *
36    *     s.t. gL <= g(x) <= gU
37    *
38    *          xL <=  x   <= xU
39    *
40    *  In order to specify an equality constraint, set gL_i = gU_i =
41    *  rhs.  The value that indicates "infinity" for the bounds
42    *  (i.e. the variable or constraint has no lower bound (-infinity)
43    *  or upper bound (+infinity)) is set through the option
44    *  nlp_lower_bound_inf and nlp_upper_bound_inf.  To indicate that a
45    *  variable has no upper or lower bound, set the bound to
46    *  -ipopt_inf or +ipopt_inf respectively
47    */
48   class TNLP : public ReferencedObject
49   {
50   public:
51     /**@name Constructors/Destructors */
52     //@{
TNLP()53     TNLP()
54     {}
55     ;
56 
57     /** Default destructor */
~TNLP()58     virtual ~TNLP()
59     {}
60     ;
61     //@}
62 
63     DECLARE_STD_EXCEPTION(INVALID_TNLP);
64 
65     /**@name methods to gather information about the NLP */
66     //@{
67     /** overload this method to return the number of variables
68      *  and constraints, and the number of non-zeros in the jacobian and
69      *  the hessian. The index_style parameter lets you specify C or Fortran
70      *  style indexing for the sparse matrix iRow and jCol parameters.
71      *  C_STYLE is 0-based, and FORTRAN_STYLE is 1-based.
72      */
73     enum IndexStyleEnum { C_STYLE=0, FORTRAN_STYLE=1 };
74     virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
75                               Index& nnz_h_lag, IndexStyleEnum& index_style)=0;
76 
77     /** overload this method to return the information about the bound
78      *  on the variables and constraints. The value that indicates
79      *  that a bound does not exist is specified in the parameters
80      *  nlp_lower_bound_inf and nlp_upper_bound_inf.  By default,
81      *  nlp_lower_bound_inf is -1e19 and nlp_upper_bound_inf is
82      *  1e19. (see TNLPAdapter) */
83     virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
84                                  Index m, Number* g_l, Number* g_u)=0;
85 
86     /** overload this method to return scaling parameters. This is
87      *  only called if the options are set to retrieve user scaling.
88      *  There, use_x_scaling (or use_g_scaling) should get set to true
89      *  only if the variables (or constraints) are to be scaled.  This
90      *  method should return true only if the scaling parameters could
91      *  be provided.
92      */
get_scaling_parameters(Number & obj_scaling,bool & use_x_scaling,Index n,Number * x_scaling,bool & use_g_scaling,Index m,Number * g_scaling)93     virtual bool get_scaling_parameters(Number& obj_scaling,
94                                         bool& use_x_scaling, Index n,
95                                         Number* x_scaling,
96                                         bool& use_g_scaling, Index m,
97                                         Number* g_scaling)
98     {
99       return false;
100     }
101 
102     /** overload this method to return the starting point. The bools
103      *  init_x and init_lambda are both inputs and outputs. As inputs,
104      *  they indicate whether or not the algorithm wants you to
105      *  initialize x and lambda respectively. If, for some reason, the
106      *  algorithm wants you to initialize these and you cannot, set
107      *  the respective bool to false.
108      */
109     virtual bool get_starting_point(Index n, bool init_x, Number* x,
110                                     bool init_z, Number* z_L, Number* z_U,
111                                     Index m, bool init_lambda,
112                                     Number* lambda)=0;
113 
114     /** overload this method to provide an Ipopt iterate (already in
115      *  the form Ipopt requires it internally) for a warm start.
116      *  Since this is only for expert users, a default dummy
117      *  implementation is provided and returns false. */
get_warm_start_iterate(IteratesVector & warm_start_iterate)118     virtual bool get_warm_start_iterate(IteratesVector& warm_start_iterate)
119     {
120       return false;
121     }
122 
123     /** overload this method to return the value of the objective function */
124     virtual bool eval_f(Index n, const Number* x, bool new_x,
125                         Number& obj_value)=0;
126 
127     /** overload this method to return the vector of the gradient of
128      *  the objective w.r.t. x */
129     virtual bool eval_grad_f(Index n, const Number* x, bool new_x,
130                              Number* grad_f)=0;
131 
132     /** overload this method to return the vector of constraint values */
133     virtual bool eval_g(Index n, const Number* x, bool new_x,
134                         Index m, Number* g)=0;
135     /** overload this method to return the jacobian of the
136      *  constraints. The vectors iRow and jCol only need to be set
137      *  once. The first call is used to set the structure only (iRow
138      *  and jCol will be non-NULL, and values will be NULL) For
139      *  subsequent calls, iRow and jCol will be NULL. */
140     virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
141                             Index m, Index nele_jac, Index* iRow,
142                             Index *jCol, Number* values)=0;
143 
144     /** overload this method to return the hessian of the
145      *  lagrangian. The vectors iRow and jCol only need to be set once
146      *  (during the first call). The first call is used to set the
147      *  structure only (iRow and jCol will be non-NULL, and values
148      *  will be NULL) For subsequent calls, iRow and jCol will be
149      *  NULL. This matrix is symmetric - specify the lower diagonal
150      *  only.  A default implementation is provided, in case the user
151      *  wants to se quasi-Newton approximations to estimate the second
152      *  derivatives and doesn't not neet to implement this method. */
eval_h(Index n,const Number * x,bool new_x,Number obj_factor,Index m,const Number * lambda,bool new_lambda,Index nele_hess,Index * iRow,Index * jCol,Number * values)153     virtual bool eval_h(Index n, const Number* x, bool new_x,
154                         Number obj_factor, Index m, const Number* lambda,
155                         bool new_lambda, Index nele_hess,
156                         Index* iRow, Index* jCol, Number* values)
157     {
158       return false;
159     }
160     //@}
161 
162     /** @name Solution Methods */
163     //@{
164     /** This method is called when the algorithm is complete so the TNLP can store/write the solution */
165     virtual void finalize_solution(SolverReturn status,
166                                    Index n, const Number* x, const Number* z_L, const Number* z_U,
167                                    Index m, const Number* g, const Number* lambda,
168                                    Number obj_value)=0;
169 
170     /** Intermediate Callback method for the user.  Providing dummy
171      *  default implementation.  For details see IntermediateCallBack
172      *  in IpNLP.hpp. */
intermediate_callback(AlgorithmMode mode,Index iter,Number obj_value,Number inf_pr,Number inf_du,Number mu,Number d_norm,Number regularization_size,Number alpha_du,Number alpha_pr,Index ls_trials,const IpoptData * ip_data,IpoptCalculatedQuantities * ip_cq)173     virtual bool intermediate_callback(AlgorithmMode mode,
174                                        Index iter, Number obj_value,
175                                        Number inf_pr, Number inf_du,
176                                        Number mu, Number d_norm,
177                                        Number regularization_size,
178                                        Number alpha_du, Number alpha_pr,
179                                        Index ls_trials,
180                                        const IpoptData* ip_data,
181                                        IpoptCalculatedQuantities* ip_cq)
182     {
183       return true;
184     }
185     //@}
186 
187     /** @name Methods for quasi-Newton approximation.  If the second
188      *  derivatives are approximated by Ipopt, it is better to do this
189      *  only in the space of nonlinear variables.  The following
190      *  methods are call by Ipopt if the quasi-Newton approximation is
191      *  selected.  If -1 is returned as number of nonlinear variables,
192      *  Ipopt assumes that all variables are nonlinear.  Otherwise, it
193      *  calls get_list_of_nonlinear_variables with an array into which
194      *  the indices of the nonlinear variables should be written - the
195      *  array has the lengths num_nonlin_vars, which is identical with
196      *  the return value of get_number_of_nonlinear_variables().  It
197      *  is assumed that the indices are counted starting with 1 in the
198      *  FORTRAN_STYLE, and 0 for the C_STYLE. */
199     //@{
get_number_of_nonlinear_variables()200     virtual Index get_number_of_nonlinear_variables()
201     {
202       return -1;
203     }
204 
get_list_of_nonlinear_variables(Index num_nonlin_vars,Index * pos_nonlin_vars)205     virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars,
206         Index* pos_nonlin_vars)
207     {
208       return false;
209     }
210     //@}
211 
212   private:
213     /**@name Default Compiler Generated Methods
214      * (Hidden to avoid implicit creation/calling).
215      * These methods are not implemented and
216      * we do not want the compiler to implement
217      * them for us, so we declare them private
218      * and do not define them. This ensures that
219      * they will not be implicitly created/called. */
220     //@{
221     /** Default Constructor */
222     //TNLP();
223 
224     /** Copy Constructor */
225     TNLP(const TNLP&);
226 
227     /** Overloaded Equals Operator */
228     void operator=(const TNLP&);
229     //@}
230   };
231 
232 } // namespace Ipopt
233 
234 #endif
235