MeshKit  1.0
IABendNlp.hpp
Go to the documentation of this file.
00001 // IABendNlp.hpp
00002 // Interval Assignment for Meshkit
00003 //
00004 // ipopt mixed-integer solution
00005 // The idea is the optimal solution will be an integer one, if one exists
00006 //
00007 
00008 #ifndef MESHKIT_IA_IABENDNLP_HP
00009 #define MESHKIT_IA_IABENDNLP_HP
00010 
00011 #include "meshkit/IANlp.hpp"
00012 #include "meshkit/IAWeights.hpp"
00013 #include "meshkit/IPBend.hpp"
00014 
00015 #include <math.h>
00016 
00017 // from Ipopot
00018 #include "IpTNLP.hpp"
00019 
00020 namespace MeshKit {
00021 
00022 class IAData;
00023 class IPData;
00024 class IASolution;
00025 
00026 class IABendNlp : public TNLP
00027 {
00028   // first set of functions required by TNLP
00029 public:
00031   IABendNlp(const IAData *data_ptr, const IPData *ip_data_ptr, const IPBendData* ip_bend_ptr, 
00032             IASolution *solution_ptr, IAWeights *weight_ptr, const bool set_silent = true); 
00033 
00035   virtual ~IABendNlp();
00036   
00037 
00041   virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
00042                             Index& nnz_h_lag, IndexStyleEnum& index_style);
00043 
00045   virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
00046                                Index m, Number* g_l, Number* g_u);
00047 
00049   virtual bool get_starting_point(Index n, bool init_x, Number* x_init,
00050                                   bool init_z, Number* z_L, Number* z_U,
00051                                   Index m, bool init_lambda,
00052                                   Number* lambda);
00053 
00055   virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value);
00056 
00058   virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f);
00059 
00061   virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g);
00062 
00067   virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
00068                           Index m, Index nele_jac, Index* iRow, Index *jCol,
00069                           Number* values);
00070 
00075   virtual bool eval_h(Index n, const Number* x, bool new_x,
00076                       Number obj_factor, Index m, const Number* lambda,
00077                       bool new_lambda, Index nele_hess, Index* iRow,
00078                       Index* jCol, Number* values);
00079 
00081 
00085   virtual void finalize_solution(SolverReturn status,
00086                                  Index n, const Number* x, const Number* z_L, const Number* z_U,
00087                                  Index m, const Number* g, const Number* lambda,
00088                                  Number obj_value,
00089                                  const IpoptData* ip_data,
00090                                  IpoptCalculatedQuantities* ip_cq);
00092 
00093 // extra stuff not required by TNLP
00094   
00095   // if true, then enforce that the sum-even values are a whole integer multiplied by two
00096   void even_constraints_active( bool set_active )
00097   { evenConstraintsActive = set_active; }
00098 
00099   // raw value, relative change to I, usually taken to some power
00100   double f_x_value( double I_i, double x_i );
00101 
00102 private:  
00103   // hide untrusted default methods
00105   //  IA_NLP();
00106   IABendNlp();
00107   IABendNlp(const IABendNlp&);
00108   IABendNlp& operator=(const IABendNlp&);
00110   
00111   // input data
00112   const IAData *data;
00113   const IPData *ipData;
00114   const IPBendData *ipBendData;
00115   
00116   // solution data
00117   IASolution *solution;
00118   
00119   
00120   // implemented using an overlay over an IANlp
00121   IANlp baseNlp;  
00122 
00123   const int base_n, base_m;
00124   const int problem_n;
00125   int problem_m;
00126   int wave_even_constraint_start;
00127 
00128   // defining / weighting objective function
00129   IAWeights *weights;
00130 
00131   // debug
00132   const bool silent;
00133   const bool debugging;
00134   const bool verbose; // verbose debugging
00135   
00136   bool evenConstraintsActive;
00137   
00138   // for non-linear even constraints
00139   struct SparseMatrixEntry
00140         {
00141           // position in matrix
00142           // column must be less than row, j <= i
00143           int i; // row
00144           int j; // col
00145           
00146           // order in sequence for hessian values array, etc.
00147           int k;
00148     
00149           static int n; // matrix is n x n
00150           int key() const { return i * n + j; }
00151           
00152           SparseMatrixEntry(const int iset, const int jset, const int kset);
00153           SparseMatrixEntry() : i(-1), j(-1), k(-1) {} // bad values if unspecified
00154         };
00155         
00156         typedef std::map<int, SparseMatrixEntry> SparseMatrixMap; 
00157         
00158         SparseMatrixMap hessian_map;  // sorted by key
00159         std::vector< SparseMatrixEntry > hessian_vector; // from 0..k
00160   
00161         void add_hessian_entry( int i, int j, int &k );
00162         void build_hessian();
00163         int get_hessian_k( int i, int j );
00164   void print_hessian(); // debug
00165   
00166   // nearest integer
00167   const double nearest_int( const double x )
00168   {
00169     const double xm = floor(x);
00170     const double xp = ceil(x);
00171     return (fabs(xm - x) < fabs(xp - x)) ? xm : xp;
00172   }
00173   const double nearest_even( const double s )
00174   {
00175     return 2. * nearest_int( s / 2. );
00176   }
00177   const double delta_x( const double x )
00178   {
00179     return x - nearest_int(x);
00180   }
00181   const double delta_s( const double s )
00182   {
00183     return s - nearest_even(s);
00184   }
00185   
00186   double eval_g_int_x( const double x )
00187   {
00188     const double d = delta_x(x);
00189     return 1. - d * d;
00190   }
00191   double eval_g_int_s( const double s )
00192   {
00193     const double d = delta_s(s);
00194     return 1. - d * d;
00195   }
00196   double eval_jac_int_x( const double x )
00197   {
00198     const double d = delta_x( x );
00199     return -2. * d; // d' is 1
00200   }
00201   double eval_jac_int_s( const double s )
00202   {
00203     double d = delta_s(s);
00204     return -2. * d; // d' is 1
00205   }
00206   double eval_hess_int_x( const double x )
00207   {
00208     return -2.; 
00209   }
00210   virtual double eval_hess_int_s( const double s )
00211   {
00212     return -2.;
00213   }
00214   
00215 };
00216 
00217 } // namespace MeshKit 
00218 
00219 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines