// this is multiplication in the matrix sense template <typename T, typename X> void permutation_matrix<T, X>::multiply_by_permutation_from_right(permutation_matrix<T, X> & p) { auto clone = clone_m_permutation(); lean_assert(p.size() == size()); unsigned i = size(); while (i-- > 0) { set_val(i, p[clone[i]]); // we have m(P)*m(Q) = m(QP), where m is the matrix of the permutation } delete [] clone; }
inline unsigned number_of_inversions(permutation_matrix<T, X> & p) { unsigned ret = 0; unsigned n = p.size(); for (unsigned i = 0; i < n; i++) { for (unsigned j = i + 1; j < n; j++) { if (p[i] > p[j]) { ret++; } } } return ret; }
void swap_columns(permutation_matrix const& P, matrix_expression<M>& A) { for(std::size_t i = 0; i != P.size(); ++i) swap_columns(A(),i,P(i)); }
void swap_rows_inverted(permutation_matrix const& P, matrix_expression<M>& A) { for(std::size_t i = P.size(); i != 0; --i) { swap_rows(A(),i-1,P(i-1)); } }
void swap_rows(permutation_matrix const& P, vector_expression<V>& v) { for (std::size_t i = 0; i != P.size(); ++ i) std::swap(v()(i),v()(P(i))); }