eliminations.cpp

Go to the documentation of this file.
00001 // $Id: eliminations.cpp,v 1.13 2008/02/28 14:57:33 gottschling Exp $
00002 #include "angel/include/eliminations.hpp"
00003 #include "angel/include/angel_tools.hpp"
00004 #include "angel/include/angel_io.hpp"
00005 
00006 namespace angel {
00007 
00008 using namespace std;
00009 using namespace boost;
00010 
00011 // =========================================================================
00012 // eliminations in c-graph
00013 // =========================================================================
00014 
00015 // -------------------------------------------------------------------------
00016 // elimination of a single vertex in compute graph
00017 // -------------------------------------------------------------------------
00018 
00019 int vertex_elimination (c_graph_t::vertex_t v, c_graph_t& cg) {
00020   // vector used since eliminations invalidate iterators
00021   vector<c_graph_t::edge_t> ev;
00022   c_graph_t::oei_t oei, oe_end;
00023   for (tie (oei, oe_end)= out_edges (v, cg); oei != oe_end; ++oei)
00024     ev.push_back (*oei);
00025 
00026   int costs= 0;
00027   for (size_t n= 0; n < ev.size(); n++)
00028     costs+= back_edge_elimination (ev[n], cg);
00029   // UN: print graph after elimination
00030   // graphviz_display(cg);
00031   return costs;
00032 }
00033 
00034 // -------------------------------------------------------------------------
00035 // elimination of a single egde in compute graph
00036 // -------------------------------------------------------------------------
00037 
00038 int front_edge_elimination (c_graph_t::edge_t edge_ij, c_graph_t& cg) {
00039   using boost::tie;
00040 
00041   typedef c_graph_t::vertex_t          vertex_t;
00042   typedef c_graph_t::edge_t            edge_t;
00043   typedef c_graph_t::oei_t             oei_t;
00044   c_graph_t::ew_t                      ew= get(edge_weight, cg);
00045   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), cg);
00046   // write_edge_property (std::cout, "edge weights ", ew, cg);
00047 
00048   vertex_t i= source (edge_ij, cg), j= target (edge_ij, cg);
00049 
00050   if (cg.vertex_type (j) == dependent) return 0;
00051 
00052   int c_ji= ew[edge_ij];
00053   // safe edges in vector because iterators will be invalidated
00054   oei_t oei, oe_end;
00055   std::vector<edge_t> ev;
00056   for (tie (oei, oe_end)= out_edges (j, cg); oei != oe_end; ++oei)
00057     ev.push_back (*oei);
00058 
00059   for (size_t n= 0; n < ev.size(); n++) {
00060     edge_t edge_jk= ev[n];
00061     vertex_t k= target (edge_jk, cg);
00062     int d= c_ji * ew[edge_jk];
00063 
00064     bool   found_ik;
00065     edge_t edge_ik;
00066     tie (edge_ik, found_ik)= edge (i, k, cg);
00067     if (found_ik) { // absorption
00068       ew[edge_ik]+= d;
00069       if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_jk] == VARIABLE_EDGE)   eType[edge_ik] = VARIABLE_EDGE;
00070       else if (eType[edge_ik] != VARIABLE_EDGE)                                 eType[edge_ik] = CONSTANT_EDGE;
00071     } 
00072     else { // fill-in
00073       tie (edge_ik, found_ik)= add_edge (i, k, cg.next_edge_number++, cg);
00074       ew[edge_ik]= d;
00075       if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_jk] == VARIABLE_EDGE)   eType[edge_ik] = VARIABLE_EDGE;
00076       else if (eType[edge_ij] == UNIT_EDGE && eType[edge_jk] == UNIT_EDGE)      eType[edge_ik] = UNIT_EDGE;
00077       else                                                                      eType[edge_ik] = CONSTANT_EDGE;
00078     }
00079   }
00080   remove_edge (edge_ij, cg);
00081 
00082   // if ij was the last in_edge of j then all out-edges (stored in ev) become unreachable
00083   // targets of out-edges shall be reachable by the set of edge_ik's
00084   if (in_degree (j, cg) == 0)
00085     for (size_t n= 0; n < ev.size(); n++)
00086     remove_edge (ev[n], cg);
00087   // is overkill: remove_unreachable_edges (j, cg);
00088 
00089   return ev.size();
00090 }
00091 
00092 int back_edge_elimination (c_graph_t::edge_t edge_ij, c_graph_t& cg) {
00093   using namespace boost;
00094   using boost::tie;
00095 
00096   typedef c_graph_t::vertex_t          vertex_t;
00097   typedef c_graph_t::edge_t            edge_t;
00098   typedef c_graph_t::iei_t             iei_t;
00099   c_graph_t::ew_t                      ew= get(edge_weight, cg);
00100   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), cg);
00101 
00102   vertex_t i= source (edge_ij, cg), j= target (edge_ij, cg);
00103 
00104   if (cg.vertex_type (i) == independent) return 0;
00105 
00106   int c_ji= ew[edge_ij];
00107   // safe edges in vector because iterators will be invalidated
00108   iei_t iei, ie_end;
00109   std::vector<edge_t> ev;
00110   for (tie (iei, ie_end)= in_edges (i, cg); iei != ie_end; ++iei)
00111     ev.push_back (*iei);
00112 
00113   for (size_t n= 0; n < ev.size(); n++) {
00114     edge_t edge_ki= ev[n];
00115     vertex_t k= source (edge_ki, cg);
00116     int d= c_ji * ew[edge_ki];
00117 
00118     bool   found_kj;
00119     edge_t edge_kj;
00120     tie (edge_kj, found_kj)= edge (k, j, cg);
00121     if (found_kj) { // absorption 
00122       ew[edge_kj]+= d;
00123       if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_ki] == VARIABLE_EDGE)   eType[edge_kj] = VARIABLE_EDGE;
00124       else if (eType[edge_kj] != VARIABLE_EDGE)                                 eType[edge_kj] = CONSTANT_EDGE;
00125     }
00126     else { // fill-in
00127       tie (edge_kj, found_kj)= add_edge (k, j, cg.next_edge_number++, cg);
00128       ew[edge_kj]= d; 
00129       if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_ki] == VARIABLE_EDGE)   eType[edge_kj] = VARIABLE_EDGE;
00130       else if (eType[edge_ij] == UNIT_EDGE && eType[edge_ki] == UNIT_EDGE)      eType[edge_kj] = UNIT_EDGE;
00131       else                                                                      eType[edge_kj] = CONSTANT_EDGE;
00132     }
00133   }
00134   remove_edge (edge_ij, cg);
00135 
00136   // if ij was the last out_edge of i then all in-edges (stored in ev) become irrelevant
00137   // except if i is a dependent vertex
00138   // sources of in-edges shall be relevant due to the set of edge_ik's
00139   if (out_degree (i, cg) == 0 && vertex_type (i, cg) != dependent)
00140     for (size_t n= 0; n < ev.size(); n++)
00141       remove_edge (ev[n], cg); 
00142   // is overkill: remove_irrelevant_edges (i, cg);
00143 
00144   return ev.size();
00145 }
00146 
00147 
00148 
00149 
00150 
00151 // =========================================================================
00152 // eliminations in line graph
00153 // =========================================================================
00154 
00155 // -------------------------------------------------------------------------
00156 // elimination of a single vertex in line graph
00157 // -------------------------------------------------------------------------
00158 
00159 int vertex_elimination (int j, line_graph_t& lg) {
00160   vector<line_graph_t::face_t> fv;
00161   line_graph_t::evn_t evn= get(vertex_name, lg);
00162   line_graph_t::ei_t        ei, eend;
00163   for (tie (ei, eend)= vertices (lg); ei != eend; ++ei) 
00164     if (evn[*ei].second == j) {
00165       line_graph_t::ofi_t ofi, of_end;
00166       for (tie (ofi, of_end)= out_edges (*ei, lg); ofi != of_end; ++ofi) 
00167         fv.push_back (*ofi);
00168     }
00169   int costs= 0;
00170   for (size_t c= 0; c < fv.size(); c++)
00171     costs+= face_elimination (fv[c], lg);
00172   return costs;
00173 }  
00174 
00175 // -------------------------------------------------------------------------
00176 // elimination of a single egde in line graph
00177 // -------------------------------------------------------------------------
00178 
00179 int front_edge_elimination (int i, int j, line_graph_t& lg) {
00180   vector<line_graph_t::edge_t>    ev;
00181   find_edge (i, j, lg, ev);
00182   int costs= 0;
00183   for (size_t c= 0; c < ev.size(); c++)
00184     costs+= front_edge_elimination (ev[c], lg);
00185 
00186   return costs;
00187 }
00188 
00189 int front_edge_elimination (line_graph_t::edge_t vij, line_graph_t& lg) { 
00190   std::vector<line_graph_t::face_t> fv;
00191   line_graph_t::ofi_t oi, oend;
00192   for (boost::tie (oi, oend)= out_edges (vij, lg); oi != oend; ++oi)
00193     fv.push_back (*oi);
00194 
00195   int costs= 0;
00196   for (size_t n= 0; n < fv.size(); n++)
00197     costs+= face_elimination (fv[n], lg);
00198 
00199   return costs;
00200 }
00201 
00202 
00203 int back_edge_elimination (int i, int j, line_graph_t& lg) {
00204   vector<line_graph_t::edge_t>    ev;
00205   find_edge (i, j, lg, ev);
00206   int costs= 0;
00207   for (size_t c= 0; c < ev.size(); c++)
00208     costs+= back_edge_elimination (ev[c], lg);
00209   return costs;
00210 }
00211 
00212 int back_edge_elimination (line_graph_t::edge_t vij,
00213                            line_graph_t& lg) {
00214   std::vector<line_graph_t::face_t> fv;
00215   line_graph_t::ifi_t ii, iend;
00216   for (boost::tie (ii, iend)= in_edges (vij, lg); ii != iend; ++ii)
00217     fv.push_back (*ii);
00218 
00219   int costs= 0;
00220   for (size_t n= 0; n < fv.size(); n++)
00221     costs+= face_elimination (fv[n], lg);
00222 
00223   return costs;
00224 }
00225 
00226 // -------------------------------------------------------------------------
00227 // elimination of a single face in line graph
00228 // -------------------------------------------------------------------------
00229 
00230 int face_elimination (line_graph_t::face_t f, int kr, line_graph_t& lg, accu_graph_t& ac) {
00231 
00232   typedef line_graph_t::edge_t edge_t;
00233   edge_t                       i= source (f, lg), j= target (f, lg);
00234   vector<edge_t>               pi, sj, same_p, same_s, same;
00235 
00236   if ((int) i >= lg.v() || (int) j >= lg.v()) {
00237     return -1;}
00238 
00239   same_predecessors (i, lg, same_p); // same pred. as i
00240   same_successors (j, lg, same_s);
00241   same.resize (max (same_p.size(), same_s.size()));
00242   vector<edge_t>::iterator se= set_intersection (same_p.begin(), same_p.end(), same_s.begin(),
00243                                                  same_s.end(), same.begin());
00244   THROW_DEBUG_EXCEPT_MACRO (se-same.begin() >= 2, consistency_exception,
00245                          "More than one mergeable vertex in face elimination"); 
00246 
00247   if (kr != -1) {
00248     if (se != same.begin()) { // if matching vertex found, it must be kr (k requested)
00249       if (same[0] != edge_t (kr)) return -1;
00250     } else {
00251       if (kr < lg.v()) {
00252         edge_t e= vertex (kr, lg);
00253         if (out_degree (e, lg) > 0 || in_degree (e, lg) > 0) {
00254           return -1; } }
00255       // insert enough empty vertices
00256       for (; kr > lg.v();) {add_vertex (lg); ac.exp_nr.push_back (-1); }
00257     } }
00258 
00259   line_graph_t::ed_t   el= get(vertex_degree, lg);  // edge label
00260   int d= el[i] * el[j];
00261 
00262   THROW_DEBUG_EXCEPT_MACRO ((int) ac.exp_nr.size() != lg.v(), consistency_exception,
00263                          "Array exp_nr has wrong size"); 
00264   edge_t k;
00265   if (se != same.begin()) { // absorption
00266     k= same[0]; el[k]+= d; 
00267     ac.accu_exp.resize (ac.accu_exp.size() + 1);
00268     ac.accu_exp[ac.accu_exp.size()-1].set_graph (k, i, j, ac.exp_nr);
00269     ac.exp_nr[k]= ac.accu_exp.size()-1;
00270   } else {                  // new or empty edge
00271     if (kr == -1 || kr == lg.v()) {
00272       k= add_vertex (lg); ac.exp_nr.push_back(-1); }
00273     else k= vertex (kr, lg);             // this is an empty edge
00274 
00275     ac.accu_exp.resize (ac.accu_exp.size() + 1);
00276     ac.accu_exp[ac.accu_exp.size()-1].set_graph(accu_exp_t::mult, i, j, ac.exp_nr);
00277     ac.exp_nr[k]= ac.accu_exp.size()-1;
00278     line_graph_t::evn_t evn= get(vertex_name, lg);
00279     // assert (evn[i].second == evn[j].first); // adjacent edges ?
00280     THROW_DEBUG_EXCEPT_MACRO (evn[i].second != evn[j].first, consistency_exception,
00281                            "Adjacency corrupted in line graph"); 
00282     evn[k]= make_pair (evn[i].first, evn[j].second);
00283 
00284     sorted_predecessor_set (i, lg, pi); sorted_successor_set (j, lg, sj);
00285     for (size_t c= 0; c < pi.size(); c++)
00286       add_edge (pi[c], k, lg);
00287     for (size_t c= 0; c < sj.size(); c++)
00288       add_edge (k, sj[c], lg);
00289     el[k]= d;
00290     lg.cons_ok= false;
00291   }
00292   THROW_DEBUG_EXCEPT_MACRO (kr != -1 && edge_t (kr) != k, consistency_exception,
00293                          "Inserted Vertex has wrong number"); 
00294 
00295   remove_edge (f, lg);
00296 
00297   if (remove_irrelevant_edges (i, lg, true) > 0) // i is isolated
00298     lg.cons_ok= false;
00299   else {
00300     THROW_DEBUG_EXCEPT_MACRO (in_degree (i, lg) == 0 || out_degree (i, lg) == 0, consistency_exception,
00301                            "Undetected isolated vertex"); 
00302     vector<edge_t> same;
00303     same_neighbors (i, lg, same);
00304     THROW_DEBUG_EXCEPT_MACRO (same.size() >= 2, consistency_exception,
00305                            "More than one mergeable vertex in face elimination"); 
00306     if (same.size() > 0) { // mergeable vertex (edge in c-graph)
00307       edge_t i2= same[0];
00308       el[i]+= el[i2];
00309       clear_vertex (i2, lg); 
00310       ac.accu_exp.resize (ac.accu_exp.size() + 1);
00311       ac.accu_exp[ac.accu_exp.size()-1].set_graph (accu_exp_t::add, i, i2, ac.exp_nr);
00312       ac.exp_nr[i]= ac.accu_exp.size()-1;
00313       lg.cons_ok= false;}
00314   }
00315     
00316   if (remove_unreachable_edges (j, lg, true) > 0)  // j is isolated
00317     lg.cons_ok= false;
00318   else {
00319     THROW_DEBUG_EXCEPT_MACRO (in_degree (j, lg) == 0 || out_degree (j, lg) == 0, consistency_exception,
00320                            "Undetected isolated vertex"); 
00321     vector<edge_t> same;
00322     same_neighbors (j, lg, same);
00323     THROW_DEBUG_EXCEPT_MACRO (same.size() >= 2, consistency_exception,
00324                            "More than one mergeable vertex in face elimination"); 
00325     if (same.size() > 0) { // mergeable vertex (edge)
00326       edge_t j2= same[0];
00327       el[j]+= el[j2];
00328       clear_vertex (j2, lg); 
00329       ac.accu_exp.resize (ac.accu_exp.size() + 1);
00330       ac.accu_exp[ac.accu_exp.size()-1].set_graph (accu_exp_t::add, j, j2, ac.exp_nr);
00331       ac.exp_nr[j]= ac.accu_exp.size()-1;
00332       lg.cons_ok= false; }
00333   }
00334  
00335   return k;
00336 }
00337 
00338 // =========================================================================
00339 // which vertices, edges or faces can be eliminated
00340 // =========================================================================
00341 
00342 int eliminatable_vertices (const c_graph_t& cg, vector<c_graph_t::vertex_t>& vv) {
00343   vv.resize (0);
00344   c_graph_t::vi_t vi, v_end;
00345   for (tie(vi, v_end)= vertices(cg); vi != v_end; ++vi)
00346     if (cg.vertex_type (*vi) == intermediate) // only intermediate vertices can be eliminated
00347       vv.push_back (*vi);
00348   return vv.size();
00349 }
00350 
00351 int semi_eliminatable_vertices (const c_graph_t& cg, vector<c_graph_t::vertex_t>& vv) {
00352   vv.resize (0);
00353   c_graph_t::vi_t vi, v_end;
00354   for (tie(vi, v_end)= vertices(cg); vi != v_end; ++vi)
00355     // either intermediate or dependent with outgoing edges
00356     if (cg.vertex_type (*vi) == intermediate 
00357         || 
00358         (cg.vertex_type (*vi) == dependent && out_degree (*vi, cg) > 0))
00359       vv.push_back (*vi);
00360   return vv.size();
00361 }
00362 
00363 int eliminatable_edges (const c_graph_t& cg, 
00364                         std::vector<c_graph_t::edge_t>& ev) {
00365   // in fact it only copies the edges into a vector for better treatment
00366   ev.resize(0);
00367   c_graph_t::ei_t      ei, e_end;
00368   for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei)
00369     ev.push_back (*ei);
00370   return ev.size();
00371 }
00372 
00373 int front_eliminatable_edges (const c_graph_t& cg, 
00374                               std::vector<c_graph_t::edge_t>& ev) {
00375   // in fact it only copies the edges into a vector for better treatment
00376   ev.resize(0);
00377   c_graph_t::ei_t      ei, e_end;
00378   for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei)
00379     if (vertex_type (target (*ei, cg), cg) != dependent)
00380       ev.push_back (*ei);
00381   return ev.size();
00382 }
00383 
00384 int back_eliminatable_edges (const c_graph_t& cg, 
00385                              std::vector<c_graph_t::edge_t>& ev) {
00386   // in fact it only copies the edges into a vector for better treatment
00387   ev.resize(0);
00388   c_graph_t::ei_t      ei, e_end;
00389   for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei)
00390     if (vertex_type (source (*ei, cg), cg) != independent)
00391       ev.push_back (*ei);
00392   return ev.size();
00393 }
00394 
00395 int eliminatable_edges (const c_graph_t& cg,
00396                         std::vector<edge_bool_t>& ev) {
00397   ev.resize(0);
00398   c_graph_t::ei_t      ei, e_end;
00399   for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei) {
00400     // can edge be back-eliminated ?
00401     if (vertex_type (source (*ei, cg), cg) != independent)
00402       ev.push_back (std::pair<c_graph_t::edge_t,bool> (*ei, false)); 
00403     // can edge be front-eliminated ?
00404     if (vertex_type (target (*ei, cg), cg) != dependent)
00405       ev.push_back (std::pair<c_graph_t::edge_t,bool> (*ei, true)); 
00406   }
00407   return ev.size();
00408 }
00409 
00410 int eliminatable_edges (const c_graph_t& cg,
00411                         std::vector<edge_ij_elim_t>& ev) {
00412   ev.resize(0);
00413   c_graph_t::ei_t      ei, e_end;
00414   for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei) {
00415     edge_ij_elim_t ee (source (*ei, cg), target (*ei, cg), false);
00416     // can edge be back-eliminated ?
00417     if (vertex_type (source (*ei, cg), cg) != independent)
00418       ev.push_back (ee); 
00419     // can edge be front-eliminated ?
00420     if (vertex_type (target (*ei, cg), cg) != dependent) {
00421       ee.front= true; ev.push_back (ee); } 
00422   }
00423   return ev.size();
00424 }
00425 
00426 unsigned int eliminatable_edges(const c_graph_t& cg,
00427                                 std::vector<EdgeElim>& ev) {
00428   ev.clear();
00429   c_graph_t::ei_t ei, e_end;
00430   for (tie(ei, e_end) = edges(cg); ei != e_end; ++ei) {
00431     // can edge be back-eliminated ?
00432     if (vertex_type(source(*ei, cg), cg) != independent)
00433       ev.push_back(EdgeElim (*ei, false, cg));
00434     // can edge be front-eliminated ?
00435     if (vertex_type(target(*ei, cg), cg) != dependent)
00436       ev.push_back(EdgeElim (*ei, true, cg));
00437   } // end iterate over all edges
00438   return ev.size();
00439 } // end eliminatable_edges()
00440 
00441 int eliminatable_faces (const line_graph_t& lg, 
00442                         std::vector<line_graph_t::face_t>& fv) {
00443   // in fact it only copies the edges into a vector for better treatment
00444   fv.resize(0);
00445   graph_traits<line_graph_t>::edge_iterator      ei, e_end;
00446   for (tie (ei, e_end)= edges (lg); ei != e_end; ++ei) {
00447     line_graph_t::vertex_descriptor s= source (*ei, lg), t= target (*ei, lg);
00448     if (vertex_type (s, lg) != independent && vertex_type (t, lg) != dependent)
00449       fv.push_back (*ei);
00450   }
00451   return fv.size();
00452 }
00453 
00454 bool convert_elimination_sequence (const vector<c_graph_t::vertex_t>& vv, 
00455                                    const c_graph_t& cg,
00456                                    vector<edge_ij_elim_t>& ev) {
00457   c_graph_t cgc (cg);
00458   ev.resize (0);
00459   for (size_t c= 0; c < vv.size(); c++) {
00460     c_graph_t::iei_t  iei, ie_end;
00461     // cout << "conv_elim_seq: eliminate vertex " << vv[c];
00462     // write_graph ("from graph", cgc);
00463     for (tie (iei, ie_end)= in_edges (vv[c], cgc); iei != ie_end; ++iei) {
00464       edge_ij_elim_t ee (source (*iei, cgc), target (*iei, cgc), true);
00465       // cout << "new edge " << ee;
00466       ev.push_back (ee); }
00467     // cout << endl;
00468     vertex_elimination (vv[c], cgc); }
00469   return true;
00470 }
00471 
00472 bool convert_elimination_sequence (const vector<edge_ij_elim_t>& ev, 
00473                                    const line_graph_t& lg,
00474                                    vector<triplet_t>& tv) {
00475   line_graph_t lgc (lg);
00476   tv.resize (0);
00477   for (size_t c= 0; c < ev.size(); c++) {
00478     edge_ij_elim_t ee = ev[c];
00479     vector<line_graph_t::edge_t> lev;
00480     // cout << "conv_elim_seq: eliminate edge " << ee;
00481     // write_graph ("from graph", lgc);
00482     // line_graph_t::evn_t            evn= get(vertex_name, lgc);
00483     // write_vertex_property (cout, "vertices of this edge graph", evn, lgc);
00484     // std::cout << "dealing with edge elim: " << ee.i << " to " << ee.j << std::endl; 
00485     line_graph_t::edge_t ledge;
00486 
00487 #ifndef NDEBUG
00488     cout << endl;
00489     cout << "convert_elimination_sequence: eliminate edge " << ee;
00490     write_graph ("from line graph: ", lgc);
00491     line_graph_t::evn_t evn = get(vertex_name, lgc);
00492     write_vertex_property (cout, "Labels of vertices in this line graph: ", evn, lgc);
00493 #endif
00494 
00495     bool found = find_edge (ee.i, ee.j, lgc, lev);
00496     THROW_EXCEPT_MACRO (!found || lev.empty(), consistency_exception, "LCG edge has no corresponding line graph node");
00497 
00498     if (lev.size() == 1) { ledge = lev[0]; }
00499     else { // if lev.size() != 1
00500       cout << lev.size() << " line graph nodes correspond to LCG edge (" << ee.i << ", " << ee.j << ")."
00501                          << "  Determining the correct one...";
00502       vector<line_graph_t::edge_t> candidates;
00503       // iterate through corresponding line graph vertices to ensure only one of them isn't isolated
00504       for (size_t l = 0; l < lev.size(); l++) {
00505         if (in_degree(lev[l], lgc) > 0 || out_degree(lev[l], lgc) > 0) candidates.push_back(lev[l]);
00506       }
00507       THROW_EXCEPT_MACRO (candidates.empty(), consistency_exception, "all corresponding line graph nodes are isolated");
00508       THROW_EXCEPT_MACRO (candidates.size() > 1, consistency_exception, "multiple non-isolated corresponding line graph nodes");
00509 
00510       cout << " Unique correlation found!\n";
00511       ledge = candidates[0];
00512     } // end lev.size() != 1
00513 
00514     if (ee.front) {
00515       line_graph_t::ofi_t oi, oend;
00516       for (boost::tie (oi, oend) = out_edges (ledge, lgc); oi != oend; ++oi) {
00517         triplet_t t (ledge, target (*oi, lgc), -1); tv.push_back (t);
00518 #ifndef NDEBUG
00519         cout << "new face " << t << endl;
00520 #endif
00521       }
00522       front_edge_elimination (ee.i, ee.j, lgc);
00523     } else {
00524       line_graph_t::ifi_t ii, iend;
00525       for (boost::tie (ii, iend) = in_edges (ledge, lgc); ii != iend; ++ii) {
00526         triplet_t t (source (*ii, lgc), ledge, -1); tv.push_back (t);
00527 #ifndef NDEBUG
00528         cout << "new face " << t << endl;
00529 #endif
00530       }
00531       back_edge_elimination (ee.i, ee.j, lgc); }
00532   } // end all edge eliminations
00533   return true;
00534 } // end convert_elimination_sequence()
00535 
00536 #ifdef USEXAIFBOOSTER
00537 //############################################################################################################
00538 // DIRECT ELIMINATIONS
00539 
00540 EdgeRefType_E getRefType (const c_graph_t::edge_t e, const c_graph_t& angelLCG, const list<EdgeRef_t>& edge_ref_list) {
00541   c_graph_t::const_eind_t eind = get(edge_index, angelLCG);
00542   for (list<EdgeRef_t>::const_iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00543     if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00544         target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00545       THROW_EXCEPT_MACRO (ref_it->my_type == UNDEFINED, consistency_exception, "requested edge reference type is UNDEFINED");
00546       return ref_it->my_type;
00547     }
00548   THROW_EXCEPT_MACRO (true, consistency_exception, "can't return reference type - no reference entry could be found for edge");
00549 } // end getRef_type ()
00550 
00551 const xaifBoosterCrossCountryInterface::LinearizedComputationalGraphEdge* getLCG_p (const c_graph_t::edge_t e,
00552                                                   const c_graph_t& angelLCG,
00553                                                   const list<EdgeRef_t>& edge_ref_list) {
00554   c_graph_t::const_eind_t eind = get(edge_index, angelLCG);
00555   for (list<EdgeRef_t>::const_iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00556     if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00557         target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00558       THROW_EXCEPT_MACRO (ref_it->my_LCG_edge_p == NULL, consistency_exception, "requested LCG edge pointer is NULL");
00559       return ref_it->my_LCG_edge_p;
00560     }
00561   THROW_EXCEPT_MACRO (true, consistency_exception, "can't return LCG_p - no reference entry could be found for edge");
00562 } // end getLCG_p ()
00563 
00564 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex* getJAE_p (const c_graph_t::edge_t e,
00565                                                                                   const c_graph_t& angelLCG,
00566                                                                                   const list<EdgeRef_t>& edge_ref_list) {
00567   c_graph_t::const_eind_t eind = get(edge_index, angelLCG);
00568   for (list<EdgeRef_t>::const_iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00569     if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00570         target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00571       THROW_EXCEPT_MACRO (ref_it->my_JAE_vertex_p == NULL, consistency_exception, "requested JAE vertex pointer is NULL");
00572       return ref_it->my_JAE_vertex_p;
00573     }
00574   THROW_EXCEPT_MACRO (true, consistency_exception, "can't return JAE_p - no reference entry could be found for edge");
00575 } // end getJAE_p ()
00576 
00577 void setJaevRef (const c_graph_t::edge_t e,
00578                  xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev,
00579                  const c_graph_t& angelLCG,
00580                  const list<EdgeRef_t>& edge_ref_list) {
00581   EdgeRefType_E e_ref_type = getRefType (e, angelLCG, edge_ref_list);
00582   if (e_ref_type == LCG_EDGE) {
00583     const xaifBoosterCrossCountryInterface::LinearizedComputationalGraphEdge* LCG_p = getLCG_p (e, angelLCG, edge_ref_list);
00584     jaev.setExternalReference (*LCG_p);
00585   }
00586   else if (e_ref_type == JAE_VERT) {
00587     xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex* JAE_p = getJAE_p (e, angelLCG, edge_ref_list);
00588     jaev.setInternalReference (*JAE_p);
00589   }
00590   else THROW_EXCEPT_MACRO (true, consistency_exception, "cannot set JAE vertex ref because edge reference type is UNDEFINED");
00591 } // end setJaevRef ()
00592 
00593 void removeRef (const c_graph_t::edge_t e,
00594                 const c_graph_t& angelLCG,
00595                 list<EdgeRef_t>& edge_ref_list) {
00596   for (list<EdgeRef_t>::iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00597     if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00598         target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00599       edge_ref_list.erase(ref_it);
00600       return;
00601     }
00602   THROW_EXCEPT_MACRO (true, consistency_exception, "couldn't find edge reference in order to remove it");
00603 } // end removeRef()
00604 
00605 // Creates a new JAE corresponding to multiplying edges e1 and e2
00606 // where e1 comes before e2
00607 unsigned int multiply_edge_pair_directly (const c_graph_t::edge_t e1,
00608                                           const c_graph_t::edge_t e2,
00609                                           c_graph_t& angelLCG,
00610                                           list<EdgeRef_t>& edge_ref_list,
00611                                           xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list) {
00612 
00613   // Create JAE with vertices for multiply and for the two edges being multiplied
00614   xaifBoosterCrossCountryInterface::JacobianAccumulationExpression& new_jae = jae_list.addExpression();
00615   xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_mult = new_jae.addVertex();
00616   jaev_mult.setOperation (xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex::MULT_OP);
00617   xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_e1 = new_jae.addVertex();
00618   xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_e2 = new_jae.addVertex();
00619   setJaevRef (e1, jaev_e1, angelLCG, edge_ref_list);
00620   setJaevRef (e2, jaev_e2, angelLCG, edge_ref_list);
00621   new_jae.addEdge(jaev_e1, jaev_mult);
00622   new_jae.addEdge(jaev_e2, jaev_mult);
00623 
00624   boost::property_map<c_graph_t, EdgeType>::type eType = get (EdgeType(), angelLCG);
00625 
00626   //test for absorption
00627   c_graph_t::edge_t fill_or_absorb_e;
00628   bool found_absorb_e;
00629   tie (fill_or_absorb_e, found_absorb_e) = edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG);
00630   if (found_absorb_e) { // absorption
00631     //create add vertex and absorb vertex, connect them up
00632     xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_add = new_jae.addVertex();
00633     jaev_add.setOperation (xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex::ADD_OP);
00634     xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_absorb_e = new_jae.addVertex();
00635     setJaevRef (fill_or_absorb_e, jaev_absorb_e, angelLCG, edge_ref_list);
00636     new_jae.addEdge(jaev_absorb_e, jaev_add);
00637     new_jae.addEdge(jaev_mult, jaev_add);
00638 
00639     // reset reference for the absorb edge
00640     removeRef (fill_or_absorb_e, angelLCG, edge_ref_list);
00641     EdgeRef_t absorb_e_ref (fill_or_absorb_e, &jaev_add);
00642     edge_ref_list.push_back(absorb_e_ref);
00643 
00644     // set edge type for absorption edge
00645     if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE)       eType[fill_or_absorb_e] = VARIABLE_EDGE;
00646     else if (eType[fill_or_absorb_e] != VARIABLE_EDGE)                  eType[fill_or_absorb_e] = CONSTANT_EDGE;
00647   }
00648   else { // fill-in
00649     tie (fill_or_absorb_e, found_absorb_e) = add_edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG.next_edge_number++, angelLCG);
00650     EdgeRef_t fill_e_ref (fill_or_absorb_e, &jaev_mult);
00651     edge_ref_list.push_back(fill_e_ref); //point the fill-in edge at the top of the new JAE
00652 
00653     // set edge type for new fill-in edge
00654     if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE)       eType[fill_or_absorb_e] = VARIABLE_EDGE;
00655     else if (eType[e1] == UNIT_EDGE && eType[e2] == UNIT_EDGE)          eType[fill_or_absorb_e] = UNIT_EDGE;
00656     else                                                                eType[fill_or_absorb_e] = CONSTANT_EDGE;
00657   }
00658   
00659   if (eType[e1] == UNIT_EDGE || eType[e2] == UNIT_EDGE)
00660     return 0;
00661   else
00662     return 1;
00663 } // end multiply_edge_pair_directly
00664 
00665 unsigned int front_eliminate_edge_directly (c_graph_t::edge_t e,
00666                                             c_graph_t& angelLCG,
00667                                             list<EdgeRef_t>& edge_ref_list,
00668                                             xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list) {
00669 #ifndef NDEBUG
00670   cout << "front eliminating edge " << e << endl;
00671 #endif
00672 
00673   unsigned int cost = 0;
00674   c_graph_t::vertex_t tgt = target (e, angelLCG);
00675   vector<c_graph_t::edge_t> tgtOutEdges;
00676   c_graph_t::oei_t oei, oe_end;
00677 
00678   // save out-edges of tgt in a vector, as pointers become invalidated
00679   for (tie (oei, oe_end) = out_edges (tgt, angelLCG); oei != oe_end; ++oei)
00680     tgtOutEdges.push_back(*oei);
00681 
00682   // multiply all edge pairs
00683   for (size_t i = 0; i < tgtOutEdges.size(); i++)
00684     cost += multiply_edge_pair_directly (e, tgtOutEdges[i], angelLCG, edge_ref_list, jae_list);
00685 
00686   // remove tgt of e and incident edges if it becomes isolated
00687   if (in_degree (tgt, angelLCG) == 1)
00688     for (size_t i = 0; i < tgtOutEdges.size(); i++) {
00689       removeRef (tgtOutEdges[i], angelLCG, edge_ref_list);
00690       remove_edge (tgtOutEdges[i], angelLCG);
00691     }
00692 
00693   removeRef (e, angelLCG, edge_ref_list);
00694   remove_edge (e, angelLCG);
00695   return cost;
00696 } // end front_eliminate_edge_directly()
00697 
00698 unsigned int back_eliminate_edge_directly (c_graph_t::edge_t e,
00699                                            c_graph_t& angelLCG,
00700                                            list<EdgeRef_t>& edge_ref_list,
00701                                            xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list) {
00702 #ifndef NDEBUG
00703   cout << "back eliminating edge " << e << endl;
00704 #endif
00705 
00706   unsigned int cost = 0;
00707   c_graph_t::vertex_t src = source (e, angelLCG);
00708   vector<c_graph_t::edge_t> srcInEdges;
00709   c_graph_t::iei_t iei, ie_end;  
00710 
00711   // save in-edges of src in a vector, as pointers become invalidated
00712   for (tie (iei, ie_end) = in_edges (src, angelLCG); iei != ie_end; ++iei)
00713       srcInEdges.push_back(*iei);
00714 
00715   // multiply all edge pairs
00716   for (size_t i = 0; i < srcInEdges.size(); i++)
00717     cost += multiply_edge_pair_directly (srcInEdges[i], e, angelLCG, edge_ref_list, jae_list);
00718 
00719   // remove src of e and incident edges if it becomes isolated and isn't a dependent
00720   if (out_degree (src, angelLCG) == 1 && vertex_type (src, angelLCG) != dependent)
00721     for (size_t i = 0; i < srcInEdges.size(); i++) {
00722       removeRef (srcInEdges[i], angelLCG, edge_ref_list);
00723       remove_edge (srcInEdges[i], angelLCG);
00724     }
00725 
00726   removeRef (e, angelLCG, edge_ref_list);
00727   remove_edge (e, angelLCG);
00728   return cost;
00729 } // end back_eliminate_edge_directly()
00730 
00731 unsigned int pair_elim (c_graph_t::edge_t e1,
00732                         c_graph_t::edge_t e2,
00733                         c_graph_t& angelLCG,
00734                         const elimSeq_cost_t& currentElimSeq,
00735                         refillDependenceMap_t& refillDependences) {
00736   boost::property_map<c_graph_t, EdgeType>::type eType = get (EdgeType(), angelLCG);
00737   c_graph_t::edge_t fill_or_absorb_e;
00738   bool found_absorb_e;
00739 
00740   // determine whether absorption edge is present
00741   tie (fill_or_absorb_e, found_absorb_e) = edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG);
00742   if (found_absorb_e) { // absorption - all we have to do is set the edge type for the absorption edge
00743     if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE)       eType[fill_or_absorb_e] = VARIABLE_EDGE;
00744     else if (eType[fill_or_absorb_e] != VARIABLE_EDGE)                  eType[fill_or_absorb_e] = CONSTANT_EDGE;
00745   }
00746   else { // fill-in
00747     
00748     // check for refill.  If found, add tgt to dependence vertex set for respective edge (from src to succ of tgt)
00749     for (size_t c = 0; c < currentElimSeq.edgeElimVector.size(); c++) {
00750       unsigned int i = currentElimSeq.edgeElimVector[c].getSource();
00751       unsigned int j = currentElimSeq.edgeElimVector[c].getTarget();
00752       if (source (e1, angelLCG) == i && target (e2, angelLCG) == j) {
00753 #ifndef NDEBUG
00754         cout << endl << "refilledge (" << i << "," << j << "), adding this information to the refillDependences map..." << endl << endl;
00755 #endif
00756         // add vertex to the refill dependence set for the refilled edge
00757         refillDependenceMap_t::iterator depMap_i = refillDependences.find(make_pair(i, j));
00758         if (depMap_i == refillDependences.end()) {
00759 #ifndef NDEBUG
00760           cout << "the edge was not found as a map key.  Creating new map key and empty set..." << endl;
00761 #endif
00762           // add the edge to the map if it isnt there
00763           depMap_i = refillDependences.insert( std::make_pair(make_pair(i, j), vertex_set_t()) ).first;
00764           currentElimSeq.revealedNewDependence = true;
00765         }
00766         bool wasntPresent = (depMap_i->second).insert(target (e1, angelLCG)).second; // add the vertex to the depSet for the current edge
00767         if (wasntPresent) currentElimSeq.revealedNewDependence = true;
00768         // refill has already been found for this edge, so break
00769         break;
00770       } // end if fill edge is found to have been previously eliminated (refill)
00771     } // end all previous elims in current sequence
00772 
00773     // create the fill-in edge and set it's edge type
00774     tie (fill_or_absorb_e, found_absorb_e) = add_edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG.next_edge_number++, angelLCG);
00775     if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE)       eType[fill_or_absorb_e] = VARIABLE_EDGE;
00776     else if (eType[e1] == UNIT_EDGE && eType[e2] == UNIT_EDGE)          eType[fill_or_absorb_e] = UNIT_EDGE;
00777     else                                                                eType[fill_or_absorb_e] = CONSTANT_EDGE;
00778   } // end fill-in
00779 
00780   if (eType[e1] == UNIT_EDGE || eType[e2] == UNIT_EDGE)
00781     return 0;
00782   else
00783     return 1;
00784 } // end pair_elim()
00785 
00786 unsigned int front_elim (c_graph_t::edge_t e,
00787                          c_graph_t& angelLCG,
00788                          const elimSeq_cost_t& currentElimSeq,
00789                          refillDependenceMap_t& refillDependences) {
00790 #ifndef NDEBUG
00791   cout << "front eliminating edge " << e << endl;
00792 #endif
00793 
00794   unsigned int cost = 0;
00795   c_graph_t::oei_t oei, oe_end;
00796   vector<c_graph_t::edge_t> tgtOutEdges;
00797 
00798   // save out-edges of tgt in a vector, as pointers become invalidated
00799   for (tie (oei, oe_end) = out_edges (target (e, angelLCG), angelLCG); oei != oe_end; ++oei)
00800     tgtOutEdges.push_back(*oei);
00801 
00802   for (size_t i = 0; i < tgtOutEdges.size(); i++)
00803     cost += pair_elim (e, tgtOutEdges[i], angelLCG, currentElimSeq, refillDependences);
00804  
00805   // if elimination isolates the target, remove vertex and incident edges
00806   if (in_degree (target (e, angelLCG), angelLCG) == 1)
00807     for (size_t i = 0; i < tgtOutEdges.size(); i++)
00808       remove_edge (tgtOutEdges[i], angelLCG);
00809 
00810   remove_edge (e, angelLCG);
00811   return cost;
00812 } // end front_elim() 
00813 
00814 unsigned int back_elim (c_graph_t::edge_t e,
00815                         c_graph_t& angelLCG,
00816                         const elimSeq_cost_t& currentElimSeq,
00817                         refillDependenceMap_t& refillDependences) {
00818 #ifndef NDEBUG
00819   cout << "back eliminating edge " << e << endl;
00820 #endif
00821 
00822   unsigned int cost = 0;
00823   c_graph_t::iei_t iei, ie_end;
00824   vector<c_graph_t::edge_t> srcInEdges;
00825 
00826   // save in-edges of src in a vector, as pointers become invalidated
00827   for (tie (iei, ie_end) = in_edges (source (e, angelLCG), angelLCG); iei != ie_end; ++iei)
00828     srcInEdges.push_back(*iei);
00829 
00830   for (size_t i = 0; i < srcInEdges.size(); i++)
00831     cost += pair_elim (srcInEdges[i], e, angelLCG, currentElimSeq, refillDependences);
00832 
00833   // remove src of e and incident edges if it becomes isolated and isn't a dependent
00834   if (out_degree (source (e, angelLCG), angelLCG) == 1 && vertex_type (source (e, angelLCG), angelLCG) != dependent)
00835     for (size_t i = 0; i < srcInEdges.size(); i++)
00836       remove_edge (srcInEdges[i], angelLCG);
00837 
00838   remove_edge (e, angelLCG);
00839   return cost;
00840 } // end back_elim()
00841 
00842 unsigned int pairElim_noJAE (c_graph_t::edge_t e1,
00843                              c_graph_t::edge_t e2,
00844                              c_graph_t& angelLCG,
00845                              const transformationSeq_cost_t* currentTransformationSequence,
00846                              refillDependenceMap_t& refillDependences) {
00847   boost::property_map<c_graph_t, EdgeType>::type eType = get (EdgeType(), angelLCG);
00848   c_graph_t::edge_t fill_or_absorb_e;
00849   bool found_absorb_e;
00850 
00851   // check for refill.  If found, add tgt to dependence vertex set for respective edge (from src to succ of tgt)
00852   for (size_t c = 0; c < currentTransformationSequence->transformationVector.size(); c++) {
00853     if (currentTransformationSequence->transformationVector[c].isRerouting())
00854       continue; // ignore reroutings
00855 
00856     unsigned int i = currentTransformationSequence->transformationVector[c].getEdgeElim().getSource();
00857     unsigned int j = currentTransformationSequence->transformationVector[c].getEdgeElim().getTarget();
00858 
00859     // the fill/absorb edge was previously eliminated
00860     if (source (e1, angelLCG) == i && target (e2, angelLCG) == j) {
00861 #ifndef NDEBUG
00862       cout << endl << "refilledge (" << i << "," << j << "), adding this information to the refillDependences map..." << endl << endl;
00863 #endif
00864       // add vertex to the refill dependence set for the refilled edge
00865       refillDependenceMap_t::iterator depMap_i = refillDependences.find(make_pair(i, j));
00866       if (depMap_i == refillDependences.end()) { // map doesn't contain a key for the refilled edge
00867 #ifndef NDEBUG
00868         cout << "the edge was not found as a map key.  Creating new map key with empty vertex set..." << endl;
00869 #endif
00870         // add the edge to the map if it isnt there
00871         depMap_i = refillDependences.insert( std::make_pair(make_pair(i, j), vertex_set_t()) ).first;
00872         currentTransformationSequence->revealedNewDependence = true; // edge newly added as map key
00873       }
00874 
00875       // add the vertex to the depSet for the current edge
00876       if ((depMap_i->second).insert(target (e1, angelLCG)).second)
00877         currentTransformationSequence->revealedNewDependence = true; // vertex newly added to dependence set for edge
00878 
00879       break; // refill has already been found for this edge, so break
00880     } // end if fill/absorb edge is found to have been previously eliminated (refill)
00881   } // end all previous elims in current sequence
00882 
00883   // determine whether absorption edge is present
00884   tie (fill_or_absorb_e, found_absorb_e) = edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG);
00885   if (found_absorb_e) { // absorption: all we have to do is set the edge type for the absorption edge
00886     if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE)       eType[fill_or_absorb_e] = VARIABLE_EDGE;
00887     else if (eType[fill_or_absorb_e] != VARIABLE_EDGE)                  eType[fill_or_absorb_e] = CONSTANT_EDGE;
00888   } // end absorption
00889   else { // fill-in: create new edge and set it's edge type
00890     tie (fill_or_absorb_e, found_absorb_e) = add_edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG.next_edge_number++, angelLCG);
00891     if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE)       eType[fill_or_absorb_e] = VARIABLE_EDGE;
00892     else if (eType[e1] == UNIT_EDGE && eType[e2] == UNIT_EDGE)          eType[fill_or_absorb_e] = UNIT_EDGE;
00893     else                                                                eType[fill_or_absorb_e] = CONSTANT_EDGE;
00894   } // end fill-in
00895 
00896   if (eType[e1] == UNIT_EDGE || eType[e2] == UNIT_EDGE)
00897     return 0;
00898   else return 1;
00899 } // end pairElim_noJAE()
00900 
00901 unsigned int frontEdgeElimination_noJAE (c_graph_t::edge_t e,
00902                                          c_graph_t& angelLCG,
00903                                          const transformationSeq_cost_t* currentTransformationSequence,
00904                                          refillDependenceMap_t& refillDependences) {
00905 #ifndef NDEBUG
00906   cout << "front eliminating edge " << e << "\t(without creating any JAEs)" << endl;
00907 #endif
00908 
00909   unsigned int cost = 0;
00910   c_graph_t::oei_t oei, oe_end;
00911   vector<c_graph_t::edge_t> tgtOutEdges;
00912 
00913   // save out-edges of tgt in a vector, as pointers become invalidated
00914   for (tie (oei, oe_end) = out_edges (target (e, angelLCG), angelLCG); oei != oe_end; ++oei)
00915     tgtOutEdges.push_back(*oei);
00916 
00917   for (size_t i = 0; i < tgtOutEdges.size(); i++)
00918     cost += pairElim_noJAE (e, tgtOutEdges[i], angelLCG, currentTransformationSequence, refillDependences);
00919  
00920   // if elimination isolates the target, remove vertex and incident edges
00921   if (in_degree (target (e, angelLCG), angelLCG) == 1)
00922     for (size_t i = 0; i < tgtOutEdges.size(); i++)
00923       remove_edge (tgtOutEdges[i], angelLCG);
00924 
00925   remove_edge (e, angelLCG);
00926   return cost;
00927 } // end frontEdgeElimination_noJAE()
00928 
00929 unsigned int backEdgeElimination_noJAE (c_graph_t::edge_t e,
00930                                          c_graph_t& angelLCG,
00931                                          const transformationSeq_cost_t* currentTransformationSequence,
00932                                          refillDependenceMap_t& refillDependences) {
00933 #ifndef NDEBUG
00934   cout << "back eliminating edge " << e << "\t(without creating any JAEs)" << endl;
00935 #endif
00936 
00937   unsigned int cost = 0;
00938   c_graph_t::iei_t iei, ie_end;
00939   vector<c_graph_t::edge_t> srcInEdges;
00940 
00941   // save in-edges of src in a vector, as pointers become invalidated
00942   for (tie (iei, ie_end) = in_edges (source (e, angelLCG), angelLCG); iei != ie_end; ++iei)
00943     srcInEdges.push_back(*iei);
00944 
00945   for (size_t i = 0; i < srcInEdges.size(); i++)
00946     cost += pairElim_noJAE (srcInEdges[i], e, angelLCG, currentTransformationSequence, refillDependences);
00947 
00948   // remove src of e and incident edges if it becomes isolated and isn't a dependent
00949   if (out_degree (source (e, angelLCG), angelLCG) == 1 && vertex_type (source (e, angelLCG), angelLCG) != dependent)
00950     for (size_t i = 0; i < srcInEdges.size(); i++)
00951       remove_edge (srcInEdges[i], angelLCG);
00952 
00953   remove_edge (e, angelLCG);
00954   return cost;
00955 } // end backEdgeElimination_noJAE()
00956 
00957 #endif // USEXAIFBOOSTER
00958 
00959 } // namespace angel
00960 

Generated on Wed Mar 11 10:33:11 2009 for angel by  doxygen 1.5.3