1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
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/.
10 #define EIGEN_NO_STATIC_ASSERT
14 template<typename ArrayType
> void vectorwiseop_array(const ArrayType
& m
)
16 typedef typename
ArrayType::Index Index
;
17 typedef typename
ArrayType::Scalar Scalar
;
18 typedef Array
<Scalar
, ArrayType::RowsAtCompileTime
, 1> ColVectorType
;
19 typedef Array
<Scalar
, 1, ArrayType::ColsAtCompileTime
> RowVectorType
;
21 Index rows
= m
.rows();
22 Index cols
= m
.cols();
23 Index r
= internal::random
<Index
>(0, rows
-1),
24 c
= internal::random
<Index
>(0, cols
-1);
26 ArrayType m1
= ArrayType::Random(rows
, cols
),
30 ColVectorType colvec
= ColVectorType::Random(rows
);
31 RowVectorType rowvec
= RowVectorType::Random(cols
);
36 m2
.colwise() += colvec
;
37 VERIFY_IS_APPROX(m2
, m1
.colwise() + colvec
);
38 VERIFY_IS_APPROX(m2
.col(c
), m1
.col(c
) + colvec
);
40 VERIFY_RAISES_ASSERT(m2
.colwise() += colvec
.transpose());
41 VERIFY_RAISES_ASSERT(m1
.colwise() + colvec
.transpose());
44 m2
.rowwise() += rowvec
;
45 VERIFY_IS_APPROX(m2
, m1
.rowwise() + rowvec
);
46 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
) + rowvec
);
48 VERIFY_RAISES_ASSERT(m2
.rowwise() += rowvec
.transpose());
49 VERIFY_RAISES_ASSERT(m1
.rowwise() + rowvec
.transpose());
54 m2
.colwise() -= colvec
;
55 VERIFY_IS_APPROX(m2
, m1
.colwise() - colvec
);
56 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());
62 m2
.rowwise() -= rowvec
;
63 VERIFY_IS_APPROX(m2
, m1
.rowwise() - rowvec
);
64 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
) - rowvec
);
66 VERIFY_RAISES_ASSERT(m2
.rowwise() -= rowvec
.transpose());
67 VERIFY_RAISES_ASSERT(m1
.rowwise() - rowvec
.transpose());
69 // test multiplication
72 m2
.colwise() *= colvec
;
73 VERIFY_IS_APPROX(m2
, m1
.colwise() * colvec
);
74 VERIFY_IS_APPROX(m2
.col(c
), m1
.col(c
) * colvec
);
76 VERIFY_RAISES_ASSERT(m2
.colwise() *= colvec
.transpose());
77 VERIFY_RAISES_ASSERT(m1
.colwise() * colvec
.transpose());
80 m2
.rowwise() *= rowvec
;
81 VERIFY_IS_APPROX(m2
, m1
.rowwise() * rowvec
);
82 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
) * rowvec
);
84 VERIFY_RAISES_ASSERT(m2
.rowwise() *= rowvec
.transpose());
85 VERIFY_RAISES_ASSERT(m1
.rowwise() * rowvec
.transpose());
90 m2
.colwise() /= colvec
;
91 VERIFY_IS_APPROX(m2
, m1
.colwise() / colvec
);
92 VERIFY_IS_APPROX(m2
.col(c
), m1
.col(c
) / colvec
);
94 VERIFY_RAISES_ASSERT(m2
.colwise() /= colvec
.transpose());
95 VERIFY_RAISES_ASSERT(m1
.colwise() / colvec
.transpose());
98 m2
.rowwise() /= rowvec
;
99 VERIFY_IS_APPROX(m2
, m1
.rowwise() / rowvec
);
100 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
) / rowvec
);
102 VERIFY_RAISES_ASSERT(m2
.rowwise() /= rowvec
.transpose());
103 VERIFY_RAISES_ASSERT(m1
.rowwise() / rowvec
.transpose());
106 // yes, there might be an aliasing issue there but ".rowwise() /="
107 // is suppposed to evaluate " m2.colwise().sum()" into to temporary to avoid
108 // evaluating the reducions multiple times
109 if(ArrayType::RowsAtCompileTime
>2 || ArrayType::RowsAtCompileTime
==Dynamic
)
111 m2
.rowwise() /= m2
.colwise().sum();
112 VERIFY_IS_APPROX(m2
, m1
.rowwise() / m1
.colwise().sum());
116 Array
<bool,Dynamic
,Dynamic
> mb(rows
,cols
);
117 mb
= (m1
.real()<=0.7).colwise().all();
118 VERIFY( (mb
.col(c
) == (m1
.real().col(c
)<=0.7).all()).all() );
119 mb
= (m1
.real()<=0.7).rowwise().all();
120 VERIFY( (mb
.row(r
) == (m1
.real().row(r
)<=0.7).all()).all() );
122 mb
= (m1
.real()>=0.7).colwise().any();
123 VERIFY( (mb
.col(c
) == (m1
.real().col(c
)>=0.7).any()).all() );
124 mb
= (m1
.real()>=0.7).rowwise().any();
125 VERIFY( (mb
.row(r
) == (m1
.real().row(r
)>=0.7).any()).all() );
128 template<typename MatrixType
> void vectorwiseop_matrix(const MatrixType
& m
)
130 typedef typename
MatrixType::Index Index
;
131 typedef typename
MatrixType::Scalar Scalar
;
132 typedef typename NumTraits
<Scalar
>::Real RealScalar
;
133 typedef Matrix
<Scalar
, MatrixType::RowsAtCompileTime
, 1> ColVectorType
;
134 typedef Matrix
<Scalar
, 1, MatrixType::ColsAtCompileTime
> RowVectorType
;
135 typedef Matrix
<RealScalar
, MatrixType::RowsAtCompileTime
, 1> RealColVectorType
;
136 typedef Matrix
<RealScalar
, 1, MatrixType::ColsAtCompileTime
> RealRowVectorType
;
138 Index rows
= m
.rows();
139 Index cols
= m
.cols();
140 Index r
= internal::random
<Index
>(0, rows
-1),
141 c
= internal::random
<Index
>(0, cols
-1);
143 MatrixType m1
= MatrixType::Random(rows
, cols
),
147 ColVectorType colvec
= ColVectorType::Random(rows
);
148 RowVectorType rowvec
= RowVectorType::Random(cols
);
149 RealColVectorType rcres
;
150 RealRowVectorType rrres
;
155 m2
.colwise() += colvec
;
156 VERIFY_IS_APPROX(m2
, m1
.colwise() + colvec
);
157 VERIFY_IS_APPROX(m2
.col(c
), m1
.col(c
) + colvec
);
159 VERIFY_RAISES_ASSERT(m2
.colwise() += colvec
.transpose());
160 VERIFY_RAISES_ASSERT(m1
.colwise() + colvec
.transpose());
163 m2
.rowwise() += rowvec
;
164 VERIFY_IS_APPROX(m2
, m1
.rowwise() + rowvec
);
165 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
) + rowvec
);
167 VERIFY_RAISES_ASSERT(m2
.rowwise() += rowvec
.transpose());
168 VERIFY_RAISES_ASSERT(m1
.rowwise() + rowvec
.transpose());
173 m2
.colwise() -= colvec
;
174 VERIFY_IS_APPROX(m2
, m1
.colwise() - colvec
);
175 VERIFY_IS_APPROX(m2
.col(c
), m1
.col(c
) - colvec
);
177 VERIFY_RAISES_ASSERT(m2
.colwise() -= colvec
.transpose());
178 VERIFY_RAISES_ASSERT(m1
.colwise() - colvec
.transpose());
181 m2
.rowwise() -= rowvec
;
182 VERIFY_IS_APPROX(m2
, m1
.rowwise() - rowvec
);
183 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
) - rowvec
);
185 VERIFY_RAISES_ASSERT(m2
.rowwise() -= rowvec
.transpose());
186 VERIFY_RAISES_ASSERT(m1
.rowwise() - rowvec
.transpose());
189 rrres
= m1
.colwise().norm();
190 VERIFY_IS_APPROX(rrres(c
), m1
.col(c
).norm());
191 rcres
= m1
.rowwise().norm();
192 VERIFY_IS_APPROX(rcres(r
), m1
.row(r
).norm());
195 m2
= m1
.colwise().normalized();
196 VERIFY_IS_APPROX(m2
.col(c
), m1
.col(c
).normalized());
197 m2
= m1
.rowwise().normalized();
198 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
).normalized());
202 m2
.colwise().normalize();
203 VERIFY_IS_APPROX(m2
.col(c
), m1
.col(c
).normalized());
205 m2
.rowwise().normalize();
206 VERIFY_IS_APPROX(m2
.row(r
), m1
.row(r
).normalized());
209 void test_vectorwiseop()
211 CALL_SUBTEST_1(vectorwiseop_array(Array22cd()));
212 CALL_SUBTEST_2(vectorwiseop_array(Array
<double, 3, 2>()));
213 CALL_SUBTEST_3(vectorwiseop_array(ArrayXXf(3, 4)));
214 CALL_SUBTEST_4(vectorwiseop_matrix(Matrix4cf()));
215 CALL_SUBTEST_5(vectorwiseop_matrix(Matrix
<float,4,5>()));
216 CALL_SUBTEST_6(vectorwiseop_matrix(MatrixXd(7,2)));