00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "main.h"
00026
00027 template<typename PermutationVectorType>
00028 void randomPermutationVector(PermutationVectorType& v, typename PermutationVectorType::Index size)
00029 {
00030 typedef typename PermutationVectorType::Index Index;
00031 typedef typename PermutationVectorType::Scalar Scalar;
00032 v.resize(size);
00033 for(Index i = 0; i < size; ++i) v(i) = Scalar(i);
00034 if(size == 1) return;
00035 for(Index n = 0; n < 3 * size; ++n)
00036 {
00037 Index i = internal::random<Index>(0, size-1);
00038 Index j;
00039 do j = internal::random<Index>(0, size-1); while(j==i);
00040 std::swap(v(i), v(j));
00041 }
00042 }
00043
00044 using namespace std;
00045 template<typename MatrixType> void permutationmatrices(const MatrixType& m)
00046 {
00047 typedef typename MatrixType::Index Index;
00048 typedef typename MatrixType::Scalar Scalar;
00049 typedef typename MatrixType::RealScalar RealScalar;
00050 enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime,
00051 Options = MatrixType::Options };
00052 typedef PermutationMatrix<Rows> LeftPermutationType;
00053 typedef Matrix<int, Rows, 1> LeftPermutationVectorType;
00054 typedef Map<LeftPermutationType> MapLeftPerm;
00055 typedef PermutationMatrix<Cols> RightPermutationType;
00056 typedef Matrix<int, Cols, 1> RightPermutationVectorType;
00057 typedef Map<RightPermutationType> MapRightPerm;
00058
00059 Index rows = m.rows();
00060 Index cols = m.cols();
00061
00062 MatrixType m_original = MatrixType::Random(rows,cols);
00063 LeftPermutationVectorType lv;
00064 randomPermutationVector(lv, rows);
00065 LeftPermutationType lp(lv);
00066 RightPermutationVectorType rv;
00067 randomPermutationVector(rv, cols);
00068 RightPermutationType rp(rv);
00069 MatrixType m_permuted = lp * m_original * rp;
00070
00071 for (int i=0; i<rows; i++)
00072 for (int j=0; j<cols; j++)
00073 VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j)));
00074
00075 Matrix<Scalar,Rows,Rows> lm(lp);
00076 Matrix<Scalar,Cols,Cols> rm(rp);
00077
00078 VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);
00079
00080 VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
00081 VERIFY_IS_APPROX(lv.asPermutation().inverse()*m_permuted*rv.asPermutation().inverse(), m_original);
00082 VERIFY_IS_APPROX(MapLeftPerm(lv.data(),lv.size()).inverse()*m_permuted*MapRightPerm(rv.data(),rv.size()).inverse(), m_original);
00083
00084 VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
00085 VERIFY((lv.asPermutation()*lv.asPermutation().inverse()).toDenseMatrix().isIdentity());
00086 VERIFY((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv.data(),lv.size()).inverse()).toDenseMatrix().isIdentity());
00087
00088 LeftPermutationVectorType lv2;
00089 randomPermutationVector(lv2, rows);
00090 LeftPermutationType lp2(lv2);
00091 Matrix<Scalar,Rows,Rows> lm2(lp2);
00092 VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2);
00093 VERIFY_IS_APPROX((lv.asPermutation()*lv2.asPermutation()).toDenseMatrix().template cast<Scalar>(), lm*lm2);
00094 VERIFY_IS_APPROX((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv2.data(),lv2.size())).toDenseMatrix().template cast<Scalar>(), lm*lm2);
00095
00096 LeftPermutationType identityp;
00097 identityp.setIdentity(rows);
00098 VERIFY_IS_APPROX(m_original, identityp*m_original);
00099
00100
00101 m_permuted = m_original;
00102 m_permuted = lp.inverse() * m_permuted;
00103 VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);
00104
00105 m_permuted = m_original;
00106 m_permuted = m_permuted * rp.inverse();
00107 VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());
00108
00109 m_permuted = m_original;
00110 m_permuted = lp * m_permuted;
00111 VERIFY_IS_APPROX(m_permuted, lp*m_original);
00112
00113 m_permuted = m_original;
00114 m_permuted = m_permuted * rp;
00115 VERIFY_IS_APPROX(m_permuted, m_original*rp);
00116
00117 if(rows>1 && cols>1)
00118 {
00119 lp2 = lp;
00120 Index i = internal::random<Index>(0, rows-1);
00121 Index j;
00122 do j = internal::random<Index>(0, rows-1); while(j==i);
00123 lp2.applyTranspositionOnTheLeft(i, j);
00124 lm = lp;
00125 lm.row(i).swap(lm.row(j));
00126 VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>());
00127
00128 RightPermutationType rp2 = rp;
00129 i = internal::random<Index>(0, cols-1);
00130 do j = internal::random<Index>(0, cols-1); while(j==i);
00131 rp2.applyTranspositionOnTheRight(i, j);
00132 rm = rp;
00133 rm.col(i).swap(rm.col(j));
00134 VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>());
00135 }
00136 }
00137
00138 void test_permutationmatrices()
00139 {
00140 for(int i = 0; i < g_repeat; i++) {
00141 CALL_SUBTEST_1( permutationmatrices(Matrix<float, 1, 1>()) );
00142 CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );
00143 CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );
00144 CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );
00145 CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );
00146 CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );
00147 CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );
00148 }
00149 }