28#ifndef REMORA_PERMUTATION_HPP 
   29#define REMORA_PERMUTATION_HPP 
   34struct permutation_matrix:
public vector<int> {
 
   36    explicit permutation_matrix(size_type size):vector<int> (size){
 
   37        for (
int i = 0; i < (int)size; ++ i)
 
   42    permutation_matrix &operator = (permutation_matrix 
const& m) {
 
   43        vector<int>::operator = (m);
 
   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));
 
   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)));
 
   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){
 
   73        if(k != std::size_t(P()(k))){
 
   75            swap(v()(k),v()(P()(k)));
 
   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));
 
   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));
 
  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));
 
  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));
 
  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));