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