00001 #ifndef _eliminations_include_
00002 #define _eliminations_include_
00003
00004 #include "angel_types.hpp"
00005 #include "angel_io.hpp"
00006
00007 #ifdef USEXAIFBOOSTER
00008 #include "xaifBooster/algorithms/CrossCountryInterface/inc/AwarenessLevel.hpp"
00009 using std::list;
00010 #endif
00011
00012 namespace angel {
00013
00014 using std::vector;
00015 using std::cout;
00016 using boost::tie;
00017
00018
00019
00020
00021
00022
00023
00024
00025
00030 int vertex_elimination (c_graph_t::vertex_t v, c_graph_t& cg);
00031
00036 inline int vertex_elimination (int j, c_graph_t& cg) {
00037 return vertex_elimination (vertex (j, cg), cg); }
00038
00039
00040
00041
00042
00047 int front_edge_elimination (c_graph_t::edge_t e,
00048 c_graph_t& cg);
00049
00054 inline int front_edge_elimination (c_graph_t::vertex_t i,
00055 c_graph_t::vertex_t j,
00056 c_graph_t& cg) {
00057 bool found_ij;
00058 c_graph_t::edge_t edge_ij;
00059 tie (edge_ij, found_ij)= edge (i, j, cg);
00060 return found_ij ? front_edge_elimination (edge_ij, cg) : 0;
00061 }
00062
00068 inline int front_edge_elimination (int i, int j, c_graph_t& cg) {
00069 return front_edge_elimination (vertex (i, cg), vertex (j, cg), cg); }
00070
00071
00076 int back_edge_elimination (c_graph_t::edge_t e,
00077 c_graph_t& cg);
00078
00082 inline int back_edge_elimination (c_graph_t::vertex_t i,
00083 c_graph_t::vertex_t j,
00084 c_graph_t& cg) {
00085 bool found_ij;
00086 c_graph_t::edge_t edge_ij;
00087 tie (edge_ij, found_ij)= edge (i, j, cg);
00088 return found_ij ? back_edge_elimination (edge_ij, cg) : 0;
00089 }
00090
00095 inline int back_edge_elimination (int i, int j, c_graph_t& cg) {
00096 return back_edge_elimination (vertex (i, cg), vertex (j, cg), cg); }
00097
00101 inline int edge_elimination (c_graph_t::edge_t e, bool front,
00102 c_graph_t& cg) {
00103 return front ? front_edge_elimination (e, cg)
00104 : back_edge_elimination (e, cg);
00105 }
00106
00110 inline int edge_elimination (edge_bool_t e, c_graph_t& cg) {
00111 return e.second ? front_edge_elimination (e.first, cg)
00112 : back_edge_elimination (e.first, cg);
00113 }
00114
00119 inline int edge_elimination (c_graph_t::vertex_t i,
00120 c_graph_t::vertex_t j,
00121 bool front, c_graph_t& cg) {
00122 return front ? front_edge_elimination (i, j, cg)
00123 : back_edge_elimination (i, j, cg);
00124 }
00125
00130 inline int edge_elimination (int i, int j, bool front, c_graph_t& cg) {
00131 return front ? front_edge_elimination (i, j, cg)
00132 : back_edge_elimination (i, j, cg);
00133 }
00134
00136 inline int edge_elimination (edge_ij_elim_t ee, c_graph_t& cg) {
00137 return edge_elimination (ee.i, ee.j, ee.front, cg); }
00138
00139
00140
00141
00142
00147 int vertex_elimination (const vector<int>& seq, c_graph_t& cg);
00148
00149
00153 inline int edge_elimination (const edge_elim_seq_t& seq, c_graph_t& cg) {
00154 int costs= 0;
00155 for (size_t i= 0; i < seq.size(); i++)
00156 costs+= edge_elimination (seq[i].edge, seq[i].front, cg);
00157 return costs;
00158 }
00159
00163 inline int edge_elimination (const edge_pair_elim_seq_t& seq, c_graph_t& cg) {
00164 int costs= 0;
00165 for (size_t k= 0; k < seq.size(); k++)
00166 costs+= edge_elimination (seq[k].i, seq[k].j, seq[k].front, cg);
00167 return costs;
00168 }
00169
00173 inline int edge_elimination (const edge_ij_elim_seq_t& seq, c_graph_t& cg) {
00174 int costs= 0;
00175 for (size_t k= 0; k < seq.size(); k++)
00176 costs+= edge_elimination (seq[k].i, seq[k].j, seq[k].front, cg);
00177 return costs;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00193 int vertex_elimination (int j, line_graph_t& lg);
00194
00195
00196
00197
00198
00204 int front_edge_elimination (int i, int j, line_graph_t& lg);
00205
00211 int front_edge_elimination (line_graph_t::edge_t vij, line_graph_t& lg);
00212
00218 int back_edge_elimination (int i, int j, line_graph_t& lg);
00219
00225 int back_edge_elimination (line_graph_t::edge_t vij, line_graph_t& lg);
00226
00229 inline int edge_elimination (int i, int j, bool front, line_graph_t& lg) {
00230 return front ? front_edge_elimination (i, j, lg)
00231 : back_edge_elimination (i, j, lg);
00232 }
00233
00235 inline int edge_elimination (line_graph_t::edge_t vij,
00236 bool front, line_graph_t& lg) {
00237 return front ? front_edge_elimination (vij, lg)
00238 : back_edge_elimination (vij, lg);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00250 struct edge_vertex_elim_t {
00251 line_graph_t::edge_t edge;
00252 bool front;
00253 };
00254
00256 typedef vector<edge_vertex_elim_t> edge_vertex_elim_seq_t;
00257
00259 inline int edge_elimination (const edge_vertex_elim_seq_t& seq, line_graph_t& lg) {
00260 int costs= 0;
00261 for (size_t k= 0; k < seq.size(); k++)
00262 costs+= edge_elimination (seq[k].edge, seq[k].front, lg);
00263 return costs;
00264 }
00265
00266
00267
00268
00269
00283 int face_elimination (line_graph_t::face_t f, int kr, line_graph_t& lg, accu_graph_t& ac);
00284
00297 inline int face_elimination (line_graph_t::face_t f, int kr, line_graph_t& lg) {
00298 accu_graph_t dummy (*lg.cgp, lg);
00299 return face_elimination (f, kr, lg, dummy); }
00300
00304 inline int face_elimination (line_graph_t::face_t f, line_graph_t& lg) {
00305 return face_elimination (f, -1, lg); }
00306
00313 inline int face_elimination (int i, int j, line_graph_t& lg) {
00314 line_graph_t::face_t f; bool found;
00315 tie (f, found)= edge (i, j, lg);
00316 return found ? face_elimination (f, lg) : -1;
00317 }
00318
00332 inline int face_elimination (int i, int j, int kr, line_graph_t& lg) {
00333 line_graph_t::face_t f; bool found;
00334 tie (f, found)= edge (i, j, lg);
00335 return found ? face_elimination (f, kr, lg) : -1;
00336 }
00337
00338 inline int face_elimination (int i, int j, int kr, line_graph_t& lg, accu_graph_t& ac) {
00339 line_graph_t::face_t f; bool found;
00340 tie (f, found)= edge (i, j, lg);
00341 return found ? face_elimination (f, kr, lg, ac) : -1;
00342 }
00343
00353 inline int face_elimination (triplet_t& t, line_graph_t& lg) {
00354 int k= face_elimination (t.i, t.j, t.k, lg);
00355 if (k != -1) t.k= k; return k != -1;
00356 }
00357
00370 inline int face_elimination (triplet_t& t, line_graph_t& lg, accu_graph_t& ac) {
00371 int k= face_elimination (t.i, t.j, t.k, lg, ac);
00372 if (k != -1) t.k= k; return k != -1;
00373 }
00374
00385 inline int was_non_trivial_elimination (int i, int j, int k, const line_graph_t& lg) {
00386 line_graph_t::const_ed_t el= get(boost::vertex_degree, lg);
00387 return ((k != -1 && el[i] != 1 && el[j] != 1) || k < lg.v()-1);
00388 }
00389
00399 inline int was_non_trivial_elimination (line_graph_t::face_t f, int k, const line_graph_t& lg) {
00400 line_graph_t::edge_t i= source (f, lg), j= target (f, lg);
00401 return was_non_trivial_elimination (i, j, k, lg);
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00414 inline int eliminate (c_graph_t::vertex_t v, c_graph_t& cg) {
00415 return vertex_elimination (v, cg); }
00416
00418 inline int eliminate (int j, c_graph_t& cg) {
00419 return vertex_elimination (j, cg); }
00420
00422 inline int eliminate (int j, line_graph_t& lg) {
00423 return vertex_elimination (j, lg); }
00424
00426 inline int eliminate (edge_bool_t e, c_graph_t& cg) {
00427 return edge_elimination (e, cg);
00428 }
00429
00431 inline int eliminate (edge_ij_elim_t ee, c_graph_t& cg) {
00432 return edge_elimination (ee, cg);
00433 }
00434
00440 inline int eliminate (line_graph_t::face_t f, line_graph_t& lg) {
00441 int k= face_elimination (f, -1, lg);
00442 return was_non_trivial_elimination (f, k, lg);
00443 }
00444
00452 inline int eliminate (triplet_t& t, line_graph_t& lg) {
00453 return face_elimination (t, lg);
00454 }
00455
00456
00457
00458
00459
00461 int eliminatable_vertices (const c_graph_t& cg,
00462 vector<c_graph_t::vertex_t>& vv);
00463
00468 int semi_eliminatable_vertices (const c_graph_t& cg, vector<c_graph_t::vertex_t>& vv);
00469
00474 int eliminatable_edges (const c_graph_t& cg,
00475 vector<c_graph_t::edge_t>& ev);
00476
00478 int front_eliminatable_edges (const c_graph_t& cg,
00479 vector<c_graph_t::edge_t>& ev);
00480
00482 int back_eliminatable_edges (const c_graph_t& cg,
00483 vector<c_graph_t::edge_t>& ev);
00484
00491 int eliminatable_edges (const c_graph_t& cg,
00492 vector<edge_bool_t>& ev);
00493
00500 int eliminatable_edges (const c_graph_t& cg,
00501 vector<edge_ij_elim_t>& ev);
00502
00504 unsigned int eliminatable_edges(const c_graph_t& cg,
00505 vector<EdgeElim>& ev);
00506
00508 int eliminatable_faces (const line_graph_t& lg,
00509 vector<line_graph_t::face_t>& fv);
00510
00517 inline int eliminatable_triplets (const line_graph_t& lg, vector<triplet_t>& tv) {
00518 vector<line_graph_t::face_t> fv;
00519 eliminatable_faces (lg, fv);
00520 tv.resize (0);
00521 for (size_t c= 0; c < fv.size(); c++) {
00522 int s= source (fv[c], lg), t= target (fv[c], lg);
00523 triplet_t tr (s, t, -1); tv.push_back (tr); }
00524 return tv.size();
00525 }
00526
00527
00528
00529
00530
00532 inline int eliminatable_objects (const c_graph_t& cg,
00533 vector<c_graph_t::vertex_t>& vv) {
00534 return eliminatable_vertices (cg, vv);
00535 }
00536
00538 inline int eliminatable_objects (const c_graph_t& cg,
00539 vector<c_graph_t::edge_t>& ev) {
00540 return eliminatable_edges (cg, ev);
00541 }
00542
00544 inline int eliminatable_objects (const c_graph_t& cg,
00545 vector<edge_bool_t>& ev) {
00546 return eliminatable_edges (cg, ev);
00547 }
00548
00550 inline int eliminatable_objects (const c_graph_t& cg,
00551 vector<edge_ij_elim_t>& ev) {
00552 return eliminatable_edges (cg, ev);
00553 }
00554
00556 inline int eliminatable_objects (const line_graph_t& lg,
00557 vector<line_graph_t::face_t>& fv) {
00558 return eliminatable_faces (lg, fv);
00559 }
00560
00562 inline int eliminatable_objects (const line_graph_t& lg,
00563 vector<triplet_t>& tv) {
00564 return eliminatable_triplets (lg, tv);
00565 }
00566
00567
00568
00577 template <typename Ad_graph_t,
00578 typename El_spec_t>
00579 class elimination_history_t {
00580 private:
00581
00582 public:
00583 const Ad_graph_t og;
00584 vector<El_spec_t> seq;
00585 Ad_graph_t cg;
00586 int ccosts;
00587
00588 typedef Ad_graph_t ad_graph_t;
00589 typedef El_spec_t el_spec_t;
00590
00595 elimination_history_t () : og () {}
00596
00600 elimination_history_t (const Ad_graph_t& _cg) :
00601 og (_cg), cg (_cg), ccosts (0) {
00602 THROW_EXCEPT_MACRO (!check (), consistency_exception, "Inconsistent input graph");}
00603
00611 elimination_history_t (const Ad_graph_t& _og, const vector<El_spec_t>& _seq,
00612 const Ad_graph_t& _cg, int _ccosts= 0) :
00613 og (_og), seq (_seq), cg (_cg), ccosts (_ccosts) {
00614 THROW_EXCEPT_MACRO (!check (), consistency_exception, "Inconsistent input graphs");}
00615
00622 elimination_history_t (const Ad_graph_t& _og, const vector<El_spec_t>& _seq) :
00623 og (_og), seq (_seq) {
00624 THROW_EXCEPT_MACRO (!og.check (), consistency_exception, "Inconsistent input graph");
00625 bool seq_ok= rebuild_graph ();
00626 THROW_EXCEPT_MACRO (!seq_ok, consistency_exception, "Inconsistent elimination sequence");
00627 }
00628
00630 elimination_history_t (const elimination_history_t& eh) :
00631 og (eh.og), seq (eh.seq), cg (eh.cg), ccosts (eh.ccosts) {
00632 THROW_EXCEPT_MACRO (!og.check (), consistency_exception, "Inconsistent start graph");
00633 THROW_EXCEPT_MACRO (!cg.check (), consistency_exception, "Inconsistent current graph");
00634 THROW_EXCEPT_MACRO (!check_sequence(), consistency_exception, "Inconsistent elimination sequence");
00635 }
00636
00638 elimination_history_t& operator= (const elimination_history_t& eh) {
00639 (Ad_graph_t&) og= eh.og; seq= eh.seq; cg= eh.cg; ccosts= eh.ccosts;
00640 THROW_DEBUG_EXCEPT_MACRO (!check (), consistency_exception, "Inconsistent graphs after assignment");
00641 return *this; }
00642
00644 void swap (elimination_history_t& eh) {
00645 ((Ad_graph_t&) og).swap ((Ad_graph_t&) eh.og);
00646 seq.swap (eh.seq); cg.swap (eh.cg); std::swap (ccosts, eh.ccosts);
00647 THROW_DEBUG_EXCEPT_MACRO (!check (), consistency_exception, "Inconsistent graphs after swapping");}
00648
00660 int elimination (El_spec_t el) {
00661 int costs= eliminate (el, cg);
00662 if (costs > 0) {seq.push_back (el); ccosts+= costs; }
00663 return costs; }
00664
00666 bool check_sequence () const {
00667 Ad_graph_t og_copy (og);
00668 int costs= 0;
00669 for (size_t c= 0; c < seq.size(); c++) {
00670 El_spec_t el= seq[c];
00671 int el_costs= eliminate (el, og_copy);
00672 if (el_costs == 0) {
00673 cout << "check_sequence failed";
00674 write_vector (" with elimination sequence", seq);
00675 cout << " at " << c << "th entry, which is " << seq[c] << std::endl;
00676 write_graph ("at this moment the graph is", og_copy);
00677 cout << "it is " << (og_copy.check() ? "" : "not ") << "consistent\n";
00678 write_vector ("complete elimination sequence is", seq);
00679 return false; }
00680 else costs+= el_costs; }
00681 if (cg != og_copy) {
00682 cout << "check_sequence failed because of different resulting graphs.\n";
00683 write_graph ("current graph is", cg);
00684 write_graph ("seq applied to og results in", og_copy);
00685 write_graph ("original graph was", og);
00686 write_vector ("elimination sequence is", seq);
00687 return false; }
00688 if (ccosts != costs) {
00689 cout << "check_sequence failed because of different elimination costs.\n";
00690 cout << "current costs are " << ccosts << std::endl;
00691 cout << "seq applied to og requires " << costs << std::endl;
00692 write_graph ("original graph was", og);
00693 write_vector ("elimination sequence is", seq);
00694 write_graph ("current graph is", cg);
00695 return false; }
00696 return true;
00697 }
00698
00700 bool check () const {
00701 if (!og.check ()) return false;
00702 if (!cg.check ()) return false;
00703 return check_sequence (); }
00704
00706 bool rebuild_graph () {
00707 Ad_graph_t og_copy (og);
00708 int costs= 0;
00709 for (size_t c= 0; c < seq.size(); c++) {
00710 int el_costs= eliminate (seq[c], og_copy);
00711 if (el_costs == 0) return false; else costs+= el_costs; }
00712 cg= og_copy; ccosts= costs; return true; }
00713
00719 template <typename Heuristic_t>
00720 void complete_sequence (Heuristic_t h) {
00721 vector<El_spec_t> v1, v2;
00722 for (eliminatable_objects (cg, v1); v1.size() > 0; eliminatable_objects (cg, v1)) {
00723 v2.resize (0); h (v1, cg, v2); elimination (v2[0]); }}
00724 };
00725
00729 typedef elimination_history_t<c_graph_t, c_graph_t::vertex_t> vertex_elimination_history_t;
00733 typedef elimination_history_t<c_graph_t, edge_ij_elim_t> edge_elimination_history_t;
00737 typedef elimination_history_t<line_graph_t, triplet_t> face_elimination_history_t;
00738
00740 bool convert_elimination_sequence (const vector<c_graph_t::vertex_t>& vv,
00741 const c_graph_t& cg,
00742 vector<edge_ij_elim_t>& ev);
00743
00745 bool convert_elimination_sequence (const vector<edge_ij_elim_t>& ev,
00746 const line_graph_t& lg,
00747 vector<triplet_t>& tv);
00748
00749 #ifdef USEXAIFBOOSTER
00750
00751 EdgeRefType_E getRefType (const c_graph_t::edge_t e,
00752 const c_graph_t& angelLCG,
00753 const list<EdgeRef_t>& edge_ref_list);
00754
00755 const xaifBoosterCrossCountryInterface::LinearizedComputationalGraphEdge* getLCG_p (const c_graph_t::edge_t e,
00756 const c_graph_t& angelLCG,
00757 const list<EdgeRef_t>& edge_ref_list);
00758
00759 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex* getJAE_p (const c_graph_t::edge_t e,
00760 const c_graph_t& angelLCG,
00761 const list<EdgeRef_t>& edge_ref_list);
00762
00763 void setJaevRef (const c_graph_t::edge_t e,
00764 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev,
00765 const c_graph_t& angelLCG,
00766 const list<EdgeRef_t>& edge_ref_list);
00767
00768 void removeRef (const c_graph_t::edge_t e,
00769 const c_graph_t& angelLCG,
00770 list<EdgeRef_t>& edge_ref_list);
00771
00787 unsigned int multiply_edge_pair_directly (const c_graph_t::edge_t e1,
00788 const c_graph_t::edge_t e2,
00789 c_graph_t& angelLCG,
00790 list<EdgeRef_t>& edge_ref_list,
00791 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list);
00792
00808 unsigned int front_eliminate_edge_directly (c_graph_t::edge_t e,
00809 c_graph_t& angelLCG,
00810 list<EdgeRef_t>& edge_ref_list,
00811 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list);
00812
00828 unsigned int back_eliminate_edge_directly (c_graph_t::edge_t e,
00829 c_graph_t& angelLCG,
00830 list<EdgeRef_t>& edge_ref_list,
00831 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list);
00832
00833 unsigned int pair_elim (c_graph_t::edge_t e1,
00834 c_graph_t::edge_t e2,
00835 c_graph_t& angelLCG,
00836 const elimSeq_cost_t& currentElimSeq,
00837 refillDependenceMap_t& refillDependences);
00838
00839 unsigned int front_elim (c_graph_t::edge_t e,
00840 c_graph_t& angelLCG,
00841 const elimSeq_cost_t& currentElimSeq,
00842 refillDependenceMap_t& refillDependences);
00843
00844 unsigned int back_elim (c_graph_t::edge_t e,
00845 c_graph_t& angelLCG,
00846 const elimSeq_cost_t& currentElimSeq,
00847 refillDependenceMap_t& refillDependences);
00848
00849 unsigned int pairElim_noJAE (c_graph_t::edge_t e1,
00850 c_graph_t::edge_t e2,
00851 c_graph_t& angelLCG,
00852 const transformationSeq_cost_t* currentTransformationSequence,
00853 refillDependenceMap_t& refillDependences);
00854
00855 unsigned int frontEdgeElimination_noJAE (c_graph_t::edge_t e,
00856 c_graph_t& angelLCG,
00857 const transformationSeq_cost_t* currentTransformationSequence,
00858 refillDependenceMap_t& refillDependences);
00859
00860 unsigned int backEdgeElimination_noJAE (c_graph_t::edge_t e,
00861 c_graph_t& angelLCG,
00862 const transformationSeq_cost_t* currentTransformationSequence,
00863 refillDependenceMap_t& refillDependences);
00864
00865 #endif // USEXAIFBOOSTER
00866
00867 }
00868
00869 #endif // _eliminations_include_
00870