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 #include <Eigen/QR>
00027
00028 template<typename MatrixType> void qr(const MatrixType& m)
00029 {
00030 typedef typename MatrixType::Index Index;
00031
00032 Index rows = m.rows();
00033 Index cols = m.cols();
00034
00035 typedef typename MatrixType::Scalar Scalar;
00036 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
00037 typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
00038
00039 MatrixType a = MatrixType::Random(rows,cols);
00040 HouseholderQR<MatrixType> qrOfA(a);
00041
00042 MatrixQType q = qrOfA.householderQ();
00043 VERIFY_IS_UNITARY(q);
00044
00045 MatrixType r = qrOfA.matrixQR().template triangularView<Upper>();
00046 VERIFY_IS_APPROX(a, qrOfA.householderQ() * r);
00047 }
00048
00049 template<typename MatrixType, int Cols2> void qr_fixedsize()
00050 {
00051 enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
00052 typedef typename MatrixType::Scalar Scalar;
00053 Matrix<Scalar,Rows,Cols> m1 = Matrix<Scalar,Rows,Cols>::Random();
00054 HouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);
00055
00056 Matrix<Scalar,Rows,Cols> r = qr.matrixQR();
00057
00058 for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
00059
00060 VERIFY_IS_APPROX(m1, qr.householderQ() * r);
00061
00062 Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
00063 Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
00064 m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
00065 m2 = qr.solve(m3);
00066 VERIFY_IS_APPROX(m3, m1*m2);
00067 }
00068
00069 template<typename MatrixType> void qr_invertible()
00070 {
00071 typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
00072 typedef typename MatrixType::Scalar Scalar;
00073
00074 int size = internal::random<int>(10,50);
00075
00076 MatrixType m1(size, size), m2(size, size), m3(size, size);
00077 m1 = MatrixType::Random(size,size);
00078
00079 if (internal::is_same<RealScalar,float>::value)
00080 {
00081
00082 MatrixType a = MatrixType::Random(size,size*2);
00083 m1 += a * a.adjoint();
00084 }
00085
00086 HouseholderQR<MatrixType> qr(m1);
00087 m3 = MatrixType::Random(size,size);
00088 m2 = qr.solve(m3);
00089 VERIFY_IS_APPROX(m3, m1*m2);
00090
00091
00092 m1.setZero();
00093 for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
00094 RealScalar absdet = internal::abs(m1.diagonal().prod());
00095 m3 = qr.householderQ();
00096 m1 = m3 * m1 * m3;
00097 qr.compute(m1);
00098 VERIFY_IS_APPROX(absdet, qr.absDeterminant());
00099 VERIFY_IS_APPROX(internal::log(absdet), qr.logAbsDeterminant());
00100 }
00101
00102 template<typename MatrixType> void qr_verify_assert()
00103 {
00104 MatrixType tmp;
00105
00106 HouseholderQR<MatrixType> qr;
00107 VERIFY_RAISES_ASSERT(qr.matrixQR())
00108 VERIFY_RAISES_ASSERT(qr.solve(tmp))
00109 VERIFY_RAISES_ASSERT(qr.householderQ())
00110 VERIFY_RAISES_ASSERT(qr.absDeterminant())
00111 VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
00112 }
00113
00114 void test_qr()
00115 {
00116 for(int i = 0; i < g_repeat; i++) {
00117 CALL_SUBTEST_1( qr(MatrixXf(internal::random<int>(1,200),internal::random<int>(1,200))) );
00118 CALL_SUBTEST_2( qr(MatrixXcd(internal::random<int>(1,200),internal::random<int>(1,200))) );
00119 CALL_SUBTEST_3(( qr_fixedsize<Matrix<float,3,4>, 2 >() ));
00120 CALL_SUBTEST_4(( qr_fixedsize<Matrix<double,6,2>, 4 >() ));
00121 CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,2,5>, 7 >() ));
00122 CALL_SUBTEST_11( qr(Matrix<float,1,1>()) );
00123 }
00124
00125 for(int i = 0; i < g_repeat; i++) {
00126 CALL_SUBTEST_1( qr_invertible<MatrixXf>() );
00127 CALL_SUBTEST_6( qr_invertible<MatrixXd>() );
00128 CALL_SUBTEST_7( qr_invertible<MatrixXcf>() );
00129 CALL_SUBTEST_8( qr_invertible<MatrixXcd>() );
00130 }
00131
00132 CALL_SUBTEST_9(qr_verify_assert<Matrix3f>());
00133 CALL_SUBTEST_10(qr_verify_assert<Matrix3d>());
00134 CALL_SUBTEST_1(qr_verify_assert<MatrixXf>());
00135 CALL_SUBTEST_6(qr_verify_assert<MatrixXd>());
00136 CALL_SUBTEST_7(qr_verify_assert<MatrixXcf>());
00137 CALL_SUBTEST_8(qr_verify_assert<MatrixXcd>());
00138
00139
00140 CALL_SUBTEST_12(HouseholderQR<MatrixXf>(10, 20));
00141 }