permutation.hpp
Go to the documentation of this file.
1 /*!
2  * \brief Permutations of vectors and matrices
3  *
4  * \author O. Krause
5  * \date 2013
6  *
7  *
8  * \par Copyright 1995-2015 Shark Development Team
9  *
10  * <BR><HR>
11  * This file is part of Shark.
12  * <http://image.diku.dk/shark/>
13  *
14  * Shark is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License as published
16  * by the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * Shark is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28 #ifndef REMORA_PERMUTATION_HPP
29 #define REMORA_PERMUTATION_HPP
30 
31 #include "vector.hpp"
32 
33 namespace remora {
34 struct permutation_matrix:public vector<int> {
35  // Construction and destruction
36  explicit permutation_matrix(size_type size):vector<int> (size){
37  for (int i = 0; i < (int)size; ++ i)
38  (*this)(i) = i;
39  }
40 
41  // Assignment
42  permutation_matrix &operator = (permutation_matrix const& m) {
43  vector<int>::operator = (m);
44  return *this;
45  }
46 };
47 
48 ///\brief implements row pivoting at matrix A using permutation P
49 ///
50 ///by convention it is not allowed that P()(i) < i.
51 template<class VecP, class M>
52 void swap_rows(vector_expression<VecP, cpu_tag> const& P, matrix_expression<M, cpu_tag>& A){
53  for (std::size_t i = 0; i != P().size(); ++ i)
54  A().swap_rows(i,P()(i));
55 }
56 
57 ///\brief implements column pivoting of vector A using permutation P
58 ///
59 ///by convention it is not allowed that P()(i) < i.
60 template<class VecP, class V>
61 void swap_rows(vector_expression<VecP, cpu_tag> const& P, vector_expression<V, cpu_tag>& v){
62  for (std::size_t i = 0; i != P().size(); ++ i)
63  std::swap(v()(i),v()(P()(i)));
64 }
65 
66 ///\brief implements the inverse row pivoting of vector v using permutation P
67 ///
68 ///This is the inverse operation to swap_rows.
69 template<class VecP, class V>
70 void swap_rows_inverted(vector_expression<VecP, cpu_tag> const& P, vector_expression<V, cpu_tag>& v){
71  for(std::size_t i = P().size(); i != 0; --i){
72  std::size_t k = i-1;
73  if(k != std::size_t(P()(k))){
74  using std::swap;
75  swap(v()(k),v()(P()(k)));
76  }
77  }
78 }
79 
80 ///\brief implements column pivoting at matrix A using permutation P
81 ///
82 ///by convention it is not allowed that P(i) < i.
83 template<class VecP, class M>
84 void swap_columns(vector_expression<VecP, cpu_tag> const& P, matrix_expression<M, cpu_tag>& A){
85  for(std::size_t i = 0; i != P().size(); ++i)
86  A().swap_columns(i,P()(i));
87 }
88 
89 ///\brief implements the inverse row pivoting at matrix A using permutation P
90 ///
91 ///This is the inverse operation to swap_rows.
92 template<class VecP, class M>
93 void swap_rows_inverted(vector_expression<VecP, cpu_tag> const& P, matrix_expression<M, cpu_tag>& A){
94  for(std::size_t i = P().size(); i != 0; --i){
95  A().swap_rows(i-1,P()(i-1));
96  }
97 }
98 
99 ///\brief implements the inverse column pivoting at matrix A using permutation P
100 ///
101 ///This is the inverse operation to swap_columns.
102 template<class VecP, class M>
103 void swap_columns_inverted(vector_expression<VecP, cpu_tag> const& P, matrix_expression<M, cpu_tag>& A){
104  for(std::size_t i = P().size(); i != 0; --i){
105  A().swap_columns(i-1,P()(i-1));
106  }
107 }
108 
109 ///\brief Implements full pivoting at matrix A using permutation P
110 ///
111 ///full pivoting does swap rows and columns such that the diagonal element
112 ///A_ii is then at position A_P(i)P(i)
113 ///by convention it is not allowed that P(i) < i.
114 template<class VecP, class M>
115 void swap_full(vector_expression<VecP, cpu_tag> const& P, matrix_expression<M, cpu_tag>& A){
116  for(std::size_t i = 0; i != P().size(); ++i){
117  A().swap_rows(i,P()(i));
118  A().swap_columns(i,P()(i));
119  }
120 }
121 ///\brief implements the inverse full pivoting at matrix A using permutation P
122 ///
123 ///This is the inverse operation to swap_full.
124 template<class VecP, class M>
125 void swap_full_inverted(vector_expression<VecP, cpu_tag> const& P, matrix_expression<M, cpu_tag>& A){
126  for(std::size_t i = P().size(); i != 0; --i){
127  A().swap_rows(i-1,P()(i-1));
128  A().swap_columns(i-1,P()(i-1));
129  }
130 }
131 
132 }
133 #endif