CMR  1.3.0
partition.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 
5 #include "matrix_transposed.hpp"
6 #include "matrix_permuted.hpp"
8 
9 namespace tu
10 {
11 
12  typedef std::pair <size_t, size_t> size_pair_t;
13 
14  namespace detail
15  {
16 
27  template <typename MatrixType, typename VectorType>
28  inline void copy_partial_row(const MatrixType& matrix, VectorType& vector, size_t row, size_t first_column, size_t beyond_column)
29  {
30  size_t j = 0;
31  for (size_t i = first_column; i < beyond_column; ++i, ++j)
32  {
33  vector[j] = matrix(row, i);
34  }
35  }
36 
47  template <typename MatrixType, typename VectorType>
48  inline void copy_partial_column(const MatrixType& matrix, VectorType& vector, size_t column, size_t first_row, size_t beyond_row)
49  {
50  copy_partial_row(matrix_transposed <const MatrixType> (matrix), vector, column, first_row, beyond_row);
51  }
52  }
53 
59  {
61  };
62 
75  template <typename MatrixType>
76  inline rank_distribution partition(matrix_permuted <const MatrixType>& matrix, size_t& top_left_height, size_t& top_left_width,
77  size_t& bottom_right_height, size_t& bottom_right_width)
78  {
79  const size_t height = matrix.size1();
80  size_t free_rows_first = top_left_height;
81  size_t free_rows_beyond = height - bottom_right_height;
82 
83  const size_t width = matrix.size2();
84  size_t free_columns_first = top_left_width;
85  size_t free_columns_beyond = width - bottom_right_width;
86 
88 
90  bool changed = true;
91  while (changed)
92  {
94  binary_linear_space bottom_left_row_space(top_left_width);
95  std::vector <bool> bottom_left_row(top_left_width);
96 
97  for (size_t row = free_rows_beyond; row < height; ++row)
98  {
99  detail::copy_partial_row(matrix, bottom_left_row, row, 0, top_left_width);
100  bottom_left_row_space.insert_checked(bottom_left_row);
101  }
102 
104  binary_linear_space top_right_row_space(bottom_right_width);
105  std::vector <bool> top_right_row(bottom_right_width);
106 
107  for (size_t row = 0; row < top_left_height; ++row)
108  {
109  detail::copy_partial_row(matrix, top_right_row, row, free_columns_beyond, width);
110  top_right_row_space.insert_checked(top_right_row);
111  }
112 
114  if (bottom_left_row_space.dimension() + top_right_row_space.dimension() != 2)
115  return RANK_TOO_HIGH;
116 
118  changed = false;
119  for (size_t row = free_rows_first; row < free_rows_beyond; ++row)
120  {
121  detail::copy_partial_row(matrix, top_right_row, row, free_columns_beyond, width);
122  if (!top_right_row_space.is_spanned(top_right_row))
123  {
124  detail::copy_partial_row(matrix, bottom_left_row, row, 0, top_left_width);
125  if (!bottom_left_row_space.is_spanned(bottom_left_row))
126  return RANK_TOO_HIGH;
127 
128  ++bottom_right_height;
129  --free_rows_beyond;
130  matrix_permute1(matrix, row, free_rows_beyond);
131  --row;
132  changed = true;
133  }
134  }
135 
137  binary_linear_space top_right_column_space(top_left_height);
138  std::vector <bool> top_right_column(top_left_height);
139 
140  for (size_t column = free_columns_beyond; column < width; ++column)
141  {
142  detail::copy_partial_column(matrix, top_right_column, column, 0, top_left_height);
143  top_right_column_space.insert_checked(top_right_column);
144  }
145 
147  binary_linear_space bottom_left_column_space(bottom_right_height);
148  std::vector <bool> bottom_left_column(bottom_right_height);
149 
150  for (size_t column = 0; column < top_left_width; ++column)
151  {
152  detail::copy_partial_column(matrix, bottom_left_column, column, free_rows_beyond, height);
153  bottom_left_column_space.insert_checked(bottom_left_column);
154  }
155 
157  assert (bottom_left_row_space.dimension () + top_right_row_space.dimension () == 2);
158 
160  for (size_t column = free_columns_first; column < free_columns_beyond; ++column)
161  {
162  detail::copy_partial_column(matrix, bottom_left_column, column, free_rows_beyond, height);
163  if (!bottom_left_column_space.is_spanned(bottom_left_column))
164  {
165  detail::copy_partial_column(matrix, top_right_column, column, 0, top_left_height);
166  if (!top_right_column_space.is_spanned(top_right_column))
167  return RANK_TOO_HIGH;
168 
169  ++bottom_right_width;
170  --free_columns_beyond;
171  matrix_permute2(matrix, column, free_columns_beyond);
172  --column;
173  changed = true;
174  }
175  }
176 
177  switch (bottom_left_column_space.dimension())
178  {
179  case 2:
180  result = RANK_BL_2_TR_0;
181  break;
182  case 1:
183  result = RANK_BL_1_TR_1;
184  break;
185  case 0:
186  result = RANK_BL_0_TR_2;
187  break;
188  default:
189  assert (false);
190  }
191  }
192 
193  top_left_height = height - bottom_right_height;
194  top_left_width = width - bottom_right_width;
195 
196  return result;
197  }
198 
199 } /* namespace tu */
Definition: binary_linear_space.hpp:16
bool insert_checked(const vector_type &vector)
Definition: binary_linear_space.hpp:96
bool is_spanned(const vector_type &vector) const
Definition: binary_linear_space.hpp:162
size_t dimension() const
Definition: binary_linear_space.hpp:83
Definition: matrix_permuted.hpp:17
size_type size2() const
Definition: matrix_permuted.hpp:65
size_type size1() const
Definition: matrix_permuted.hpp:56
Definition: matrix_transposed.hpp:47
void copy_partial_column(const MatrixType &matrix, VectorType &vector, size_t column, size_t first_row, size_t beyond_row)
Definition: partition.hpp:48
void copy_partial_row(const MatrixType &matrix, VectorType &vector, size_t row, size_t first_column, size_t beyond_column)
Definition: partition.hpp:28
Definition: algorithm.hpp:14
std::pair< size_t, size_t > size_pair_t
Definition: partition.hpp:12
rank_distribution
Definition: partition.hpp:59
@ RANK_TOO_HIGH
Definition: partition.hpp:60
@ RANK_BL_1_TR_1
Definition: partition.hpp:60
@ RANK_BL_2_TR_0
Definition: partition.hpp:60
@ RANK_BL_0_TR_2
Definition: partition.hpp:60
void matrix_permute1(MatrixType &matrix, size_t index1, size_t index2)
Definition: matrix.hpp:1723
rank_distribution partition(matrix_permuted< const MatrixType > &matrix, size_t &top_left_height, size_t &top_left_width, size_t &bottom_right_height, size_t &bottom_right_width)
Definition: partition.hpp:76
void matrix_permute2(MatrixType &matrix, size_t index1, size_t index2)
Definition: matrix.hpp:1740