You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
4.3 KiB

  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@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. #include "main.h"
  10. template<typename MatrixType>
  11. bool equalsIdentity(const MatrixType& A)
  12. {
  13. typedef typename MatrixType::Scalar Scalar;
  14. Scalar zero = static_cast<Scalar>(0);
  15. bool offDiagOK = true;
  16. for (Index i = 0; i < A.rows(); ++i) {
  17. for (Index j = i+1; j < A.cols(); ++j) {
  18. offDiagOK = offDiagOK && (A(i,j) == zero);
  19. }
  20. }
  21. for (Index i = 0; i < A.rows(); ++i) {
  22. for (Index j = 0; j < (std::min)(i, A.cols()); ++j) {
  23. offDiagOK = offDiagOK && (A(i,j) == zero);
  24. }
  25. }
  26. bool diagOK = (A.diagonal().array() == 1).all();
  27. return offDiagOK && diagOK;
  28. }
  29. template<typename VectorType>
  30. void testVectorType(const VectorType& base)
  31. {
  32. typedef typename VectorType::Scalar Scalar;
  33. const Index size = base.size();
  34. Scalar high = internal::random<Scalar>(-500,500);
  35. Scalar low = (size == 1 ? high : internal::random<Scalar>(-500,500));
  36. if (low>high) std::swap(low,high);
  37. const Scalar step = ((size == 1) ? 1 : (high-low)/(size-1));
  38. // check whether the result yields what we expect it to do
  39. VectorType m(base);
  40. m.setLinSpaced(size,low,high);
  41. VectorType n(size);
  42. for (int i=0; i<size; ++i)
  43. n(i) = low+i*step;
  44. VERIFY_IS_APPROX(m,n);
  45. // random access version
  46. m = VectorType::LinSpaced(size,low,high);
  47. VERIFY_IS_APPROX(m,n);
  48. // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).
  49. VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<Scalar>::epsilon() );
  50. // These guys sometimes fail! This is not good. Any ideas how to fix them!?
  51. //VERIFY( m(m.size()-1) == high );
  52. //VERIFY( m(0) == low );
  53. // sequential access version
  54. m = VectorType::LinSpaced(Sequential,size,low,high);
  55. VERIFY_IS_APPROX(m,n);
  56. // These guys sometimes fail! This is not good. Any ideas how to fix them!?
  57. //VERIFY( m(m.size()-1) == high );
  58. //VERIFY( m(0) == low );
  59. // check whether everything works with row and col major vectors
  60. Matrix<Scalar,Dynamic,1> row_vector(size);
  61. Matrix<Scalar,1,Dynamic> col_vector(size);
  62. row_vector.setLinSpaced(size,low,high);
  63. col_vector.setLinSpaced(size,low,high);
  64. // when using the extended precision (e.g., FPU) the relative error might exceed 1 bit
  65. // when computing the squared sum in isApprox, thus the 2x factor.
  66. VERIFY( row_vector.isApprox(col_vector.transpose(), Scalar(2)*NumTraits<Scalar>::epsilon()));
  67. Matrix<Scalar,Dynamic,1> size_changer(size+50);
  68. size_changer.setLinSpaced(size,low,high);
  69. VERIFY( size_changer.size() == size );
  70. typedef Matrix<Scalar,1,1> ScalarMatrix;
  71. ScalarMatrix scalar;
  72. scalar.setLinSpaced(1,low,high);
  73. VERIFY_IS_APPROX( scalar, ScalarMatrix::Constant(high) );
  74. VERIFY_IS_APPROX( ScalarMatrix::LinSpaced(1,low,high), ScalarMatrix::Constant(high) );
  75. // regression test for bug 526 (linear vectorized transversal)
  76. if (size > 1) {
  77. m.tail(size-1).setLinSpaced(low, high);
  78. VERIFY_IS_APPROX(m(size-1), high);
  79. }
  80. }
  81. template<typename MatrixType>
  82. void testMatrixType(const MatrixType& m)
  83. {
  84. const Index rows = m.rows();
  85. const Index cols = m.cols();
  86. MatrixType A;
  87. A.setIdentity(rows, cols);
  88. VERIFY(equalsIdentity(A));
  89. VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));
  90. }
  91. void test_nullary()
  92. {
  93. CALL_SUBTEST_1( testMatrixType(Matrix2d()) );
  94. CALL_SUBTEST_2( testMatrixType(MatrixXcf(internal::random<int>(1,300),internal::random<int>(1,300))) );
  95. CALL_SUBTEST_3( testMatrixType(MatrixXf(internal::random<int>(1,300),internal::random<int>(1,300))) );
  96. for(int i = 0; i < g_repeat; i++) {
  97. CALL_SUBTEST_4( testVectorType(VectorXd(internal::random<int>(1,300))) );
  98. CALL_SUBTEST_5( testVectorType(Vector4d()) ); // regression test for bug 232
  99. CALL_SUBTEST_6( testVectorType(Vector3d()) );
  100. CALL_SUBTEST_7( testVectorType(VectorXf(internal::random<int>(1,300))) );
  101. CALL_SUBTEST_8( testVectorType(Vector3f()) );
  102. CALL_SUBTEST_8( testVectorType(Vector4f()) );
  103. CALL_SUBTEST_8( testVectorType(Matrix<float,8,1>()) );
  104. CALL_SUBTEST_8( testVectorType(Matrix<float,1,1>()) );
  105. }
  106. }