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/Array>
00027 #include <Eigen/QR>
00028
00029 template<typename Derived1, typename Derived2>
00030 bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = precision<typename Derived1::RealScalar>())
00031 {
00032 return !((m1-m2).cwise().abs2().maxCoeff() < epsilon * epsilon
00033 * std::max(m1.cwise().abs2().maxCoeff(), m2.cwise().abs2().maxCoeff()));
00034 }
00035
00036 template<typename MatrixType> void product(const MatrixType& m)
00037 {
00038
00039
00040
00041
00042 typedef typename MatrixType::Scalar Scalar;
00043 typedef typename NumTraits<Scalar>::FloatingPoint FloatingPoint;
00044 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> RowVectorType;
00045 typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> ColVectorType;
00046 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RowSquareMatrixType;
00047 typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> ColSquareMatrixType;
00048 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,
00049 MatrixType::Options^RowMajor> OtherMajorMatrixType;
00050
00051 int rows = m.rows();
00052 int cols = m.cols();
00053
00054
00055
00056 MatrixType m1 = MatrixType::Random(rows, cols),
00057 m2 = MatrixType::Random(rows, cols),
00058 m3(rows, cols),
00059 mzero = MatrixType::Zero(rows, cols);
00060 RowSquareMatrixType
00061 identity = RowSquareMatrixType::Identity(rows, rows),
00062 square = RowSquareMatrixType::Random(rows, rows),
00063 res = RowSquareMatrixType::Random(rows, rows);
00064 ColSquareMatrixType
00065 square2 = ColSquareMatrixType::Random(cols, cols),
00066 res2 = ColSquareMatrixType::Random(cols, cols);
00067 RowVectorType v1 = RowVectorType::Random(rows),
00068 v2 = RowVectorType::Random(rows),
00069 vzero = RowVectorType::Zero(rows);
00070 ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols);
00071 OtherMajorMatrixType tm1 = m1;
00072
00073 Scalar s1 = ei_random<Scalar>();
00074
00075 int r = ei_random<int>(0, rows-1),
00076 c = ei_random<int>(0, cols-1);
00077
00078
00079
00080
00081 VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2));
00082 m3 = m1;
00083 m3 *= m1.transpose() * m2;
00084 VERIFY_IS_APPROX(m3, m1 * (m1.transpose()*m2));
00085 VERIFY_IS_APPROX(m3, m1.lazy() * (m1.transpose()*m2));
00086
00087
00088 VERIFY_IS_APPROX(square*(m1 + m2), square*m1+square*m2);
00089 VERIFY_IS_APPROX(square*(m1 - m2), square*m1-square*m2);
00090
00091
00092 VERIFY_IS_APPROX(s1*(square*m1), (s1*square)*m1);
00093 VERIFY_IS_APPROX(s1*(square*m1), square*(m1*s1));
00094
00095
00096 s1 += (square.lazy() * m1)(r,c);
00097
00098
00099 VERIFY_IS_APPROX(v1, identity*v1);
00100 VERIFY_IS_APPROX(v1.transpose(), v1.transpose() * identity);
00101
00102 VERIFY_IS_APPROX(MatrixType::Identity(rows, cols)(r,c), static_cast<Scalar>(r==c));
00103
00104 if (rows!=cols)
00105 VERIFY_RAISES_ASSERT(m3 = m1*m1);
00106
00107
00108
00109 if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1)
00110 {
00111 VERIFY(areNotApprox(m1.transpose()*m2,m2.transpose()*m1));
00112 }
00113
00114
00115 res = square;
00116 res += (m1 * m2.transpose()).lazy();
00117 VERIFY_IS_APPROX(res, square + m1 * m2.transpose());
00118 if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1)
00119 {
00120 VERIFY(areNotApprox(res,square + m2 * m1.transpose()));
00121 }
00122 vcres = vc2;
00123 vcres += (m1.transpose() * v1).lazy();
00124 VERIFY_IS_APPROX(vcres, vc2 + m1.transpose() * v1);
00125 tm1 = m1;
00126 VERIFY_IS_APPROX(tm1.transpose() * v1, m1.transpose() * v1);
00127 VERIFY_IS_APPROX(v1.transpose() * tm1, v1.transpose() * m1);
00128
00129
00130 for (int i=0; i<rows; ++i)
00131 res.row(i) = m1.row(i) * m2.transpose();
00132 VERIFY_IS_APPROX(res, m1 * m2.transpose());
00133
00134 for (int i=0; i<rows; ++i)
00135 res.col(i) = m1 * m2.transpose().col(i);
00136 VERIFY_IS_APPROX(res, m1 * m2.transpose());
00137
00138 res2 = square2;
00139 res2 += (m1.transpose() * m2).lazy();
00140 VERIFY_IS_APPROX(res2, square2 + m1.transpose() * m2);
00141
00142 if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1)
00143 {
00144 VERIFY(areNotApprox(res2,square2 + m2.transpose() * m1));
00145 }
00146 }
00147