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 "dense.hpp"
32
33namespace remora {
34struct 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.
51template<class VecP, class M>
52void 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.
60template<class VecP, class V>
61void 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.
69template<class VecP, class V>
70void 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.
83template<class VecP, class M>
84void 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.
92template<class VecP, class M>
93void 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.
102template<class VecP, class M>
103void 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.
114template<class VecP, class M>
115void 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.
124template<class VecP, class M>
125void 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