Go to the documentation of this file.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 <limits>
00027 #include <Eigen/Eigenvalues>
00028
00029 template<typename MatrixType> void verifyIsQuasiTriangular(const MatrixType& T)
00030 {
00031 typedef typename MatrixType::Index Index;
00032
00033 const Index size = T.cols();
00034 typedef typename MatrixType::Scalar Scalar;
00035
00036
00037 for(int row = 2; row < size; ++row) {
00038 for(int col = 0; col < row - 1; ++col) {
00039 VERIFY(T(row,col) == Scalar(0));
00040 }
00041 }
00042
00043
00044
00045 for(int row = 1; row < size; ++row) {
00046 if (T(row,row-1) != Scalar(0)) {
00047 VERIFY(row == size-1 || T(row+1,row) == 0);
00048 Scalar tr = T(row-1,row-1) + T(row,row);
00049 Scalar det = T(row-1,row-1) * T(row,row) - T(row-1,row) * T(row,row-1);
00050 VERIFY(4 * det > tr * tr);
00051 }
00052 }
00053 }
00054
00055 template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTime)
00056 {
00057
00058 for(int counter = 0; counter < g_repeat; ++counter) {
00059 MatrixType A = MatrixType::Random(size, size);
00060 RealSchur<MatrixType> schurOfA(A);
00061 VERIFY_IS_EQUAL(schurOfA.info(), Success);
00062 MatrixType U = schurOfA.matrixU();
00063 MatrixType T = schurOfA.matrixT();
00064 verifyIsQuasiTriangular(T);
00065 VERIFY_IS_APPROX(A, U * T * U.transpose());
00066 }
00067
00068
00069 RealSchur<MatrixType> rsUninitialized;
00070 VERIFY_RAISES_ASSERT(rsUninitialized.matrixT());
00071 VERIFY_RAISES_ASSERT(rsUninitialized.matrixU());
00072 VERIFY_RAISES_ASSERT(rsUninitialized.info());
00073
00074
00075 MatrixType A = MatrixType::Random(size, size);
00076 RealSchur<MatrixType> rs1;
00077 rs1.compute(A);
00078 RealSchur<MatrixType> rs2(A);
00079 VERIFY_IS_EQUAL(rs1.info(), Success);
00080 VERIFY_IS_EQUAL(rs2.info(), Success);
00081 VERIFY_IS_EQUAL(rs1.matrixT(), rs2.matrixT());
00082 VERIFY_IS_EQUAL(rs1.matrixU(), rs2.matrixU());
00083
00084
00085 RealSchur<MatrixType> rsOnlyT(A, false);
00086 VERIFY_IS_EQUAL(rsOnlyT.info(), Success);
00087 VERIFY_IS_EQUAL(rs1.matrixT(), rsOnlyT.matrixT());
00088 VERIFY_RAISES_ASSERT(rsOnlyT.matrixU());
00089
00090 if (size > 2)
00091 {
00092
00093 A(0,0) = std::numeric_limits<typename MatrixType::Scalar>::quiet_NaN();
00094 RealSchur<MatrixType> rsNaN(A);
00095 VERIFY_IS_EQUAL(rsNaN.info(), NoConvergence);
00096 }
00097 }
00098
00099 void test_schur_real()
00100 {
00101 CALL_SUBTEST_1(( schur<Matrix4f>() ));
00102 CALL_SUBTEST_2(( schur<MatrixXd>(internal::random<int>(1,50)) ));
00103 CALL_SUBTEST_3(( schur<Matrix<float, 1, 1> >() ));
00104 CALL_SUBTEST_4(( schur<Matrix<double, 3, 3, Eigen::RowMajor> >() ));
00105
00106
00107 CALL_SUBTEST_5(RealSchur<MatrixXf>(10));
00108 }