template<typename MatrixType> void determinant(const MatrixType& m) { /* this test covers the following files: Determinant.h */ typedef typename MatrixType::Index Index; Index size = m.rows(); MatrixType m1(size, size), m2(size, size); m1.setRandom(); m2.setRandom(); typedef typename MatrixType::Scalar Scalar; Scalar x = ei_random<Scalar>(); VERIFY_IS_APPROX(MatrixType::Identity(size, size).determinant(), Scalar(1)); VERIFY_IS_APPROX((m1*m2).eval().determinant(), m1.determinant() * m2.determinant()); if(size==1) return; Index i = ei_random<Index>(0, size-1); Index j; do { j = ei_random<Index>(0, size-1); } while(j==i); m2 = m1; m2.row(i).swap(m2.row(j)); VERIFY_IS_APPROX(m2.determinant(), -m1.determinant()); m2 = m1; m2.col(i).swap(m2.col(j)); VERIFY_IS_APPROX(m2.determinant(), -m1.determinant()); VERIFY_IS_APPROX(m2.determinant(), m2.transpose().determinant()); VERIFY_IS_APPROX(ei_conj(m2.determinant()), m2.adjoint().determinant()); m2 = m1; m2.row(i) += x*m2.row(j); VERIFY_IS_APPROX(m2.determinant(), m1.determinant()); m2 = m1; m2.row(i) *= x; VERIFY_IS_APPROX(m2.determinant(), m1.determinant() * x); // check empty matrix VERIFY_IS_APPROX(m2.block(0,0,0,0).determinant(), Scalar(1)); }
template<typename Scalar> void trmm(int size,int /*othersize*/) { typedef typename NumTraits<Scalar>::Real RealScalar; typedef Matrix<Scalar,Dynamic,Dynamic,ColMajor> MatrixColMaj; typedef Matrix<Scalar,Dynamic,Dynamic,RowMajor> MatrixRowMaj; DenseIndex rows = size; DenseIndex cols = ei_random<DenseIndex>(1,size); MatrixColMaj triV(rows,cols), triH(cols,rows), upTri(cols,rows), loTri(rows,cols), unitUpTri(cols,rows), unitLoTri(rows,cols), strictlyUpTri(cols,rows), strictlyLoTri(rows,cols); MatrixColMaj ge1(rows,cols), ge2(cols,rows), ge3; MatrixRowMaj rge3; Scalar s1 = ei_random<Scalar>(), s2 = ei_random<Scalar>(); triV.setRandom(); triH.setRandom(); loTri = triV.template triangularView<Lower>(); upTri = triH.template triangularView<Upper>(); unitLoTri = triV.template triangularView<UnitLower>(); unitUpTri = triH.template triangularView<UnitUpper>(); strictlyLoTri = triV.template triangularView<StrictlyLower>(); strictlyUpTri = triH.template triangularView<StrictlyUpper>(); ge1.setRandom(); ge2.setRandom(); VERIFY_IS_APPROX( ge3 = triV.template triangularView<Lower>() * ge2, loTri * ge2); VERIFY_IS_APPROX( ge3 = ge2 * triV.template triangularView<Lower>(), ge2 * loTri); VERIFY_IS_APPROX( ge3 = triH.template triangularView<Upper>() * ge1, upTri * ge1); VERIFY_IS_APPROX( ge3 = ge1 * triH.template triangularView<Upper>(), ge1 * upTri); VERIFY_IS_APPROX( ge3 = (s1*triV.adjoint()).template triangularView<Upper>() * (s2*ge1), s1*loTri.adjoint() * (s2*ge1)); VERIFY_IS_APPROX( ge3 = ge1 * triV.adjoint().template triangularView<Upper>(), ge1 * loTri.adjoint()); VERIFY_IS_APPROX( ge3 = triH.adjoint().template triangularView<Lower>() * ge2, upTri.adjoint() * ge2); VERIFY_IS_APPROX( ge3 = ge2 * triH.adjoint().template triangularView<Lower>(), ge2 * upTri.adjoint()); VERIFY_IS_APPROX( ge3 = triV.template triangularView<Lower>() * ge1.adjoint(), loTri * ge1.adjoint()); VERIFY_IS_APPROX( ge3 = ge1.adjoint() * triV.template triangularView<Lower>(), ge1.adjoint() * loTri); VERIFY_IS_APPROX( ge3 = triH.template triangularView<Upper>() * ge2.adjoint(), upTri * ge2.adjoint()); VERIFY_IS_APPROX(rge3.noalias() = triH.template triangularView<Upper>() * ge2.adjoint(), upTri * ge2.adjoint()); VERIFY_IS_APPROX( ge3 = (s1*triV).adjoint().template triangularView<Upper>() * ge2.adjoint(), ei_conj(s1) * loTri.adjoint() * ge2.adjoint()); VERIFY_IS_APPROX(rge3.noalias() = triV.adjoint().template triangularView<Upper>() * ge2.adjoint(), loTri.adjoint() * ge2.adjoint()); VERIFY_IS_APPROX( ge3 = triH.adjoint().template triangularView<Lower>() * ge1.adjoint(), upTri.adjoint() * ge1.adjoint()); VERIFY_IS_APPROX(rge3.noalias() = triH.adjoint().template triangularView<Lower>() * ge1.adjoint(), upTri.adjoint() * ge1.adjoint()); VERIFY_IS_APPROX( ge3 = triV.template triangularView<UnitLower>() * ge2, unitLoTri * ge2); VERIFY_IS_APPROX( rge3.noalias() = ge2 * triV.template triangularView<UnitLower>(), ge2 * unitLoTri); VERIFY_IS_APPROX( ge3 = ge2 * triV.template triangularView<UnitLower>(), ge2 * unitLoTri); VERIFY_IS_APPROX( ge3 = (s1*triV).adjoint().template triangularView<UnitUpper>() * ge2.adjoint(), ei_conj(s1) * unitLoTri.adjoint() * ge2.adjoint()); VERIFY_IS_APPROX( ge3 = triV.template triangularView<StrictlyLower>() * ge2, strictlyLoTri * ge2); VERIFY_IS_APPROX( rge3.noalias() = ge2 * triV.template triangularView<StrictlyLower>(), ge2 * strictlyLoTri); VERIFY_IS_APPROX( ge3 = ge2 * triV.template triangularView<StrictlyLower>(), ge2 * strictlyLoTri); VERIFY_IS_APPROX( ge3 = (s1*triV).adjoint().template triangularView<StrictlyUpper>() * ge2.adjoint(), ei_conj(s1) * strictlyLoTri.adjoint() * ge2.adjoint()); }
template<typename MatrixType> void adjoint(const MatrixType& m) { /* this test covers the following files: Transpose.h Conjugate.h Dot.h */ typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType; int rows = m.rows(); int cols = m.cols(); RealScalar largerEps = test_precision<RealScalar>(); if (ei_is_same_type<RealScalar,float>::ret) largerEps = RealScalar(1e-3f); MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = SquareMatrixType::Identity(rows, rows), square = SquareMatrixType::Random(rows, rows); VectorType v1 = VectorType::Random(rows), v2 = VectorType::Random(rows), v3 = VectorType::Random(rows), vzero = VectorType::Zero(rows); Scalar s1 = ei_random<Scalar>(), s2 = ei_random<Scalar>(); // check basic compatibility of adjoint, transpose, conjugate VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(), m1); VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(), m1); // check multiplicative behavior VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(), m2.adjoint() * m1); VERIFY_IS_APPROX((s1 * m1).adjoint(), ei_conj(s1) * m1.adjoint()); // check basic properties of dot, norm, norm2 typedef typename NumTraits<Scalar>::Real RealScalar; VERIFY(ei_isApprox((s1 * v1 + s2 * v2).dot(v3), s1 * v1.dot(v3) + s2 * v2.dot(v3), largerEps)); VERIFY(ei_isApprox(v3.dot(s1 * v1 + s2 * v2), ei_conj(s1)*v3.dot(v1)+ei_conj(s2)*v3.dot(v2), largerEps)); VERIFY_IS_APPROX(ei_conj(v1.dot(v2)), v2.dot(v1)); VERIFY_IS_APPROX(ei_abs(v1.dot(v1)), v1.squaredNorm()); if(NumTraits<Scalar>::HasFloatingPoint) VERIFY_IS_APPROX(v1.squaredNorm(), v1.norm() * v1.norm()); VERIFY_IS_MUCH_SMALLER_THAN(ei_abs(vzero.dot(v1)), static_cast<RealScalar>(1)); if(NumTraits<Scalar>::HasFloatingPoint) VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1)); // check compatibility of dot and adjoint VERIFY(ei_isApprox(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), largerEps)); // like in testBasicStuff, test operator() to check const-qualification int r = ei_random<int>(0, rows-1), c = ei_random<int>(0, cols-1); VERIFY_IS_APPROX(m1.conjugate()(r,c), ei_conj(m1(r,c))); VERIFY_IS_APPROX(m1.adjoint()(c,r), ei_conj(m1(r,c))); if(NumTraits<Scalar>::HasFloatingPoint) { // check that Random().normalized() works: tricky as the random xpr must be evaluated by // normalized() in order to produce a consistent result. VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1)); } // check inplace transpose m3 = m1; m3.transposeInPlace(); VERIFY_IS_APPROX(m3,m1.transpose()); m3.transposeInPlace(); VERIFY_IS_APPROX(m3,m1); }