permutationmatrices.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
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   // check inplace permutations
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 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:06