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
10 #define EIGEN_NO_STATIC_ASSERT
11
12 #include "main.h"
13
vectorwiseop_array(const ArrayType & m)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
vectorwiseop_matrix(const MatrixType & m)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
test_vectorwiseop()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