1 #ifndef VIENNACL_MISC_CUTHILL_MCKEE_HPP 
    2 #define VIENNACL_MISC_CUTHILL_MCKEE_HPP 
   46   template<
typename IndexT, 
typename ValueT>
 
   48                            std::vector<bool> & dof_assigned_to_node,
 
   49                            std::vector<IndexT> 
const & permutation)
 
   53     for (
vcl_size_t i = 0; i < permutation.size(); i++)
 
   55       if (!dof_assigned_to_node[i])
 
   58       IndexT min_index = 
static_cast<IndexT
>(
matrix.size());
 
   60       for (
typename std::map<IndexT, ValueT>::const_iterator it = 
matrix[i].begin(); it != 
matrix[i].end(); it++)
 
   63         if (!dof_assigned_to_node[col_index])
 
   66         if (permutation[col_index] > max_index)
 
   67           max_index = permutation[col_index];
 
   68         if (permutation[col_index] < min_index)
 
   69           min_index = permutation[col_index];
 
   71       if (max_index > min_index)
 
   72         bw = 
std::max(bw, max_index - min_index);
 
   88   template<
typename IndexT>
 
   97     while ( (k > 0) && ( ((k == m) && (comb[k-1] == static_cast<IndexT>(n)-1)) ||
 
   98                          ((k <  m) && (comb[k-1] == comb[k] - 1) )) )
 
  111       comb[i] = comb[k-1] + IndexT(i - k);
 
  121   template<
