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.

172 lines
5.3 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@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. #define EIGEN_NO_STATIC_ASSERT
  10. #include "main.h"
  11. template<typename ArrayType> void vectorwiseop_array(const ArrayType& m)
  12. {
  13. typedef typename ArrayType::Index Index;
  14. typedef typename ArrayType::Scalar Scalar;
  15. typedef typename NumTraits<Scalar>::Real RealScalar;
  16. typedef Array<Scalar, ArrayType::RowsAtCompileTime, 1> ColVectorType;
  17. typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType;
  18. Index rows = m.rows();
  19. Index cols = m.cols();
  20. Index r = internal::random<Index>(0, rows-1),
  21. c = internal::random<Index>(0, cols-1);
  22. ArrayType m1 = ArrayType::Random(rows, cols),
  23. m2(rows, cols),
  24. m3(rows, cols);
  25. ColVectorType colvec = ColVectorType::Random(rows);
  26. RowVectorType rowvec = RowVectorType::Random(cols);
  27. // test addition
  28. m2 = m1;
  29. m2.colwise() += colvec;
  30. VERIFY_IS_APPROX(m2, m1.colwise() + colvec);
  31. VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec);
  32. VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose());
  33. VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose());
  34. m2 = m1;
  35. m2.rowwise() += rowvec;
  36. VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec);
  37. VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec);
  38. VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose());
  39. VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose());
  40. // test substraction
  41. m2 = m1;
  42. m2.colwise() -= colvec;
  43. VERIFY_IS_APPROX(m2, m1.colwise() - colvec);
  44. VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec);
  45. VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose());
  46. VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose());
  47. m2 = m1;
  48. m2.rowwise() -= rowvec;
  49. VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec);
  50. VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec);
  51. VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose());
  52. VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose());
  53. // test multiplication
  54. m2 = m1;
  55. m2.colwise() *= colvec;
  56. VERIFY_IS_APPROX(m2, m1.colwise() * colvec);
  57. VERIFY_IS_APPROX(m2.col(c), m1.col(c) * colvec);
  58. VERIFY_RAISES_ASSERT(m2.colwise() *= colvec.transpose());
  59. VERIFY_RAISES_ASSERT(m1.colwise() * colvec.transpose());
  60. m2 = m1;
  61. m2.rowwise() *= rowvec;
  62. VERIFY_IS_APPROX(m2, m1.rowwise() * rowvec);
  63. VERIFY_IS_APPROX(m2.row(r), m1.row(r) * rowvec);
  64. VERIFY_RAISES_ASSERT(m2.rowwise() *= rowvec.transpose());
  65. VERIFY_RAISES_ASSERT(m1.rowwise() * rowvec.transpose());
  66. // test quotient
  67. m2 = m1;
  68. m2.colwise() /= colvec;
  69. VERIFY_IS_APPROX(m2, m1.colwise() / colvec);
  70. VERIFY_IS_APPROX(m2.col(c), m1.col(c) / colvec);
  71. VERIFY_RAISES_ASSERT(m2.colwise() /= colvec.transpose());
  72. VERIFY_RAISES_ASSERT(m1.colwise() / colvec.transpose());
  73. m2 = m1;
  74. m2.rowwise() /= rowvec;
  75. VERIFY_IS_APPROX(m2, m1.rowwise() / rowvec);
  76. VERIFY_IS_APPROX(m2.row(r), m1.row(r) / rowvec);
  77. VERIFY_RAISES_ASSERT(m2.rowwise() /= rowvec.transpose());
  78. VERIFY_RAISES_ASSERT(m1.rowwise() / rowvec.transpose());
  79. }
  80. template<typename MatrixType> void vectorwiseop_matrix(const MatrixType& m)
  81. {
  82. typedef typename MatrixType::Index Index;
  83. typedef typename MatrixType::Scalar Scalar;
  84. typedef typename NumTraits<Scalar>::Real RealScalar;
  85. typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
  86. typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
  87. Index rows = m.rows();
  88. Index cols = m.cols();
  89. Index r = internal::random<Index>(0, rows-1),
  90. c = internal::random<Index>(0, cols-1);
  91. MatrixType m1 = MatrixType::Random(rows, cols),
  92. m2(rows, cols),
  93. m3(rows, cols);
  94. ColVectorType colvec = ColVectorType::Random(rows);
  95. RowVectorType rowvec = RowVectorType::Random(cols);
  96. // test addition
  97. m2 = m1;
  98. m2.colwise() += colvec;
  99. VERIFY_IS_APPROX(m2, m1.colwise() + colvec);
  100. VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec);
  101. VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose());
  102. VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose());
  103. m2 = m1;
  104. m2.rowwise() += rowvec;
  105. VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec);
  106. VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec);
  107. VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose());
  108. VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose());
  109. // test substraction
  110. m2 = m1;
  111. m2.colwise() -= colvec;
  112. VERIFY_IS_APPROX(m2, m1.colwise() - colvec);
  113. VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec);
  114. VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose());
  115. VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose());
  116. m2 = m1;
  117. m2.rowwise() -= rowvec;
  118. VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec);
  119. VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec);
  120. VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose());
  121. VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose());
  122. }
  123. void test_vectorwiseop()
  124. {
  125. CALL_SUBTEST_1(vectorwiseop_array(Array22cd()));
  126. CALL_SUBTEST_2(vectorwiseop_array(Array<double, 3, 2>()));
  127. CALL_SUBTEST_3(vectorwiseop_array(ArrayXXf(3, 4)));
  128. CALL_SUBTEST_4(vectorwiseop_matrix(Matrix4cf()));
  129. CALL_SUBTEST_5(vectorwiseop_matrix(Matrix<float,4,5>()));
  130. CALL_SUBTEST_6(vectorwiseop_matrix(MatrixXd(7,2)));
  131. }