00001
00002
00003
00004
00005
00006
00007 #ifndef DUALQQP_H
00008 #define DUALQQP_H
00009
00010 #include "standard.h"
00011 #include "usermatrix.h"
00012 #include "func.h"
00013 #include "problem.h"
00014 #include "param.h"
00015
00025 class DualFunc: public Func {
00026 public:
00029 MinlpProblem &qqp;
00030
00034 vector<double> dual_bounds;
00035
00038 Param ¶m;
00039
00047 DualFunc(MinlpProblem &qqp_, Param ¶m_, Pointer<ostream> out_func_p_=out_out_p, Pointer<ostream> out_func_log_p_=out_log_p)
00048 : Func(0, out_func_p_, out_func_log_p_), qqp(qqp_), param(param_)
00049 { }
00050
00054 int primal_dim() const { return qqp.dim(); };
00055
00059 virtual dvector get_dual_point() const=0;
00060
00064 virtual double get_dual_val() const=0;
00065
00072 virtual dvector get_orig_point(int i=0) const=0;
00073
00077 virtual int nr_of_orig_points() const { return 1; }
00078
00079 virtual void set_curvature(CurvatureType ct) { out_err << "DualFunc::set_curvature() not implemented. Aborting." << endl; exit (-1); };
00080 virtual CurvatureType get_curvature() const { out_err << "DualFunc::get_curvature() not implemented. Aborting." << endl; exit (-1); return Func::UNKNOWN; };
00081 };
00082
00083 class QqpMatrix;
00084 class QqpExtMatrix;
00085
00100 class QqpDualFunc: public DualFunc {
00101 friend class QqpMatrix;
00102 friend class QqpExtMatrix;
00103
00104 protected:
00112 typedef enum { LIN, QUAD, EXTQUAD } b_type;
00113
00120 vector<b_type> block_type;
00121
00124 ivector i_ext;
00125
00128 int num_ext;
00129
00133 ivector i_q;
00134
00137 int n_q;
00138
00143 dvector mid_point;
00144
00149 BlockMatrix W;
00150
00153 dvector radius;
00154
00161 vector<bool> ball_con;
00162
00169
00170
00175 vector<dvector> b_con;
00176
00181 dvector b_obj;
00182
00187 dvector c_con;
00188
00193 double c_obj;
00194
00199 vector<Pointer<UserMatrix> > A_lag;
00200
00205 mutable vector<dvector> b_lag;
00206
00211 mutable double c_lag;
00212
00216 mutable dvector x_lag;
00217
00220 mutable double dual_val;
00221
00224 mutable dvector subgrad;
00225
00228 mutable vector<vector<double> > eig_val;
00229
00232 mutable vector<vector<dvector> > eig_vec;
00233
00237 int num_qbox() const { return n_q+num_ext; }
00238
00242 int num_blocks() const { return qqp.block.size(); };
00243
00250 void init_ext();
00251
00263 void init();
00264
00270 void set_ball_con();
00271
00279 void get_bc(double &c_,dvector &b_,SepQcFunc &q);
00280
00289 void set_bc();
00290
00296 int set_dual_val() const;
00297
00302 double eval_mod_con(int con_nr) const;
00303
00307 double eval_mod_obj() const;
00308
00314 void set_subgrad() const;
00315
00316 public:
00318 int num_matmult;
00320 mutable double eig_time;
00321
00326 mutable dvector dual_point;
00327
00334 QqpDualFunc(MinlpProblem &qqp_, Param ¶m_, Pointer<ostream> out_func_p_=out_out_p, Pointer<ostream> out_func_log_p_=out_log_p)
00335 : DualFunc(qqp_, param_, out_func_p_, out_func_log_p_), num_matmult(0), eig_time(0),
00336 eig_vec(qqp_.block.size()), eig_val(qqp_.block.size()),
00337 radius(qqp_.block.size()), ball_con(qqp_.block.size()),
00338 block_type(qqp_.block.size()), i_ext(qqp_.block.size()), i_q(qqp_.block.size()),
00339 c_con(qqp_.con.size()), b_obj(qqp_.dim()), b_con(qqp_.con.size()),
00340 A_lag(qqp.block.size()), b_lag(qqp.block.size()),
00341 mid_point(qqp_.dim()), W(qqp_.block)
00342 { init();
00343 };
00344
00353 virtual int valgrad(double& val, UserVector<double>& g, const UserVector<double>& z) const;
00354
00355 using DualFunc::valgrad;
00356
00364 double eval(const UserVector<double>& z) const {
00365 assert(z.dim() == dim());
00366 dual_point=z;
00367 set_dual_val();
00368 return dual_val;
00369 }
00370
00371 using DualFunc::eval;
00372
00373
00374
00375
00376
00377
00384
00385
00386
00387
00388
00389 void grad(UserVector<double>& g, const UserVector<double>& x) const {
00390 double val;
00391 valgrad(val, g, x);
00392 }
00393
00394 using Func::grad;
00395
00402
00403
00406 virtual void HessMult(UserVector<double>& y, const UserVector<double>& x, const UserVector<double>& z) const { };
00407
00408 using Func::HessMult;
00409
00412
00413
00417 dvector get_dual_point() const;
00418
00425 dvector get_dual_point(dvector& ext_dual_point) const {
00426 if (!(ext_dual_point==dual_point)) eval(ext_dual_point);
00427 return get_dual_point();
00428 }
00429
00433 double get_dual_val() const { return dual_val; }
00434
00441 double get_dual_val(dvector& ext_dual_point) const {
00442 if (!(ext_dual_point==dual_point)) eval(ext_dual_point);
00443 return get_dual_val();
00444 }
00445
00450 dvector get_orig_point(int use_eig_vec=0) const;
00451
00458 dvector get_orig_point(dvector& ext_dual_point, int use_eig_vec=0) const {
00459 if (!(ext_dual_point==dual_point)) eval(ext_dual_point);
00460 return get_orig_point(use_eig_vec);
00461 }
00462
00466 int nr_of_orig_points() const { return eig_vec[0].size(); }
00467
00471 void print(ostream &out) const;
00472 };
00473
00478
00479
00480
00487
00488
00489
00490
00494
00495
00496
00497
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00528 class QqpMatrix: public UserMatrix {
00529 protected:
00531 int b_num;
00532 public:
00534 QqpDualFunc &d;
00535
00536
00541 QqpMatrix(QqpDualFunc &d_,int b_num_)
00542 : UserMatrix(d_.qqp.block[b_num_].size()), d(d_), b_num(b_num_)
00543 { };
00544
00549 void MultV(dvector &y,const dvector &x) const;
00550
00551 void MultV(UserVector<double>& y, const UserVector<double>& x) const {
00552 dvector x0(x);
00553 dvector y0(y.size());
00554 MultV(y0,x0);
00555 y=y0;
00556 }
00557
00558 using UserMatrix::MultV;
00559 };
00560
00563 class QqpExtMatrix : public UserMatrix {
00564 protected:
00566 int b_num;
00567 public:
00569 QqpDualFunc &d;
00570
00575 QqpExtMatrix(QqpDualFunc &d_,int b_num_)
00576 : UserMatrix(d_.qqp.block[b_num_].size()+1), d(d_), b_num(b_num_)
00577 { };
00578
00583 void MultV(dvector &y, const dvector &x) const;
00584
00585 void MultV(UserVector<double>& y, const UserVector<double>& x) const {
00586 dvector x0(x);
00587 dvector y0(y.size());
00588 MultV(y0,x0);
00589 y=y0;
00590 }
00591
00592 using UserMatrix::MultV;
00593 };
00594
00595 #endif // DUALQQP_H