reroutings.cpp

Go to the documentation of this file.
00001 #ifdef USEXAIFBOOSTER
00002 
00003 #include "angel/include/angel_tools.hpp"
00004 #include "angel/include/eliminations.hpp"
00005 #include "angel/include/reroutings.hpp"
00006 
00007 using namespace std;
00008 using namespace boost;
00009 using namespace xaifBoosterCrossCountryInterface;
00010 
00011 namespace angel {
00012 
00013 void reroutable_edges (c_graph_t& angelLCG,
00014                        vector<edge_reroute_t>& erv) {
00015   erv.clear();
00016   set<c_graph_t::vertex_t> downset, upset;
00017   c_graph_t::edge_t decrement_e;
00018   bool found_decrement_e;
00019   c_graph_t::ei_t ei, e_end;
00020   c_graph_t::iei_t iei, ie_end;
00021   c_graph_t::oei_t oei, oe_end;
00022   property_map<pure_c_graph_t, VertexVisited>::type visited = get(VertexVisited(), angelLCG);
00023   c_graph_t::vi_t cleari, clear_end;
00024 
00025   // iterate over all edges; consider each to be pre-routed and post-routed
00026   for (tie (ei, e_end) = edges (angelLCG); ei != e_end; ++ei) {
00027     c_graph_t::edge_t e = *ei;
00028 
00029     // check for preroutability
00030     if (in_degree (target (e, angelLCG), angelLCG) > 1) {
00031       // iterate over possible pivots (inedges of tgt(e))
00032       for (tie (iei, ie_end) = in_edges (target (*ei, angelLCG), angelLCG); iei != ie_end; ++iei) {
00033         c_graph_t::edge_t pivot_e = *iei;
00034         // skip the edge we're considering for rerouting
00035         if (source (pivot_e, angelLCG) == source (e, angelLCG)) continue;
00036         // the source of the pivot edge can't be an independent (we add an edge into it)
00037         if (in_degree (source (pivot_e, angelLCG), angelLCG) == 0) continue;
00038         // ensure that no decrement fill-in is created
00039         for (tie(oei, oe_end) = out_edges(source(pivot_e, angelLCG), angelLCG); oei != oe_end; ++oei) {
00040           if (*oei == pivot_e) continue; // skip the pivot edge
00041           tie(decrement_e, found_decrement_e) = edge(source(e, angelLCG), target(*oei, angelLCG), angelLCG);
00042           if (!found_decrement_e) break; // decrement fill-in has been found (not allowed)
00043         }
00044         if (oei != oe_end) continue; // this will be true iff some decrement fill is detected
00045 
00046         // ensure that we cant reach src(e) from src(pivot_e) (would create cycle)
00047         // first clear visited list
00048         for (tie(cleari, clear_end) = vertices(angelLCG); cleari != clear_end; ++cleari) visited[*cleari] = false;
00049         if (reachable (source(pivot_e, angelLCG), source(e, angelLCG), angelLCG)) continue;
00050         erv.push_back (edge_reroute_t (e, pivot_e, true));
00051 
00052       } // end all pivot candidates
00053     } // end check for pre-routability
00054 
00055     // check for postroutability
00056     if (out_degree (source (e, angelLCG), angelLCG) > 1) {
00057       // iterate over possible pivots (outedges of src(e))
00058       for (tie (oei, oe_end) = out_edges (source (e, angelLCG), angelLCG); oei != oe_end; ++oei) {
00059         c_graph_t::edge_t pivot_e = *oei;
00060         // skip the edge we're considering for rerouting
00061         if (target (pivot_e, angelLCG) == target (e, angelLCG)) continue;
00062         // tgt(pivot_e) can't be a dependent vertex (we add an edge out of it)
00063         if (out_degree (target (pivot_e, angelLCG), angelLCG) == 0) continue;
00064         // ensure that no decrement fill-in is created
00065         for (tie(iei, ie_end) = in_edges(target(pivot_e, angelLCG), angelLCG); iei != ie_end; ++iei) {
00066           if (*iei == pivot_e) continue; // skip the pivot edge
00067           tie(decrement_e, found_decrement_e) = edge(source(*iei, angelLCG), target(e, angelLCG), angelLCG);
00068           if (!found_decrement_e) break; // decrement fill-in has been found (not allowed)
00069         }
00070         if (iei != ie_end) continue; // this will be true iff some decrement fill is detected
00071 
00072         // ensure that we cant reach tgt(pivot_e) from tgt(e) (would create cycle)
00073         // first clear visited list
00074         for (tie(cleari, clear_end) = vertices(angelLCG); cleari != clear_end; ++cleari) visited[*cleari] = false;
00075         if (reachable (target(e, angelLCG), target(pivot_e, angelLCG), angelLCG)) continue;
00076         erv.push_back (edge_reroute_t (e, pivot_e, false));
00077 
00078       } // end all pivot candidates
00079     } // end check for postroutability
00080     
00081   } // end all edges in angelLCG
00082 
00083 #ifndef NDEBUG
00084   cout << "     There are " << erv.size() << " reroutings in G" << endl;
00085 #endif
00086   
00087 } // end reroutable_edges()
00088 
00089 unsigned int reroutable_edges(c_graph_t& angelLCG,
00090                               vector<Rerouting>& allReroutingsV) {
00091   allReroutingsV.clear();
00092   vector <edge_reroute_t> tempRerouteTV;
00093   reroutable_edges(angelLCG, tempRerouteTV);
00094   if (tempRerouteTV.empty())
00095     return 0;
00096 
00097   for (size_t i = 0; i < tempRerouteTV.size(); i++)
00098    allReroutingsV.push_back(Rerouting (tempRerouteTV[i], angelLCG));
00099   return allReroutingsV.size();
00100 } // end reroutable_edges()
00101 
00102 int reroute_effect (const edge_reroute_t er,
00103                     const c_graph_t& angelLCG,
00104                     const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
00105                     bool& incrementIsTrivial) {
00106 
00107   c_graph_t::edge_t e = er.e;
00108   c_graph_t::edge_t pe = er.pivot_e;
00109   c_graph_t::iei_t iei, ie_end;
00110   c_graph_t::oei_t oei, oe_end;
00111   boost::property_map<c_graph_t, EdgeType>::const_type eType = get(EdgeType(), angelLCG);
00112   c_graph_t::edge_t increment_e, decrement_e;
00113   bool found_increment_e, found_decrement_e;
00114 
00115   int nontrivial_edge_change = 0;
00116 
00117   // consider the loss of the rerouted edge
00118   if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS
00119   || (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[e] != UNIT_EDGE)
00120   || (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[e] == VARIABLE_EDGE)) nontrivial_edge_change--;
00121 
00122   if (er.isPre) { // pre-routing
00123     // DECREMENT EDGES: No fill-in, but we allow when a decrement edge goes from trivial to nontrivial
00124     for (tie(oei, oe_end) = out_edges(source(pe, angelLCG), angelLCG); oei != oe_end; ++oei) {
00125       if (*oei == pe) continue; // skip the pivot edge
00126       tie (decrement_e, found_decrement_e) = edge(source(e, angelLCG), target(*oei, angelLCG), angelLCG);
00127       THROW_EXCEPT_MACRO (!found_decrement_e, consistency_exception, "Pre-routing passed to filter causes decrement fill-in");  
00128       // no awareness: no effect
00129       // unit awareness:
00130       if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[decrement_e] == UNIT_EDGE) nontrivial_edge_change++;
00131       // constant awareness:
00132       else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[decrement_e] != VARIABLE_EDGE)
00133         if (eType[e] == VARIABLE_EDGE || eType[pe] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE) nontrivial_edge_change++;
00134     } // end all outedges of src(pivot_e)
00135 
00136     // INCREMENT EDGE: change occurs only when increment edge was nontrivial to begin with
00137     tie(increment_e, found_increment_e) = edge(target(pe, angelLCG), target(e, angelLCG), angelLCG);
00138     if (found_increment_e) { // increment absorption
00139       if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) incrementIsTrivial = false;
00140       else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS) {
00141         incrementIsTrivial = false; // because of absorption (addition) it will be nontrivial no matter what
00142         if (eType[increment_e] == UNIT_EDGE) nontrivial_edge_change++;
00143       } // end unit awareness
00144       else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS) {
00145         // if ANY involved edge is variable, then increment edge is nontrivial
00146         if (eType[increment_e] == VARIABLE_EDGE || eType[e] == VARIABLE_EDGE || eType[pe] == VARIABLE_EDGE) incrementIsTrivial = false;
00147         else incrementIsTrivial = true;
00148         // if the result is nontrivial, but the increment edge WAS trivial to begin with, our nontriv count goes up
00149         if (eType[increment_e] != VARIABLE_EDGE && !incrementIsTrivial) nontrivial_edge_change++;
00150       } // end constant awareness
00151     } // end increment absorption
00152     else { // increment fill-in
00153       if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) {
00154         nontrivial_edge_change++;
00155         incrementIsTrivial = false;
00156       } // end no awareness
00157       else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS) {
00158         if (eType[e] != UNIT_EDGE || eType[pe] != UNIT_EDGE) {
00159           nontrivial_edge_change++;
00160           incrementIsTrivial = false;
00161         }
00162         else incrementIsTrivial = true;
00163       } // end unit awareness
00164       else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS) {
00165         if (eType[e] == VARIABLE_EDGE || eType[pe] == VARIABLE_EDGE) {
00166           nontrivial_edge_change++;
00167           incrementIsTrivial = false;
00168         }
00169         else incrementIsTrivial = true;
00170       } // end constant awareness
00171     } // end increment fill-in
00172 
00173   } // end pre-routing
00174   else { // post-routing
00175 
00176     // DECREMENT EDGES: No fill-in, but we allow when a decrement edge goes from trivial to nontrivial
00177     for (tie(iei, ie_end) = in_edges(target(pe, angelLCG), angelLCG); iei != ie_end; ++iei) {
00178       if (*iei == pe) continue; // skip the pivot edge
00179       tie (decrement_e, found_decrement_e) = edge (source(*iei, angelLCG), target(e, angelLCG), angelLCG);
00180       THROW_EXCEPT_MACRO (!found_decrement_e, consistency_exception, "Post-routing passed to filter causes decrement fill-in"); 
00181       // no awareness: no effect
00182       // unit awareness:
00183       if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[decrement_e] == UNIT_EDGE) nontrivial_edge_change++;
00184       // constant awareness:
00185       else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[decrement_e] != VARIABLE_EDGE)
00186         if (eType[e] == VARIABLE_EDGE || eType[pe] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE) nontrivial_edge_change++;
00187     } // end all outedges of src(pivot_e)
00188 
00189     // INCREMENT EDGE: change occurs only when increment edge was nontrivial to begin with
00190     tie(increment_e, found_increment_e) = edge(target(pe, angelLCG), target(e, angelLCG), angelLCG);
00191     if (found_increment_e) { // increment absorption
00192       if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) incrementIsTrivial = false;
00193       else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS) { // increase iff edge was trivial to begin with
00194         incrementIsTrivial = false; // because of absorption (addition) it will be nontrivial no matter what
00195         if (eType[increment_e] == UNIT_EDGE) nontrivial_edge_change++;
00196       } // end unit awareness
00197       else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS) { // if ANY involved edge is variable, then increment edge is nontrivial
00198         if (eType[increment_e] == VARIABLE_EDGE || eType[e] == VARIABLE_EDGE || eType[pe] == VARIABLE_EDGE) incrementIsTrivial = false;
00199         else incrementIsTrivial = true;
00200         if (eType[increment_e] != VARIABLE_EDGE && !incrementIsTrivial) nontrivial_edge_change++;
00201       } // end constant awareness
00202     } // end increment absorption
00203     else { // increment fill-in
00204       if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS) {
00205         nontrivial_edge_change++;
00206         incrementIsTrivial = false;
00207       } // end no awareness
00208       else if (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS) {
00209         if (eType[e] != UNIT_EDGE || eType[pe] != UNIT_EDGE) {
00210           nontrivial_edge_change++;
00211           incrementIsTrivial = false;
00212         }
00213         else incrementIsTrivial = true;
00214       } // end unit awareness
00215       else if (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS) {
00216         if (eType[e] == VARIABLE_EDGE || eType[pe] == VARIABLE_EDGE) {
00217           nontrivial_edge_change++;
00218           incrementIsTrivial = false;
00219         }
00220         else incrementIsTrivial = true;
00221       } // end constant awareness
00222     } // end increment fill-in
00223 
00224   } // end post-routing
00225 
00226   return nontrivial_edge_change;
00227 } // end reroute_effect()
00228 
00229 // pre-/post-routing an edge cannot isolate a vertex
00230 unsigned int preroute_edge_directly (edge_reroute_t er,
00231                                      c_graph_t& angelLCG,
00232                                      list<EdgeRef_t>& edge_ref_list,
00233                                      JacobianAccumulationExpressionList& jae_list) {
00234   #ifndef NDEBUG
00235     cout << "prerouting edge " << er.e << " about pivot edge " << er.pivot_e << "\t(and creating the corresponding JAEs)" << endl;
00236   #endif
00237 
00238   unsigned int cost = 0;
00239   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), angelLCG);
00240   c_graph_t::iei_t iei, ie_end; 
00241   c_graph_t::oei_t oei, oe_end; 
00242 
00243   JacobianAccumulationExpression& new_jae = jae_list.addExpression();
00244   // Increment the edge from the source of e to to v by the quotient e/pivot_e (create it if it doesnt exist)
00245   JacobianAccumulationExpressionVertex& jaev_divide = new_jae.addVertex();
00246   //jaev_divide.setOperation (JacobianAccumulationExpressionVertex::DIVIDE_OP);
00247   jaev_divide.setOperation (JacobianAccumulationExpressionVertex::ADD_OP);
00248   JacobianAccumulationExpressionVertex& jaev_e = new_jae.addVertex();
00249   JacobianAccumulationExpressionVertex& jaev_pivot_e = new_jae.addVertex();
00250   setJaevRef (er.e, jaev_e, angelLCG, edge_ref_list);
00251   setJaevRef (er.pivot_e, jaev_pivot_e, angelLCG, edge_ref_list);
00252   new_jae.addEdge(jaev_e, jaev_divide);
00253   new_jae.addEdge(jaev_pivot_e, jaev_divide);
00254 
00255   // INCREMENT EDGE
00256   bool found_increment_e;
00257   c_graph_t::edge_t increment_e;
00258   tie (increment_e, found_increment_e) = edge (source (er.e, angelLCG), source (er.pivot_e, angelLCG), angelLCG);
00259   if (found_increment_e) { // increment absorption
00260     JacobianAccumulationExpressionVertex& jaev_increment_e = new_jae.addVertex();
00261     setJaevRef (increment_e, jaev_increment_e, angelLCG, edge_ref_list);
00262     JacobianAccumulationExpressionVertex& jaev_add = new_jae.addVertex();
00263     jaev_add.setOperation (JacobianAccumulationExpressionVertex::ADD_OP);
00264     new_jae.addEdge(jaev_increment_e, jaev_add);
00265     new_jae.addEdge(jaev_divide, jaev_add);
00266 
00267     //point increment_e at the top of the new JAE
00268     removeRef (increment_e, angelLCG, edge_ref_list);
00269     EdgeRef_t new_increment_e_ref (increment_e, &jaev_add);
00270     edge_ref_list.push_back(new_increment_e_ref);
00271 
00272     //set edge type for absorption increment edge
00273     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00274     else if (eType[increment_e] != VARIABLE_EDGE)                               eType[increment_e] = CONSTANT_EDGE;
00275   } // end increment absorption
00276   else { //no increment edge was already present (fill-in)
00277     tie (increment_e, found_increment_e) = add_edge (source (er.e, angelLCG), source (er.pivot_e, angelLCG), angelLCG.next_edge_number++, angelLCG);
00278 
00279     // point the new edge at the divide operation in the new JAE
00280     EdgeRef_t new_increment_e_ref (increment_e, &jaev_divide);
00281     edge_ref_list.push_back(new_increment_e_ref);
00282 
00283     //set edge type for fill-in increment edge
00284     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00285     else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE)        eType[increment_e] = UNIT_EDGE;
00286     else                                                                        eType[increment_e] = CONSTANT_EDGE;
00287   }
00288 
00289   // determine cost of creating increment edge (we divide e/pivot_e, so trivial iff pivot_e is unit)
00290   if (eType[er.pivot_e] != UNIT_EDGE)
00291     cost++;
00292 
00293   // DECREMENT OPERATIONS
00294 
00295   // for all successors of v (except the target of e), perform decrement operations on edges from src_of_e to 
00296   for (tie (oei, oe_end) = out_edges (source (er.pivot_e, angelLCG), angelLCG); oei != oe_end; oei++) {
00297     if (target (*oei, angelLCG) == target (er.e, angelLCG)) continue;
00298     JacobianAccumulationExpression& new_jae = jae_list.addExpression();
00299     JacobianAccumulationExpressionVertex& jaev_divide = new_jae.addVertex();
00300     //jaev_divide.setOperation (JacobianAccumulationExpressionVertex::DIVIDE_OP);
00301     jaev_divide.setOperation (JacobianAccumulationExpressionVertex::MULT_OP);
00302     JacobianAccumulationExpressionVertex& jaev_e = new_jae.addVertex();
00303     JacobianAccumulationExpressionVertex& jaev_pivot_e = new_jae.addVertex();
00304     setJaevRef (er.e, jaev_e, angelLCG, edge_ref_list);
00305     setJaevRef (er.pivot_e, jaev_pivot_e, angelLCG, edge_ref_list);
00306     new_jae.addEdge(jaev_e, jaev_divide);
00307     new_jae.addEdge(jaev_pivot_e, jaev_divide);
00308     // create mult vertex and connect it up
00309     JacobianAccumulationExpressionVertex& jaev_mult = new_jae.addVertex();
00310     jaev_mult.setOperation (JacobianAccumulationExpressionVertex::MULT_OP);
00311     new_jae.addEdge(jaev_divide, jaev_mult);
00312     JacobianAccumulationExpressionVertex& jaev_vout_e = new_jae.addVertex();
00313     setJaevRef (*oei, jaev_vout_e, angelLCG, edge_ref_list);
00314     new_jae.addEdge(jaev_vout_e, jaev_mult);
00315 
00316     bool found_decrement_e;
00317     c_graph_t::edge_t decrement_e;
00318     tie (decrement_e, found_decrement_e) = edge (source (er.e, angelLCG), target (*oei, angelLCG), angelLCG);
00319 
00320     if (found_decrement_e) { // decrement absorption
00321       JacobianAccumulationExpressionVertex& jaev_decrement_e = new_jae.addVertex();
00322       JacobianAccumulationExpressionVertex& jaev_subtract = new_jae.addVertex();
00323       //jaev_subtract.setOperation (JacobianAccumulationExpressionVertex::SUBTRACT_OP);
00324       jaev_subtract.setOperation (JacobianAccumulationExpressionVertex::ADD_OP);
00325       new_jae.addEdge(jaev_mult, jaev_subtract);
00326       new_jae.addEdge(jaev_decrement_e, jaev_subtract);
00327 
00328       // point the decrement edge at the divide operation in the new JAE
00329       removeRef (decrement_e, angelLCG, edge_ref_list);
00330       EdgeRef_t new_decrement_e_ref (decrement_e, &jaev_subtract);
00331       edge_ref_list.push_back(new_decrement_e_ref);
00332 
00333       //set edge type for absorption decrement edge
00334       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE)
00335         eType[decrement_e] = VARIABLE_EDGE;
00336       else if (eType[decrement_e] != VARIABLE_EDGE)
00337         eType[decrement_e] = CONSTANT_EDGE;
00338     } // end decrement absorption
00339     else { // decrement fill-in
00340       tie (decrement_e, found_decrement_e) = add_edge (source (er.e, angelLCG), target (*oei, angelLCG), angelLCG.next_edge_number++, angelLCG);
00341 
00342       // point the new edge at the divide operation in the new JAE
00343       EdgeRef_t new_decrement_e_ref (decrement_e, &jaev_divide);
00344       edge_ref_list.push_back(new_decrement_e_ref);
00345 
00346       //set edge type for fill-in decrement edge
00347       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE)
00348         eType[decrement_e] = VARIABLE_EDGE;
00349       else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE && eType[*oei] == UNIT_EDGE)
00350         eType[decrement_e] = UNIT_EDGE;
00351       else
00352         eType[decrement_e] = CONSTANT_EDGE;
00353     }
00354 
00355     // eval cost for decrements: trivial if both e and pivot_e are unit or if decrement is unit
00356     if (!((eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE) || eType[*oei] == UNIT_EDGE))
00357       cost++;
00358   } // end all decrements
00359 
00360   remove_edge (er.e, angelLCG);
00361 
00362   return cost;
00363 } // end preroute_edge_directly()
00364 
00365 unsigned int postroute_edge_directly (edge_reroute_t er,
00366                                       c_graph_t& angelLCG,
00367                                       list<EdgeRef_t>& edge_ref_list,
00368                                       JacobianAccumulationExpressionList& jae_list) {
00369   #ifndef NDEBUG
00370     cout << "postrouting edge " << er.e << " about pivot edge " << er.pivot_e << "\t(and creating the corresponding JAEs)" << endl;
00371   #endif
00372 
00373   unsigned int cost = 0;
00374   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), angelLCG);
00375   c_graph_t::iei_t iei, ie_end; 
00376   c_graph_t::oei_t oei, oe_end; 
00377 
00378   // Increment the edge from the source of e to to v by the quotient e/pivot_e (create it if it doesnt exist)
00379   JacobianAccumulationExpression& new_jae = jae_list.addExpression();
00380   JacobianAccumulationExpressionVertex& jaev_divide = new_jae.addVertex();
00381   //jaev_divide.setOperation (JacobianAccumulationExpressionVertex::DIVIDE_OP);
00382   jaev_divide.setOperation (JacobianAccumulationExpressionVertex::ADD_OP);
00383   JacobianAccumulationExpressionVertex& jaev_e = new_jae.addVertex();
00384   JacobianAccumulationExpressionVertex& jaev_pivot_e = new_jae.addVertex();
00385   setJaevRef (er.e, jaev_e, angelLCG, edge_ref_list);
00386   setJaevRef (er.pivot_e, jaev_pivot_e, angelLCG, edge_ref_list);
00387   new_jae.addEdge(jaev_e, jaev_divide);
00388   new_jae.addEdge(jaev_pivot_e, jaev_divide);
00389 
00390   // INCREMENT EDGE
00391   bool found_increment_e;
00392   c_graph_t::edge_t increment_e;
00393   tie (increment_e, found_increment_e) = edge (target (er.pivot_e, angelLCG), target (er.e, angelLCG), angelLCG);
00394   if (found_increment_e) { // increment absorption
00395     JacobianAccumulationExpressionVertex& jaev_increment_e = new_jae.addVertex();
00396     setJaevRef (increment_e, jaev_increment_e, angelLCG, edge_ref_list);
00397     JacobianAccumulationExpressionVertex& jaev_add = new_jae.addVertex();
00398     jaev_add.setOperation (JacobianAccumulationExpressionVertex::ADD_OP);
00399     new_jae.addEdge(jaev_increment_e, jaev_add);
00400     new_jae.addEdge(jaev_divide, jaev_add);
00401 
00402     //point increment_e at the top of the new JAE
00403     removeRef (increment_e, angelLCG, edge_ref_list);
00404     EdgeRef_t new_increment_e_ref (increment_e, &jaev_add);
00405     edge_ref_list.push_back(new_increment_e_ref);
00406 
00407     //set edge type for absorption increment edge
00408     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00409     else if (eType[increment_e] != VARIABLE_EDGE)                               eType[increment_e] = CONSTANT_EDGE;
00410   } // end increment absorption
00411   else { //no increment edge was already present (fill-in)
00412     tie (increment_e, found_increment_e) = add_edge (target (er.pivot_e, angelLCG), target (er.e, angelLCG), angelLCG.next_edge_number++, angelLCG);
00413 
00414     // point the new edge at the divide operation in the new JAE
00415     EdgeRef_t new_increment_e_ref (increment_e, &jaev_divide);
00416     edge_ref_list.push_back(new_increment_e_ref);
00417 
00418     //set edge type for fill-in increment edge
00419     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00420     else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE)        eType[increment_e] = UNIT_EDGE;
00421     else                                                                        eType[increment_e] = CONSTANT_EDGE;
00422   }
00423 
00424   // determine cost of creating increment edge (we divide e/pivot_e, so trivial iff pivot_e is unit)
00425   if (eType[er.pivot_e] != UNIT_EDGE)
00426     cost++;
00427 
00428   // DECREMENT OPERATIONS
00429 
00430   // for all predecessors of tgt(pivot_e) (except src(e)), perform decrement operations on edges to tgt(e) 
00431   for (tie (iei, ie_end) = in_edges (target (er.pivot_e, angelLCG), angelLCG); iei != ie_end; iei++) {
00432     if (source (*iei, angelLCG) == source (er.pivot_e, angelLCG)) continue;
00433     JacobianAccumulationExpression& new_jae = jae_list.addExpression(); 
00434     JacobianAccumulationExpressionVertex& jaev_divide = new_jae.addVertex();
00435     //jaev_divide.setOperation (JacobianAccumulationExpressionVertex::DIVIDE_OP);
00436     jaev_divide.setOperation(JacobianAccumulationExpressionVertex::MULT_OP);
00437     JacobianAccumulationExpressionVertex& jaev_e = new_jae.addVertex();
00438     JacobianAccumulationExpressionVertex& jaev_pivot_e = new_jae.addVertex();
00439     setJaevRef (er.e, jaev_e, angelLCG, edge_ref_list);
00440     setJaevRef (er.pivot_e, jaev_pivot_e, angelLCG, edge_ref_list);
00441     new_jae.addEdge(jaev_e, jaev_divide);
00442     new_jae.addEdge(jaev_pivot_e, jaev_divide);
00443     // create mult vertex and connect it up
00444     JacobianAccumulationExpressionVertex& jaev_mult = new_jae.addVertex();
00445     jaev_mult.setOperation (JacobianAccumulationExpressionVertex::MULT_OP);
00446     new_jae.addEdge(jaev_divide, jaev_mult);
00447     JacobianAccumulationExpressionVertex& jaev_vin_e = new_jae.addVertex();
00448     setJaevRef (*iei, jaev_vin_e, angelLCG, edge_ref_list);
00449     new_jae.addEdge(jaev_vin_e, jaev_mult);
00450 
00451     bool found_decrement_e;
00452     c_graph_t::edge_t decrement_e;
00453     tie (decrement_e, found_decrement_e) = edge (source (*iei, angelLCG), target (er.e, angelLCG), angelLCG);
00454     if (found_decrement_e) { // decrement absorption
00455       JacobianAccumulationExpressionVertex& jaev_decrement_e = new_jae.addVertex();
00456       JacobianAccumulationExpressionVertex& jaev_subtract = new_jae.addVertex();
00457       //jaev_subtract.setOperation (JacobianAccumulationExpressionVertex::SUBTRACT_OP);
00458       jaev_subtract.setOperation(JacobianAccumulationExpressionVertex::ADD_OP);
00459       new_jae.addEdge(jaev_mult, jaev_subtract);
00460       new_jae.addEdge(jaev_decrement_e, jaev_subtract);
00461 
00462       // point the decrement edge at the divide operation in the new JAE
00463       removeRef (decrement_e, angelLCG, edge_ref_list);
00464       EdgeRef_t new_decrement_e_ref (decrement_e, &jaev_subtract);
00465       edge_ref_list.push_back(new_decrement_e_ref);
00466 
00467       //set edge type for absorption decrement edge
00468       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)
00469         eType[decrement_e] = VARIABLE_EDGE;
00470       else if (eType[decrement_e] != VARIABLE_EDGE)
00471         eType[decrement_e] = CONSTANT_EDGE;
00472     } // end decrement absorption
00473     else { // decrement fill-in
00474       tie (decrement_e, found_decrement_e) = add_edge (source (*iei, angelLCG), target (er.e, angelLCG), angelLCG.next_edge_number++, angelLCG);
00475 
00476       // point the new edge at the divide operation in the new JAE
00477       EdgeRef_t new_decrement_e_ref (decrement_e, &jaev_divide);
00478       edge_ref_list.push_back(new_decrement_e_ref);
00479 
00480       //set edge type for fill-in decrement edge
00481       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)
00482         eType[decrement_e] = VARIABLE_EDGE;
00483       else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE && eType[*iei] == UNIT_EDGE)
00484         eType[decrement_e] = UNIT_EDGE;
00485       else
00486         eType[decrement_e] = CONSTANT_EDGE;
00487     }
00488 
00489     // eval cost for decrements: trivial if both e and pivot_e are unit or if decrement is unit
00490     if (!((eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE) || eType[*iei] == UNIT_EDGE))
00491       cost++;
00492   } // end all decrements
00493 
00494   remove_edge (er.e, angelLCG);
00495 
00496   return cost;
00497 } // end postroute_edge_directly()
00498 
00499 unsigned int prerouteEdge_noJAE (edge_reroute_t er,
00500                                  c_graph_t& angelLCG) {
00501   #ifndef NDEBUG
00502     cout << "prerouting edge " << er.e << " about pivot edge " << er.pivot_e << "\t(without creating any JAEs)" << endl;
00503   #endif
00504 
00505   unsigned int cost = 0;
00506   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), angelLCG);
00507   c_graph_t::iei_t iei, ie_end; 
00508   c_graph_t::oei_t oei, oe_end; 
00509 
00510   // INCREMENT EDGE
00511   bool found_increment_e;
00512   c_graph_t::edge_t increment_e;
00513   tie (increment_e, found_increment_e) = edge (source (er.e, angelLCG), source (er.pivot_e, angelLCG), angelLCG);
00514   if (found_increment_e) { // increment absorption
00515     //set edge type for absorption increment edge
00516     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00517     else if (eType[increment_e] != VARIABLE_EDGE)                               eType[increment_e] = CONSTANT_EDGE;
00518   } // end increment absorption
00519   else { //no increment edge was already present (fill-in)
00520     tie (increment_e, found_increment_e) = add_edge (source (er.e, angelLCG), source (er.pivot_e, angelLCG), angelLCG.next_edge_number++, angelLCG);
00521     //set edge type for fill-in increment edge
00522     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00523     else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE)        eType[increment_e] = UNIT_EDGE;
00524     else                                                                        eType[increment_e] = CONSTANT_EDGE;
00525   }
00526   // determine cost of creating increment edge (we divide e/pivot_e, so trivial iff pivot_e is unit)
00527   if (eType[er.pivot_e] != UNIT_EDGE)
00528     cost++;
00529 
00530   // DECREMENT EDGES
00531   for (tie (oei, oe_end) = out_edges (source (er.pivot_e, angelLCG), angelLCG); oei != oe_end; oei++) {
00532     if (target (*oei, angelLCG) == target (er.e, angelLCG)) continue;
00533     bool found_decrement_e;
00534     c_graph_t::edge_t decrement_e;
00535     tie (decrement_e, found_decrement_e) = edge (source (er.e, angelLCG), target (*oei, angelLCG), angelLCG);
00536     if (found_decrement_e) { // decrement absorption
00537       //set edge type for absorption decrement edge
00538       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE)   eType[decrement_e] = VARIABLE_EDGE;
00539       else if (eType[decrement_e] != VARIABLE_EDGE)                                                             eType[decrement_e] = CONSTANT_EDGE;
00540     } // end decrement absorption
00541     else { // decrement fill-in
00542       tie (decrement_e, found_decrement_e) = add_edge (source (er.e, angelLCG), target (*oei, angelLCG), angelLCG.next_edge_number++, angelLCG);
00543       //set edge type for fill-in decrement edge
00544       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*oei] == VARIABLE_EDGE)   eType[decrement_e] = VARIABLE_EDGE;
00545       else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE && eType[*oei] == UNIT_EDGE)          eType[decrement_e] = UNIT_EDGE;
00546       else                                                                                                      eType[decrement_e] = CONSTANT_EDGE;
00547     }
00548     // eval cost for decrements: trivial if both e and pivot_e are unit or if decrement is unit
00549     if (!((eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE) || eType[*iei] == UNIT_EDGE))
00550       cost++;
00551   } // end all decrements
00552   remove_edge (er.e, angelLCG);
00553   return cost;
00554 } // end prerouteEdge_noJAE()
00555 
00556 unsigned int postrouteEdge_noJAE (edge_reroute_t er,
00557                                   c_graph_t& angelLCG) {
00558   #ifndef NDEBUG
00559     cout << "postrouting edge " << er.e << " about pivot edge " << er.pivot_e << "\t(without creating any JAEs)" << endl;
00560   #endif
00561 
00562   unsigned int cost = 0;
00563   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), angelLCG);
00564   c_graph_t::iei_t iei, ie_end; 
00565   c_graph_t::oei_t oei, oe_end; 
00566 
00567   // INCREMENT EDGE
00568   bool found_increment_e;
00569   c_graph_t::edge_t increment_e;
00570   tie (increment_e, found_increment_e) = edge (target (er.pivot_e, angelLCG), target (er.e, angelLCG), angelLCG);
00571   if (found_increment_e) { // increment absorption
00572     //set edge type for absorption increment edge
00573     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00574     else if (eType[increment_e] != VARIABLE_EDGE)                               eType[increment_e] = CONSTANT_EDGE;
00575   } // end increment absorption
00576   else { //no increment edge was already present (fill-in)
00577     tie (increment_e, found_increment_e) = add_edge (target (er.pivot_e, angelLCG), target (er.e, angelLCG), angelLCG.next_edge_number++, angelLCG);
00578     //set edge type for fill-in increment edge
00579     if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE)     eType[increment_e] = VARIABLE_EDGE;
00580     else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE)        eType[increment_e] = UNIT_EDGE;
00581     else                                                                        eType[increment_e] = CONSTANT_EDGE;
00582   }
00583   // determine cost of creating increment edge (we divide e/pivot_e, so trivial iff pivot_e is unit)
00584   if (eType[er.pivot_e] != UNIT_EDGE)
00585     cost++;
00586 
00587   // DECREMENT EDGES
00588   for (tie (iei, ie_end) = in_edges (target (er.pivot_e, angelLCG), angelLCG); iei != ie_end; iei++) {
00589     if (source (*iei, angelLCG) == source (er.pivot_e, angelLCG)) continue;
00590     bool found_decrement_e;
00591     c_graph_t::edge_t decrement_e;
00592     tie (decrement_e, found_decrement_e) = edge (source (*iei, angelLCG), target (er.e, angelLCG), angelLCG);
00593     if (found_decrement_e) { // decrement absorption
00594       //set edge type for absorption decrement edge
00595       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)   eType[decrement_e] = VARIABLE_EDGE;
00596       else if (eType[decrement_e] != VARIABLE_EDGE)                                                             eType[decrement_e] = CONSTANT_EDGE;
00597     } // end decrement absorption
00598     else { // decrement fill-in
00599       tie (decrement_e, found_decrement_e) = add_edge (source (*iei, angelLCG), target (er.e, angelLCG), angelLCG.next_edge_number++, angelLCG);
00600       //set edge type for fill-in decrement edge
00601       if (eType[er.e] == VARIABLE_EDGE || eType[er.pivot_e] == VARIABLE_EDGE || eType[*iei] == VARIABLE_EDGE)   eType[decrement_e] = VARIABLE_EDGE;
00602       else if (eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE && eType[*iei] == UNIT_EDGE)          eType[decrement_e] = UNIT_EDGE;
00603       else                                                                                                      eType[decrement_e] = CONSTANT_EDGE;
00604     }
00605     // eval cost for decrements: trivial if both e and pivot_e are unit or if decrement is unit
00606     if (!((eType[er.e] == UNIT_EDGE && eType[er.pivot_e] == UNIT_EDGE) || eType[*iei] == UNIT_EDGE))
00607       cost++;
00608   } // end all decrements
00609   remove_edge (er.e, angelLCG);
00610   return cost;
00611 } // end postrouteEdge_noJAE()
00612 
00613 } // namespace angel
00614 
00615 #endif // USEXAIFBOOSTER
00616 

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