| 13 | |
| 14 | using namespace std; |
| 15 | template<typename MatrixType> void permutationmatrices(const MatrixType& m) |
| 16 | { |
| 17 | typedef typename MatrixType::Scalar Scalar; |
| 18 | enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime, |
| 19 | Options = MatrixType::Options }; |
| 20 | typedef PermutationMatrix<Rows> LeftPermutationType; |
| 21 | typedef Transpositions<Rows> LeftTranspositionsType; |
| 22 | typedef Matrix<int, Rows, 1> LeftPermutationVectorType; |
| 23 | typedef Map<LeftPermutationType> MapLeftPerm; |
| 24 | typedef PermutationMatrix<Cols> RightPermutationType; |
| 25 | typedef Transpositions<Cols> RightTranspositionsType; |
| 26 | typedef Matrix<int, Cols, 1> RightPermutationVectorType; |
| 27 | typedef Map<RightPermutationType> MapRightPerm; |
| 28 | |
| 29 | Index rows = m.rows(); |
| 30 | Index cols = m.cols(); |
| 31 | |
| 32 | MatrixType m_original = MatrixType::Random(rows,cols); |
| 33 | LeftPermutationVectorType lv; |
| 34 | randomPermutationVector(lv, rows); |
| 35 | LeftPermutationType lp(lv); |
| 36 | RightPermutationVectorType rv; |
| 37 | randomPermutationVector(rv, cols); |
| 38 | RightPermutationType rp(rv); |
| 39 | LeftTranspositionsType lt(lv); |
| 40 | RightTranspositionsType rt(rv); |
| 41 | MatrixType m_permuted = MatrixType::Random(rows,cols); |
| 42 | |
| 43 | VERIFY_EVALUATION_COUNT(m_permuted = lp * m_original * rp, 1); // 1 temp for sub expression "lp * m_original" |
| 44 | |
| 45 | for (int i=0; i<rows; i++) |
| 46 | for (int j=0; j<cols; j++) |
| 47 | VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j))); |
| 48 | |
| 49 | Matrix<Scalar,Rows,Rows> lm(lp); |
| 50 | Matrix<Scalar,Cols,Cols> rm(rp); |
| 51 | |
| 52 | VERIFY_IS_APPROX(m_permuted, lm*m_original*rm); |
| 53 | |
| 54 | m_permuted = m_original; |
| 55 | VERIFY_EVALUATION_COUNT(m_permuted = lp * m_permuted * rp, 1); |
| 56 | VERIFY_IS_APPROX(m_permuted, lm*m_original*rm); |
| 57 | |
| 58 | LeftPermutationType lpi; |
| 59 | lpi = lp.inverse(); |
| 60 | VERIFY_IS_APPROX(lpi*m_permuted,lp.inverse()*m_permuted); |
| 61 | |
| 62 | VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original); |
| 63 | VERIFY_IS_APPROX(lv.asPermutation().inverse()*m_permuted*rv.asPermutation().inverse(), m_original); |
| 64 | VERIFY_IS_APPROX(MapLeftPerm(lv.data(),lv.size()).inverse()*m_permuted*MapRightPerm(rv.data(),rv.size()).inverse(), m_original); |
| 65 | |
| 66 | VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity()); |
| 67 | VERIFY((lv.asPermutation()*lv.asPermutation().inverse()).toDenseMatrix().isIdentity()); |
| 68 | VERIFY((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv.data(),lv.size()).inverse()).toDenseMatrix().isIdentity()); |
| 69 | |
| 70 | LeftPermutationVectorType lv2; |
| 71 | randomPermutationVector(lv2, rows); |
| 72 | LeftPermutationType lp2(lv2); |
no test coverage detected