Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 1 | // This file is part of Eigen, a lightweight C++ template library |
| 2 | // for linear algebra. |
| 3 | // |
Gael Guennebaud | 28e64b0 | 2010-06-24 23:21:58 +0200 | [diff] [blame] | 4 | // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 5 | // |
Benoit Jacob | 69124cf | 2012-07-13 14:42:47 -0400 | [diff] [blame] | 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/. |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 9 | |
| 10 | #include "main.h" |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 11 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 12 | template <typename MatrixType> |
| 13 | void array_for_matrix(const MatrixType& m) { |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 14 | typedef typename MatrixType::Scalar Scalar; |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 15 | typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType; |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 16 | typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 17 | |
Hauke Heibel | f1679c7 | 2010-06-20 17:37:56 +0200 | [diff] [blame] | 18 | Index rows = m.rows(); |
| 19 | Index cols = m.cols(); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 20 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 21 | MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 22 | ColVectorType cv1 = ColVectorType::Random(rows); |
| 23 | RowVectorType rv1 = RowVectorType::Random(cols); |
Rasmus Munk Larsen | 3460f35 | 2023-02-01 13:49:56 -0800 | [diff] [blame] | 24 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 25 | Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>(); |
Rasmus Munk Larsen | 3460f35 | 2023-02-01 13:49:56 -0800 | [diff] [blame] | 26 | |
Antonio Sánchez | 3ebaab8 | 2024-02-05 20:07:15 +0000 | [diff] [blame] | 27 | // Prevent overflows for integer types. |
| 28 | if (Eigen::NumTraits<Scalar>::IsInteger) { |
Antonio Sánchez | de8013f | 2024-05-16 18:47:36 +0000 | [diff] [blame] | 29 | Scalar kMaxVal = Scalar(1000); |
Antonio Sánchez | 3ebaab8 | 2024-02-05 20:07:15 +0000 | [diff] [blame] | 30 | m1.array() = m1.array() - kMaxVal * (m1.array() / kMaxVal); |
| 31 | m2.array() = m2.array() - kMaxVal * (m2.array() / kMaxVal); |
| 32 | } |
| 33 | |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 34 | // scalar addition |
| 35 | VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array()); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 36 | VERIFY_IS_APPROX((m1.array() + s1).matrix(), MatrixType::Constant(rows, cols, s1) + m1); |
| 37 | VERIFY_IS_APPROX(((m1 * Scalar(2)).array() - s2).matrix(), (m1 + m1) - MatrixType::Constant(rows, cols, s2)); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 38 | m3 = m1; |
| 39 | m3.array() += s2; |
| 40 | VERIFY_IS_APPROX(m3, (m1.array() + s2).matrix()); |
| 41 | m3 = m1; |
| 42 | m3.array() -= s1; |
| 43 | VERIFY_IS_APPROX(m3, (m1.array() - s1).matrix()); |
| 44 | |
| 45 | // reductions |
Hauke Heibel | b5d8299 | 2013-02-28 12:33:34 +0100 | [diff] [blame] | 46 | VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.squaredNorm()); |
| 47 | VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.squaredNorm()); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 48 | VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1 + m2).colwise().sum(), |
| 49 | (m1 + m2).squaredNorm()); |
| 50 | VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1 - m2).rowwise().sum(), |
| 51 | (m1 - m2).squaredNorm()); |
| 52 | VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar, Scalar>())); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 53 | |
| 54 | // vector-wise ops |
| 55 | m3 = m1; |
| 56 | VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1); |
| 57 | m3 = m1; |
| 58 | VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1); |
| 59 | m3 = m1; |
| 60 | VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1); |
| 61 | m3 = m1; |
| 62 | VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1); |
Gael Guennebaud | c0c3be2 | 2018-10-09 22:54:54 +0200 | [diff] [blame] | 63 | |
Rasmus Munk Larsen | 3460f35 | 2023-02-01 13:49:56 -0800 | [diff] [blame] | 64 | // empty objects |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 65 | VERIFY_IS_EQUAL((m1.template block<0, Dynamic>(0, 0, 0, cols).colwise().sum()), RowVectorType::Zero(cols)); |
| 66 | VERIFY_IS_EQUAL((m1.template block<Dynamic, 0>(0, 0, rows, 0).rowwise().sum()), ColVectorType::Zero(rows)); |
| 67 | VERIFY_IS_EQUAL((m1.template block<0, Dynamic>(0, 0, 0, cols).colwise().prod()), RowVectorType::Ones(cols)); |
| 68 | VERIFY_IS_EQUAL((m1.template block<Dynamic, 0>(0, 0, rows, 0).rowwise().prod()), ColVectorType::Ones(rows)); |
Rasmus Munk Larsen | 3460f35 | 2023-02-01 13:49:56 -0800 | [diff] [blame] | 69 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 70 | VERIFY_IS_EQUAL(m1.block(0, 0, 0, cols).colwise().sum(), RowVectorType::Zero(cols)); |
| 71 | VERIFY_IS_EQUAL(m1.block(0, 0, rows, 0).rowwise().sum(), ColVectorType::Zero(rows)); |
| 72 | VERIFY_IS_EQUAL(m1.block(0, 0, 0, cols).colwise().prod(), RowVectorType::Ones(cols)); |
| 73 | VERIFY_IS_EQUAL(m1.block(0, 0, rows, 0).rowwise().prod(), ColVectorType::Ones(rows)); |
Rasmus Munk Larsen | 3460f35 | 2023-02-01 13:49:56 -0800 | [diff] [blame] | 74 | |
Hauke Heibel | d5e81d8 | 2011-01-27 16:37:06 +0100 | [diff] [blame] | 75 | // verify the const accessors exist |
| 76 | const Scalar& ref_m1 = m.matrix().array().coeffRef(0); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 77 | const Scalar& ref_m2 = m.matrix().array().coeffRef(0, 0); |
Hauke Heibel | d5e81d8 | 2011-01-27 16:37:06 +0100 | [diff] [blame] | 78 | const Scalar& ref_a1 = m.array().matrix().coeffRef(0); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 79 | const Scalar& ref_a2 = m.array().matrix().coeffRef(0, 0); |
Hauke Heibel | d5e81d8 | 2011-01-27 16:37:06 +0100 | [diff] [blame] | 80 | VERIFY(&ref_a1 == &ref_m1); |
| 81 | VERIFY(&ref_a2 == &ref_m2); |
Gael Guennebaud | c1d900a | 2016-01-28 21:43:20 +0100 | [diff] [blame] | 82 | |
| 83 | // Check write accessors: |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 84 | m1.array().coeffRef(0, 0) = 1; |
| 85 | VERIFY_IS_APPROX(m1(0, 0), Scalar(1)); |
| 86 | m1.array()(0, 0) = 2; |
| 87 | VERIFY_IS_APPROX(m1(0, 0), Scalar(2)); |
| 88 | m1.array().matrix().coeffRef(0, 0) = 3; |
| 89 | VERIFY_IS_APPROX(m1(0, 0), Scalar(3)); |
| 90 | m1.array().matrix()(0, 0) = 4; |
| 91 | VERIFY_IS_APPROX(m1(0, 0), Scalar(4)); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 92 | } |
| 93 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 94 | template <typename MatrixType> |
| 95 | void comparisons(const MatrixType& m) { |
Gael Guennebaud | a76fbbf | 2012-11-06 15:25:50 +0100 | [diff] [blame] | 96 | using std::abs; |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 97 | typedef typename MatrixType::Scalar Scalar; |
| 98 | typedef typename NumTraits<Scalar>::Real RealScalar; |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 99 | |
Hauke Heibel | f1679c7 | 2010-06-20 17:37:56 +0200 | [diff] [blame] | 100 | Index rows = m.rows(); |
| 101 | Index cols = m.cols(); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 102 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 103 | Index r = internal::random<Index>(0, rows - 1), c = internal::random<Index>(0, cols - 1); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 104 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 105 | MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 106 | |
| 107 | VERIFY(((m1.array() + Scalar(1)) > m1.array()).all()); |
| 108 | VERIFY(((m1.array() - Scalar(1)) < m1.array()).all()); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 109 | if (rows * cols > 1) { |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 110 | m3 = m1; |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 111 | m3(r, c) += 1; |
| 112 | VERIFY(!(m1.array() < m3.array()).all()); |
| 113 | VERIFY(!(m1.array() > m3.array()).all()); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 114 | } |
| 115 | |
| 116 | // comparisons to scalar |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 117 | VERIFY((m1.array() != (m1(r, c) + 1)).any()); |
| 118 | VERIFY((m1.array() > (m1(r, c) - 1)).any()); |
| 119 | VERIFY((m1.array() < (m1(r, c) + 1)).any()); |
| 120 | VERIFY((m1.array() == m1(r, c)).any()); |
| 121 | VERIFY(m1.cwiseEqual(m1(r, c)).any()); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 122 | |
| 123 | // test Select |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 124 | VERIFY_IS_APPROX((m1.array() < m2.array()).select(m1, m2), m1.cwiseMin(m2)); |
| 125 | VERIFY_IS_APPROX((m1.array() > m2.array()).select(m1, m2), m1.cwiseMax(m2)); |
Antonio Sánchez | de8013f | 2024-05-16 18:47:36 +0000 | [diff] [blame] | 126 | Scalar mid = m1.cwiseAbs().minCoeff() / Scalar(2) + m1.cwiseAbs().maxCoeff() / Scalar(2); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 127 | for (int j = 0; j < cols; ++j) |
| 128 | for (int i = 0; i < rows; ++i) m3(i, j) = abs(m1(i, j)) < mid ? 0 : m1(i, j); |
| 129 | VERIFY_IS_APPROX( |
| 130 | (m1.array().abs() < MatrixType::Constant(rows, cols, mid).array()).select(MatrixType::Zero(rows, cols), m1), m3); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 131 | // shorter versions: |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 132 | VERIFY_IS_APPROX((m1.array().abs() < MatrixType::Constant(rows, cols, mid).array()).select(0, m1), m3); |
| 133 | VERIFY_IS_APPROX((m1.array().abs() >= MatrixType::Constant(rows, cols, mid).array()).select(m1, 0), m3); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 134 | // even shorter version: |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 135 | VERIFY_IS_APPROX((m1.array().abs() < mid).select(0, m1), m3); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 136 | |
| 137 | // count |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 138 | VERIFY(((m1.array().abs() + 1) > RealScalar(0.1)).count() == rows * cols); |
Benoit Jacob | aaaade4 | 2010-05-30 16:00:58 -0400 | [diff] [blame] | 139 | |
Gael Guennebaud | 2e334f5 | 2016-11-14 18:47:02 +0100 | [diff] [blame] | 140 | // and/or |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 141 | VERIFY(((m1.array() < RealScalar(0)).matrix() && (m1.array() > RealScalar(0)).matrix()).count() == 0); |
| 142 | VERIFY(((m1.array() < RealScalar(0)).matrix() || (m1.array() >= RealScalar(0)).matrix()).count() == rows * cols); |
Tyler Veness | d165c73 | 2024-05-20 23:02:42 +0000 | [diff] [blame] | 143 | VERIFY(((m1.array() < -mid).matrix() || (m1.array() > mid).matrix()).count() == |
| 144 | (m1.cwiseAbs().array() > mid).count()); |
Gael Guennebaud | 2e334f5 | 2016-11-14 18:47:02 +0100 | [diff] [blame] | 145 | |
Gael Guennebaud | 12e1ebb | 2018-07-12 17:16:40 +0200 | [diff] [blame] | 146 | typedef Matrix<Index, Dynamic, 1> VectorOfIndices; |
Benoit Jacob | aaaade4 | 2010-05-30 16:00:58 -0400 | [diff] [blame] | 147 | |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 148 | // TODO allows colwise/rowwise for array |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 149 | VERIFY_IS_APPROX(((m1.array().abs() + 1) > RealScalar(0.1)).matrix().colwise().count(), |
| 150 | VectorOfIndices::Constant(cols, rows).transpose()); |
| 151 | VERIFY_IS_APPROX(((m1.array().abs() + 1) > RealScalar(0.1)).matrix().rowwise().count(), |
| 152 | VectorOfIndices::Constant(rows, cols)); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 153 | } |
| 154 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 155 | template <typename VectorType> |
| 156 | void lpNorm(const VectorType& v) { |
Gael Guennebaud | a76fbbf | 2012-11-06 15:25:50 +0100 | [diff] [blame] | 157 | using std::sqrt; |
Gael Guennebaud | 8b6f532 | 2016-06-02 15:29:59 +0200 | [diff] [blame] | 158 | typedef typename VectorType::RealScalar RealScalar; |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 159 | VectorType u = VectorType::Random(v.size()); |
| 160 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 161 | if (v.size() == 0) { |
Gael Guennebaud | 8b6f532 | 2016-06-02 15:29:59 +0200 | [diff] [blame] | 162 | VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), RealScalar(0)); |
| 163 | VERIFY_IS_APPROX(u.template lpNorm<1>(), RealScalar(0)); |
| 164 | VERIFY_IS_APPROX(u.template lpNorm<2>(), RealScalar(0)); |
| 165 | VERIFY_IS_APPROX(u.template lpNorm<5>(), RealScalar(0)); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 166 | } else { |
Gael Guennebaud | 8b6f532 | 2016-06-02 15:29:59 +0200 | [diff] [blame] | 167 | VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff()); |
| 168 | } |
| 169 | |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 170 | VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum()); |
Gael Guennebaud | a76fbbf | 2012-11-06 15:25:50 +0100 | [diff] [blame] | 171 | VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum())); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 172 | VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), |
| 173 | u.array().abs().pow(5).sum()); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 174 | } |
| 175 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 176 | template <typename MatrixType> |
| 177 | void cwise_min_max(const MatrixType& m) { |
Abraham Bachrach | 039408c | 2012-01-11 11:00:30 -0500 | [diff] [blame] | 178 | typedef typename MatrixType::Scalar Scalar; |
| 179 | |
| 180 | Index rows = m.rows(); |
| 181 | Index cols = m.cols(); |
| 182 | |
| 183 | MatrixType m1 = MatrixType::Random(rows, cols); |
| 184 | |
| 185 | // min/max with array |
| 186 | Scalar maxM1 = m1.maxCoeff(); |
| 187 | Scalar minM1 = m1.minCoeff(); |
| 188 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 189 | VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1), m1.cwiseMin(MatrixType::Constant(rows, cols, minM1))); |
| 190 | VERIFY_IS_APPROX(m1, m1.cwiseMin(MatrixType::Constant(rows, cols, maxM1))); |
Abraham Bachrach | 039408c | 2012-01-11 11:00:30 -0500 | [diff] [blame] | 191 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 192 | VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1), m1.cwiseMax(MatrixType::Constant(rows, cols, maxM1))); |
| 193 | VERIFY_IS_APPROX(m1, m1.cwiseMax(MatrixType::Constant(rows, cols, minM1))); |
Abraham Bachrach | 039408c | 2012-01-11 11:00:30 -0500 | [diff] [blame] | 194 | |
| 195 | // min/max with scalar input |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 196 | VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1), m1.cwiseMin(minM1)); |
Gael Guennebaud | 2c0303c | 2013-10-15 23:51:01 +0200 | [diff] [blame] | 197 | VERIFY_IS_APPROX(m1, m1.cwiseMin(maxM1)); |
| 198 | VERIFY_IS_APPROX(-m1, (-m1).cwiseMin(-minM1)); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 199 | VERIFY_IS_APPROX(-m1.array(), ((-m1).array().min)(-minM1)); |
Abraham Bachrach | 039408c | 2012-01-11 11:00:30 -0500 | [diff] [blame] | 200 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 201 | VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1), m1.cwiseMax(maxM1)); |
Gael Guennebaud | 2c0303c | 2013-10-15 23:51:01 +0200 | [diff] [blame] | 202 | VERIFY_IS_APPROX(m1, m1.cwiseMax(minM1)); |
| 203 | VERIFY_IS_APPROX(-m1, (-m1).cwiseMax(-maxM1)); |
| 204 | VERIFY_IS_APPROX(-m1.array(), ((-m1).array().max)(-maxM1)); |
Abraham Bachrach | 039408c | 2012-01-11 11:00:30 -0500 | [diff] [blame] | 205 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 206 | VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1).array(), (m1.array().min)(minM1)); |
| 207 | VERIFY_IS_APPROX(m1.array(), (m1.array().min)(maxM1)); |
Gael Guennebaud | 0c584dc | 2012-09-12 17:50:07 +0200 | [diff] [blame] | 208 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 209 | VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1).array(), (m1.array().max)(maxM1)); |
| 210 | VERIFY_IS_APPROX(m1.array(), (m1.array().max)(minM1)); |
Gael Guennebaud | 0c584dc | 2012-09-12 17:50:07 +0200 | [diff] [blame] | 211 | |
Rasmus Munk Larsen | 2d3fec8 | 2021-10-21 12:00:50 -0700 | [diff] [blame] | 212 | // Test NaN propagation for min/max. |
| 213 | if (!NumTraits<Scalar>::IsInteger) { |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 214 | m1(0, 0) = NumTraits<Scalar>::quiet_NaN(); |
Rasmus Munk Larsen | 2d3fec8 | 2021-10-21 12:00:50 -0700 | [diff] [blame] | 215 | // Elementwise. |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 216 | VERIFY((numext::isnan)(m1.template cwiseMax<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0))); |
| 217 | VERIFY((numext::isnan)(m1.template cwiseMin<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0))); |
| 218 | VERIFY(!(numext::isnan)(m1.template cwiseMax<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0))); |
| 219 | VERIFY(!(numext::isnan)(m1.template cwiseMin<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0))); |
| 220 | VERIFY((numext::isnan)(m1.template cwiseMax<PropagateNaN>(Scalar(1))(0, 0))); |
| 221 | VERIFY((numext::isnan)(m1.template cwiseMin<PropagateNaN>(Scalar(1))(0, 0))); |
| 222 | VERIFY(!(numext::isnan)(m1.template cwiseMax<PropagateNumbers>(Scalar(1))(0, 0))); |
| 223 | VERIFY(!(numext::isnan)(m1.template cwiseMin<PropagateNumbers>(Scalar(1))(0, 0))); |
Antonio Sánchez | f845a8b | 2022-04-16 05:07:44 +0000 | [diff] [blame] | 224 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 225 | VERIFY((numext::isnan)( |
| 226 | m1.array().template max<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0))); |
| 227 | VERIFY((numext::isnan)( |
| 228 | m1.array().template min<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0))); |
| 229 | VERIFY(!(numext::isnan)( |
| 230 | m1.array().template max<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0))); |
| 231 | VERIFY(!(numext::isnan)( |
| 232 | m1.array().template min<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0))); |
| 233 | VERIFY((numext::isnan)(m1.array().template max<PropagateNaN>(Scalar(1))(0, 0))); |
| 234 | VERIFY((numext::isnan)(m1.array().template min<PropagateNaN>(Scalar(1))(0, 0))); |
| 235 | VERIFY(!(numext::isnan)(m1.array().template max<PropagateNumbers>(Scalar(1))(0, 0))); |
| 236 | VERIFY(!(numext::isnan)(m1.array().template min<PropagateNumbers>(Scalar(1))(0, 0))); |
Rasmus Munk Larsen | 2d3fec8 | 2021-10-21 12:00:50 -0700 | [diff] [blame] | 237 | |
| 238 | // Reductions. |
| 239 | VERIFY((numext::isnan)(m1.template maxCoeff<PropagateNaN>())); |
| 240 | VERIFY((numext::isnan)(m1.template minCoeff<PropagateNaN>())); |
| 241 | if (m1.size() > 1) { |
| 242 | VERIFY(!(numext::isnan)(m1.template maxCoeff<PropagateNumbers>())); |
| 243 | VERIFY(!(numext::isnan)(m1.template minCoeff<PropagateNumbers>())); |
| 244 | } else { |
| 245 | VERIFY((numext::isnan)(m1.template maxCoeff<PropagateNumbers>())); |
| 246 | VERIFY((numext::isnan)(m1.template minCoeff<PropagateNumbers>())); |
| 247 | } |
| 248 | } |
Abraham Bachrach | 039408c | 2012-01-11 11:00:30 -0500 | [diff] [blame] | 249 | } |
| 250 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 251 | template <typename MatrixTraits> |
| 252 | void resize(const MatrixTraits& t) { |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 253 | typedef typename MatrixTraits::Scalar Scalar; |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 254 | typedef Matrix<Scalar, Dynamic, Dynamic> MatrixType; |
| 255 | typedef Array<Scalar, Dynamic, Dynamic> Array2DType; |
| 256 | typedef Matrix<Scalar, Dynamic, 1> VectorType; |
| 257 | typedef Array<Scalar, Dynamic, 1> Array1DType; |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 258 | |
| 259 | Index rows = t.rows(), cols = t.cols(); |
| 260 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 261 | MatrixType m(rows, cols); |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 262 | VectorType v(rows); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 263 | Array2DType a2(rows, cols); |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 264 | Array1DType a1(rows); |
| 265 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 266 | m.array().resize(rows + 1, cols + 1); |
| 267 | VERIFY(m.rows() == rows + 1 && m.cols() == cols + 1); |
| 268 | a2.matrix().resize(rows + 1, cols + 1); |
| 269 | VERIFY(a2.rows() == rows + 1 && a2.cols() == cols + 1); |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 270 | v.array().resize(cols); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 271 | VERIFY(v.size() == cols); |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 272 | a1.matrix().resize(cols); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 273 | VERIFY(a1.size() == cols); |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 274 | } |
| 275 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 276 | template <int> |
| 277 | void regression_bug_654() { |
Gael Guennebaud | 07417bd | 2013-09-07 00:01:04 +0200 | [diff] [blame] | 278 | ArrayXf a = RowVectorXf(3); |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 279 | VectorXf v = Array<float, 1, Dynamic>(3); |
Gael Guennebaud | 07417bd | 2013-09-07 00:01:04 +0200 | [diff] [blame] | 280 | } |
| 281 | |
Gael Guennebaud | fb1ee04 | 2017-06-09 13:13:03 +0200 | [diff] [blame] | 282 | // Check propagation of LvalueBit through Array/Matrix-Wrapper |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 283 | template <int> |
| 284 | void regrrssion_bug_1410() { |
Gael Guennebaud | fb1ee04 | 2017-06-09 13:13:03 +0200 | [diff] [blame] | 285 | const Matrix4i M; |
| 286 | const Array4i A; |
| 287 | ArrayWrapper<const Matrix4i> MA = M.array(); |
| 288 | MA.row(0); |
| 289 | MatrixWrapper<const Array4i> AM = A.matrix(); |
| 290 | AM.row(0); |
| 291 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 292 | VERIFY((internal::traits<ArrayWrapper<const Matrix4i> >::Flags & LvalueBit) == 0); |
| 293 | VERIFY((internal::traits<MatrixWrapper<const Array4i> >::Flags & LvalueBit) == 0); |
Gael Guennebaud | fb1ee04 | 2017-06-09 13:13:03 +0200 | [diff] [blame] | 294 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 295 | VERIFY((internal::traits<ArrayWrapper<Matrix4i> >::Flags & LvalueBit) == LvalueBit); |
| 296 | VERIFY((internal::traits<MatrixWrapper<Array4i> >::Flags & LvalueBit) == LvalueBit); |
Gael Guennebaud | fb1ee04 | 2017-06-09 13:13:03 +0200 | [diff] [blame] | 297 | } |
| 298 | |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 299 | EIGEN_DECLARE_TEST(array_for_matrix) { |
| 300 | for (int i = 0; i < g_repeat; i++) { |
| 301 | CALL_SUBTEST_1(array_for_matrix(Matrix<float, 1, 1>())); |
| 302 | CALL_SUBTEST_2(array_for_matrix(Matrix2f())); |
| 303 | CALL_SUBTEST_3(array_for_matrix(Matrix4d())); |
| 304 | CALL_SUBTEST_4(array_for_matrix( |
| 305 | MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
| 306 | CALL_SUBTEST_5(array_for_matrix( |
| 307 | MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
| 308 | CALL_SUBTEST_6(array_for_matrix( |
| 309 | MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 310 | } |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 311 | for (int i = 0; i < g_repeat; i++) { |
| 312 | CALL_SUBTEST_1(comparisons(Matrix<float, 1, 1>())); |
| 313 | CALL_SUBTEST_2(comparisons(Matrix2f())); |
| 314 | CALL_SUBTEST_3(comparisons(Matrix4d())); |
| 315 | CALL_SUBTEST_5(comparisons( |
| 316 | MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
| 317 | CALL_SUBTEST_6(comparisons( |
| 318 | MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 319 | } |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 320 | for (int i = 0; i < g_repeat; i++) { |
| 321 | CALL_SUBTEST_1(cwise_min_max(Matrix<float, 1, 1>())); |
| 322 | CALL_SUBTEST_2(cwise_min_max(Matrix2f())); |
| 323 | CALL_SUBTEST_3(cwise_min_max(Matrix4d())); |
| 324 | CALL_SUBTEST_5(cwise_min_max( |
| 325 | MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
| 326 | CALL_SUBTEST_6(cwise_min_max( |
| 327 | MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
Abraham Bachrach | 039408c | 2012-01-11 11:00:30 -0500 | [diff] [blame] | 328 | } |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 329 | for (int i = 0; i < g_repeat; i++) { |
| 330 | CALL_SUBTEST_1(lpNorm(Matrix<float, 1, 1>())); |
| 331 | CALL_SUBTEST_2(lpNorm(Vector2f())); |
| 332 | CALL_SUBTEST_7(lpNorm(Vector3d())); |
| 333 | CALL_SUBTEST_8(lpNorm(Vector4f())); |
| 334 | CALL_SUBTEST_5(lpNorm(VectorXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
| 335 | CALL_SUBTEST_4(lpNorm(VectorXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 336 | } |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 337 | CALL_SUBTEST_5(lpNorm(VectorXf(0))); |
| 338 | CALL_SUBTEST_4(lpNorm(VectorXcf(0))); |
| 339 | for (int i = 0; i < g_repeat; i++) { |
| 340 | CALL_SUBTEST_4(resize( |
| 341 | MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
| 342 | CALL_SUBTEST_5( |
| 343 | resize(MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
| 344 | CALL_SUBTEST_6( |
| 345 | resize(MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE)))); |
Gael Guennebaud | 9da41cc | 2012-08-30 16:28:53 +0200 | [diff] [blame] | 346 | } |
Antonio Sánchez | 46e9cdb | 2023-12-05 21:22:55 +0000 | [diff] [blame] | 347 | CALL_SUBTEST_6(regression_bug_654<0>()); |
| 348 | CALL_SUBTEST_6(regrrssion_bug_1410<0>()); |
Gael Guennebaud | c70d542 | 2010-01-18 22:54:20 +0100 | [diff] [blame] | 349 | } |