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 (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 #define EIGEN_NO_STATIC_ASSERT 11 12 #include "main.h" 13 14 template<typename ArrayType> void vectorwiseop_array(const ArrayType& m) 15 { 16 typedef typename ArrayType::Index Index; 17 typedef typename ArrayType::Scalar Scalar; 18 typedef typename NumTraits<Scalar>::Real RealScalar; 19 typedef Array<Scalar, ArrayType::RowsAtCompileTime, 1> ColVectorType; 20 typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType; 21 22 Index rows = m.rows(); 23 Index cols = m.cols(); 24 Index r = internal::random<Index>(0, rows-1), 25 c = internal::random<Index>(0, cols-1); 26 27 ArrayType m1 = ArrayType::Random(rows, cols), 28 m2(rows, cols), 29 m3(rows, cols); 30 31 ColVectorType colvec = ColVectorType::Random(rows); 32 RowVectorType rowvec = RowVectorType::Random(cols); 33 34 // test addition 35 36 m2 = m1; 37 m2.colwise() += colvec; 38 VERIFY_IS_APPROX(m2, m1.colwise() + colvec); 39 VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec); 40 41 VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose()); 42 VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose()); 43 44 m2 = m1; 45 m2.rowwise() += rowvec; 46 VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec); 47 VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec); 48 49 VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose()); 50 VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose()); 51 52 // test substraction 53 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 59 VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose()); 60 VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose()); 61 62 m2 = m1; 63 m2.rowwise() -= rowvec; 64 VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec); 65 VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec); 66 67 VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose()); 68 VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose()); 69 70 // test multiplication 71 72 m2 = m1; 73 m2.colwise() *= colvec; 74 VERIFY_IS_APPROX(m2, m1.colwise() * colvec); 75 VERIFY_IS_APPROX(m2.col(c), m1.col(c) * colvec); 76 77 VERIFY_RAISES_ASSERT(m2.colwise() *= colvec.transpose()); 78 VERIFY_RAISES_ASSERT(m1.colwise() * colvec.transpose()); 79 80 m2 = m1; 81 m2.rowwise() *= rowvec; 82 VERIFY_IS_APPROX(m2, m1.rowwise() * rowvec); 83 VERIFY_IS_APPROX(m2.row(r), m1.row(r) * rowvec); 84 85 VERIFY_RAISES_ASSERT(m2.rowwise() *= rowvec.transpose()); 86 VERIFY_RAISES_ASSERT(m1.rowwise() * rowvec.transpose()); 87 88 // test quotient 89 90 m2 = m1; 91 m2.colwise() /= colvec; 92 VERIFY_IS_APPROX(m2, m1.colwise() / colvec); 93 VERIFY_IS_APPROX(m2.col(c), m1.col(c) / colvec); 94 95 VERIFY_RAISES_ASSERT(m2.colwise() /= colvec.transpose()); 96 VERIFY_RAISES_ASSERT(m1.colwise() / colvec.transpose()); 97 98 m2 = m1; 99 m2.rowwise() /= rowvec; 100 VERIFY_IS_APPROX(m2, m1.rowwise() / rowvec); 101 VERIFY_IS_APPROX(m2.row(r), m1.row(r) / rowvec); 102 103 VERIFY_RAISES_ASSERT(m2.rowwise() /= rowvec.transpose()); 104 VERIFY_RAISES_ASSERT(m1.rowwise() / rowvec.transpose()); 105 } 106 107 template<typename MatrixType> void vectorwiseop_matrix(const MatrixType& m) 108 { 109 typedef typename MatrixType::Index Index; 110 typedef typename MatrixType::Scalar Scalar; 111 typedef typename NumTraits<Scalar>::Real RealScalar; 112 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType; 113 typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; 114 115 Index rows = m.rows(); 116 Index cols = m.cols(); 117 Index r = internal::random<Index>(0, rows-1), 118 c = internal::random<Index>(0, cols-1); 119 120 MatrixType m1 = MatrixType::Random(rows, cols), 121 m2(rows, cols), 122 m3(rows, cols); 123 124 ColVectorType colvec = ColVectorType::Random(rows); 125 RowVectorType rowvec = RowVectorType::Random(cols); 126 127 // test addition 128 129 m2 = m1; 130 m2.colwise() += colvec; 131 VERIFY_IS_APPROX(m2, m1.colwise() + colvec); 132 VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec); 133 134 VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose()); 135 VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose()); 136 137 m2 = m1; 138 m2.rowwise() += rowvec; 139 VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec); 140 VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec); 141 142 VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose()); 143 VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose()); 144 145 // test substraction 146 147 m2 = m1; 148 m2.colwise() -= colvec; 149 VERIFY_IS_APPROX(m2, m1.colwise() - colvec); 150 VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec); 151 152 VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose()); 153 VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose()); 154 155 m2 = m1; 156 m2.rowwise() -= rowvec; 157 VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec); 158 VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec); 159 160 VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose()); 161 VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose()); 162 } 163 164 void test_vectorwiseop() 165 { 166 CALL_SUBTEST_1(vectorwiseop_array(Array22cd())); 167 CALL_SUBTEST_2(vectorwiseop_array(Array<double, 3, 2>())); 168 CALL_SUBTEST_3(vectorwiseop_array(ArrayXXf(3, 4))); 169 CALL_SUBTEST_4(vectorwiseop_matrix(Matrix4cf())); 170 CALL_SUBTEST_5(vectorwiseop_matrix(Matrix<float,4,5>())); 171 CALL_SUBTEST_6(vectorwiseop_matrix(MatrixXd(7,2))); 172 } 173