예제 #1
0
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));
}
예제 #2
0
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());
}
예제 #3
0
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);

}