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) 2010-2011 Jitse Niesen <jitse (at) maths.leeds.ac.uk>
      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>
     13 bool equalsIdentity(const MatrixType& A)
     14 {
     15   typedef typename MatrixType::Index Index;
     16   typedef typename MatrixType::Scalar Scalar;
     17   Scalar zero = static_cast<Scalar>(0);
     18 
     19   bool offDiagOK = true;
     20   for (Index i = 0; i < A.rows(); ++i) {
     21     for (Index j = i+1; j < A.cols(); ++j) {
     22       offDiagOK = offDiagOK && (A(i,j) == zero);
     23     }
     24   }
     25   for (Index i = 0; i < A.rows(); ++i) {
     26     for (Index j = 0; j < (std::min)(i, A.cols()); ++j) {
     27       offDiagOK = offDiagOK && (A(i,j) == zero);
     28     }
     29   }
     30 
     31   bool diagOK = (A.diagonal().array() == 1).all();
     32   return offDiagOK && diagOK;
     33 }
     34 
     35 template<typename VectorType>
     36 void testVectorType(const VectorType& base)
     37 {
     38   typedef typename internal::traits<VectorType>::Index Index;
     39   typedef typename internal::traits<VectorType>::Scalar Scalar;
     40 
     41   const Index size = base.size();
     42 
     43   Scalar high = internal::random<Scalar>(-500,500);
     44   Scalar low = (size == 1 ? high : internal::random<Scalar>(-500,500));
     45   if (low>high) std::swap(low,high);
     46 
     47   const Scalar step = ((size == 1) ? 1 : (high-low)/(size-1));
     48 
     49   // check whether the result yields what we expect it to do
     50   VectorType m(base);
     51   m.setLinSpaced(size,low,high);
     52 
     53   VectorType n(size);
     54   for (int i=0; i<size; ++i)
     55     n(i) = low+i*step;
     56 
     57   VERIFY_IS_APPROX(m,n);
     58 
     59   // random access version
     60   m = VectorType::LinSpaced(size,low,high);
     61   VERIFY_IS_APPROX(m,n);
     62 
     63   // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).
     64   VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<Scalar>::epsilon() );
     65 
     66   // These guys sometimes fail! This is not good. Any ideas how to fix them!?
     67   //VERIFY( m(m.size()-1) == high );
     68   //VERIFY( m(0) == low );
     69 
     70   // sequential access version
     71   m = VectorType::LinSpaced(Sequential,size,low,high);
     72   VERIFY_IS_APPROX(m,n);
     73 
     74   // These guys sometimes fail! This is not good. Any ideas how to fix them!?
     75   //VERIFY( m(m.size()-1) == high );
     76   //VERIFY( m(0) == low );
     77 
     78   // check whether everything works with row and col major vectors
     79   Matrix<Scalar,Dynamic,1> row_vector(size);
     80   Matrix<Scalar,1,Dynamic> col_vector(size);
     81   row_vector.setLinSpaced(size,low,high);
     82   col_vector.setLinSpaced(size,low,high);
     83   VERIFY( row_vector.isApprox(col_vector.transpose(), NumTraits<Scalar>::epsilon()));
     84 
     85   Matrix<Scalar,Dynamic,1> size_changer(size+50);
     86   size_changer.setLinSpaced(size,low,high);
     87   VERIFY( size_changer.size() == size );
     88 
     89   typedef Matrix<Scalar,1,1> ScalarMatrix;
     90   ScalarMatrix scalar;
     91   scalar.setLinSpaced(1,low,high);
     92   VERIFY_IS_APPROX( scalar, ScalarMatrix::Constant(high) );
     93   VERIFY_IS_APPROX( ScalarMatrix::LinSpaced(1,low,high), ScalarMatrix::Constant(high) );
     94 
     95   // regression test for bug 526 (linear vectorized transversal)
     96   if (size > 1) {
     97     m.tail(size-1).setLinSpaced(low, high);
     98     VERIFY_IS_APPROX(m(size-1), high);
     99   }
    100 }
    101 
    102 template<typename MatrixType>
    103 void testMatrixType(const MatrixType& m)
    104 {
    105   typedef typename MatrixType::Index Index;
    106   const Index rows = m.rows();
    107   const Index cols = m.cols();
    108 
    109   MatrixType A;
    110   A.setIdentity(rows, cols);
    111   VERIFY(equalsIdentity(A));
    112   VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));
    113 }
    114 
    115 void test_nullary()
    116 {
    117   CALL_SUBTEST_1( testMatrixType(Matrix2d()) );
    118   CALL_SUBTEST_2( testMatrixType(MatrixXcf(internal::random<int>(1,300),internal::random<int>(1,300))) );
    119   CALL_SUBTEST_3( testMatrixType(MatrixXf(internal::random<int>(1,300),internal::random<int>(1,300))) );
    120 
    121   for(int i = 0; i < g_repeat; i++) {
    122     CALL_SUBTEST_4( testVectorType(VectorXd(internal::random<int>(1,300))) );
    123     CALL_SUBTEST_5( testVectorType(Vector4d()) );  // regression test for bug 232
    124     CALL_SUBTEST_6( testVectorType(Vector3d()) );
    125     CALL_SUBTEST_7( testVectorType(VectorXf(internal::random<int>(1,300))) );
    126     CALL_SUBTEST_8( testVectorType(Vector3f()) );
    127     CALL_SUBTEST_8( testVectorType(Matrix<float,1,1>()) );
    128   }
    129 }
    130