dune-istl  2.6-git
aggregates.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_AMG_AGGREGATES_HH
4 #define DUNE_AMG_AGGREGATES_HH
5 
6 
7 #include "parameters.hh"
8 #include "graph.hh"
9 #include "properties.hh"
10 #include "combinedfunctor.hh"
11 
12 #include <dune/common/timer.hh>
13 #include <dune/common/stdstreams.hh>
14 #include <dune/common/poolallocator.hh>
15 #include <dune/common/sllist.hh>
16 #include <dune/common/unused.hh>
17 #include <dune/common/ftraits.hh>
18 
19 #include <utility>
20 #include <set>
21 #include <algorithm>
22 #include <complex>
23 #include <limits>
24 #include <ostream>
25 #include <tuple>
26 
27 namespace Dune
28 {
29  namespace Amg
30  {
31 
45  template<class T>
46  class AggregationCriterion : public T
47  {
48 
49  public:
53  typedef T DependencyPolicy;
54 
65  : T()
66  {}
67 
69  : T(parms)
70  {}
80  void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
81  {
82  this->setMaxDistance(diameter-1);
83  std::size_t csize=1;
84 
85  for(; dim>0; dim--) {
86  csize*=diameter;
87  this->setMaxDistance(this->maxDistance()+diameter-1);
88  }
89  this->setMinAggregateSize(csize);
90  this->setMaxAggregateSize(static_cast<std::size_t>(csize*1.5));
91  }
92 
103  void setDefaultValuesAnisotropic(std::size_t dim,std::size_t diameter=2)
104  {
105  setDefaultValuesIsotropic(dim, diameter);
106  this->setMaxDistance(this->maxDistance()+dim-1);
107  }
108  };
109 
110  template<class T>
111  std::ostream& operator<<(std::ostream& os, const AggregationCriterion<T>& criterion)
112  {
113  os<<"{ maxdistance="<<criterion.maxDistance()<<" minAggregateSize="
114  <<criterion.minAggregateSize()<< " maxAggregateSize="<<criterion.maxAggregateSize()
115  <<" connectivity="<<criterion.maxConnectivity()<<" debugLevel="<<criterion.debugLevel()<<"}";
116  return os;
117  }
118 
130  template<class M, class N>
132  {
133  public:
137  typedef M Matrix;
138 
142  typedef N Norm;
143 
147  typedef typename Matrix::row_type Row;
148 
153 
154  void init(const Matrix* matrix);
155 
156  void initRow(const Row& row, int index);
157 
158  void examine(const ColIter& col);
159 
160  template<class G>
161  void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
162 
163  bool isIsolated();
164 
165 
167  : Parameters(parms)
168  {}
170  : Parameters()
171  {}
172 
173  protected:
175  const Matrix* matrix_;
177  typedef typename Matrix::field_type field_type;
178  typedef typename FieldTraits<field_type>::real_type real_type;
179  real_type maxValue_;
181  Norm norm_;
183  int row_;
185  real_type diagonal_;
186  std::vector<real_type> vals_;
187  typename std::vector<real_type>::iterator valIter_;
188 
189  };
190 
191 
192  template<class M, class N>
193  inline void SymmetricMatrixDependency<M,N>::init(const Matrix* matrix)
194  {
195  matrix_ = matrix;
196  }
197 
198  template<class M, class N>
199  inline void SymmetricMatrixDependency<M,N>::initRow(const Row& row, int index)
200  {
201  vals_.assign(row.size(), 0.0);
202  assert(vals_.size()==row.size());
203  valIter_=vals_.begin();
204 
205  maxValue_ = std::min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
206  diagonal_=norm_(row[index]);
207  row_ = index;
208  }
209 
210  template<class M, class N>
212  {
213  // skip positive offdiagonals if norm preserves sign of them.
214  real_type eij = norm_(*col);
215  if(!N::is_sign_preserving || eij<0) // || eji<0)
216  {
217  *valIter_ = eij/diagonal_*eij/norm_(matrix_->operator[](col.index())[col.index()]);
218  maxValue_ = std::max(maxValue_, *valIter_);
219  }else
220  *valIter_ =0;
221  ++valIter_;
222  }
223 
224  template<class M, class N>
225  template<class G>
226  inline void SymmetricMatrixDependency<M,N>::examine(G&, const typename G::EdgeIterator& edge, const ColIter&)
227  {
228  if(*valIter_ > alpha() * maxValue_) {
229  edge.properties().setDepends();
230  edge.properties().setInfluences();
231  }
232  ++valIter_;
233  }
234 
235  template<class M, class N>
237  {
238  if(diagonal_==0)
239  DUNE_THROW(Dune::ISTLError, "No diagonal entry for row "<<row_<<".");
240  valIter_=vals_.begin();
241  return maxValue_ < beta();
242  }
243 
247  template<class M, class N>
248  class Dependency : public Parameters
249  {
250  public:
254  typedef M Matrix;
255 
259  typedef N Norm;
260 
264  typedef typename Matrix::row_type Row;
265 
270 
271  void init(const Matrix* matrix);
272 
273  void initRow(const Row& row, int index);
274 
275  void examine(const ColIter& col);
276 
277  template<class G>
278  void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
279 
280  bool isIsolated();
281 
282  Dependency(const Parameters& parms)
283  : Parameters(parms)
284  {}
285 
287  : Parameters()
288  {}
289 
290  protected:
292  const Matrix* matrix_;
294  typedef typename Matrix::field_type field_type;
295  typedef typename FieldTraits<field_type>::real_type real_type;
296  real_type maxValue_;
298  Norm norm_;
300  int row_;
302  real_type diagonal_;
303  };
304 
308  template<class M, class N>
310  {
311  public:
315  typedef M Matrix;
316 
320  typedef N Norm;
321 
325  typedef typename Matrix::row_type Row;
326 
331 
332  void init(const Matrix* matrix);
333 
334  void initRow(const Row& row, int index);
335 
336  void examine(const ColIter& col);
337 
338  template<class G>
339  void examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col);
340 
341  bool isIsolated();
342 
343 
345  : Parameters(parms)
346  {}
348  : Parameters()
349  {}
350 
351  protected:
353  const Matrix* matrix_;
355  typedef typename Matrix::field_type field_type;
356  typedef typename FieldTraits<field_type>::real_type real_type;
357  real_type maxValue_;
359  Norm norm_;
361  int row_;
363  real_type diagonal_;
364  };
365 
370  template<int N>
371  class Diagonal
372  {
373  public:
374  enum { /* @brief We preserve the sign.*/
375  is_sign_preserving = true
376  };
377 
382  template<class M>
383  typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
384  {
385  typedef typename M::field_type field_type;
386  typedef typename FieldTraits<field_type>::real_type real_type;
387  static_assert( std::is_convertible<field_type, real_type >::value,
388  "use of diagonal norm in AMG not implemented for complex field_type");
389  return m[N][N];
390  // possible implementation for complex types: return signed_abs(m[N][N]);
391  }
392 
393  private:
394 
396  template<typename T>
397  static T signed_abs(const T & v)
398  {
399  return v;
400  }
401 
403  template<typename T>
404  static T signed_abs(const std::complex<T> & v)
405  {
406  // return sign * abs_value
407  // in case of complex numbers this extends to using the csgn function to determine the sign
408  return csgn(v) * std::abs(v);
409  }
410 
412  template<typename T>
413  static T csgn(const T & v)
414  {
415  return (T(0) < v) - (v < T(0));
416  }
417 
419  template<typename T>
420  static T csgn(std::complex<T> a)
421  {
422  return csgn(a.real())+(a.real() == 0.0)*csgn(a.imag());
423  }
424 
425  };
426 
431  class FirstDiagonal : public Diagonal<0>
432  {};
433 
439  struct RowSum
440  {
441 
442  enum { /* @brief We preserve the sign.*/
443  is_sign_preserving = false
444  };
449  template<class M>
450  typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
451  {
452  return m.infinity_norm();
453  }
454  };
455 
457  {
458 
459  enum { /* @brief We preserve the sign.*/
460  is_sign_preserving = false
461  };
466  template<class M>
467  typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
468  {
469  return m.frobenius_norm();
470  }
471  };
473  {
474 
475  enum { /* @brief We preserve the sign.*/
476  is_sign_preserving = false
477  };
482  template<class M>
483  typename FieldTraits<typename M::field_type>::real_type operator()(const M& m) const
484  {
485  return 1;
486  }
487  };
497  template<class M, class Norm>
498  class SymmetricCriterion : public AggregationCriterion<SymmetricDependency<M,Norm> >
499  {
500  public:
503  {}
505  {}
506  };
507 
508 
520  template<class M, class Norm>
521  class UnSymmetricCriterion : public AggregationCriterion<Dependency<M,Norm> >
522  {
523  public:
525  : AggregationCriterion<Dependency<M,Norm> >(parms)
526  {}
528  {}
529  };
530  // forward declaration
531  template<class G> class Aggregator;
532 
533 
541  template<class V>
543  {
544  public:
545 
549  static const V UNAGGREGATED;
550 
554  static const V ISOLATED;
558  typedef V VertexDescriptor;
559 
564 
569  typedef PoolAllocator<VertexDescriptor,100> Allocator;
570 
575  typedef SLList<VertexDescriptor,Allocator> VertexList;
576 
581  {
582  public:
583  template<class EdgeIterator>
584  void operator()(const EdgeIterator& edge) const
585  {
586  DUNE_UNUSED_PARAMETER(edge);
587  }
588  };
589 
590 
594  AggregatesMap();
595 
601  AggregatesMap(std::size_t noVertices);
602 
606  ~AggregatesMap();
607 
619  template<class M, class G, class C>
620  std::tuple<int,int,int,int> buildAggregates(const M& matrix, G& graph, const C& criterion,
621  bool finestLevel);
622 
642  template<bool reset, class G, class F, class VM>
643  std::size_t breadthFirstSearch(const VertexDescriptor& start,
644  const AggregateDescriptor& aggregate,
645  const G& graph,
646  F& aggregateVisitor,
647  VM& visitedMap) const;
648 
672  template<bool remove, bool reset, class G, class L, class F1, class F2, class VM>
673  std::size_t breadthFirstSearch(const VertexDescriptor& start,
674  const AggregateDescriptor& aggregate,
675  const G& graph, L& visited, F1& aggregateVisitor,
676  F2& nonAggregateVisitor,
677  VM& visitedMap) const;
678 
684  void allocate(std::size_t noVertices);
685 
689  std::size_t noVertices() const;
690 
694  void free();
695 
701  AggregateDescriptor& operator[](const VertexDescriptor& v);
702 
708  const AggregateDescriptor& operator[](const VertexDescriptor& v) const;
709 
710  typedef const AggregateDescriptor* const_iterator;
711 
712  const_iterator begin() const
713  {
714  return aggregates_;
715  }
716 
717  const_iterator end() const
718  {
719  return aggregates_+noVertices();
720  }
721 
722  typedef AggregateDescriptor* iterator;
723 
724  iterator begin()
725  {
726  return aggregates_;
727  }
728 
729  iterator end()
730  {
731  return aggregates_+noVertices();
732  }
733  private:
735  AggregatesMap(const AggregatesMap<V>&) = delete;
737  AggregatesMap<V>& operator=(const AggregatesMap<V>&) = delete;
738 
742  AggregateDescriptor* aggregates_;
743 
747  std::size_t noVertices_;
748  };
749 
753  template<class G, class C>
754  void buildDependency(G& graph,
755  const typename C::Matrix& matrix,
756  C criterion,
757  bool finestLevel);
758 
763  template<class G, class S>
764  class Aggregate
765  {
766 
767  public:
768 
769  /***
770  * @brief The type of the matrix graph we work with.
771  */
772  typedef G MatrixGraph;
777 
782  typedef PoolAllocator<Vertex,100> Allocator;
783 
788  typedef S VertexSet;
789 
791  typedef typename VertexSet::const_iterator const_iterator;
792 
796  typedef std::size_t* SphereMap;
797 
806  Aggregate(MatrixGraph& graph, AggregatesMap<Vertex>& aggregates,
807  VertexSet& connectivity, std::vector<Vertex>& front_);
808 
809  void invalidate()
810  {
811  --id_;
812  }
813 
820  void reconstruct(const Vertex& vertex);
821 
825  void seed(const Vertex& vertex);
826 
830  void add(const Vertex& vertex);
831 
832  void add(std::vector<Vertex>& vertex);
836  void clear();
837 
841  typename VertexSet::size_type size();
845  typename VertexSet::size_type connectSize();
846 
850  int id();
851 
853  const_iterator begin() const;
854 
856  const_iterator end() const;
857 
858  private:
862  VertexSet vertices_;
863 
868  int id_;
869 
873  MatrixGraph& graph_;
874 
878  AggregatesMap<Vertex>& aggregates_;
879 
883  VertexSet& connected_;
884 
888  std::vector<Vertex>& front_;
889  };
890 
894  template<class G>
895  class Aggregator
896  {
897  public:
898 
902  typedef G MatrixGraph;
903 
908 
911 
915  Aggregator();
916 
920  ~Aggregator();
921 
938  template<class M, class C>
939  std::tuple<int,int,int,int> build(const M& m, G& graph,
940  AggregatesMap<Vertex>& aggregates, const C& c,
941  bool finestLevel);
942  private:
947  typedef PoolAllocator<Vertex,100> Allocator;
948 
952  typedef SLList<Vertex,Allocator> VertexList;
953 
957  typedef std::set<Vertex,std::less<Vertex>,Allocator> VertexSet;
958 
962  typedef std::size_t* SphereMap;
963 
967  MatrixGraph* graph_;
968 
973 
977  std::vector<Vertex> front_;
978 
982  VertexSet connected_;
983 
987  int size_;
988 
992  class Stack
993  {
994  public:
995  static const Vertex NullEntry;
996 
997  Stack(const MatrixGraph& graph,
998  const Aggregator<G>& aggregatesBuilder,
999  const AggregatesMap<Vertex>& aggregates);
1000  ~Stack();
1001  Vertex pop();
1002  private:
1003  enum { N = 1300000 };
1004 
1006  const MatrixGraph& graph_;
1008  const Aggregator<G>& aggregatesBuilder_;
1010  const AggregatesMap<Vertex>& aggregates_;
1012  int size_;
1013  Vertex maxSize_;
1015  typename MatrixGraph::ConstVertexIterator begin_;
1016  typename MatrixGraph::ConstVertexIterator end_;
1017 
1019  Vertex* vals_;
1020 
1021  };
1022 
1023  friend class Stack;
1024 
1035  template<class V>
1036  void visitAggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate,
1037  const AggregatesMap<Vertex>& aggregates,
1038  V& visitor) const;
1039 
1044  template<class V>
1045  class AggregateVisitor
1046  {
1047  public:
1051  typedef V Visitor;
1059  AggregateVisitor(const AggregatesMap<Vertex>& aggregates, const AggregateDescriptor& aggregate,
1060  Visitor& visitor);
1061 
1068  void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
1069 
1070  private:
1072  const AggregatesMap<Vertex>& aggregates_;
1074  AggregateDescriptor aggregate_;
1076  Visitor* visitor_;
1077  };
1078 
1082  class Counter
1083  {
1084  public:
1086  Counter();
1088  int value();
1089 
1090  protected:
1092  void increment();
1094  void decrement();
1095 
1096  private:
1097  int count_;
1098  };
1099 
1100 
1105  class FrontNeighbourCounter : public Counter
1106  {
1107  public:
1112  FrontNeighbourCounter(const MatrixGraph& front);
1113 
1114  void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
1115 
1116  private:
1117  const MatrixGraph& graph_;
1118  };
1119 
1124  int noFrontNeighbours(const Vertex& vertex) const;
1125 
1129  class TwoWayCounter : public Counter
1130  {
1131  public:
1132  void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
1133  };
1134 
1146  int twoWayConnections(const Vertex&, const AggregateDescriptor& aggregate,
1147  const AggregatesMap<Vertex>& aggregates) const;
1148 
1152  class OneWayCounter : public Counter
1153  {
1154  public:
1155  void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
1156  };
1157 
1169  int oneWayConnections(const Vertex&, const AggregateDescriptor& aggregate,
1170  const AggregatesMap<Vertex>& aggregates) const;
1171 
1178  class ConnectivityCounter : public Counter
1179  {
1180  public:
1187  ConnectivityCounter(const VertexSet& connected, const AggregatesMap<Vertex>& aggregates);
1188 
1189  void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
1190 
1191  private:
1193  const VertexSet& connected_;
1195  const AggregatesMap<Vertex>& aggregates_;
1196 
1197  };
1198 
1210  double connectivity(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
1218  bool connected(const Vertex& vertex, const AggregateDescriptor& aggregate,
1219  const AggregatesMap<Vertex>& aggregates) const;
1220 
1228  bool connected(const Vertex& vertex, const SLList<AggregateDescriptor>& aggregateList,
1229  const AggregatesMap<Vertex>& aggregates) const;
1230 
1238  class DependencyCounter : public Counter
1239  {
1240  public:
1244  DependencyCounter();
1245 
1246  void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
1247  };
1248 
1255  class FrontMarker
1256  {
1257  public:
1264  FrontMarker(std::vector<Vertex>& front, MatrixGraph& graph);
1265 
1266  void operator()(const typename MatrixGraph::ConstEdgeIterator& edge);
1267 
1268  private:
1270  std::vector<Vertex>& front_;
1272  MatrixGraph& graph_;
1273  };
1274 
1278  void unmarkFront();
1279 
1294  int unusedNeighbours(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
1295 
1309  std::pair<int,int> neighbours(const Vertex& vertex,
1310  const AggregateDescriptor& aggregate,
1311  const AggregatesMap<Vertex>& aggregates) const;
1328  int aggregateNeighbours(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const;
1329 
1337  bool admissible(const Vertex& vertex, const AggregateDescriptor& aggregate, const AggregatesMap<Vertex>& aggregates) const;
1338 
1346  std::size_t distance(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates);
1347 
1356  Vertex mergeNeighbour(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates) const;
1357 
1366  void nonisoNeighbourAggregate(const Vertex& vertex,
1367  const AggregatesMap<Vertex>& aggregates,
1368  SLList<Vertex>& neighbours) const;
1369 
1377  template<class C>
1378  void growAggregate(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates, const C& c);
1379  template<class C>
1380  void growIsolatedAggregate(const Vertex& vertex, const AggregatesMap<Vertex>& aggregates, const C& c);
1381  };
1382 
1383 #ifndef DOXYGEN
1384 
1385  template<class M, class N>
1386  inline void SymmetricDependency<M,N>::init(const Matrix* matrix)
1387  {
1388  matrix_ = matrix;
1389  }
1390 
1391  template<class M, class N>
1392  inline void SymmetricDependency<M,N>::initRow(const Row& row, int index)
1393  {
1394  DUNE_UNUSED_PARAMETER(row);
1395  maxValue_ = std::min(- std::numeric_limits<typename Matrix::field_type>::max(), std::numeric_limits<typename Matrix::field_type>::min());
1396  row_ = index;
1397  diagonal_ = norm_(matrix_->operator[](row_)[row_]);
1398  }
1399 
1400  template<class M, class N>
1401  inline void SymmetricDependency<M,N>::examine(const ColIter& col)
1402  {
1403  real_type eij = norm_(*col);
1404  typename Matrix::ConstColIterator opposite_entry =
1405  matrix_->operator[](col.index()).find(row_);
1406  if ( opposite_entry == matrix_->operator[](col.index()).end() )
1407  {
1408  // Consider this a weak connection we disregard.
1409  return;
1410  }
1411  real_type eji = norm_(*opposite_entry);
1412 
1413  // skip positive offdiagonals if norm preserves sign of them.
1414  if(!N::is_sign_preserving || eij<0 || eji<0)
1415  maxValue_ = std::max(maxValue_,
1416  eij /diagonal_ * eji/
1417  norm_(matrix_->operator[](col.index())[col.index()]));
1418  }
1419 
1420  template<class M, class N>
1421  template<class G>
1422  inline void SymmetricDependency<M,N>::examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col)
1423  {
1424  real_type eij = norm_(*col);
1425  typename Matrix::ConstColIterator opposite_entry =
1426  matrix_->operator[](col.index()).find(row_);
1427 
1428  if ( opposite_entry == matrix_->operator[](col.index()).end() )
1429  {
1430  // Consider this as a weak connection we disregard.
1431  return;
1432  }
1433  real_type eji = norm_(*opposite_entry);
1434  // skip positve offdiagonals if norm preserves sign of them.
1435  if(!N::is_sign_preserving || (eij<0 || eji<0))
1436  if(eji / norm_(matrix_->operator[](edge.target())[edge.target()]) *
1437  eij/ diagonal_ > alpha() * maxValue_) {
1438  edge.properties().setDepends();
1439  edge.properties().setInfluences();
1440  typename G::EdgeProperties& other = graph.getEdgeProperties(edge.target(), edge.source());
1441  other.setInfluences();
1442  other.setDepends();
1443  }
1444  }
1445 
1446  template<class M, class N>
1448  {
1449  return maxValue_ < beta();
1450  }
1451 
1452 
1453  template<class M, class N>
1454  inline void Dependency<M,N>::init(const Matrix* matrix)
1455  {
1456  matrix_ = matrix;
1457  }
1458 
1459  template<class M, class N>
1460  inline void Dependency<M,N>::initRow(const Row& row, int index)
1461  {
1462  DUNE_UNUSED_PARAMETER(row);
1463  maxValue_ = std::min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
1464  row_ = index;
1465  diagonal_ = norm_(matrix_->operator[](row_)[row_]);
1466  }
1467 
1468  template<class M, class N>
1469  inline void Dependency<M,N>::examine(const ColIter& col)
1470  {
1471  maxValue_ = std::max(maxValue_,
1472  -norm_(*col));
1473  }
1474 
1475  template<class M, class N>
1476  template<class G>
1477  inline void Dependency<M,N>::examine(G& graph, const typename G::EdgeIterator& edge, const ColIter& col)
1478  {
1479  if(-norm_(*col) >= maxValue_ * alpha()) {
1480  edge.properties().setDepends();
1481  typedef typename G::EdgeDescriptor ED;
1482  ED e= graph.findEdge(edge.target(), edge.source());
1483  if(e!=std::numeric_limits<ED>::max())
1484  {
1485  typename G::EdgeProperties& other = graph.getEdgeProperties(e);
1486  other.setInfluences();
1487  }
1488  }
1489  }
1490 
1491  template<class M, class N>
1492  inline bool Dependency<M,N>::isIsolated()
1493  {
1494  return maxValue_ < beta() * diagonal_;
1495  }
1496 
1497  template<class G,class S>
1499  VertexSet& connected, std::vector<Vertex>& front)
1500  : vertices_(), id_(-1), graph_(graph), aggregates_(aggregates),
1501  connected_(connected), front_(front)
1502  {}
1503 
1504  template<class G,class S>
1505  void Aggregate<G,S>::reconstruct(const Vertex& vertex)
1506  {
1507  /*
1508  vertices_.push_back(vertex);
1509  typedef typename VertexList::const_iterator iterator;
1510  iterator begin = vertices_.begin();
1511  iterator end = vertices_.end();*/
1512  throw "Not yet implemented";
1513 
1514  // while(begin!=end){
1515  //for();
1516  // }
1517 
1518  }
1519 
1520  template<class G,class S>
1521  inline void Aggregate<G,S>::seed(const Vertex& vertex)
1522  {
1523  dvverb<<"Connected cleared"<<std::endl;
1524  connected_.clear();
1525  vertices_.clear();
1526  connected_.insert(vertex);
1527  dvverb << " Inserting "<<vertex<<" size="<<connected_.size();
1528  ++id_ ;
1529  add(vertex);
1530  }
1531 
1532 
1533  template<class G,class S>
1534  inline void Aggregate<G,S>::add(const Vertex& vertex)
1535  {
1536  vertices_.insert(vertex);
1537  aggregates_[vertex]=id_;
1538  if(front_.size())
1539  front_.erase(std::lower_bound(front_.begin(), front_.end(), vertex));
1540 
1541 
1542  typedef typename MatrixGraph::ConstEdgeIterator iterator;
1543  const iterator end = graph_.endEdges(vertex);
1544  for(iterator edge = graph_.beginEdges(vertex); edge != end; ++edge) {
1545  dvverb << " Inserting "<<aggregates_[edge.target()];
1546  connected_.insert(aggregates_[edge.target()]);
1547  dvverb <<" size="<<connected_.size();
1548  if