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 <Eigen/SVD>
00027
00028 template<typename MatrixType> void svd(const MatrixType& m)
00029 {
00030
00031
00032
00033 int rows = m.rows();
00034 int cols = m.cols();
00035
00036 typedef typename MatrixType::Scalar Scalar;
00037 typedef typename NumTraits<Scalar>::Real RealScalar;
00038 MatrixType a = MatrixType::Random(rows,cols);
00039 Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> b =
00040 Matrix<Scalar, MatrixType::RowsAtCompileTime, 1>::Random(rows,1);
00041 Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> x(cols,1), x2(cols,1);
00042
00043 RealScalar largerEps = test_precision<RealScalar>();
00044 if (ei_is_same_type<RealScalar,float>::ret)
00045 largerEps = 1e-3f;
00046
00047 {
00048 SVD<MatrixType> svd(a);
00049 MatrixType sigma = MatrixType::Zero(rows,cols);
00050 MatrixType matU = MatrixType::Zero(rows,rows);
00051 sigma.block(0,0,cols,cols) = svd.singularValues().asDiagonal();
00052 matU.block(0,0,rows,cols) = svd.matrixU();
00053 VERIFY_IS_APPROX(a, matU * sigma * svd.matrixV().transpose());
00054 }
00055
00056
00057 if (rows==cols)
00058 {
00059 if (ei_is_same_type<RealScalar,float>::ret)
00060 {
00061 MatrixType a1 = MatrixType::Random(rows,cols);
00062 a += a * a.adjoint() + a1 * a1.adjoint();
00063 }
00064 SVD<MatrixType> svd(a);
00065 svd.solve(b, &x);
00066 VERIFY_IS_APPROX(a * x,b);
00067 }
00068
00069
00070 if(rows==cols)
00071 {
00072 SVD<MatrixType> svd(a);
00073 MatrixType unitary, positive;
00074 svd.computeUnitaryPositive(&unitary, &positive);
00075 VERIFY_IS_APPROX(unitary * unitary.adjoint(), MatrixType::Identity(unitary.rows(),unitary.rows()));
00076 VERIFY_IS_APPROX(positive, positive.adjoint());
00077 for(int i = 0; i < rows; i++) VERIFY(positive.diagonal()[i] >= 0);
00078 VERIFY_IS_APPROX(unitary*positive, a);
00079
00080 svd.computePositiveUnitary(&positive, &unitary);
00081 VERIFY_IS_APPROX(unitary * unitary.adjoint(), MatrixType::Identity(unitary.rows(),unitary.rows()));
00082 VERIFY_IS_APPROX(positive, positive.adjoint());
00083 for(int i = 0; i < rows; i++) VERIFY(positive.diagonal()[i] >= 0);
00084 VERIFY_IS_APPROX(positive*unitary, a);
00085 }
00086 }
00087
00088 void test_eigen2_svd()
00089 {
00090 for(int i = 0; i < g_repeat; i++) {
00091 CALL_SUBTEST_1( svd(Matrix3f()) );
00092 CALL_SUBTEST_2( svd(Matrix4d()) );
00093 CALL_SUBTEST_3( svd(MatrixXf(7,7)) );
00094 CALL_SUBTEST_4( svd(MatrixXd(14,7)) );
00095
00096
00097
00098 SVD<MatrixXf> s;
00099 MatrixXf m = MatrixXf::Random(10,1);
00100 s.compute(m);
00101 }
00102 }