Home | History | Annotate | Download | only in test
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #include "main.h"
     11 
     12 template<typename MatrixType> void matrixVisitor(const MatrixType& p)
     13 {
     14   typedef typename MatrixType::Scalar Scalar;
     15   typedef typename MatrixType::Index Index;
     16 
     17   Index rows = p.rows();
     18   Index cols = p.cols();
     19 
     20   // construct a random matrix where all coefficients are different
     21   MatrixType m;
     22   m = MatrixType::Random(rows, cols);
     23   for(Index i = 0; i < m.size(); i++)
     24     for(Index i2 = 0; i2 < i; i2++)
     25       while(m(i) == m(i2)) // yes, ==
     26         m(i) = internal::random<Scalar>();
     27 
     28   Scalar minc = Scalar(1000), maxc = Scalar(-1000);
     29   Index minrow=0,mincol=0,maxrow=0,maxcol=0;
     30   for(Index j = 0; j < cols; j++)
     31   for(Index i = 0; i < rows; i++)
     32   {
     33     if(m(i,j) < minc)
     34     {
     35       minc = m(i,j);
     36       minrow = i;
     37       mincol = j;
     38     }
     39     if(m(i,j) > maxc)
     40     {
     41       maxc = m(i,j);
     42       maxrow = i;
     43       maxcol = j;
     44     }
     45   }
     46   Index eigen_minrow, eigen_mincol, eigen_maxrow, eigen_maxcol;
     47   Scalar eigen_minc, eigen_maxc;
     48   eigen_minc = m.minCoeff(&eigen_minrow,&eigen_mincol);
     49   eigen_maxc = m.maxCoeff(&eigen_maxrow,&eigen_maxcol);
     50   VERIFY(minrow == eigen_minrow);
     51   VERIFY(maxrow == eigen_maxrow);
     52   VERIFY(mincol == eigen_mincol);
     53   VERIFY(maxcol == eigen_maxcol);
     54   VERIFY_IS_APPROX(minc, eigen_minc);
     55   VERIFY_IS_APPROX(maxc, eigen_maxc);
     56   VERIFY_IS_APPROX(minc, m.minCoeff());
     57   VERIFY_IS_APPROX(maxc, m.maxCoeff());
     58 
     59   eigen_maxc = (m.adjoint()*m).maxCoeff(&eigen_maxrow,&eigen_maxcol);
     60   eigen_maxc = (m.adjoint()*m).eval().maxCoeff(&maxrow,&maxcol);
     61   VERIFY(maxrow == eigen_maxrow);
     62   VERIFY(maxcol == eigen_maxcol);
     63 }
     64 
     65 template<typename VectorType> void vectorVisitor(const VectorType& w)
     66 {
     67   typedef typename VectorType::Scalar Scalar;
     68   typedef typename VectorType::Index Index;
     69 
     70   Index size = w.size();
     71 
     72   // construct a random vector where all coefficients are different
     73   VectorType v;
     74   v = VectorType::Random(size);
     75   for(Index i = 0; i < size; i++)
     76     for(Index i2 = 0; i2 < i; i2++)
     77       while(v(i) == v(i2)) // yes, ==
     78         v(i) = internal::random<Scalar>();
     79 
     80   Scalar minc = v(0), maxc = v(0);
     81   Index minidx=0, maxidx=0;
     82   for(Index i = 0; i < size; i++)
     83   {
     84     if(v(i) < minc)
     85     {
     86       minc = v(i);
     87       minidx = i;
     88     }
     89     if(v(i) > maxc)
     90     {
     91       maxc = v(i);
     92       maxidx = i;
     93     }
     94   }
     95   Index eigen_minidx, eigen_maxidx;
     96   Scalar eigen_minc, eigen_maxc;
     97   eigen_minc = v.minCoeff(&eigen_minidx);
     98   eigen_maxc = v.maxCoeff(&eigen_maxidx);
     99   VERIFY(minidx == eigen_minidx);
    100   VERIFY(maxidx == eigen_maxidx);
    101   VERIFY_IS_APPROX(minc, eigen_minc);
    102   VERIFY_IS_APPROX(maxc, eigen_maxc);
    103   VERIFY_IS_APPROX(minc, v.minCoeff());
    104   VERIFY_IS_APPROX(maxc, v.maxCoeff());
    105 
    106   Index idx0 = internal::random<Index>(0,size-1);
    107   Index idx1 = eigen_minidx;
    108   Index idx2 = eigen_maxidx;
    109   VectorType v1(v), v2(v);
    110   v1(idx0) = v1(idx1);
    111   v2(idx0) = v2(idx2);
    112   v1.minCoeff(&eigen_minidx);
    113   v2.maxCoeff(&eigen_maxidx);
    114   VERIFY(eigen_minidx == (std::min)(idx0,idx1));
    115   VERIFY(eigen_maxidx == (std::min)(idx0,idx2));
    116 }
    117 
    118 void test_visitor()
    119 {
    120   for(int i = 0; i < g_repeat; i++) {
    121     CALL_SUBTEST_1( matrixVisitor(Matrix<float, 1, 1>()) );
    122     CALL_SUBTEST_2( matrixVisitor(Matrix2f()) );
    123     CALL_SUBTEST_3( matrixVisitor(Matrix4d()) );
    124     CALL_SUBTEST_4( matrixVisitor(MatrixXd(8, 12)) );
    125     CALL_SUBTEST_5( matrixVisitor(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 20)) );
    126     CALL_SUBTEST_6( matrixVisitor(MatrixXi(8, 12)) );
    127   }
    128   for(int i = 0; i < g_repeat; i++) {
    129     CALL_SUBTEST_7( vectorVisitor(Vector4f()) );
    130     CALL_SUBTEST_7( vectorVisitor(Matrix<int,12,1>()) );
    131     CALL_SUBTEST_8( vectorVisitor(VectorXd(10)) );
    132     CALL_SUBTEST_9( vectorVisitor(RowVectorXd(10)) );
    133     CALL_SUBTEST_10( vectorVisitor(VectorXf(33)) );
    134   }
    135 }
    136