MeshKit
1.0
|
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