typename MatrixT, 
typename IndexT>
 
  123                          std::vector< std::vector<IndexT> > & layer_list)
 
  125     std::vector<bool> node_visited_already(matrix.size(), 
false);
 
  130     for (
vcl_size_t i=0; i<layer_list.size(); ++i)
 
  132       for (
typename std::vector<IndexT>::iterator it  = layer_list[i].begin();
 
  133            it != layer_list[i].end();
 
  135         node_visited_already[*it] = 
true;
 
  141     while (layer_list.back().size() > 0)
 
  144       layer_list.push_back(std::vector<IndexT>());
 
  146       for (
typename std::vector<IndexT>::iterator it  = layer_list[layer_index].begin();
 
  147            it != layer_list[layer_index].end();
 
  150         for (
typename MatrixT::value_type::const_iterator it2  = matrix[*it].begin();
 
  151              it2 != matrix[*it].end();
 
  154           if (it2->first == *it) 
continue;
 
  155           if (node_visited_already[it2->first]) 
continue;
 
  157           layer_list.back().push_back(it2->first);
 
  158           node_visited_already[it2->first] = 
true;
 
  164     layer_list.resize(layer_list.size()-1);
 
  169   template<
typename MatrixType>
 
  171                          std::vector< std::vector<int> > & l,
 
  176     std::vector<bool> inr(n, 
false);
 
  177     std::vector<int> nlist;
 
  186       for (std::vector<int>::iterator it  = l.back().begin();
 
  187            it != l.back().end();
 
  190         for (
typename MatrixType::value_type::const_iterator it2  = matrix[static_cast<vcl_size_t>(*it)].begin();
 
  191              it2 != matrix[
static_cast<vcl_size_t>(*it)].end();
 
  194           if (it2->first == *it) 
continue;
 
  195           if (inr[static_cast<vcl_size_t>(it2->first)]) 
continue;
 
  197           nlist.push_back(it2->first);
 
  198           inr[
static_cast<vcl_size_t>(it2->first)] = 
true;
 
  202       if (nlist.size() == 0)
 
  214   template<
typename MatrixT, 
typename IndexT>
 
  216                                              std::vector<IndexT> & node_list)
 
  218     std::vector<bool> node_visited_already(matrix.size(), 
false);
 
  219     std::deque<IndexT> node_queue;
 
  224     for (
typename std::vector<IndexT>::iterator it  = node_list.begin();
 
  225          it != node_list.end();
 
  228       node_queue.push_back(*it);
 
  235     while (!node_queue.empty())
 
  238       node_queue.pop_front();
 
  240       if (!node_visited_already[node_id])
 
  242         node_list.push_back(IndexT(node_id));
 
  243         node_visited_already[node_id] = 
true;
 
  245         for (
typename MatrixT::value_type::const_iterator it  = matrix[node_id].begin();
 
  246              it != matrix[node_id].end();
 
  250           if (neighbor_node_id == node_id) 
continue;
 
  251           if (node_visited_already[neighbor_node_id]) 
continue;
 
  253           node_queue.push_back(IndexT(neighbor_node_id));
 
  264                                       std::vector<int> 
const & b)
 
  266     return (a[1] < b[1]);
 
  269   template<
typename IndexT>
 
  271                                     std::pair<IndexT, IndexT> 
const & b)
 
  273     return (a.second < b.second);
 
  286   template<
typename IndexT, 
typename ValueT>
 
  288                                                            std::deque<IndexT> & node_assignment_queue,
 
  289                                                            std::vector<bool>  & dof_assigned_to_node,
 
  290                                                            std::vector<IndexT> & permutation,
 
  293     typedef std::pair<IndexT, IndexT> NodeIdDegreePair; 
 
  295     std::vector< NodeIdDegreePair > local_neighbor_nodes(
matrix.size());
 
  297     while (!node_assignment_queue.empty())
 
  301       node_assignment_queue.pop_front();
 
  304       if (!dof_assigned_to_node[node_id])
 
  306         permutation[node_id] = 
static_cast<IndexT
>(current_dof);  
 
  308         dof_assigned_to_node[node_id] = 
true;
 
  314         for (
typename std::map<IndexT, ValueT>::const_iterator neighbor_it  = 
matrix[node_id].begin();
 
  315              neighbor_it != 
matrix[node_id].end();
 
  319           if (!dof_assigned_to_node[neighbor_node_index])
 
  321             local_neighbor_nodes[num_neighbors] = NodeIdDegreePair(neighbor_it->first, static_cast<IndexT>(
matrix[neighbor_node_index].size()));
 
  327         std::sort(local_neighbor_nodes.begin(),
 
  328                   local_neighbor_nodes.begin() + 
static_cast<typename std::vector< NodeIdDegreePair >::difference_type
>(num_neighbors),
 
  329                   detail::cuthill_mckee_comp_func_pair<IndexT>);
 
  333           node_assignment_queue.push_back(local_neighbor_nodes[i].first);
 
  366 template<
typename IndexT, 
typename ValueT>
 
  369   std::vector<IndexT> permutation(
matrix.size());
 
  370   std::vector<bool>   dof_assigned_to_node(
matrix.size(), 
false);   
 
  371   std::deque<IndexT>  node_assignment_queue;
 
  375   while (current_dof < 
matrix.size()) 
 
  382     bool found_unassigned_node = 
false;
 
  385       if (!dof_assigned_to_node[i])
 
  389           permutation[i] = 
static_cast<IndexT
>(current_dof);
 
  390           dof_assigned_to_node[i] = 
true;
 
  395         if (!found_unassigned_node) 
 
  397           current_min_degree = 
matrix[i].size();
 
  398           node_with_minimum_degree = i;
 
  399           found_unassigned_node = 
true;
 
  404           current_min_degree = 
matrix[i].size();
 
  405           node_with_minimum_degree = i;
 
  413     if (found_unassigned_node) 
 
  415       node_assignment_queue.push_back(static_cast<IndexT>(node_with_minimum_degree));
 
  459   double starting_node_param_;
 
  473 template<
typename IndexT, 
typename ValueT>
 
  474 std::vector<IndexT> 
reorder(std::vector< std::map<IndexT, ValueT> > 
const & 
matrix,
 
  480   std::vector<IndexT> permutation(n);
 
  481   std::vector<bool>   dof_assigned_to_node(n, 
false);
 
  482   std::vector<IndexT> nodes_in_strongly_connected_component;
 
  483   std::vector<IndexT> parent_nodes;
 
  488   std::vector<IndexT> comb;
 
  490   nodes_in_strongly_connected_component.reserve(n);
 
  491   parent_nodes.reserve(n);
 
  496   while (current_dof < 
matrix.size()) 
 
  499     nodes_in_strongly_connected_component.resize(0);
 
  502       if (!dof_assigned_to_node[i])
 
  504         nodes_in_strongly_connected_component.push_back(static_cast<IndexT>(i));
 
  513     for (
typename std::vector<IndexT>::iterator it  = nodes_in_strongly_connected_component.begin();
 
  514          it != nodes_in_strongly_connected_component.end();
 
  518       if (deg_min == 0 || deg < deg_min)
 
  520       if (deg_max == 0 || deg > deg_max)
 
  523     deg_a = deg_min + 
static_cast<vcl_size_t>(a * double(deg_max - deg_min));
 
  527     for (
typename std::vector<IndexT>::iterator it  = nodes_in_strongly_connected_component.begin();
 
  528          it != nodes_in_strongly_connected_component.end();
 
  531       if (
matrix[static_cast<vcl_size_t>(*it)].size() <= deg_a)
 
  532         parent_nodes.push_back(*it);
 
  538     std::vector<bool> dof_assigned_to_node_backup = dof_assigned_to_node;
 
  539     std::vector<bool> dof_assigned_to_node_best;
 
  541     std::vector<IndexT> permutation_backup = permutation;
 
  542     std::vector<IndexT> permutation_best = permutation;
 
  558       dof_assigned_to_node = dof_assigned_to_node_backup;
 
  559       permutation          = permutation_backup;
 
  560       current_dof          = current_dof_backup;
 
  562       std::deque<IndexT>  node_queue;
 
  565       for (
typename std::vector<IndexT>::iterator it = comb.begin(); it != comb.end(); it++)
 
  566         node_queue.push_back(parent_nodes[static_cast<vcl_size_t>(*it)]);
 
  575       if (bw_best == 0 || bw < bw_best)
 
  577         permutation_best = permutation;
 
  579         dof_assigned_to_node_best = dof_assigned_to_node;
 
  587         if ( (gmax > 0 && g > gmax) || g > parent_nodes.size())
 
  592           comb[i] = static_cast<IndexT>(i);
 
  599     permutation = permutation_best;
 
  600     dof_assigned_to_node = dof_assigned_to_node_best;
 
std::vector< IndexT > reorder(std::vector< std::map< IndexT, ValueT > > const &matrix, cuthill_mckee_tag)
Function for the calculation of a node number permutation to reduce the bandwidth of an incidence mat...
void nodes_of_strongly_connected_component(MatrixT const &matrix, std::vector< IndexT > &node_list)
Fills the provided nodelist with all nodes of the same strongly connected component as the nodes in t...
advanced_cuthill_mckee_tag(double a=0.0, vcl_size_t gmax=1)
CTOR which may take the additional parameters for the advanced algorithm. 
This file provides the forward declarations for the main types used within ViennaCL. 
T max(const T &lhs, const T &rhs)
Maximum. 
void generate_layering(MatrixT const &matrix, std::vector< std::vector< IndexT > > &layer_list)
Function to generate a node layering as a tree structure. 
void resize(size_type rows, size_type columns, bool preserve=true)
Resizes the matrix. Existing entries can optionally be preserved. 
void starting_node_param(double a)
double starting_node_param() const 
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.) 
void max_root_nodes(vcl_size_t gmax)
vcl_size_t cuthill_mckee_on_strongly_connected_component(std::vector< std::map< IndexT, ValueT > > const &matrix, std::deque< IndexT > &node_assignment_queue, std::vector< bool > &dof_assigned_to_node, std::vector< IndexT > &permutation, vcl_size_t current_dof)
Runs the Cuthill-McKee algorithm on a strongly connected component of a graph. 
vcl_size_t max_root_nodes() const 
IndexT calc_reordered_bw(std::vector< std::map< IndexT, ValueT > > const &matrix, std::vector< bool > &dof_assigned_to_node, std::vector< IndexT > const &permutation)
bool comb_inc(std::vector< IndexT > &comb, vcl_size_t n)
bool cuthill_mckee_comp_func_pair(std::pair< IndexT, IndexT > const &a, std::pair< IndexT, IndexT > const &b)
Tag for the advanced Cuthill-McKee algorithm (i.e. running the 'standard' Cuthill-McKee algorithm for...
A tag class for selecting the Cuthill-McKee algorithm for reducing the bandwidth of a sparse matrix...
bool cuthill_mckee_comp_func(std::vector< int > const &a, std::vector< int > const &b)