00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wgraph.h"
00011 #include "filekl.h"
00012 #include "bitset.h"
00013 #include "blocks.h"
00014
00015 #include <algorithm>
00016 #include <iostream>
00017
00018 namespace atlas {
00019
00020
00021
00022
00023
00024
00025
00026 namespace wgraph {
00027
00028
00029 WGraph::WGraph(size_t r)
00030 :d_rank(r)
00031
00032
00033
00034
00035
00036
00037
00038 {}
00039
00040 WGraph::~WGraph()
00041
00042 {}
00043
00044
00045 void WGraph::swap(WGraph& other)
00046
00047 {
00048 std::swap(d_rank,other.d_rank);
00049 d_graph.swap(other.d_graph);
00050 d_coeff.swap(other.d_coeff);
00051 d_descent.swap(other.d_descent);
00052
00053 return;
00054 }
00055
00056
00057 void WGraph::reset()
00058
00059
00060
00061
00062
00063
00064
00065
00066 {
00067 d_graph.reset();
00068 d_coeff.assign(size(),CoeffList());
00069 d_descent.assign(size(),bitset::RankFlags());
00070
00071 return;
00072 }
00073
00074 void WGraph::resize(size_t n)
00075
00076
00077
00078
00079
00080
00081
00082 {
00083 d_graph.resize(n);
00084 d_coeff.resize(n);
00085 d_descent.resize(n);
00086
00087 return;
00088 }
00089
00090 DecomposedWGraph::DecomposedWGraph(const WGraph& wg)
00091 : d_cell(), d_part(wg.size()), d_id(), d_induced()
00092 {
00093 using partition::Partition; using partition::PartitionIterator;
00094
00095 Partition pi;
00096 wg.cells(pi,&d_induced);
00097
00098 d_cell.reserve(pi.classCount());
00099 d_id.resize(pi.classCount());
00100
00101
00102 std::vector<unsigned int> relno(wg.size());
00103 PartitionIterator i(pi);
00104 for (cell_no n=0; n<d_id.size(); ++n,++i)
00105 {
00106 d_cell.push_back(WGraph(wg.rank()));
00107 WGraph& cur_cell = d_cell.back();
00108 cur_cell.resize(i->second-i->first);
00109 std::vector<unsigned int>& idn=d_id[n];
00110 idn.resize(cur_cell.size());
00111
00112 for (PartitionIterator::SubIterator j=i->first; j!=i->second; ++j)
00113 {
00114 size_t y = *j; size_t z=j-i->first;
00115
00116 d_part[y]=n;
00117 relno[y]=z; idn[z]=y;
00118
00119 cur_cell.descent(z) = wg.descent(y);
00120 }
00121 }
00122
00123
00124 for (i.rewind(); i(); ++i)
00125 {
00126 cell_no n=d_part[*i->first];
00127 for (PartitionIterator::SubIterator j=i->first; j!=i->second; ++j)
00128 {
00129 size_t y = *j; size_t z=relno[y];
00130 const graph::EdgeList& edge = wg.edgeList(y);
00131 const CoeffList& coeff = wg.coeffList(y);
00132 graph::EdgeList& cur_el = d_cell[n].edgeList(z);
00133 CoeffList& cur_cl = d_cell[n].coeffList(z);
00134 for (size_t k = 0; k < edge.size(); ++k)
00135 if (d_part[edge[k]]==n)
00136 {
00137 cur_el.push_back(relno[edge[k]]);
00138 cur_cl.push_back( coeff[k]);
00139 }
00140 }
00141 }
00142
00143 }
00144
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 namespace wgraph {
00154
00155 void cells(std::vector<WGraph>& wc, const WGraph& wg)
00156
00157
00158
00159
00160
00161 {
00162 using namespace graph;
00163 using namespace partition;
00164
00165 Partition pi;
00166 wg.cells(pi);
00167
00168 for (PartitionIterator i(pi); i(); ++i) {
00169 wc.push_back(WGraph(wg.rank()));
00170 WGraph& wci = wc.back();
00171 wci.resize(i->second - i->first);
00172
00173
00174
00175
00176 for (size_t z = 0; z < wci.size(); ++z) {
00177 size_t y = i->first[z];
00178 wci.descent(z) = wg.descent(y);
00179 const EdgeList& el = wg.edgeList(y);
00180 EdgeList& eli = wci.edgeList(z);
00181 const CoeffList& cl = wg.coeffList(y);
00182 CoeffList& cli = wci.coeffList(z);
00183 for (size_t j = 0; j < el.size(); ++j) {
00184 size_t x = el[j];
00185 if (pi(x) != pi(y))
00186 continue;
00187
00188 size_t xi = std::lower_bound(i->first,i->second,x) - i->first;
00189 eli.push_back(xi);
00190 cli.push_back(cl[j]);
00191 }
00192 }
00193 }
00194
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204 WGraph wGraph
00205 ( std::ifstream& block_file
00206 , std::ifstream& matrix_file
00207 , std::ifstream& KL_file)
00208 {
00209 using blocks::BlockElt;
00210 typedef std::auto_ptr<filekl::polynomial_info> pol_aptr;
00211
00212 filekl::matrix_info mi(block_file,matrix_file);
00213 pol_aptr pol_p(NULL);
00214
00215 try
00216 { pol_p=pol_aptr(new filekl::cached_pol_info(KL_file));
00217 }
00218 catch (std::exception& e)
00219 {
00220 std::cerr << "Failed to use cached polynomials: " << e.what() << std::endl;
00221 pol_p=pol_aptr(new filekl::polynomial_info(KL_file));
00222 }
00223
00224 filekl::polynomial_info& poli=*pol_p;
00225
00226 size_t max_mu=1;
00227 std::pair<BlockElt,BlockElt> max_pair;
00228
00229 WGraph result(mi.rank()); result.resize(mi.block_size());
00230
00231
00232 for (BlockElt y = 0; y < mi.block_size(); ++y)
00233 {
00234 bitset::RankFlags d_y = result.descent(y) = mi.descent_set(y);
00235 size_t ly = mi.length(y);
00236 if (ly==0) continue;
00237
00238 #ifdef VERBOSE
00239 std::cerr << "reading edges for y=" << y;
00240 if (max_mu>1) std::cerr << ", maximal mu: " << max_mu;
00241 std::cerr << '\r';
00242 #endif
00243
00244 const filekl::strong_prim_list& spy=mi.strongly_primitives(y);
00245
00246 filekl::strong_prim_list::const_iterator start= spy.begin();
00247
00248 for (size_t lx=(ly-1)%2,d = (ly-1)/2; d>0; --d,lx+=2)
00249 {
00250 filekl::strong_prim_list::const_iterator stop =
00251 std::lower_bound(start,spy.end()-1,mi.first_of_length(lx+1));
00252 for (start= std::lower_bound(start,stop,mi.first_of_length(lx));
00253 start<stop; ++start)
00254 if (mi.descent_set(*start)!=d_y)
00255 {
00256 BlockElt x = *start;
00257 filekl::KLIndex klp = mi.find_pol_nr(x,y);
00258
00259 if (poli.degree(klp)==d)
00260 {
00261 result.edgeList(x).push_back(y);
00262 size_t mu=poli.leading_coeff(klp);
00263 if (mu>max_mu) { max_mu=mu; max_pair=std::make_pair(x,y); }
00264 result.coeffList(x).push_back(mu);
00265 }
00266
00267 }
00268 }
00269
00270
00271 BlockElt end=mi.first_of_length(ly);
00272 for (BlockElt x=mi.first_of_length(ly-1); x<end; ++x)
00273 {
00274 bitset::RankFlags d_x=mi.descent_set(x);
00275 if (d_x==d_y) continue;
00276 filekl::KLIndex klp = mi.find_pol_nr(x,y);
00277 if (klp!=filekl::KLIndex(0))
00278 {
00279 size_t mu=poli.leading_coeff(klp);
00280 if (mu>max_mu) { max_mu=mu; max_pair=std::make_pair(x,y); }
00281 if (not d_y.contains(d_x))
00282 {
00283 result.edgeList(x).push_back(y);
00284 result.coeffList(x).push_back(mu);
00285 }
00286 if (not d_x.contains(d_y))
00287 {
00288 result.edgeList(y).push_back(x);
00289 result.coeffList(y).push_back(mu);
00290 }
00291 }
00292 }
00293 }
00294
00295 size_t n_edges=0;
00296 for (BlockElt y = 0; y < mi.block_size(); ++y)
00297 n_edges+=result.edgeList(y).size();
00298
00299 if (max_mu==1) std::cout << "All edges found are simple.\n";
00300 else std::cout << "Maximal edge multiplicity " << max_mu << " for ("
00301 << max_pair.first << ',' << max_pair.second <<")\n";
00302 std::cout << "Total number of (directed) edges in graph is " << n_edges
00303 << '.' << std::endl;
00304
00305 return result;
00306 }
00307
00308
00309 }
00310
00311 }