Spaces:
Running on Zero
Running on Zero
Upload 191 files
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/AnnoyingScalar.h +204 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/CMakeLists.txt +506 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/CustomComplex.h +132 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/MovableScalar.h +54 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/OffByOneScalar.h +20 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/SafeScalar.h +33 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/accelerate_support.cpp +166 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/adjoint.cpp +236 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_cwise.cpp +1432 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_for_matrix.cpp +349 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_of_string.cpp +31 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_replicate.cpp +73 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_reverse.cpp +199 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/assignment_threaded.cpp +84 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bandmatrix.cpp +66 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/basicstuff.cpp +352 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bdcsvd.cpp +177 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bfloat16_float.cpp +402 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bicgstab.cpp +88 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/blasutil.cpp +178 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/block.cpp +381 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/boostmultiprec.cpp +212 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bug1213.cpp +7 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bug1213.h +7 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bug1213_main.cpp +13 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/cholesky.cpp +500 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/cholmod_support.cpp +81 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/clz.cpp +74 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/commainitializer.cpp +107 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/complex_qz.cpp +84 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/conjugate_gradient.cpp +33 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/conservative_resize.cpp +162 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/constexpr.cpp +82 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/constructor.cpp +97 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/corners.cpp +125 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/ctorleak.cpp +79 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/denseLM.cpp +172 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/dense_storage.cpp +285 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/determinant.cpp +65 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/diagonal.cpp +102 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/diagonal_matrix_variadic_ctor.cpp +150 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/diagonalmatrices.cpp +197 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/dontalign.cpp +60 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/dynalloc.cpp +168 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigen2support.cpp +62 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_complex.cpp +173 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_generalized_real.cpp +139 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_generic.cpp +233 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_selfadjoint.cpp +281 -0
- wheels/TRELLIS.2/o-voxels/third_party/eigen/test/evaluator_common.h +0 -0
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/AnnoyingScalar.h
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2011-2018 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#ifndef EIGEN_TEST_ANNOYING_SCALAR_H
|
| 11 |
+
#define EIGEN_TEST_ANNOYING_SCALAR_H
|
| 12 |
+
|
| 13 |
+
#include <ostream>
|
| 14 |
+
|
| 15 |
+
#if EIGEN_COMP_GNUC
|
| 16 |
+
#pragma GCC diagnostic ignored "-Wshadow"
|
| 17 |
+
#endif
|
| 18 |
+
|
| 19 |
+
#if defined(EIGEN_EXCEPTIONS) && !defined(EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW)
|
| 20 |
+
struct my_exception {
|
| 21 |
+
my_exception() {}
|
| 22 |
+
~my_exception() {}
|
| 23 |
+
};
|
| 24 |
+
#endif
|
| 25 |
+
|
| 26 |
+
// An AnnoyingScalar is a pseudo scalar type that:
|
| 27 |
+
// - can randomly through an exception in operator +
|
| 28 |
+
// - randomly allocate on the heap or initialize a reference to itself making it non trivially copyable, nor movable,
|
| 29 |
+
// nor relocatable.
|
| 30 |
+
|
| 31 |
+
class AnnoyingScalar {
|
| 32 |
+
public:
|
| 33 |
+
AnnoyingScalar() {
|
| 34 |
+
init();
|
| 35 |
+
*v = 0;
|
| 36 |
+
}
|
| 37 |
+
AnnoyingScalar(long double _v) {
|
| 38 |
+
init();
|
| 39 |
+
*v = static_cast<float>(_v);
|
| 40 |
+
}
|
| 41 |
+
AnnoyingScalar(double _v) {
|
| 42 |
+
init();
|
| 43 |
+
*v = static_cast<float>(_v);
|
| 44 |
+
}
|
| 45 |
+
AnnoyingScalar(float _v) {
|
| 46 |
+
init();
|
| 47 |
+
*v = _v;
|
| 48 |
+
}
|
| 49 |
+
AnnoyingScalar(int _v) {
|
| 50 |
+
init();
|
| 51 |
+
*v = static_cast<float>(_v);
|
| 52 |
+
}
|
| 53 |
+
AnnoyingScalar(long _v) {
|
| 54 |
+
init();
|
| 55 |
+
*v = static_cast<float>(_v);
|
| 56 |
+
}
|
| 57 |
+
AnnoyingScalar(long long _v) {
|
| 58 |
+
init();
|
| 59 |
+
*v = static_cast<float>(_v);
|
| 60 |
+
}
|
| 61 |
+
AnnoyingScalar(const AnnoyingScalar& other) {
|
| 62 |
+
init();
|
| 63 |
+
*v = *(other.v);
|
| 64 |
+
}
|
| 65 |
+
~AnnoyingScalar() {
|
| 66 |
+
if (v != &data) delete v;
|
| 67 |
+
instances--;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
void init() {
|
| 71 |
+
if (internal::random<bool>())
|
| 72 |
+
v = new float;
|
| 73 |
+
else
|
| 74 |
+
v = &data;
|
| 75 |
+
instances++;
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
AnnoyingScalar operator+(const AnnoyingScalar& other) const {
|
| 79 |
+
#if defined(EIGEN_EXCEPTIONS) && !defined(EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW)
|
| 80 |
+
countdown--;
|
| 81 |
+
if (countdown <= 0 && !dont_throw) throw my_exception();
|
| 82 |
+
#endif
|
| 83 |
+
return AnnoyingScalar(*v + *other.v);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
AnnoyingScalar operator-() const { return AnnoyingScalar(-*v); }
|
| 87 |
+
|
| 88 |
+
AnnoyingScalar operator-(const AnnoyingScalar& other) const { return AnnoyingScalar(*v - *other.v); }
|
| 89 |
+
|
| 90 |
+
AnnoyingScalar operator*(const AnnoyingScalar& other) const { return AnnoyingScalar((*v) * (*other.v)); }
|
| 91 |
+
|
| 92 |
+
AnnoyingScalar operator/(const AnnoyingScalar& other) const { return AnnoyingScalar((*v) / (*other.v)); }
|
| 93 |
+
|
| 94 |
+
AnnoyingScalar& operator+=(const AnnoyingScalar& other) {
|
| 95 |
+
*v += *other.v;
|
| 96 |
+
return *this;
|
| 97 |
+
}
|
| 98 |
+
AnnoyingScalar& operator-=(const AnnoyingScalar& other) {
|
| 99 |
+
*v -= *other.v;
|
| 100 |
+
return *this;
|
| 101 |
+
}
|
| 102 |
+
AnnoyingScalar& operator*=(const AnnoyingScalar& other) {
|
| 103 |
+
*v *= *other.v;
|
| 104 |
+
return *this;
|
| 105 |
+
}
|
| 106 |
+
AnnoyingScalar& operator/=(const AnnoyingScalar& other) {
|
| 107 |
+
*v /= *other.v;
|
| 108 |
+
return *this;
|
| 109 |
+
}
|
| 110 |
+
AnnoyingScalar& operator=(const AnnoyingScalar& other) {
|
| 111 |
+
*v = *other.v;
|
| 112 |
+
return *this;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
bool operator==(const AnnoyingScalar& other) const { return numext::equal_strict(*v, *other.v); }
|
| 116 |
+
bool operator!=(const AnnoyingScalar& other) const { return numext::not_equal_strict(*v, *other.v); }
|
| 117 |
+
bool operator<=(const AnnoyingScalar& other) const { return *v <= *other.v; }
|
| 118 |
+
bool operator<(const AnnoyingScalar& other) const { return *v < *other.v; }
|
| 119 |
+
bool operator>=(const AnnoyingScalar& other) const { return *v >= *other.v; }
|
| 120 |
+
bool operator>(const AnnoyingScalar& other) const { return *v > *other.v; }
|
| 121 |
+
|
| 122 |
+
float* v;
|
| 123 |
+
float data;
|
| 124 |
+
static int instances;
|
| 125 |
+
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
|
| 126 |
+
static int countdown;
|
| 127 |
+
static bool dont_throw;
|
| 128 |
+
#endif
|
| 129 |
+
};
|
| 130 |
+
|
| 131 |
+
AnnoyingScalar real(const AnnoyingScalar& x) { return x; }
|
| 132 |
+
AnnoyingScalar imag(const AnnoyingScalar&) { return 0; }
|
| 133 |
+
AnnoyingScalar conj(const AnnoyingScalar& x) { return x; }
|
| 134 |
+
AnnoyingScalar sqrt(const AnnoyingScalar& x) { return std::sqrt(*x.v); }
|
| 135 |
+
AnnoyingScalar abs(const AnnoyingScalar& x) { return std::abs(*x.v); }
|
| 136 |
+
AnnoyingScalar cos(const AnnoyingScalar& x) { return std::cos(*x.v); }
|
| 137 |
+
AnnoyingScalar sin(const AnnoyingScalar& x) { return std::sin(*x.v); }
|
| 138 |
+
AnnoyingScalar acos(const AnnoyingScalar& x) { return std::acos(*x.v); }
|
| 139 |
+
AnnoyingScalar atan2(const AnnoyingScalar& y, const AnnoyingScalar& x) { return std::atan2(*y.v, *x.v); }
|
| 140 |
+
|
| 141 |
+
std::ostream& operator<<(std::ostream& stream, const AnnoyingScalar& x) {
|
| 142 |
+
stream << (*(x.v));
|
| 143 |
+
return stream;
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
int AnnoyingScalar::instances = 0;
|
| 147 |
+
|
| 148 |
+
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
|
| 149 |
+
int AnnoyingScalar::countdown = 0;
|
| 150 |
+
bool AnnoyingScalar::dont_throw = false;
|
| 151 |
+
#endif
|
| 152 |
+
|
| 153 |
+
namespace Eigen {
|
| 154 |
+
template <>
|
| 155 |
+
struct NumTraits<AnnoyingScalar> : NumTraits<float> {
|
| 156 |
+
enum {
|
| 157 |
+
RequireInitialization = 1,
|
| 158 |
+
};
|
| 159 |
+
typedef AnnoyingScalar Real;
|
| 160 |
+
typedef AnnoyingScalar Nested;
|
| 161 |
+
typedef AnnoyingScalar Literal;
|
| 162 |
+
typedef AnnoyingScalar NonInteger;
|
| 163 |
+
};
|
| 164 |
+
|
| 165 |
+
template <>
|
| 166 |
+
inline AnnoyingScalar test_precision<AnnoyingScalar>() {
|
| 167 |
+
return test_precision<float>();
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
namespace numext {
|
| 171 |
+
template <>
|
| 172 |
+
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isfinite)(const AnnoyingScalar& x) {
|
| 173 |
+
return (numext::isfinite)(*x.v);
|
| 174 |
+
}
|
| 175 |
+
} // namespace numext
|
| 176 |
+
|
| 177 |
+
namespace internal {
|
| 178 |
+
template <>
|
| 179 |
+
EIGEN_STRONG_INLINE double cast(const AnnoyingScalar& x) {
|
| 180 |
+
return double(*x.v);
|
| 181 |
+
}
|
| 182 |
+
template <>
|
| 183 |
+
EIGEN_STRONG_INLINE float cast(const AnnoyingScalar& x) {
|
| 184 |
+
return *x.v;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
} // namespace internal
|
| 188 |
+
} // namespace Eigen
|
| 189 |
+
|
| 190 |
+
AnnoyingScalar get_test_precision(const AnnoyingScalar&) { return Eigen::test_precision<AnnoyingScalar>(); }
|
| 191 |
+
|
| 192 |
+
AnnoyingScalar test_relative_error(const AnnoyingScalar& a, const AnnoyingScalar& b) {
|
| 193 |
+
return test_relative_error(*a.v, *b.v);
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
inline bool test_isApprox(const AnnoyingScalar& a, const AnnoyingScalar& b) {
|
| 197 |
+
return internal::isApprox(*a.v, *b.v, test_precision<float>());
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
inline bool test_isMuchSmallerThan(const AnnoyingScalar& a, const AnnoyingScalar& b) {
|
| 201 |
+
return test_isMuchSmallerThan(*a.v, *b.v);
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
#endif // EIGEN_TEST_ANNOYING_SCALAR_H
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/CMakeLists.txt
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# The file split_test_helper.h was generated at first run,
|
| 2 |
+
# it is now included in test/
|
| 3 |
+
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/split_test_helper.h)
|
| 4 |
+
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/split_test_helper.h)
|
| 5 |
+
endif()
|
| 6 |
+
|
| 7 |
+
# check if we have a Fortran compiler
|
| 8 |
+
include(CheckLanguage)
|
| 9 |
+
check_language(Fortran)
|
| 10 |
+
if(CMAKE_Fortran_COMPILER)
|
| 11 |
+
enable_language(Fortran)
|
| 12 |
+
set(EIGEN_Fortran_COMPILER_WORKS ON)
|
| 13 |
+
else()
|
| 14 |
+
set(EIGEN_Fortran_COMPILER_WORKS OFF)
|
| 15 |
+
# search for a default Lapack library to complete Eigen's one
|
| 16 |
+
find_package(LAPACK QUIET)
|
| 17 |
+
endif()
|
| 18 |
+
|
| 19 |
+
# TODO do the same for EXTERNAL_LAPACK
|
| 20 |
+
option(EIGEN_TEST_EXTERNAL_BLAS "Use external BLAS library for testsuite" OFF)
|
| 21 |
+
if(EIGEN_TEST_EXTERNAL_BLAS)
|
| 22 |
+
find_package(BLAS REQUIRED)
|
| 23 |
+
message(STATUS "BLAS_COMPILER_FLAGS: ${BLAS_COMPILER_FLAGS}")
|
| 24 |
+
add_definitions("-DEIGEN_USE_BLAS") # is adding ${BLAS_COMPILER_FLAGS} necessary?
|
| 25 |
+
list(APPEND EXTERNAL_LIBS "${BLAS_LIBRARIES}")
|
| 26 |
+
endif()
|
| 27 |
+
|
| 28 |
+
# configure blas/lapack (use Eigen's ones)
|
| 29 |
+
set(EIGEN_BLAS_LIBRARIES eigen_blas)
|
| 30 |
+
set(EIGEN_LAPACK_LIBRARIES eigen_lapack)
|
| 31 |
+
|
| 32 |
+
set(EIGEN_TEST_MATRIX_DIR "" CACHE STRING "Enable testing of realword sparse matrices contained in the specified path")
|
| 33 |
+
if(EIGEN_TEST_MATRIX_DIR)
|
| 34 |
+
if(NOT WIN32)
|
| 35 |
+
message(STATUS "Test realworld sparse matrices: ${EIGEN_TEST_MATRIX_DIR}")
|
| 36 |
+
add_definitions( -DTEST_REAL_CASES="${EIGEN_TEST_MATRIX_DIR}" )
|
| 37 |
+
else()
|
| 38 |
+
message(STATUS "REAL CASES CAN NOT BE CURRENTLY TESTED ON WIN32")
|
| 39 |
+
endif()
|
| 40 |
+
endif()
|
| 41 |
+
|
| 42 |
+
set(SPARSE_LIBS " ")
|
| 43 |
+
|
| 44 |
+
find_package(CHOLMOD)
|
| 45 |
+
if(CHOLMOD_FOUND AND EIGEN_BUILD_BLAS AND EIGEN_BUILD_LAPACK)
|
| 46 |
+
add_definitions("-DEIGEN_CHOLMOD_SUPPORT")
|
| 47 |
+
include_directories(${CHOLMOD_INCLUDES})
|
| 48 |
+
set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES})
|
| 49 |
+
set(CHOLMOD_ALL_LIBS ${CHOLMOD_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES})
|
| 50 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "CHOLMOD, ")
|
| 51 |
+
|
| 52 |
+
ei_add_test(cholmod_support "" "${CHOLMOD_ALL_LIBS}")
|
| 53 |
+
else()
|
| 54 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "CHOLMOD, ")
|
| 55 |
+
endif()
|
| 56 |
+
|
| 57 |
+
find_package(UMFPACK)
|
| 58 |
+
if(UMFPACK_FOUND AND EIGEN_BUILD_BLAS)
|
| 59 |
+
add_definitions("-DEIGEN_UMFPACK_SUPPORT")
|
| 60 |
+
include_directories(${UMFPACK_INCLUDES})
|
| 61 |
+
set(SPARSE_LIBS ${SPARSE_LIBS} ${UMFPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
|
| 62 |
+
set(UMFPACK_ALL_LIBS ${UMFPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
|
| 63 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "UMFPACK, ")
|
| 64 |
+
|
| 65 |
+
ei_add_test(umfpack_support "" "${UMFPACK_ALL_LIBS}")
|
| 66 |
+
else()
|
| 67 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "UMFPACK, ")
|
| 68 |
+
endif()
|
| 69 |
+
|
| 70 |
+
find_package(KLU)
|
| 71 |
+
if(KLU_FOUND AND EIGEN_BUILD_BLAS)
|
| 72 |
+
add_definitions("-DEIGEN_KLU_SUPPORT")
|
| 73 |
+
include_directories(${KLU_INCLUDES})
|
| 74 |
+
set(SPARSE_LIBS ${SPARSE_LIBS} ${KLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
|
| 75 |
+
set(KLU_ALL_LIBS ${KLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
|
| 76 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "KLU, ")
|
| 77 |
+
|
| 78 |
+
ei_add_test(klu_support "" "${KLU_ALL_LIBS}")
|
| 79 |
+
else()
|
| 80 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "KLU, ")
|
| 81 |
+
endif()
|
| 82 |
+
|
| 83 |
+
find_package(SuperLU 4.0)
|
| 84 |
+
if(SuperLU_FOUND AND EIGEN_BUILD_BLAS)
|
| 85 |
+
add_definitions("-DEIGEN_SUPERLU_SUPPORT")
|
| 86 |
+
include_directories(${SUPERLU_INCLUDES})
|
| 87 |
+
set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
|
| 88 |
+
set(SUPERLU_ALL_LIBS ${SUPERLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
|
| 89 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "SuperLU, ")
|
| 90 |
+
|
| 91 |
+
ei_add_test(superlu_support "" "${SUPERLU_ALL_LIBS}")
|
| 92 |
+
else()
|
| 93 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "SuperLU, ")
|
| 94 |
+
endif()
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
find_package(PASTIX QUIET COMPONENTS METIS SEQ)
|
| 98 |
+
# check that the PASTIX found is a version without MPI
|
| 99 |
+
find_path(PASTIX_pastix_nompi.h_INCLUDE_DIRS
|
| 100 |
+
NAMES pastix_nompi.h
|
| 101 |
+
HINTS ${PASTIX_INCLUDE_DIRS}
|
| 102 |
+
)
|
| 103 |
+
if (NOT PASTIX_pastix_nompi.h_INCLUDE_DIRS)
|
| 104 |
+
message(STATUS "A version of Pastix has been found but pastix_nompi.h does not exist in the include directory."
|
| 105 |
+
" Because Eigen tests require a version without MPI, we disable the Pastix backend.")
|
| 106 |
+
endif()
|
| 107 |
+
if(PASTIX_FOUND AND PASTIX_pastix_nompi.h_INCLUDE_DIRS)
|
| 108 |
+
add_definitions("-DEIGEN_PASTIX_SUPPORT")
|
| 109 |
+
include_directories(${PASTIX_INCLUDE_DIRS_DEP})
|
| 110 |
+
if(SCOTCH_FOUND)
|
| 111 |
+
include_directories(${SCOTCH_INCLUDE_DIRS})
|
| 112 |
+
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})
|
| 113 |
+
elseif(METIS_FOUND)
|
| 114 |
+
include_directories(${METIS_INCLUDE_DIRS})
|
| 115 |
+
set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${METIS_LIBRARIES})
|
| 116 |
+
else()
|
| 117 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "PaStiX, ")
|
| 118 |
+
endif()
|
| 119 |
+
set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES_DEP} ${ORDERING_LIBRARIES})
|
| 120 |
+
set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES_DEP})
|
| 121 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "PaStiX, ")
|
| 122 |
+
else()
|
| 123 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "PaStiX, ")
|
| 124 |
+
endif()
|
| 125 |
+
|
| 126 |
+
if(METIS_FOUND)
|
| 127 |
+
add_definitions("-DEIGEN_METIS_SUPPORT")
|
| 128 |
+
include_directories(${METIS_INCLUDE_DIRS})
|
| 129 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "METIS, ")
|
| 130 |
+
else()
|
| 131 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "METIS, ")
|
| 132 |
+
endif()
|
| 133 |
+
|
| 134 |
+
find_package(SPQR)
|
| 135 |
+
if(SPQR_FOUND AND CHOLMOD_FOUND AND EIGEN_BUILD_BLAS AND EIGEN_BUILD_LAPACK AND (EIGEN_Fortran_COMPILER_WORKS OR LAPACK_FOUND) )
|
| 136 |
+
add_definitions("-DEIGEN_SPQR_SUPPORT")
|
| 137 |
+
include_directories(${SPQR_INCLUDES})
|
| 138 |
+
set(SPQR_ALL_LIBS ${SPQR_LIBRARIES} ${CHOLMOD_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
|
| 139 |
+
set(SPARSE_LIBS ${SPARSE_LIBS} ${SPQR_ALL_LIBS})
|
| 140 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "SPQR, ")
|
| 141 |
+
else()
|
| 142 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "SPQR, ")
|
| 143 |
+
endif()
|
| 144 |
+
|
| 145 |
+
find_package(Accelerate)
|
| 146 |
+
if(Accelerate_FOUND)
|
| 147 |
+
add_definitions("-DEIGEN_ACCELERATE_SUPPORT")
|
| 148 |
+
include_directories(${Accelerate_INCLUDES})
|
| 149 |
+
set(SPARSE_LIBS ${SPARSE_LIBS} ${Accelerate_LIBRARIES})
|
| 150 |
+
set(Accelerate_ALL_LIBS ${Accelerate_LIBRARIES})
|
| 151 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "Accelerate, ")
|
| 152 |
+
else()
|
| 153 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "Accelerate, ")
|
| 154 |
+
endif()
|
| 155 |
+
|
| 156 |
+
option(EIGEN_TEST_NOQT "Disable Qt support in unit tests" OFF)
|
| 157 |
+
if(NOT EIGEN_TEST_NOQT)
|
| 158 |
+
find_package(Qt4)
|
| 159 |
+
if(QT4_FOUND)
|
| 160 |
+
include(${QT_USE_FILE})
|
| 161 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "Qt4 support, ")
|
| 162 |
+
else()
|
| 163 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "Qt4 support, ")
|
| 164 |
+
endif()
|
| 165 |
+
endif()
|
| 166 |
+
|
| 167 |
+
if(TEST_LIB)
|
| 168 |
+
add_definitions("-DEIGEN_EXTERN_INSTANTIATIONS=1")
|
| 169 |
+
endif()
|
| 170 |
+
|
| 171 |
+
set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official")
|
| 172 |
+
add_custom_target(BuildOfficial)
|
| 173 |
+
|
| 174 |
+
ei_add_test(clz)
|
| 175 |
+
ei_add_test(rand)
|
| 176 |
+
ei_add_test(meta)
|
| 177 |
+
ei_add_test(maxsizevector)
|
| 178 |
+
ei_add_test(numext)
|
| 179 |
+
ei_add_test(sizeof)
|
| 180 |
+
ei_add_test(dynalloc)
|
| 181 |
+
ei_add_test(nomalloc)
|
| 182 |
+
ei_add_test(first_aligned)
|
| 183 |
+
ei_add_test(type_alias)
|
| 184 |
+
ei_add_test(nullary)
|
| 185 |
+
ei_add_test(mixingtypes)
|
| 186 |
+
ei_add_test(float_conversion)
|
| 187 |
+
ei_add_test(io)
|
| 188 |
+
ei_add_test(packetmath "-DEIGEN_FAST_MATH=1")
|
| 189 |
+
ei_add_test(packet_segment)
|
| 190 |
+
ei_add_test(vectorization_logic)
|
| 191 |
+
ei_add_test(basicstuff)
|
| 192 |
+
ei_add_test(constexpr)
|
| 193 |
+
ei_add_test(constructor)
|
| 194 |
+
ei_add_test(linearstructure)
|
| 195 |
+
ei_add_test(integer_types)
|
| 196 |
+
ei_add_test(unalignedcount)
|
| 197 |
+
if(NOT EIGEN_TEST_NO_EXCEPTIONS AND NOT EIGEN_TEST_OPENMP)
|
| 198 |
+
ei_add_test(exceptions)
|
| 199 |
+
endif()
|
| 200 |
+
ei_add_test(redux)
|
| 201 |
+
ei_add_test(visitor)
|
| 202 |
+
ei_add_test(block)
|
| 203 |
+
ei_add_test(corners)
|
| 204 |
+
ei_add_test(symbolic_index)
|
| 205 |
+
ei_add_test(indexed_view)
|
| 206 |
+
ei_add_test(reshape)
|
| 207 |
+
ei_add_test(swap)
|
| 208 |
+
ei_add_test(resize)
|
| 209 |
+
ei_add_test(conservative_resize)
|
| 210 |
+
ei_add_test(product_small)
|
| 211 |
+
ei_add_test(product_large)
|
| 212 |
+
ei_add_test(product_extra)
|
| 213 |
+
ei_add_test(diagonalmatrices)
|
| 214 |
+
ei_add_test(skew_symmetric_matrix3)
|
| 215 |
+
ei_add_test(adjoint)
|
| 216 |
+
ei_add_test(diagonal)
|
| 217 |
+
ei_add_test(miscmatrices)
|
| 218 |
+
ei_add_test(commainitializer)
|
| 219 |
+
ei_add_test(smallvectors)
|
| 220 |
+
ei_add_test(mapped_matrix)
|
| 221 |
+
ei_add_test(mapstride)
|
| 222 |
+
ei_add_test(unaryview)
|
| 223 |
+
ei_add_test(mapstaticmethods)
|
| 224 |
+
ei_add_test(array_cwise)
|
| 225 |
+
ei_add_test(matrix_cwise)
|
| 226 |
+
ei_add_test(array_for_matrix)
|
| 227 |
+
ei_add_test(array_replicate)
|
| 228 |
+
ei_add_test(array_reverse)
|
| 229 |
+
ei_add_test(ref)
|
| 230 |
+
ei_add_test(is_same_dense)
|
| 231 |
+
ei_add_test(triangular)
|
| 232 |
+
ei_add_test(selfadjoint)
|
| 233 |
+
ei_add_test(product_selfadjoint)
|
| 234 |
+
ei_add_test(product_symm)
|
| 235 |
+
ei_add_test(product_syrk)
|
| 236 |
+
ei_add_test(product_trmv)
|
| 237 |
+
ei_add_test(product_trmm)
|
| 238 |
+
ei_add_test(product_trsolve)
|
| 239 |
+
ei_add_test(product_mmtr)
|
| 240 |
+
ei_add_test(product_notemporary)
|
| 241 |
+
ei_add_test(product_threaded "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
| 242 |
+
ei_add_test(stable_norm)
|
| 243 |
+
ei_add_test(permutationmatrices)
|
| 244 |
+
ei_add_test(bandmatrix)
|
| 245 |
+
ei_add_test(cholesky)
|
| 246 |
+
ei_add_test(lu)
|
| 247 |
+
ei_add_test(determinant)
|
| 248 |
+
ei_add_test(inverse)
|
| 249 |
+
ei_add_test(qr)
|
| 250 |
+
ei_add_test(qr_colpivoting)
|
| 251 |
+
ei_add_test(qr_fullpivoting)
|
| 252 |
+
ei_add_test(upperbidiagonalization)
|
| 253 |
+
ei_add_test(hessenberg)
|
| 254 |
+
ei_add_test(schur_real)
|
| 255 |
+
ei_add_test(schur_complex)
|
| 256 |
+
ei_add_test(eigensolver_selfadjoint)
|
| 257 |
+
ei_add_test(eigensolver_generic)
|
| 258 |
+
ei_add_test(eigensolver_complex)
|
| 259 |
+
ei_add_test(real_qz)
|
| 260 |
+
ei_add_test(complex_qz)
|
| 261 |
+
ei_add_test(eigensolver_generalized_real)
|
| 262 |
+
ei_add_test(jacobi)
|
| 263 |
+
ei_add_test(jacobisvd)
|
| 264 |
+
ei_add_test(bdcsvd)
|
| 265 |
+
ei_add_test(householder)
|
| 266 |
+
ei_add_test(geo_orthomethods)
|
| 267 |
+
ei_add_test(geo_quaternion)
|
| 268 |
+
ei_add_test(geo_eulerangles)
|
| 269 |
+
ei_add_test(geo_parametrizedline)
|
| 270 |
+
ei_add_test(geo_alignedbox)
|
| 271 |
+
ei_add_test(geo_hyperplane)
|
| 272 |
+
ei_add_test(geo_transformations)
|
| 273 |
+
ei_add_test(geo_homogeneous)
|
| 274 |
+
ei_add_test(stdvector)
|
| 275 |
+
ei_add_test(stdvector_overload)
|
| 276 |
+
ei_add_test(stdlist)
|
| 277 |
+
ei_add_test(stdlist_overload)
|
| 278 |
+
ei_add_test(stddeque)
|
| 279 |
+
ei_add_test(stddeque_overload)
|
| 280 |
+
ei_add_test(sparse_basic)
|
| 281 |
+
ei_add_test(sparse_block)
|
| 282 |
+
ei_add_test(sparse_vector)
|
| 283 |
+
ei_add_test(sparse_product)
|
| 284 |
+
ei_add_test(sparse_ref)
|
| 285 |
+
ei_add_test(sparse_solvers)
|
| 286 |
+
ei_add_test(sparse_permutations)
|
| 287 |
+
ei_add_test(simplicial_cholesky)
|
| 288 |
+
ei_add_test(conjugate_gradient)
|
| 289 |
+
ei_add_test(incomplete_cholesky)
|
| 290 |
+
ei_add_test(incomplete_LUT)
|
| 291 |
+
ei_add_test(bicgstab)
|
| 292 |
+
ei_add_test(lscg)
|
| 293 |
+
ei_add_test(sparselu)
|
| 294 |
+
ei_add_test(sparseqr)
|
| 295 |
+
ei_add_test(umeyama)
|
| 296 |
+
ei_add_test(nesting_ops "${CMAKE_CXX_FLAGS_DEBUG}")
|
| 297 |
+
ei_add_test(nestbyvalue)
|
| 298 |
+
ei_add_test(zerosized)
|
| 299 |
+
ei_add_test(dontalign)
|
| 300 |
+
ei_add_test(evaluators)
|
| 301 |
+
if(NOT EIGEN_TEST_NO_EXCEPTIONS)
|
| 302 |
+
ei_add_test(sizeoverflow)
|
| 303 |
+
endif()
|
| 304 |
+
ei_add_test(prec_inverse_4x4)
|
| 305 |
+
ei_add_test(vectorwiseop)
|
| 306 |
+
ei_add_test(special_numbers)
|
| 307 |
+
ei_add_test(rvalue_types)
|
| 308 |
+
ei_add_test(dense_storage)
|
| 309 |
+
ei_add_test(ctorleak)
|
| 310 |
+
ei_add_test(inplace_decomposition)
|
| 311 |
+
ei_add_test(half_float)
|
| 312 |
+
ei_add_test(bfloat16_float)
|
| 313 |
+
ei_add_test(array_of_string)
|
| 314 |
+
ei_add_test(num_dimensions)
|
| 315 |
+
ei_add_test(stl_iterators)
|
| 316 |
+
ei_add_test(blasutil)
|
| 317 |
+
ei_add_test(random_matrix)
|
| 318 |
+
ei_add_test(initializer_list_construction)
|
| 319 |
+
ei_add_test(diagonal_matrix_variadic_ctor)
|
| 320 |
+
ei_add_test(serializer)
|
| 321 |
+
ei_add_test(tuple_test)
|
| 322 |
+
ei_add_test(threads_eventcount "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
| 323 |
+
ei_add_test(threads_runqueue "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
| 324 |
+
ei_add_test(threads_non_blocking_thread_pool "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
| 325 |
+
ei_add_test(threads_fork_join "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
| 326 |
+
add_executable(bug1213 bug1213.cpp bug1213_main.cpp)
|
| 327 |
+
target_link_libraries(bug1213 Eigen3::Eigen)
|
| 328 |
+
|
| 329 |
+
check_cxx_compiler_flag("-ffast-math" COMPILER_SUPPORT_FASTMATH)
|
| 330 |
+
if(COMPILER_SUPPORT_FASTMATH)
|
| 331 |
+
set(EIGEN_FASTMATH_FLAGS "-ffast-math")
|
| 332 |
+
else()
|
| 333 |
+
check_cxx_compiler_flag("/fp:fast" COMPILER_SUPPORT_FPFAST)
|
| 334 |
+
if(COMPILER_SUPPORT_FPFAST)
|
| 335 |
+
set(EIGEN_FASTMATH_FLAGS "/fp:fast")
|
| 336 |
+
endif()
|
| 337 |
+
endif()
|
| 338 |
+
|
| 339 |
+
ei_add_test(fastmath "${EIGEN_FASTMATH_FLAGS}")
|
| 340 |
+
|
| 341 |
+
# # ei_add_test(denseLM)
|
| 342 |
+
|
| 343 |
+
if(QT4_FOUND)
|
| 344 |
+
ei_add_test(qtvector "" "${QT_QTCORE_LIBRARY}")
|
| 345 |
+
endif()
|
| 346 |
+
|
| 347 |
+
if(PARDISO_FOUND)
|
| 348 |
+
ei_add_test(pardiso_support "" "${PARDISO_ALL_LIBS}")
|
| 349 |
+
endif()
|
| 350 |
+
|
| 351 |
+
if(PASTIX_FOUND AND (SCOTCH_FOUND OR METIS_FOUND))
|
| 352 |
+
ei_add_test(pastix_support "" "${PASTIX_ALL_LIBS}")
|
| 353 |
+
endif()
|
| 354 |
+
|
| 355 |
+
if(SPQR_FOUND AND CHOLMOD_FOUND AND EIGEN_BUILD_BLAS AND EIGEN_BUILD_LAPACK)
|
| 356 |
+
ei_add_test(spqr_support "" "${SPQR_ALL_LIBS}")
|
| 357 |
+
endif()
|
| 358 |
+
|
| 359 |
+
if(METIS_FOUND)
|
| 360 |
+
ei_add_test(metis_support "" "${METIS_LIBRARIES}")
|
| 361 |
+
endif()
|
| 362 |
+
|
| 363 |
+
if(Accelerate_FOUND)
|
| 364 |
+
ei_add_test(accelerate_support "" "${Accelerate_ALL_LIBS}")
|
| 365 |
+
endif()
|
| 366 |
+
|
| 367 |
+
string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower)
|
| 368 |
+
if(cmake_cxx_compiler_tolower MATCHES "qcc")
|
| 369 |
+
set(CXX_IS_QCC "ON")
|
| 370 |
+
endif()
|
| 371 |
+
|
| 372 |
+
ei_add_property(EIGEN_TESTING_SUMMARY "CXX: ${CMAKE_CXX_COMPILER}\n")
|
| 373 |
+
if(CMAKE_COMPILER_IS_GNUCXX AND NOT CXX_IS_QCC)
|
| 374 |
+
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)
|
| 375 |
+
ei_add_property(EIGEN_TESTING_SUMMARY "CXX_VERSION: ${EIGEN_CXX_VERSION_STRING}\n")
|
| 376 |
+
endif()
|
| 377 |
+
ei_add_property(EIGEN_TESTING_SUMMARY "CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n")
|
| 378 |
+
if (EIGEN_TEST_CUSTOM_CXX_FLAGS)
|
| 379 |
+
ei_add_property(EIGEN_TESTING_SUMMARY "Custom CXX flags: ${EIGEN_TEST_CUSTOM_CXX_FLAGS}\n")
|
| 380 |
+
endif()
|
| 381 |
+
ei_add_property(EIGEN_TESTING_SUMMARY "Sparse lib flags: ${SPARSE_LIBS}\n")
|
| 382 |
+
|
| 383 |
+
option(EIGEN_TEST_EIGEN2 "Run whole Eigen2 test suite against EIGEN2_SUPPORT" OFF)
|
| 384 |
+
mark_as_advanced(EIGEN_TEST_EIGEN2)
|
| 385 |
+
if(EIGEN_TEST_EIGEN2)
|
| 386 |
+
message(WARNING "The Eigen2 test suite has been removed")
|
| 387 |
+
endif()
|
| 388 |
+
|
| 389 |
+
# boost MP unit test
|
| 390 |
+
find_package(Boost 1.53.0 CONFIG)
|
| 391 |
+
if(Boost_FOUND)
|
| 392 |
+
include_directories(${Boost_INCLUDE_DIRS})
|
| 393 |
+
ei_add_test(boostmultiprec "" "${Boost_LIBRARIES}")
|
| 394 |
+
ei_add_property(EIGEN_TESTED_BACKENDS "Boost.Multiprecision, ")
|
| 395 |
+
else()
|
| 396 |
+
ei_add_property(EIGEN_MISSING_BACKENDS "Boost.Multiprecision, ")
|
| 397 |
+
endif()
|
| 398 |
+
|
| 399 |
+
|
| 400 |
+
# CUDA unit tests
|
| 401 |
+
option(EIGEN_TEST_CUDA "Enable CUDA support in unit tests" OFF)
|
| 402 |
+
option(EIGEN_TEST_CUDA_CLANG "Use clang instead of nvcc to compile the CUDA tests" OFF)
|
| 403 |
+
|
| 404 |
+
if(EIGEN_TEST_CUDA_CLANG AND NOT CMAKE_CXX_COMPILER MATCHES "clang")
|
| 405 |
+
message(WARNING "EIGEN_TEST_CUDA_CLANG is set, but CMAKE_CXX_COMPILER does not appear to be clang.")
|
| 406 |
+
endif()
|
| 407 |
+
|
| 408 |
+
find_package(CUDA 9.0)
|
| 409 |
+
if(CUDA_FOUND AND EIGEN_TEST_CUDA)
|
| 410 |
+
# Make sure to compile without the -pedantic, -Wundef, -Wnon-virtual-dtor
|
| 411 |
+
# and -fno-check-new flags since they trigger thousands of compilation warnings
|
| 412 |
+
# in the CUDA runtime
|
| 413 |
+
string(REPLACE "-pedantic" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
| 414 |
+
string(REPLACE "-Wundef" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
| 415 |
+
string(REPLACE "-Wnon-virtual-dtor" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
| 416 |
+
string(REPLACE "-fno-check-new" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
| 417 |
+
|
| 418 |
+
if(EIGEN_TEST_CUDA_CLANG)
|
| 419 |
+
string(APPEND CMAKE_CXX_FLAGS " --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}")
|
| 420 |
+
foreach(GPU IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
|
| 421 |
+
string(APPEND CMAKE_CXX_FLAGS " --cuda-gpu-arch=sm_${GPU}")
|
| 422 |
+
endforeach()
|
| 423 |
+
string(APPEND CMAKE_CXX_FLAGS " ${EIGEN_CUDA_CXX_FLAGS}")
|
| 424 |
+
else()
|
| 425 |
+
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
|
| 426 |
+
set(NVCC_ARCH_FLAGS)
|
| 427 |
+
# Define an -arch=sm_<arch>, otherwise if GPU does not exactly match one of
|
| 428 |
+
# those in the arch list for -gencode, the kernels will fail to run with
|
| 429 |
+
# cudaErrorNoKernelImageForDevice
|
| 430 |
+
# This can happen with newer cards (e.g. sm_75) and compiling with older
|
| 431 |
+
# versions of nvcc (e.g. 9.2) that do not support their specific arch.
|
| 432 |
+
list(LENGTH EIGEN_CUDA_COMPUTE_ARCH EIGEN_CUDA_COMPUTE_ARCH_SIZE)
|
| 433 |
+
if(EIGEN_CUDA_COMPUTE_ARCH_SIZE)
|
| 434 |
+
list(GET EIGEN_CUDA_COMPUTE_ARCH 0 EIGEN_CUDA_COMPUTE_DEFAULT)
|
| 435 |
+
set(NVCC_ARCH_FLAGS " -arch=sm_${EIGEN_CUDA_COMPUTE_DEFAULT}")
|
| 436 |
+
endif()
|
| 437 |
+
foreach(ARCH IN LISTS EIGEN_CUDA_COMPUTE_ARCH)
|
| 438 |
+
string(APPEND NVCC_ARCH_FLAGS " -gencode arch=compute_${ARCH},code=sm_${ARCH}")
|
| 439 |
+
endforeach()
|
| 440 |
+
set(CUDA_NVCC_FLAGS "--expt-relaxed-constexpr -Xcudafe \"--display_error_number\" ${NVCC_ARCH_FLAGS} ${CUDA_NVCC_FLAGS} ${EIGEN_CUDA_CXX_FLAGS}")
|
| 441 |
+
cuda_include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}/include")
|
| 442 |
+
endif()
|
| 443 |
+
|
| 444 |
+
set(EIGEN_ADD_TEST_FILENAME_EXTENSION "cu")
|
| 445 |
+
|
| 446 |
+
ei_add_test(gpu_example)
|
| 447 |
+
ei_add_test(gpu_basic)
|
| 448 |
+
|
| 449 |
+
unset(EIGEN_ADD_TEST_FILENAME_EXTENSION)
|
| 450 |
+
|
| 451 |
+
endif()
|
| 452 |
+
|
| 453 |
+
|
| 454 |
+
# HIP unit tests
|
| 455 |
+
option(EIGEN_TEST_HIP "Add HIP support." OFF)
|
| 456 |
+
if (EIGEN_TEST_HIP)
|
| 457 |
+
|
| 458 |
+
set(ROCM_PATH "/opt/rocm" CACHE STRING "Path to the ROCm installation.")
|
| 459 |
+
|
| 460 |
+
if (EXISTS ${ROCM_PATH}/hip)
|
| 461 |
+
set(HIP_PATH ${ROCM_PATH}/hip)
|
| 462 |
+
list(APPEND CMAKE_MODULE_PATH ${HIP_PATH}/cmake)
|
| 463 |
+
elseif (EXISTS ${ROCM_PATH}/lib/cmake/hip)
|
| 464 |
+
set(HIP_PATH ${ROCM_PATH})
|
| 465 |
+
list(APPEND CMAKE_MODULE_PATH ${HIP_PATH}/lib/cmake/hip)
|
| 466 |
+
else ()
|
| 467 |
+
message(FATAL_ERROR "EIGEN_TEST_HIP is ON, but could not find the ROCm installation under ${ROCM_PATH}")
|
| 468 |
+
endif()
|
| 469 |
+
|
| 470 |
+
find_package(HIP REQUIRED)
|
| 471 |
+
if (HIP_FOUND)
|
| 472 |
+
execute_process(COMMAND ${HIP_PATH}/bin/hipconfig --platform OUTPUT_VARIABLE HIP_PLATFORM)
|
| 473 |
+
|
| 474 |
+
if ((${HIP_PLATFORM} STREQUAL "hcc") OR (${HIP_PLATFORM} STREQUAL "amd"))
|
| 475 |
+
|
| 476 |
+
include_directories(${HIP_PATH}/include)
|
| 477 |
+
|
| 478 |
+
set(EIGEN_ADD_TEST_FILENAME_EXTENSION "cu")
|
| 479 |
+
ei_add_test(gpu_basic)
|
| 480 |
+
ei_add_test(gpu_example)
|
| 481 |
+
unset(EIGEN_ADD_TEST_FILENAME_EXTENSION)
|
| 482 |
+
|
| 483 |
+
elseif ((${HIP_PLATFORM} STREQUAL "nvcc") OR (${HIP_PLATFORM} STREQUAL "nvidia"))
|
| 484 |
+
message(FATAL_ERROR "HIP_PLATFORM = nvcc is not supported within Eigen")
|
| 485 |
+
else ()
|
| 486 |
+
message(FATAL_ERROR "Unknown HIP_PLATFORM = ${HIP_PLATFORM}")
|
| 487 |
+
endif()
|
| 488 |
+
endif()
|
| 489 |
+
endif()
|
| 490 |
+
|
| 491 |
+
if(EIGEN_TEST_SYCL)
|
| 492 |
+
set(EIGEN_SYCL ON)
|
| 493 |
+
include(SyclConfigureTesting)
|
| 494 |
+
|
| 495 |
+
ei_add_test(sycl_basic)
|
| 496 |
+
set(EIGEN_SYCL OFF)
|
| 497 |
+
endif()
|
| 498 |
+
|
| 499 |
+
cmake_dependent_option(EIGEN_TEST_BUILD_DOCUMENTATION "Test building the doxygen documentation" OFF "EIGEN_BUILD_DOC" OFF)
|
| 500 |
+
if(EIGEN_TEST_BUILD_DOCUMENTATION)
|
| 501 |
+
add_dependencies(buildtests doc)
|
| 502 |
+
endif()
|
| 503 |
+
|
| 504 |
+
# Register all smoke tests
|
| 505 |
+
include("EigenSmokeTestList")
|
| 506 |
+
ei_add_smoke_tests("${ei_smoke_test_list}")
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/CustomComplex.h
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2025 The Eigen Authors.
|
| 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 |
+
#ifndef EIGEN_TEST_CUSTOM_COMPLEX_H
|
| 11 |
+
#define EIGEN_TEST_CUSTOM_COMPLEX_H
|
| 12 |
+
|
| 13 |
+
#include <ostream>
|
| 14 |
+
#include <sstream>
|
| 15 |
+
|
| 16 |
+
namespace custom_complex {
|
| 17 |
+
|
| 18 |
+
template <typename Real>
|
| 19 |
+
struct CustomComplex {
|
| 20 |
+
CustomComplex() : re{0}, im{0} {}
|
| 21 |
+
CustomComplex(const CustomComplex& other) = default;
|
| 22 |
+
CustomComplex(CustomComplex&& other) = default;
|
| 23 |
+
CustomComplex& operator=(const CustomComplex& other) = default;
|
| 24 |
+
CustomComplex& operator=(CustomComplex&& other) = default;
|
| 25 |
+
CustomComplex(Real x) : re{x}, im{0} {}
|
| 26 |
+
CustomComplex(Real x, Real y) : re{x}, im{y} {}
|
| 27 |
+
|
| 28 |
+
CustomComplex operator+(const CustomComplex& other) const { return CustomComplex(re + other.re, im + other.im); }
|
| 29 |
+
|
| 30 |
+
CustomComplex operator-() const { return CustomComplex(-re, -im); }
|
| 31 |
+
|
| 32 |
+
CustomComplex operator-(const CustomComplex& other) const { return CustomComplex(re - other.re, im - other.im); }
|
| 33 |
+
|
| 34 |
+
CustomComplex operator*(const CustomComplex& other) const {
|
| 35 |
+
return CustomComplex(re * other.re - im * other.im, re * other.im + im * other.re);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
CustomComplex operator/(const CustomComplex& other) const {
|
| 39 |
+
// Smith's complex division (https://arxiv.org/pdf/1210.4539.pdf),
|
| 40 |
+
// guards against over/under-flow.
|
| 41 |
+
const bool scale_imag = numext::abs(other.im) <= numext::abs(other.re);
|
| 42 |
+
const Real rscale = scale_imag ? Real(1) : other.re / other.im;
|
| 43 |
+
const Real iscale = scale_imag ? other.im / other.re : Real(1);
|
| 44 |
+
const Real denominator = other.re * rscale + other.im * iscale;
|
| 45 |
+
return CustomComplex((re * rscale + im * iscale) / denominator, (im * rscale - re * iscale) / denominator);
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
CustomComplex& operator+=(const CustomComplex& other) {
|
| 49 |
+
*this = *this + other;
|
| 50 |
+
return *this;
|
| 51 |
+
}
|
| 52 |
+
CustomComplex& operator-=(const CustomComplex& other) {
|
| 53 |
+
*this = *this - other;
|
| 54 |
+
return *this;
|
| 55 |
+
}
|
| 56 |
+
CustomComplex& operator*=(const CustomComplex& other) {
|
| 57 |
+
*this = *this * other;
|
| 58 |
+
return *this;
|
| 59 |
+
}
|
| 60 |
+
CustomComplex& operator/=(const CustomComplex& other) {
|
| 61 |
+
*this = *this / other;
|
| 62 |
+
return *this;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
bool operator==(const CustomComplex& other) const {
|
| 66 |
+
return numext::equal_strict(re, other.re) && numext::equal_strict(im, other.im);
|
| 67 |
+
}
|
| 68 |
+
bool operator!=(const CustomComplex& other) const { return !(*this == other); }
|
| 69 |
+
|
| 70 |
+
friend CustomComplex operator+(const Real& a, const CustomComplex& b) { return CustomComplex(a + b.re, b.im); }
|
| 71 |
+
|
| 72 |
+
friend CustomComplex operator-(const Real& a, const CustomComplex& b) { return CustomComplex(a - b.re, -b.im); }
|
| 73 |
+
|
| 74 |
+
friend CustomComplex operator*(const Real& a, const CustomComplex& b) { return CustomComplex(a * b.re, a * b.im); }
|
| 75 |
+
|
| 76 |
+
friend CustomComplex operator*(const CustomComplex& a, const Real& b) { return CustomComplex(a.re * b, a.im * b); }
|
| 77 |
+
|
| 78 |
+
friend CustomComplex operator/(const CustomComplex& a, const Real& b) { return CustomComplex(a.re / b, a.im / b); }
|
| 79 |
+
|
| 80 |
+
friend std::ostream& operator<<(std::ostream& stream, const CustomComplex& x) {
|
| 81 |
+
std::stringstream ss;
|
| 82 |
+
ss << "(" << x.re << ", " << x.im << ")";
|
| 83 |
+
stream << ss.str();
|
| 84 |
+
return stream;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
Real re;
|
| 88 |
+
Real im;
|
| 89 |
+
};
|
| 90 |
+
|
| 91 |
+
template <typename Real>
|
| 92 |
+
Real real(const CustomComplex<Real>& x) {
|
| 93 |
+
return x.re;
|
| 94 |
+
}
|
| 95 |
+
template <typename Real>
|
| 96 |
+
Real imag(const CustomComplex<Real>& x) {
|
| 97 |
+
return x.im;
|
| 98 |
+
}
|
| 99 |
+
template <typename Real>
|
| 100 |
+
CustomComplex<Real> conj(const CustomComplex<Real>& x) {
|
| 101 |
+
return CustomComplex<Real>(x.re, -x.im);
|
| 102 |
+
}
|
| 103 |
+
template <typename Real>
|
| 104 |
+
CustomComplex<Real> sqrt(const CustomComplex<Real>& x) {
|
| 105 |
+
return Eigen::internal::complex_sqrt(x);
|
| 106 |
+
}
|
| 107 |
+
template <typename Real>
|
| 108 |
+
Real abs(const CustomComplex<Real>& x) {
|
| 109 |
+
return Eigen::numext::sqrt(x.re * x.re + x.im * x.im);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
} // namespace custom_complex
|
| 113 |
+
|
| 114 |
+
template <typename Real>
|
| 115 |
+
using CustomComplex = custom_complex::CustomComplex<Real>;
|
| 116 |
+
|
| 117 |
+
namespace Eigen {
|
| 118 |
+
template <typename Real>
|
| 119 |
+
struct NumTraits<CustomComplex<Real>> : NumTraits<Real> {
|
| 120 |
+
enum { IsComplex = 1 };
|
| 121 |
+
};
|
| 122 |
+
|
| 123 |
+
namespace numext {
|
| 124 |
+
template <typename Real>
|
| 125 |
+
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool(isfinite)(const CustomComplex<Real>& x) {
|
| 126 |
+
return (numext::isfinite)(x.re) && (numext::isfinite)(x.im);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
} // namespace numext
|
| 130 |
+
} // namespace Eigen
|
| 131 |
+
|
| 132 |
+
#endif // EIGEN_TEST_CUSTOM_COMPLEX_H
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/MovableScalar.h
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2020 Sebastien Boisvert <seb@boisvert.info>
|
| 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 |
+
#ifndef EIGEN_MISC_MOVABLE_SCALAR_H
|
| 11 |
+
#define EIGEN_MISC_MOVABLE_SCALAR_H
|
| 12 |
+
|
| 13 |
+
namespace Eigen {
|
| 14 |
+
template <typename Scalar>
|
| 15 |
+
struct MovableScalar {
|
| 16 |
+
MovableScalar() : m_data(new Scalar) {}
|
| 17 |
+
~MovableScalar() { delete m_data; }
|
| 18 |
+
MovableScalar(const MovableScalar& other) : m_data(new Scalar) { set(other.get()); }
|
| 19 |
+
MovableScalar(MovableScalar&& other) noexcept : m_data(other.m_data) { other.m_data = nullptr; }
|
| 20 |
+
MovableScalar& operator=(const MovableScalar& other) {
|
| 21 |
+
set(other.get());
|
| 22 |
+
return *this;
|
| 23 |
+
}
|
| 24 |
+
MovableScalar& operator=(MovableScalar&& other) noexcept {
|
| 25 |
+
m_data = other.m_data;
|
| 26 |
+
other.m_data = nullptr;
|
| 27 |
+
return *this;
|
| 28 |
+
}
|
| 29 |
+
MovableScalar(const Scalar& scalar) : m_data(new Scalar) { set(scalar); }
|
| 30 |
+
|
| 31 |
+
operator Scalar() const { return get(); }
|
| 32 |
+
|
| 33 |
+
private:
|
| 34 |
+
void set(const Scalar& value) {
|
| 35 |
+
eigen_assert(m_data != nullptr);
|
| 36 |
+
// suppress compiler warnings
|
| 37 |
+
if (m_data != nullptr) *m_data = value;
|
| 38 |
+
}
|
| 39 |
+
Scalar get() const {
|
| 40 |
+
eigen_assert(m_data != nullptr);
|
| 41 |
+
// suppress compiler warnings
|
| 42 |
+
return m_data == nullptr ? Scalar() : *m_data;
|
| 43 |
+
}
|
| 44 |
+
Scalar* m_data = nullptr;
|
| 45 |
+
};
|
| 46 |
+
|
| 47 |
+
template <typename Scalar>
|
| 48 |
+
struct NumTraits<MovableScalar<Scalar>> : NumTraits<Scalar> {
|
| 49 |
+
enum { RequireInitialization = 1 };
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
} // namespace Eigen
|
| 53 |
+
|
| 54 |
+
#endif
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/OffByOneScalar.h
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
// A Scalar with internal representation T+1 so that zero is internally
|
| 3 |
+
// represented by T(1). This is used to test memory fill.
|
| 4 |
+
//
|
| 5 |
+
#pragma once
|
| 6 |
+
template <typename T>
|
| 7 |
+
class OffByOneScalar {
|
| 8 |
+
public:
|
| 9 |
+
OffByOneScalar() : val_(1) {}
|
| 10 |
+
OffByOneScalar(const OffByOneScalar& other) = default;
|
| 11 |
+
OffByOneScalar& operator=(const OffByOneScalar& other) = default;
|
| 12 |
+
|
| 13 |
+
OffByOneScalar(T val) : val_(val + 1) {}
|
| 14 |
+
OffByOneScalar& operator=(T val) { val_ = val + 1; }
|
| 15 |
+
|
| 16 |
+
operator T() const { return val_ - 1; }
|
| 17 |
+
|
| 18 |
+
private:
|
| 19 |
+
T val_;
|
| 20 |
+
};
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/SafeScalar.h
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
// A Scalar that asserts for uninitialized access.
|
| 3 |
+
template <typename T>
|
| 4 |
+
class SafeScalar {
|
| 5 |
+
public:
|
| 6 |
+
SafeScalar() : initialized_(false) {}
|
| 7 |
+
|
| 8 |
+
SafeScalar(const T& val) : val_(val), initialized_(true) {}
|
| 9 |
+
|
| 10 |
+
template <typename Source>
|
| 11 |
+
explicit SafeScalar(const Source& val) : SafeScalar(T(val)) {}
|
| 12 |
+
|
| 13 |
+
operator T() const {
|
| 14 |
+
VERIFY(initialized_ && "Uninitialized access.");
|
| 15 |
+
return val_;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
template <typename Target>
|
| 19 |
+
explicit operator Target() const {
|
| 20 |
+
return Target(this->operator T());
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
private:
|
| 24 |
+
T val_;
|
| 25 |
+
bool initialized_;
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
namespace Eigen {
|
| 29 |
+
template <typename T>
|
| 30 |
+
struct NumTraits<SafeScalar<T>> : GenericNumTraits<T> {
|
| 31 |
+
enum { RequireInitialization = 1 };
|
| 32 |
+
};
|
| 33 |
+
} // namespace Eigen
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/accelerate_support.cpp
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#define EIGEN_NO_DEBUG_SMALL_PRODUCT_BLOCKS
|
| 2 |
+
#include "sparse_solver.h"
|
| 3 |
+
|
| 4 |
+
#if defined(DEBUG)
|
| 5 |
+
#undef DEBUG
|
| 6 |
+
#endif
|
| 7 |
+
|
| 8 |
+
#include <Eigen/AccelerateSupport>
|
| 9 |
+
|
| 10 |
+
template <typename MatrixType, typename DenseMat>
|
| 11 |
+
int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows = 300, int maxCols = 300) {
|
| 12 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 13 |
+
int rows = internal::random<int>(1, maxRows);
|
| 14 |
+
int cols = internal::random<int>(1, maxCols);
|
| 15 |
+
double density = (std::max)(8.0 / (rows * cols), 0.01);
|
| 16 |
+
|
| 17 |
+
A.resize(rows, cols);
|
| 18 |
+
dA.resize(rows, cols);
|
| 19 |
+
initSparse<Scalar>(density, dA, A, ForceNonZeroDiag);
|
| 20 |
+
A.makeCompressed();
|
| 21 |
+
return rows;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
template <typename MatrixType, typename DenseMat>
|
| 25 |
+
int generate_sparse_square_symmetric_problem(MatrixType& A, DenseMat& dA, int maxSize = 300) {
|
| 26 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 27 |
+
int rows = internal::random<int>(1, maxSize);
|
| 28 |
+
int cols = rows;
|
| 29 |
+
double density = (std::max)(8.0 / (rows * cols), 0.01);
|
| 30 |
+
|
| 31 |
+
A.resize(rows, cols);
|
| 32 |
+
dA.resize(rows, cols);
|
| 33 |
+
initSparse<Scalar>(density, dA, A, ForceNonZeroDiag);
|
| 34 |
+
dA = dA * dA.transpose();
|
| 35 |
+
A = A * A.transpose();
|
| 36 |
+
A.makeCompressed();
|
| 37 |
+
return rows;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
template <typename Scalar, typename Solver>
|
| 41 |
+
void test_accelerate_ldlt() {
|
| 42 |
+
typedef SparseMatrix<Scalar> MatrixType;
|
| 43 |
+
typedef Matrix<Scalar, Dynamic, 1> DenseVector;
|
| 44 |
+
|
| 45 |
+
MatrixType A;
|
| 46 |
+
Matrix<Scalar, Dynamic, Dynamic> dA;
|
| 47 |
+
|
| 48 |
+
generate_sparse_square_symmetric_problem(A, dA);
|
| 49 |
+
|
| 50 |
+
DenseVector b = DenseVector::Random(A.rows());
|
| 51 |
+
|
| 52 |
+
Solver solver;
|
| 53 |
+
solver.compute(A);
|
| 54 |
+
|
| 55 |
+
if (solver.info() != Success) {
|
| 56 |
+
std::cerr << "sparse LDLT factorization failed\n";
|
| 57 |
+
exit(0);
|
| 58 |
+
return;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
DenseVector x = solver.solve(b);
|
| 62 |
+
|
| 63 |
+
if (solver.info() != Success) {
|
| 64 |
+
std::cerr << "sparse LDLT factorization failed\n";
|
| 65 |
+
exit(0);
|
| 66 |
+
return;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
// Compare with a dense solver
|
| 70 |
+
DenseVector refX = dA.ldlt().solve(b);
|
| 71 |
+
VERIFY((A * x).isApprox(A * refX, test_precision<Scalar>()));
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
template <typename Scalar, typename Solver>
|
| 75 |
+
void test_accelerate_llt() {
|
| 76 |
+
typedef SparseMatrix<Scalar> MatrixType;
|
| 77 |
+
typedef Matrix<Scalar, Dynamic, 1> DenseVector;
|
| 78 |
+
|
| 79 |
+
MatrixType A;
|
| 80 |
+
Matrix<Scalar, Dynamic, Dynamic> dA;
|
| 81 |
+
|
| 82 |
+
generate_sparse_square_symmetric_problem(A, dA);
|
| 83 |
+
|
| 84 |
+
DenseVector b = DenseVector::Random(A.rows());
|
| 85 |
+
|
| 86 |
+
Solver solver;
|
| 87 |
+
solver.compute(A);
|
| 88 |
+
|
| 89 |
+
if (solver.info() != Success) {
|
| 90 |
+
std::cerr << "sparse LLT factorization failed\n";
|
| 91 |
+
exit(0);
|
| 92 |
+
return;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
DenseVector x = solver.solve(b);
|
| 96 |
+
|
| 97 |
+
if (solver.info() != Success) {
|
| 98 |
+
std::cerr << "sparse LLT factorization failed\n";
|
| 99 |
+
exit(0);
|
| 100 |
+
return;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
// Compare with a dense solver
|
| 104 |
+
DenseVector refX = dA.llt().solve(b);
|
| 105 |
+
VERIFY((A * x).isApprox(A * refX, test_precision<Scalar>()));
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
template <typename Scalar, typename Solver>
|
| 109 |
+
void test_accelerate_qr() {
|
| 110 |
+
typedef SparseMatrix<Scalar> MatrixType;
|
| 111 |
+
typedef Matrix<Scalar, Dynamic, 1> DenseVector;
|
| 112 |
+
|
| 113 |
+
MatrixType A;
|
| 114 |
+
Matrix<Scalar, Dynamic, Dynamic> dA;
|
| 115 |
+
|
| 116 |
+
generate_sparse_rectangular_problem(A, dA);
|
| 117 |
+
|
| 118 |
+
DenseVector b = DenseVector::Random(A.rows());
|
| 119 |
+
|
| 120 |
+
Solver solver;
|
| 121 |
+
solver.compute(A);
|
| 122 |
+
|
| 123 |
+
if (solver.info() != Success) {
|
| 124 |
+
std::cerr << "sparse QR factorization failed\n";
|
| 125 |
+
exit(0);
|
| 126 |
+
return;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
DenseVector x = solver.solve(b);
|
| 130 |
+
|
| 131 |
+
if (solver.info() != Success) {
|
| 132 |
+
std::cerr << "sparse QR factorization failed\n";
|
| 133 |
+
exit(0);
|
| 134 |
+
return;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
// Compare with a dense solver
|
| 138 |
+
DenseVector refX = dA.colPivHouseholderQr().solve(b);
|
| 139 |
+
VERIFY((A * x).isApprox(A * refX, test_precision<Scalar>()));
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
template <typename Scalar>
|
| 143 |
+
void run_tests() {
|
| 144 |
+
typedef SparseMatrix<Scalar> MatrixType;
|
| 145 |
+
|
| 146 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLT<MatrixType, Lower> >();
|
| 147 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLTUnpivoted<MatrixType, Lower> >();
|
| 148 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLTSBK<MatrixType, Lower> >();
|
| 149 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLTTPP<MatrixType, Lower> >();
|
| 150 |
+
|
| 151 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLT<MatrixType, Upper> >();
|
| 152 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLTUnpivoted<MatrixType, Upper> >();
|
| 153 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLTSBK<MatrixType, Upper> >();
|
| 154 |
+
test_accelerate_ldlt<Scalar, AccelerateLDLTTPP<MatrixType, Upper> >();
|
| 155 |
+
|
| 156 |
+
test_accelerate_llt<Scalar, AccelerateLLT<MatrixType, Lower> >();
|
| 157 |
+
|
| 158 |
+
test_accelerate_llt<Scalar, AccelerateLLT<MatrixType, Upper> >();
|
| 159 |
+
|
| 160 |
+
test_accelerate_qr<Scalar, AccelerateQR<MatrixType> >();
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
EIGEN_DECLARE_TEST(accelerate_support) {
|
| 164 |
+
CALL_SUBTEST_1(run_tests<float>());
|
| 165 |
+
CALL_SUBTEST_2(run_tests<double>());
|
| 166 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/adjoint.cpp
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2006-2008 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <bool IsInteger>
|
| 13 |
+
struct adjoint_specific;
|
| 14 |
+
|
| 15 |
+
template <>
|
| 16 |
+
struct adjoint_specific<true> {
|
| 17 |
+
template <typename Vec, typename Mat, typename Scalar>
|
| 18 |
+
static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
|
| 19 |
+
VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),
|
| 20 |
+
numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), 0));
|
| 21 |
+
VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2), s1 * v3.dot(v1) + s2 * v3.dot(v2), 0));
|
| 22 |
+
|
| 23 |
+
// check compatibility of dot and adjoint
|
| 24 |
+
VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), 0));
|
| 25 |
+
}
|
| 26 |
+
};
|
| 27 |
+
|
| 28 |
+
template <>
|
| 29 |
+
struct adjoint_specific<false> {
|
| 30 |
+
template <typename Vec, typename Mat, typename Scalar>
|
| 31 |
+
static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {
|
| 32 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 33 |
+
using std::abs;
|
| 34 |
+
|
| 35 |
+
RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : (std::max)((s1 * v1 + s2 * v2).norm(), v3.norm());
|
| 36 |
+
VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3),
|
| 37 |
+
numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), ref));
|
| 38 |
+
VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2), s1 * v3.dot(v1) + s2 * v3.dot(v2), ref));
|
| 39 |
+
|
| 40 |
+
VERIFY_IS_APPROX(v1.squaredNorm(), v1.norm() * v1.norm());
|
| 41 |
+
// check normalized() and normalize()
|
| 42 |
+
VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
|
| 43 |
+
v3 = v1;
|
| 44 |
+
v3.normalize();
|
| 45 |
+
VERIFY_IS_APPROX(v1, v1.norm() * v3);
|
| 46 |
+
VERIFY_IS_APPROX(v3, v1.normalized());
|
| 47 |
+
VERIFY_IS_APPROX(v3.norm(), RealScalar(1));
|
| 48 |
+
|
| 49 |
+
// check null inputs
|
| 50 |
+
VERIFY_IS_APPROX((v1 * 0).normalized(), (v1 * 0));
|
| 51 |
+
#if (!EIGEN_ARCH_i386) || defined(EIGEN_VECTORIZE)
|
| 52 |
+
RealScalar very_small = (std::numeric_limits<RealScalar>::min)();
|
| 53 |
+
VERIFY(numext::is_exactly_zero((v1 * very_small).norm()));
|
| 54 |
+
VERIFY_IS_APPROX((v1 * very_small).normalized(), (v1 * very_small));
|
| 55 |
+
v3 = v1 * very_small;
|
| 56 |
+
v3.normalize();
|
| 57 |
+
VERIFY_IS_APPROX(v3, (v1 * very_small));
|
| 58 |
+
#endif
|
| 59 |
+
|
| 60 |
+
// check compatibility of dot and adjoint
|
| 61 |
+
ref = NumTraits<Scalar>::IsInteger ? 0
|
| 62 |
+
: (std::max)((std::max)(v1.norm(), v2.norm()),
|
| 63 |
+
(std::max)((square * v2).norm(), (square.adjoint() * v1).norm()));
|
| 64 |
+
VERIFY(internal::isMuchSmallerThan(abs(v1.dot(square * v2) - (square.adjoint() * v1).dot(v2)), ref,
|
| 65 |
+
test_precision<Scalar>()));
|
| 66 |
+
|
| 67 |
+
// check that Random().normalized() works: tricky as the random xpr must be evaluated by
|
| 68 |
+
// normalized() in order to produce a consistent result.
|
| 69 |
+
VERIFY_IS_APPROX(Vec::Random(v1.size()).normalized().norm(), RealScalar(1));
|
| 70 |
+
}
|
| 71 |
+
};
|
| 72 |
+
|
| 73 |
+
template <typename MatrixType, typename Scalar = typename MatrixType::Scalar>
|
| 74 |
+
MatrixType RandomMatrix(Index rows, Index cols, Scalar min, Scalar max) {
|
| 75 |
+
MatrixType M = MatrixType(rows, cols);
|
| 76 |
+
for (Index i = 0; i < rows; ++i) {
|
| 77 |
+
for (Index j = 0; j < cols; ++j) {
|
| 78 |
+
M(i, j) = Eigen::internal::random<Scalar>(min, max);
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
return M;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
template <typename MatrixType>
|
| 85 |
+
void adjoint(const MatrixType& m) {
|
| 86 |
+
/* this test covers the following files:
|
| 87 |
+
Transpose.h Conjugate.h Dot.h
|
| 88 |
+
*/
|
| 89 |
+
using std::abs;
|
| 90 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 91 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 92 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 93 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
|
| 94 |
+
const Index PacketSize = internal::packet_traits<Scalar>::size;
|
| 95 |
+
|
| 96 |
+
Index rows = m.rows();
|
| 97 |
+
Index cols = m.cols();
|
| 98 |
+
|
| 99 |
+
// Avoid integer overflow by limiting input values.
|
| 100 |
+
RealScalar rmin = static_cast<RealScalar>(NumTraits<Scalar>::IsInteger ? NumTraits<Scalar>::IsSigned ? -100 : 0 : -1);
|
| 101 |
+
RealScalar rmax = static_cast<RealScalar>(NumTraits<Scalar>::IsInteger ? 100 : 1);
|
| 102 |
+
|
| 103 |
+
MatrixType m1 = RandomMatrix<MatrixType>(rows, cols, rmin, rmax),
|
| 104 |
+
m2 = RandomMatrix<MatrixType>(rows, cols, rmin, rmax), m3(rows, cols),
|
| 105 |
+
square = RandomMatrix<SquareMatrixType>(rows, rows, rmin, rmax);
|
| 106 |
+
VectorType v1 = RandomMatrix<VectorType>(rows, 1, rmin, rmax), v2 = RandomMatrix<VectorType>(rows, 1, rmin, rmax),
|
| 107 |
+
v3 = RandomMatrix<VectorType>(rows, 1, rmin, rmax), vzero = VectorType::Zero(rows);
|
| 108 |
+
|
| 109 |
+
Scalar s1 = internal::random<Scalar>(rmin, rmax), s2 = internal::random<Scalar>(rmin, rmax);
|
| 110 |
+
|
| 111 |
+
// check basic compatibility of adjoint, transpose, conjugate
|
| 112 |
+
VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(), m1);
|
| 113 |
+
VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(), m1);
|
| 114 |
+
|
| 115 |
+
// check multiplicative behavior
|
| 116 |
+
VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(), m2.adjoint() * m1);
|
| 117 |
+
VERIFY_IS_APPROX((s1 * m1).adjoint(), numext::conj(s1) * m1.adjoint());
|
| 118 |
+
|
| 119 |
+
// check basic properties of dot, squaredNorm
|
| 120 |
+
VERIFY_IS_APPROX(numext::conj(v1.dot(v2)), v2.dot(v1));
|
| 121 |
+
VERIFY_IS_APPROX(numext::real(v1.dot(v1)), v1.squaredNorm());
|
| 122 |
+
|
| 123 |
+
adjoint_specific<NumTraits<Scalar>::IsInteger>::run(v1, v2, v3, square, s1, s2);
|
| 124 |
+
|
| 125 |
+
VERIFY_IS_MUCH_SMALLER_THAN(abs(vzero.dot(v1)), static_cast<RealScalar>(1));
|
| 126 |
+
|
| 127 |
+
// like in testBasicStuff, test operator() to check const-qualification
|
| 128 |
+
Index r = internal::random<Index>(0, rows - 1), c = internal::random<Index>(0, cols - 1);
|
| 129 |
+
VERIFY_IS_APPROX(m1.conjugate()(r, c), numext::conj(m1(r, c)));
|
| 130 |
+
VERIFY_IS_APPROX(m1.adjoint()(c, r), numext::conj(m1(r, c)));
|
| 131 |
+
|
| 132 |
+
// check inplace transpose
|
| 133 |
+
m3 = m1;
|
| 134 |
+
m3.transposeInPlace();
|
| 135 |
+
VERIFY_IS_APPROX(m3, m1.transpose());
|
| 136 |
+
m3.transposeInPlace();
|
| 137 |
+
VERIFY_IS_APPROX(m3, m1);
|
| 138 |
+
|
| 139 |
+
if (PacketSize < m3.rows() && PacketSize < m3.cols()) {
|
| 140 |
+
m3 = m1;
|
| 141 |
+
Index i = internal::random<Index>(0, m3.rows() - PacketSize);
|
| 142 |
+
Index j = internal::random<Index>(0, m3.cols() - PacketSize);
|
| 143 |
+
m3.template block<PacketSize, PacketSize>(i, j).transposeInPlace();
|
| 144 |
+
VERIFY_IS_APPROX((m3.template block<PacketSize, PacketSize>(i, j)),
|
| 145 |
+
(m1.template block<PacketSize, PacketSize>(i, j).transpose()));
|
| 146 |
+
m3.template block<PacketSize, PacketSize>(i, j).transposeInPlace();
|
| 147 |
+
VERIFY_IS_APPROX(m3, m1);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
// check inplace adjoint
|
| 151 |
+
m3 = m1;
|
| 152 |
+
m3.adjointInPlace();
|
| 153 |
+
VERIFY_IS_APPROX(m3, m1.adjoint());
|
| 154 |
+
m3.transposeInPlace();
|
| 155 |
+
VERIFY_IS_APPROX(m3, m1.conjugate());
|
| 156 |
+
|
| 157 |
+
// check mixed dot product
|
| 158 |
+
typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;
|
| 159 |
+
RealVectorType rv1 = RandomMatrix<RealVectorType>(rows, 1, rmin, rmax);
|
| 160 |
+
|
| 161 |
+
VERIFY_IS_APPROX(v1.dot(rv1.template cast<Scalar>()), v1.dot(rv1));
|
| 162 |
+
VERIFY_IS_APPROX(rv1.template cast<Scalar>().dot(v1), rv1.dot(v1));
|
| 163 |
+
|
| 164 |
+
VERIFY(is_same_type(m1, m1.template conjugateIf<false>()));
|
| 165 |
+
VERIFY(is_same_type(m1.conjugate(), m1.template conjugateIf<true>()));
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
template <int>
|
| 169 |
+
void adjoint_extra() {
|
| 170 |
+
MatrixXcf a(10, 10), b(10, 10);
|
| 171 |
+
VERIFY_RAISES_ASSERT(a = a.transpose());
|
| 172 |
+
VERIFY_RAISES_ASSERT(a = a.transpose() + b);
|
| 173 |
+
VERIFY_RAISES_ASSERT(a = b + a.transpose());
|
| 174 |
+
VERIFY_RAISES_ASSERT(a = a.conjugate().transpose());
|
| 175 |
+
VERIFY_RAISES_ASSERT(a = a.adjoint());
|
| 176 |
+
VERIFY_RAISES_ASSERT(a = a.adjoint() + b);
|
| 177 |
+
VERIFY_RAISES_ASSERT(a = b + a.adjoint());
|
| 178 |
+
|
| 179 |
+
// no assertion should be triggered for these cases:
|
| 180 |
+
a.transpose() = a.transpose();
|
| 181 |
+
a.transpose() += a.transpose();
|
| 182 |
+
a.transpose() += a.transpose() + b;
|
| 183 |
+
a.transpose() = a.adjoint();
|
| 184 |
+
a.transpose() += a.adjoint();
|
| 185 |
+
a.transpose() += a.adjoint() + b;
|
| 186 |
+
|
| 187 |
+
// regression tests for check_for_aliasing
|
| 188 |
+
MatrixXd c(10, 10);
|
| 189 |
+
c = 1.0 * MatrixXd::Ones(10, 10) + c;
|
| 190 |
+
c = MatrixXd::Ones(10, 10) * 1.0 + c;
|
| 191 |
+
c = c + MatrixXd::Ones(10, 10).cwiseProduct(MatrixXd::Zero(10, 10));
|
| 192 |
+
c = MatrixXd::Ones(10, 10) * MatrixXd::Zero(10, 10);
|
| 193 |
+
|
| 194 |
+
// regression for bug 1646
|
| 195 |
+
for (int j = 0; j < 10; ++j) {
|
| 196 |
+
c.col(j).head(j) = c.row(j).head(j);
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
for (int j = 0; j < 10; ++j) {
|
| 200 |
+
c.col(j) = c.row(j);
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
a.conservativeResize(1, 1);
|
| 204 |
+
a = a.transpose();
|
| 205 |
+
|
| 206 |
+
a.conservativeResize(0, 0);
|
| 207 |
+
a = a.transpose();
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
EIGEN_DECLARE_TEST(adjoint) {
|
| 211 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 212 |
+
CALL_SUBTEST_1(adjoint(Matrix<float, 1, 1>()));
|
| 213 |
+
CALL_SUBTEST_2(adjoint(Matrix3d()));
|
| 214 |
+
CALL_SUBTEST_3(adjoint(Matrix4f()));
|
| 215 |
+
|
| 216 |
+
CALL_SUBTEST_4(adjoint(MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 2),
|
| 217 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 2))));
|
| 218 |
+
CALL_SUBTEST_5(adjoint(
|
| 219 |
+
MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 220 |
+
CALL_SUBTEST_6(adjoint(
|
| 221 |
+
MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 222 |
+
|
| 223 |
+
// Complement for 128 bits vectorization:
|
| 224 |
+
CALL_SUBTEST_8(adjoint(Matrix2d()));
|
| 225 |
+
CALL_SUBTEST_9(adjoint(Matrix<int, 4, 4>()));
|
| 226 |
+
|
| 227 |
+
// 256 bits vectorization:
|
| 228 |
+
CALL_SUBTEST_10(adjoint(Matrix<float, 8, 8>()));
|
| 229 |
+
CALL_SUBTEST_11(adjoint(Matrix<double, 4, 4>()));
|
| 230 |
+
CALL_SUBTEST_12(adjoint(Matrix<int, 8, 8>()));
|
| 231 |
+
}
|
| 232 |
+
// test a large static matrix only once
|
| 233 |
+
CALL_SUBTEST_7(adjoint(Matrix<float, 100, 100>()));
|
| 234 |
+
|
| 235 |
+
CALL_SUBTEST_13(adjoint_extra<0>());
|
| 236 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_cwise.cpp
ADDED
|
@@ -0,0 +1,1432 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include <vector>
|
| 11 |
+
#include "main.h"
|
| 12 |
+
#include "random_without_cast_overflow.h"
|
| 13 |
+
|
| 14 |
+
// suppress annoying unsigned integer warnings
|
| 15 |
+
template <typename Scalar, bool IsSigned = NumTraits<Scalar>::IsSigned>
|
| 16 |
+
struct negative_or_zero_impl {
|
| 17 |
+
static Scalar run(const Scalar& a) { return -a; }
|
| 18 |
+
};
|
| 19 |
+
template <typename Scalar>
|
| 20 |
+
struct negative_or_zero_impl<Scalar, false> {
|
| 21 |
+
static Scalar run(const Scalar&) { return 0; }
|
| 22 |
+
};
|
| 23 |
+
template <typename Scalar>
|
| 24 |
+
Scalar negative_or_zero(const Scalar& a) {
|
| 25 |
+
return negative_or_zero_impl<Scalar>::run(a);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
template <typename Scalar, std::enable_if_t<NumTraits<Scalar>::IsInteger, int> = 0>
|
| 29 |
+
std::vector<Scalar> special_values() {
|
| 30 |
+
const Scalar zero = Scalar(0);
|
| 31 |
+
const Scalar one = Scalar(1);
|
| 32 |
+
const Scalar two = Scalar(2);
|
| 33 |
+
const Scalar three = Scalar(3);
|
| 34 |
+
const Scalar min = (std::numeric_limits<Scalar>::min)();
|
| 35 |
+
const Scalar max = (std::numeric_limits<Scalar>::max)();
|
| 36 |
+
return {zero, min, one, two, three, max};
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
template <typename Scalar, std::enable_if_t<!NumTraits<Scalar>::IsInteger, int> = 0>
|
| 40 |
+
std::vector<Scalar> special_values() {
|
| 41 |
+
const Scalar zero = Scalar(0);
|
| 42 |
+
const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
|
| 43 |
+
const Scalar one_half = Scalar(0.5);
|
| 44 |
+
const Scalar one = Scalar(1);
|
| 45 |
+
const Scalar two = Scalar(2);
|
| 46 |
+
const Scalar three = Scalar(3);
|
| 47 |
+
const Scalar sqrt_half = Scalar(std::sqrt(0.5));
|
| 48 |
+
const Scalar sqrt2 = Scalar(std::sqrt(2));
|
| 49 |
+
const Scalar inf = Eigen::NumTraits<Scalar>::infinity();
|
| 50 |
+
const Scalar nan = Eigen::NumTraits<Scalar>::quiet_NaN();
|
| 51 |
+
// For 32-bit arm, working within or near the subnormal range can lead to incorrect results
|
| 52 |
+
// due to FTZ.
|
| 53 |
+
const Scalar denorm_min = EIGEN_ARCH_ARM ? zero : std::numeric_limits<Scalar>::denorm_min();
|
| 54 |
+
const Scalar min =
|
| 55 |
+
EIGEN_ARCH_ARM ? Scalar(1.1) * (std::numeric_limits<Scalar>::min)() : (std::numeric_limits<Scalar>::min)();
|
| 56 |
+
const Scalar max = (std::numeric_limits<Scalar>::max)();
|
| 57 |
+
const Scalar max_exp = (static_cast<Scalar>(int(Eigen::NumTraits<Scalar>::max_exponent())) * Scalar(EIGEN_LN2)) / eps;
|
| 58 |
+
std::vector<Scalar> values = {zero, denorm_min, min, eps, sqrt_half, one_half, one,
|
| 59 |
+
sqrt2, two, three, max_exp, max, inf, nan};
|
| 60 |
+
std::vector<Scalar> signed_values;
|
| 61 |
+
for (Scalar value : values) {
|
| 62 |
+
signed_values.push_back(value);
|
| 63 |
+
signed_values.push_back(-value);
|
| 64 |
+
}
|
| 65 |
+
return signed_values;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
template <typename Scalar>
|
| 69 |
+
void special_value_pairs(Array<Scalar, Dynamic, Dynamic>& x, Array<Scalar, Dynamic, Dynamic>& y) {
|
| 70 |
+
std::vector<Scalar> vals = special_values<Scalar>();
|
| 71 |
+
std::size_t num_cases = vals.size() * vals.size();
|
| 72 |
+
// ensure both vectorized and non-vectorized paths taken
|
| 73 |
+
const Index num_repeats = 2 * (Index)internal::packet_traits<Scalar>::size + 1;
|
| 74 |
+
x.resize(num_repeats, num_cases);
|
| 75 |
+
y.resize(num_repeats, num_cases);
|
| 76 |
+
int count = 0;
|
| 77 |
+
for (const Scalar x_case : vals) {
|
| 78 |
+
for (const Scalar y_case : vals) {
|
| 79 |
+
for (Index repeat = 0; repeat < num_repeats; ++repeat) {
|
| 80 |
+
x(repeat, count) = x_case;
|
| 81 |
+
y(repeat, count) = y_case;
|
| 82 |
+
}
|
| 83 |
+
++count;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
template <typename Scalar, typename Fn, typename RefFn>
|
| 89 |
+
void binary_op_test(std::string name, Fn fun, RefFn ref) {
|
| 90 |
+
const Scalar tol = test_precision<Scalar>();
|
| 91 |
+
Array<Scalar, Dynamic, Dynamic> lhs;
|
| 92 |
+
Array<Scalar, Dynamic, Dynamic> rhs;
|
| 93 |
+
special_value_pairs(lhs, rhs);
|
| 94 |
+
|
| 95 |
+
Array<Scalar, Dynamic, Dynamic> actual = fun(lhs, rhs);
|
| 96 |
+
bool all_pass = true;
|
| 97 |
+
for (Index i = 0; i < lhs.rows(); ++i) {
|
| 98 |
+
for (Index j = 0; j < lhs.cols(); ++j) {
|
| 99 |
+
Scalar e = static_cast<Scalar>(ref(lhs(i, j), rhs(i, j)));
|
| 100 |
+
Scalar a = actual(i, j);
|
| 101 |
+
#if EIGEN_ARCH_ARM
|
| 102 |
+
// Work around NEON flush-to-zero mode.
|
| 103 |
+
// If ref returns a subnormal value and Eigen returns 0, then skip the test.
|
| 104 |
+
if (a == Scalar(0) && (e > -(std::numeric_limits<Scalar>::min)() && e < (std::numeric_limits<Scalar>::min)()) &&
|
| 105 |
+
(e <= -std::numeric_limits<Scalar>::denorm_min() || e >= std::numeric_limits<Scalar>::denorm_min())) {
|
| 106 |
+
continue;
|
| 107 |
+
}
|
| 108 |
+
#endif
|
| 109 |
+
bool success = (a == e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) ||
|
| 110 |
+
((numext::isnan)(a) && (numext::isnan)(e));
|
| 111 |
+
if ((a == a) && (e == e)) success &= (bool)numext::signbit(e) == (bool)numext::signbit(a);
|
| 112 |
+
all_pass &= success;
|
| 113 |
+
if (!success) {
|
| 114 |
+
std::cout << name << "(" << lhs(i, j) << "," << rhs(i, j) << ") = " << a << " != " << e << std::endl;
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
}
|
| 118 |
+
VERIFY(all_pass);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
#define BINARY_FUNCTOR_TEST_ARGS(fun) \
|
| 122 |
+
#fun, [](const auto& x_, const auto& y_) { return (Eigen::fun)(x_, y_); }, \
|
| 123 |
+
[](const auto& x_, const auto& y_) { return (std::fun)(x_, y_); }
|
| 124 |
+
|
| 125 |
+
template <typename Scalar>
|
| 126 |
+
void binary_ops_test() {
|
| 127 |
+
binary_op_test<Scalar>(BINARY_FUNCTOR_TEST_ARGS(pow));
|
| 128 |
+
#ifndef EIGEN_COMP_MSVC
|
| 129 |
+
binary_op_test<Scalar>(BINARY_FUNCTOR_TEST_ARGS(atan2));
|
| 130 |
+
#else
|
| 131 |
+
binary_op_test<Scalar>(
|
| 132 |
+
"atan2", [](const auto& x, const auto& y) { return Eigen::atan2(x, y); },
|
| 133 |
+
[](Scalar x, Scalar y) {
|
| 134 |
+
auto t = Scalar(std::atan2(x, y));
|
| 135 |
+
// Work around MSVC return value on underflow.
|
| 136 |
+
// |atan(y/x)| is bounded above by |y/x|, so on underflow return y/x according to POSIX spec.
|
| 137 |
+
// MSVC otherwise returns denorm_min.
|
| 138 |
+
if (EIGEN_PREDICT_FALSE(std::abs(t) == std::numeric_limits<decltype(t)>::denorm_min())) {
|
| 139 |
+
return x / y;
|
| 140 |
+
}
|
| 141 |
+
return t;
|
| 142 |
+
});
|
| 143 |
+
#endif
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
template <typename Scalar, typename Fn, typename RefFn>
|
| 147 |
+
void unary_op_test(std::string name, Fn fun, RefFn ref) {
|
| 148 |
+
const Scalar tol = test_precision<Scalar>();
|
| 149 |
+
auto values = special_values<Scalar>();
|
| 150 |
+
Map<Array<Scalar, Dynamic, 1>> valuesMap(values.data(), values.size());
|
| 151 |
+
|
| 152 |
+
Array<Scalar, Dynamic, Dynamic> actual = fun(valuesMap);
|
| 153 |
+
bool all_pass = true;
|
| 154 |
+
for (Index i = 0; i < valuesMap.size(); ++i) {
|
| 155 |
+
Scalar e = static_cast<Scalar>(ref(valuesMap(i)));
|
| 156 |
+
Scalar a = actual(i);
|
| 157 |
+
#if EIGEN_ARCH_ARM
|
| 158 |
+
// Work around NEON flush-to-zero mode.
|
| 159 |
+
// If ref returns a subnormal value and Eigen returns 0, then skip the test.
|
| 160 |
+
if (a == Scalar(0) && (e > -(std::numeric_limits<Scalar>::min)() && e < (std::numeric_limits<Scalar>::min)()) &&
|
| 161 |
+
(e <= -std::numeric_limits<Scalar>::denorm_min() || e >= std::numeric_limits<Scalar>::denorm_min())) {
|
| 162 |
+
continue;
|
| 163 |
+
}
|
| 164 |
+
#endif
|
| 165 |
+
bool success = (a == e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) ||
|
| 166 |
+
((numext::isnan)(a) && (numext::isnan)(e));
|
| 167 |
+
if ((a == a) && (e == e)) success &= (bool)numext::signbit(e) == (bool)numext::signbit(a);
|
| 168 |
+
all_pass &= success;
|
| 169 |
+
if (!success) {
|
| 170 |
+
std::cout << name << "(" << valuesMap(i) << ") = " << a << " != " << e << std::endl;
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
VERIFY(all_pass);
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
#define UNARY_FUNCTOR_TEST_ARGS(fun) \
|
| 177 |
+
#fun, [](const auto& x_) { return (Eigen::fun)(x_); }, [](const auto& y_) { return (std::fun)(y_); }
|
| 178 |
+
|
| 179 |
+
template <typename Scalar>
|
| 180 |
+
void unary_ops_test() {
|
| 181 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sqrt));
|
| 182 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(cbrt));
|
| 183 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(exp));
|
| 184 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(exp2));
|
| 185 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(log));
|
| 186 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sin));
|
| 187 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(cos));
|
| 188 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(tan));
|
| 189 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(asin));
|
| 190 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(acos));
|
| 191 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(atan));
|
| 192 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sinh));
|
| 193 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(cosh));
|
| 194 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(tanh));
|
| 195 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(asinh));
|
| 196 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(acosh));
|
| 197 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(atanh));
|
| 198 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(rint));
|
| 199 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(floor));
|
| 200 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(ceil));
|
| 201 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(round));
|
| 202 |
+
unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(trunc));
|
| 203 |
+
/* FIXME: Enable when the behavior of rsqrt on denormals for half and double is fixed.
|
| 204 |
+
unary_op_test<Scalar>("rsqrt",
|
| 205 |
+
[](const auto& x) { return Eigen::rsqrt(x); },
|
| 206 |
+
[](Scalar x) {
|
| 207 |
+
if (x >= 0 && x < (std::numeric_limits<Scalar>::min)()) {
|
| 208 |
+
// rsqrt return +inf for positive subnormals.
|
| 209 |
+
return NumTraits<Scalar>::infinity();
|
| 210 |
+
} else {
|
| 211 |
+
return Scalar(std::sqrt(Scalar(1)/x));
|
| 212 |
+
}
|
| 213 |
+
});
|
| 214 |
+
*/
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
template <typename Base, typename Exponent, bool ExpIsInteger = NumTraits<Exponent>::IsInteger>
|
| 218 |
+
struct ref_pow {
|
| 219 |
+
static Base run(Base base, Exponent exponent) {
|
| 220 |
+
EIGEN_USING_STD(pow);
|
| 221 |
+
return static_cast<Base>(pow(base, static_cast<Base>(exponent)));
|
| 222 |
+
}
|
| 223 |
+
};
|
| 224 |
+
|
| 225 |
+
template <typename Base, typename Exponent>
|
| 226 |
+
struct ref_pow<Base, Exponent, true> {
|
| 227 |
+
static Base run(Base base, Exponent exponent) {
|
| 228 |
+
EIGEN_USING_STD(pow);
|
| 229 |
+
return static_cast<Base>(pow(base, exponent));
|
| 230 |
+
}
|
| 231 |
+
};
|
| 232 |
+
|
| 233 |
+
template <typename Exponent, bool ExpIsInteger = NumTraits<Exponent>::IsInteger>
|
| 234 |
+
struct pow_helper {
|
| 235 |
+
static bool is_integer_impl(const Exponent& exp) { return (numext::isfinite)(exp) && exp == numext::floor(exp); }
|
| 236 |
+
static bool is_odd_impl(const Exponent& exp) {
|
| 237 |
+
Exponent exp_div_2 = exp / Exponent(2);
|
| 238 |
+
Exponent floor_exp_div_2 = numext::floor(exp_div_2);
|
| 239 |
+
return exp_div_2 != floor_exp_div_2;
|
| 240 |
+
}
|
| 241 |
+
};
|
| 242 |
+
template <typename Exponent>
|
| 243 |
+
struct pow_helper<Exponent, true> {
|
| 244 |
+
static bool is_integer_impl(const Exponent&) { return true; }
|
| 245 |
+
static bool is_odd_impl(const Exponent& exp) { return exp % 2 != 0; }
|
| 246 |
+
};
|
| 247 |
+
template <typename Exponent>
|
| 248 |
+
bool is_integer(const Exponent& exp) {
|
| 249 |
+
return pow_helper<Exponent>::is_integer_impl(exp);
|
| 250 |
+
}
|
| 251 |
+
template <typename Exponent>
|
| 252 |
+
bool is_odd(const Exponent& exp) {
|
| 253 |
+
return pow_helper<Exponent>::is_odd_impl(exp);
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
template <typename Base, typename Exponent>
|
| 257 |
+
void float_pow_test_impl() {
|
| 258 |
+
const Base tol = test_precision<Base>();
|
| 259 |
+
std::vector<Base> abs_base_vals = special_values<Base>();
|
| 260 |
+
std::vector<Exponent> abs_exponent_vals = special_values<Exponent>();
|
| 261 |
+
for (int i = 0; i < 100; i++) {
|
| 262 |
+
abs_base_vals.push_back(internal::random<Base>(Base(0), Base(10)));
|
| 263 |
+
abs_exponent_vals.push_back(internal::random<Exponent>(Exponent(0), Exponent(10)));
|
| 264 |
+
}
|
| 265 |
+
const Index num_repeats = internal::packet_traits<Base>::size + 1;
|
| 266 |
+
ArrayX<Base> bases(num_repeats), eigenPow(num_repeats);
|
| 267 |
+
bool all_pass = true;
|
| 268 |
+
for (Base abs_base : abs_base_vals)
|
| 269 |
+
for (Base base : {negative_or_zero(abs_base), abs_base}) {
|
| 270 |
+
bases.setConstant(base);
|
| 271 |
+
for (Exponent abs_exponent : abs_exponent_vals) {
|
| 272 |
+
for (Exponent exponent : {negative_or_zero(abs_exponent), abs_exponent}) {
|
| 273 |
+
eigenPow = bases.pow(exponent);
|
| 274 |
+
for (Index j = 0; j < num_repeats; j++) {
|
| 275 |
+
Base e = ref_pow<Base, Exponent>::run(bases(j), exponent);
|
| 276 |
+
if (is_integer(exponent)) {
|
| 277 |
+
// std::pow may return an incorrect result for a very large integral exponent
|
| 278 |
+
// if base is negative and the exponent is odd, then the result must be negative
|
| 279 |
+
// if std::pow returns otherwise, flip the sign
|
| 280 |
+
bool exp_is_odd = is_odd(exponent);
|
| 281 |
+
bool base_is_neg = !(numext::isnan)(base) && (bool)numext::signbit(base);
|
| 282 |
+
bool result_is_neg = exp_is_odd && base_is_neg;
|
| 283 |
+
bool ref_is_neg = !(numext::isnan)(e) && (bool)numext::signbit(e);
|
| 284 |
+
bool flip_sign = result_is_neg != ref_is_neg;
|
| 285 |
+
if (flip_sign) e = -e;
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
Base a = eigenPow(j);
|
| 289 |
+
#ifdef EIGEN_COMP_MSVC
|
| 290 |
+
// Work around MSVC return value on underflow.
|
| 291 |
+
// if std::pow returns 0 and Eigen returns a denormalized value, then skip the test
|
| 292 |
+
int eigen_fpclass = std::fpclassify(a);
|
| 293 |
+
if (e == Base(0) && eigen_fpclass == FP_SUBNORMAL) continue;
|
| 294 |
+
#endif
|
| 295 |
+
|
| 296 |
+
#ifdef EIGEN_VECTORIZE_NEON
|
| 297 |
+
// Work around NEON flush-to-zero mode
|
| 298 |
+
// if std::pow returns denormalized value and Eigen returns 0, then skip the test
|
| 299 |
+
int ref_fpclass = std::fpclassify(e);
|
| 300 |
+
if (a == Base(0) && ref_fpclass == FP_SUBNORMAL) continue;
|
| 301 |
+
#endif
|
| 302 |
+
|
| 303 |
+
bool both_nan = (numext::isnan)(a) && (numext::isnan)(e);
|
| 304 |
+
bool exact_or_approx = (a == e) || internal::isApprox(a, e, tol);
|
| 305 |
+
bool same_sign = (bool)numext::signbit(e) == (bool)numext::signbit(a);
|
| 306 |
+
bool success = both_nan || (exact_or_approx && same_sign);
|
| 307 |
+
all_pass &= success;
|
| 308 |
+
if (!success) {
|
| 309 |
+
std::cout << "Base type: " << type_name(base) << ", Exponent type: " << type_name(exponent) << std::endl;
|
| 310 |
+
std::cout << "pow(" << bases(j) << "," << exponent << ") = " << a << " != " << e << std::endl;
|
| 311 |
+
}
|
| 312 |
+
}
|
| 313 |
+
}
|
| 314 |
+
}
|
| 315 |
+
}
|
| 316 |
+
VERIFY(all_pass);
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
template <typename Scalar, typename ScalarExponent>
|
| 320 |
+
Scalar calc_overflow_threshold(const ScalarExponent exponent) {
|
| 321 |
+
EIGEN_USING_STD(exp2);
|
| 322 |
+
EIGEN_USING_STD(log2);
|
| 323 |
+
EIGEN_STATIC_ASSERT((NumTraits<Scalar>::digits() < 2 * NumTraits<double>::digits()), BASE_TYPE_IS_TOO_BIG);
|
| 324 |
+
|
| 325 |
+
if (exponent < 2)
|
| 326 |
+
return NumTraits<Scalar>::highest();
|
| 327 |
+
else {
|
| 328 |
+
// base^e <= highest ==> base <= 2^(log2(highest)/e)
|
| 329 |
+
// For floating-point types, consider the bound for integer values that can be reproduced exactly = 2 ^ digits
|
| 330 |
+
double highest_bits = numext::mini(static_cast<double>(NumTraits<Scalar>::digits()),
|
| 331 |
+
static_cast<double>(log2(NumTraits<Scalar>::highest())));
|
| 332 |
+
return static_cast<Scalar>(numext::floor(exp2(highest_bits / static_cast<double>(exponent))));
|
| 333 |
+
}
|
| 334 |
+
}
|
| 335 |
+
|
| 336 |
+
template <typename Base, typename Exponent>
|
| 337 |
+
void test_exponent(Exponent exponent) {
|
| 338 |
+
EIGEN_STATIC_ASSERT(NumTraits<Base>::IsInteger, THIS TEST IS ONLY INTENDED FOR BASE INTEGER TYPES)
|
| 339 |
+
const Base max_abs_bases = static_cast<Base>(10000);
|
| 340 |
+
// avoid integer overflow in Base type
|
| 341 |
+
Base threshold = calc_overflow_threshold<Base, Exponent>(numext::abs(exponent));
|
| 342 |
+
// avoid numbers that can't be verified with std::pow
|
| 343 |
+
double double_threshold = calc_overflow_threshold<double, Exponent>(numext::abs(exponent));
|
| 344 |
+
// use the lesser of these two thresholds
|
| 345 |
+
Base testing_threshold =
|
| 346 |
+
static_cast<double>(threshold) < double_threshold ? threshold : static_cast<Base>(double_threshold);
|
| 347 |
+
// test both vectorized and non-vectorized code paths
|
| 348 |
+
const Index array_size = 2 * internal::packet_traits<Base>::size + 1;
|
| 349 |
+
|
| 350 |
+
Base max_base = numext::mini(testing_threshold, max_abs_bases);
|
| 351 |
+
Base min_base = negative_or_zero(max_base);
|
| 352 |
+
|
| 353 |
+
ArrayX<Base> x(array_size), y(array_size);
|
| 354 |
+
bool all_pass = true;
|
| 355 |
+
for (Base base = min_base; base <= max_base; base++) {
|
| 356 |
+
if (exponent < 0 && base == 0) continue;
|
| 357 |
+
x.setConstant(base);
|
| 358 |
+
y = x.pow(exponent);
|
| 359 |
+
for (Base a : y) {
|
| 360 |
+
Base e = ref_pow<Base, Exponent>::run(base, exponent);
|
| 361 |
+
bool pass = (a == e);
|
| 362 |
+
all_pass &= pass;
|
| 363 |
+
if (!pass) {
|
| 364 |
+
std::cout << "pow(" << base << "," << exponent << ") = " << a << " != " << e << std::endl;
|
| 365 |
+
}
|
| 366 |
+
}
|
| 367 |
+
}
|
| 368 |
+
VERIFY(all_pass);
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
template <typename Base, typename Exponent>
|
| 372 |
+
void int_pow_test_impl() {
|
| 373 |
+
Exponent max_exponent = static_cast<Exponent>(NumTraits<Base>::digits());
|
| 374 |
+
Exponent min_exponent = negative_or_zero(max_exponent);
|
| 375 |
+
|
| 376 |
+
for (Exponent exponent = min_exponent; exponent < max_exponent; ++exponent) {
|
| 377 |
+
test_exponent<Base, Exponent>(exponent);
|
| 378 |
+
}
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
void float_pow_test() {
|
| 382 |
+
float_pow_test_impl<float, float>();
|
| 383 |
+
float_pow_test_impl<double, double>();
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
void mixed_pow_test() {
|
| 387 |
+
// The following cases will test promoting a smaller exponent type
|
| 388 |
+
// to a wider base type.
|
| 389 |
+
float_pow_test_impl<double, int>();
|
| 390 |
+
float_pow_test_impl<double, float>();
|
| 391 |
+
float_pow_test_impl<float, half>();
|
| 392 |
+
float_pow_test_impl<double, half>();
|
| 393 |
+
float_pow_test_impl<float, bfloat16>();
|
| 394 |
+
float_pow_test_impl<double, bfloat16>();
|
| 395 |
+
|
| 396 |
+
// Although in the following cases the exponent cannot be represented exactly
|
| 397 |
+
// in the base type, we do not perform a conversion, but implement
|
| 398 |
+
// the operation using repeated squaring.
|
| 399 |
+
float_pow_test_impl<float, int>();
|
| 400 |
+
float_pow_test_impl<double, long long>();
|
| 401 |
+
|
| 402 |
+
// The following cases will test promoting a wider exponent type
|
| 403 |
+
// to a narrower base type. This should compile but would generate a
|
| 404 |
+
// deprecation warning:
|
| 405 |
+
// unary_pow_test<float, double>();
|
| 406 |
+
}
|
| 407 |
+
|
| 408 |
+
void int_pow_test() {
|
| 409 |
+
int_pow_test_impl<int, int>();
|
| 410 |
+
int_pow_test_impl<unsigned int, unsigned int>();
|
| 411 |
+
int_pow_test_impl<long long, long long>();
|
| 412 |
+
int_pow_test_impl<unsigned long long, unsigned long long>();
|
| 413 |
+
|
| 414 |
+
// Although in the following cases the exponent cannot be represented exactly
|
| 415 |
+
// in the base type, we do not perform a conversion, but implement the
|
| 416 |
+
// operation using repeated squaring.
|
| 417 |
+
int_pow_test_impl<long long, int>();
|
| 418 |
+
int_pow_test_impl<int, unsigned int>();
|
| 419 |
+
int_pow_test_impl<unsigned int, int>();
|
| 420 |
+
int_pow_test_impl<long long, unsigned long long>();
|
| 421 |
+
int_pow_test_impl<unsigned long long, long long>();
|
| 422 |
+
int_pow_test_impl<long long, int>();
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
namespace Eigen {
|
| 426 |
+
namespace internal {
|
| 427 |
+
template <typename Scalar>
|
| 428 |
+
struct test_signbit_op {
|
| 429 |
+
Scalar constexpr operator()(const Scalar& a) const { return numext::signbit(a); }
|
| 430 |
+
template <typename Packet>
|
| 431 |
+
inline Packet packetOp(const Packet& a) const {
|
| 432 |
+
return psignbit(a);
|
| 433 |
+
}
|
| 434 |
+
};
|
| 435 |
+
template <typename Scalar>
|
| 436 |
+
struct functor_traits<test_signbit_op<Scalar>> {
|
| 437 |
+
enum { Cost = 1, PacketAccess = true }; // todo: define HasSignbit flag
|
| 438 |
+
};
|
| 439 |
+
} // namespace internal
|
| 440 |
+
} // namespace Eigen
|
| 441 |
+
|
| 442 |
+
template <typename Scalar>
|
| 443 |
+
void signbit_test() {
|
| 444 |
+
const size_t size = 100 * internal::packet_traits<Scalar>::size;
|
| 445 |
+
ArrayX<Scalar> x(size), y(size);
|
| 446 |
+
x.setRandom();
|
| 447 |
+
std::vector<Scalar> special_vals = special_values<Scalar>();
|
| 448 |
+
for (size_t i = 0; i < special_vals.size(); i++) {
|
| 449 |
+
x(2 * i + 0) = special_vals[i];
|
| 450 |
+
x(2 * i + 1) = negative_or_zero(special_vals[i]);
|
| 451 |
+
}
|
| 452 |
+
y = x.unaryExpr(internal::test_signbit_op<Scalar>());
|
| 453 |
+
|
| 454 |
+
bool all_pass = true;
|
| 455 |
+
for (size_t i = 0; i < size; i++) {
|
| 456 |
+
const Scalar ref_val = numext::signbit(x(i));
|
| 457 |
+
bool not_same = internal::predux_any(internal::bitwise_helper<Scalar>::bitwise_xor(ref_val, y(i)));
|
| 458 |
+
if (not_same) std::cout << "signbit(" << x(i) << ") != " << y(i) << "\n";
|
| 459 |
+
all_pass = all_pass && !not_same;
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
VERIFY(all_pass);
|
| 463 |
+
}
|
| 464 |
+
void signbit_tests() {
|
| 465 |
+
signbit_test<float>();
|
| 466 |
+
signbit_test<double>();
|
| 467 |
+
signbit_test<Eigen::half>();
|
| 468 |
+
signbit_test<Eigen::bfloat16>();
|
| 469 |
+
signbit_test<int8_t>();
|
| 470 |
+
signbit_test<int16_t>();
|
| 471 |
+
signbit_test<int32_t>();
|
| 472 |
+
signbit_test<int64_t>();
|
| 473 |
+
}
|
| 474 |
+
|
| 475 |
+
template <typename ArrayType>
|
| 476 |
+
void array_generic(const ArrayType& m) {
|
| 477 |
+
typedef typename ArrayType::Scalar Scalar;
|
| 478 |
+
typedef typename ArrayType::RealScalar RealScalar;
|
| 479 |
+
typedef Array<Scalar, ArrayType::RowsAtCompileTime, 1> ColVectorType;
|
| 480 |
+
typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType;
|
| 481 |
+
|
| 482 |
+
Index rows = m.rows();
|
| 483 |
+
Index cols = m.cols();
|
| 484 |
+
|
| 485 |
+
ArrayType m1 = ArrayType::Random(rows, cols);
|
| 486 |
+
if (NumTraits<RealScalar>::IsInteger && NumTraits<RealScalar>::IsSigned && !NumTraits<Scalar>::IsComplex) {
|
| 487 |
+
// Here we cap the size of the values in m1 such that pow(3)/cube()
|
| 488 |
+
// doesn't overflow and result in undefined behavior. Notice that because
|
| 489 |
+
// pow(int, int) promotes its inputs and output to double (according to
|
| 490 |
+
// the C++ standard), we have to make sure that the result fits in 53 bits
|
| 491 |
+
// for int64,
|
| 492 |
+
RealScalar max_val =
|
| 493 |
+
numext::mini(RealScalar(std::cbrt(NumTraits<RealScalar>::highest())), RealScalar(std::cbrt(1LL << 53))) / 2;
|
| 494 |
+
m1.array() = (m1.abs().array() <= max_val).select(m1, Scalar(max_val));
|
| 495 |
+
}
|
| 496 |
+
ArrayType m2 = ArrayType::Random(rows, cols), m3(rows, cols);
|
| 497 |
+
ArrayType m4 = m1; // copy constructor
|
| 498 |
+
VERIFY_IS_APPROX(m1, m4);
|
| 499 |
+
|
| 500 |
+
ColVectorType cv1 = ColVectorType::Random(rows);
|
| 501 |
+
RowVectorType rv1 = RowVectorType::Random(cols);
|
| 502 |
+
|
| 503 |
+
Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>();
|
| 504 |
+
|
| 505 |
+
// scalar addition
|
| 506 |
+
VERIFY_IS_APPROX(m1 + s1, s1 + m1);
|
| 507 |
+
VERIFY_IS_APPROX(m1 + s1, ArrayType::Constant(rows, cols, s1) + m1);
|
| 508 |
+
VERIFY_IS_APPROX(s1 - m1, (-m1) + s1);
|
| 509 |
+
VERIFY_IS_APPROX(m1 - s1, m1 - ArrayType::Constant(rows, cols, s1));
|
| 510 |
+
VERIFY_IS_APPROX(s1 - m1, ArrayType::Constant(rows, cols, s1) - m1);
|
| 511 |
+
VERIFY_IS_APPROX((m1 * Scalar(2)) - s2, (m1 + m1) - ArrayType::Constant(rows, cols, s2));
|
| 512 |
+
m3 = m1;
|
| 513 |
+
m3 += s2;
|
| 514 |
+
VERIFY_IS_APPROX(m3, m1 + s2);
|
| 515 |
+
m3 = m1;
|
| 516 |
+
m3 -= s1;
|
| 517 |
+
VERIFY_IS_APPROX(m3, m1 - s1);
|
| 518 |
+
|
| 519 |
+
// scalar operators via Maps
|
| 520 |
+
m3 = m1;
|
| 521 |
+
m4 = m1;
|
| 522 |
+
ArrayType::Map(m4.data(), m4.rows(), m4.cols()) -= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
|
| 523 |
+
VERIFY_IS_APPROX(m4, m3 - m2);
|
| 524 |
+
|
| 525 |
+
m3 = m1;
|
| 526 |
+
m4 = m1;
|
| 527 |
+
ArrayType::Map(m4.data(), m4.rows(), m4.cols()) += ArrayType::Map(m2.data(), m2.rows(), m2.cols());
|
| 528 |
+
VERIFY_IS_APPROX(m4, m3 + m2);
|
| 529 |
+
|
| 530 |
+
m3 = m1;
|
| 531 |
+
m4 = m1;
|
| 532 |
+
ArrayType::Map(m4.data(), m4.rows(), m4.cols()) *= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
|
| 533 |
+
VERIFY_IS_APPROX(m4, m3 * m2);
|
| 534 |
+
|
| 535 |
+
m3 = m1;
|
| 536 |
+
m4 = m1;
|
| 537 |
+
m2 = ArrayType::Random(rows, cols);
|
| 538 |
+
m2 = (m2 == 0).select(1, m2);
|
| 539 |
+
ArrayType::Map(m4.data(), m4.rows(), m4.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
|
| 540 |
+
VERIFY_IS_APPROX(m4, m3 / m2);
|
| 541 |
+
|
| 542 |
+
// reductions
|
| 543 |
+
VERIFY_IS_APPROX(m1.abs().colwise().sum().sum(), m1.abs().sum());
|
| 544 |
+
VERIFY_IS_APPROX(m1.abs().rowwise().sum().sum(), m1.abs().sum());
|
| 545 |
+
using numext::abs;
|
| 546 |
+
VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.colwise().sum().sum() - m1.sum()), m1.abs().sum());
|
| 547 |
+
VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.rowwise().sum().sum() - m1.sum()), m1.abs().sum());
|
| 548 |
+
if (!internal::isMuchSmallerThan(abs(m1.sum() - (m1 + m2).sum()), m1.abs().sum(), test_precision<Scalar>()))
|
| 549 |
+
VERIFY_IS_NOT_APPROX(((m1 + m2).rowwise().sum()).sum(), m1.sum());
|
| 550 |
+
VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar, Scalar>()));
|
| 551 |
+
|
| 552 |
+
// vector-wise ops
|
| 553 |
+
m3 = m1;
|
| 554 |
+
VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);
|
| 555 |
+
m3 = m1;
|
| 556 |
+
VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);
|
| 557 |
+
m3 = m1;
|
| 558 |
+
VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
|
| 559 |
+
m3 = m1;
|
| 560 |
+
VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);
|
| 561 |
+
|
| 562 |
+
// Conversion from scalar
|
| 563 |
+
VERIFY_IS_APPROX((m3 = s1), ArrayType::Constant(rows, cols, s1));
|
| 564 |
+
VERIFY_IS_APPROX((m3 = 1), ArrayType::Constant(rows, cols, 1));
|
| 565 |
+
VERIFY_IS_APPROX((m3.topLeftCorner(rows, cols) = 1), ArrayType::Constant(rows, cols, 1));
|
| 566 |
+
typedef Array<Scalar, ArrayType::RowsAtCompileTime == Dynamic ? 2 : ArrayType::RowsAtCompileTime,
|
| 567 |
+
ArrayType::ColsAtCompileTime == Dynamic ? 2 : ArrayType::ColsAtCompileTime, ArrayType::Options>
|
| 568 |
+
FixedArrayType;
|
| 569 |
+
{
|
| 570 |
+
FixedArrayType f1(s1);
|
| 571 |
+
VERIFY_IS_APPROX(f1, FixedArrayType::Constant(s1));
|
| 572 |
+
FixedArrayType f2(numext::real(s1));
|
| 573 |
+
VERIFY_IS_APPROX(f2, FixedArrayType::Constant(numext::real(s1)));
|
| 574 |
+
FixedArrayType f3((int)100 * numext::real(s1));
|
| 575 |
+
VERIFY_IS_APPROX(f3, FixedArrayType::Constant((int)100 * numext::real(s1)));
|
| 576 |
+
f1.setRandom();
|
| 577 |
+
FixedArrayType f4(f1.data());
|
| 578 |
+
VERIFY_IS_APPROX(f4, f1);
|
| 579 |
+
}
|
| 580 |
+
{
|
| 581 |
+
FixedArrayType f1{s1};
|
| 582 |
+
VERIFY_IS_APPROX(f1, FixedArrayType::Constant(s1));
|
| 583 |
+
FixedArrayType f2{numext::real(s1)};
|
| 584 |
+
VERIFY_IS_APPROX(f2, FixedArrayType::Constant(numext::real(s1)));
|
| 585 |
+
FixedArrayType f3{(int)100 * numext::real(s1)};
|
| 586 |
+
VERIFY_IS_APPROX(f3, FixedArrayType::Constant((int)100 * numext::real(s1)));
|
| 587 |
+
f1.setRandom();
|
| 588 |
+
FixedArrayType f4{f1.data()};
|
| 589 |
+
VERIFY_IS_APPROX(f4, f1);
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
// pow
|
| 593 |
+
VERIFY_IS_APPROX(m1.pow(2), m1.square());
|
| 594 |
+
VERIFY_IS_APPROX(pow(m1, 2), m1.square());
|
| 595 |
+
VERIFY_IS_APPROX(m1.pow(3), m1.cube());
|
| 596 |
+
VERIFY_IS_APPROX(pow(m1, 3), m1.cube());
|
| 597 |
+
VERIFY_IS_APPROX((-m1).pow(3), -m1.cube());
|
| 598 |
+
VERIFY_IS_APPROX(pow(2 * m1, 3), 8 * m1.cube());
|
| 599 |
+
ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2));
|
| 600 |
+
VERIFY_IS_APPROX(Eigen::pow(m1, exponents), m1.square());
|
| 601 |
+
VERIFY_IS_APPROX(m1.pow(exponents), m1.square());
|
| 602 |
+
VERIFY_IS_APPROX(Eigen::pow(2 * m1, exponents), 4 * m1.square());
|
| 603 |
+
VERIFY_IS_APPROX((2 * m1).pow(exponents), 4 * m1.square());
|
| 604 |
+
VERIFY_IS_APPROX(Eigen::pow(m1, 2 * exponents), m1.square().square());
|
| 605 |
+
VERIFY_IS_APPROX(m1.pow(2 * exponents), m1.square().square());
|
| 606 |
+
VERIFY_IS_APPROX(Eigen::pow(m1(0, 0), exponents), ArrayType::Constant(rows, cols, m1(0, 0) * m1(0, 0)));
|
| 607 |
+
|
| 608 |
+
// Check possible conflicts with 1D ctor
|
| 609 |
+
typedef Array<Scalar, Dynamic, 1> OneDArrayType;
|
| 610 |
+
{
|
| 611 |
+
OneDArrayType o1(rows);
|
| 612 |
+
VERIFY(o1.size() == rows);
|
| 613 |
+
OneDArrayType o2(static_cast<int>(rows));
|
| 614 |
+
VERIFY(o2.size() == rows);
|
| 615 |
+
}
|
| 616 |
+
{
|
| 617 |
+
OneDArrayType o1{rows};
|
| 618 |
+
VERIFY(o1.size() == rows);
|
| 619 |
+
OneDArrayType o4{int(rows)};
|
| 620 |
+
VERIFY(o4.size() == rows);
|
| 621 |
+
}
|
| 622 |
+
// Check possible conflicts with 2D ctor
|
| 623 |
+
typedef Array<Scalar, Dynamic, Dynamic> TwoDArrayType;
|
| 624 |
+
typedef Array<Scalar, 2, 1> ArrayType2;
|
| 625 |
+
{
|
| 626 |
+
TwoDArrayType o1(rows, cols);
|
| 627 |
+
VERIFY(o1.rows() == rows);
|
| 628 |
+
VERIFY(o1.cols() == cols);
|
| 629 |
+
TwoDArrayType o2(static_cast<int>(rows), static_cast<int>(cols));
|
| 630 |
+
VERIFY(o2.rows() == rows);
|
| 631 |
+
VERIFY(o2.cols() == cols);
|
| 632 |
+
|
| 633 |
+
ArrayType2 o3(rows, cols);
|
| 634 |
+
VERIFY(o3(0) == RealScalar(rows) && o3(1) == RealScalar(cols));
|
| 635 |
+
ArrayType2 o4(static_cast<int>(rows), static_cast<int>(cols));
|
| 636 |
+
VERIFY(o4(0) == RealScalar(rows) && o4(1) == RealScalar(cols));
|
| 637 |
+
}
|
| 638 |
+
{
|
| 639 |
+
TwoDArrayType o1{rows, cols};
|
| 640 |
+
VERIFY(o1.rows() == rows);
|
| 641 |
+
VERIFY(o1.cols() == cols);
|
| 642 |
+
TwoDArrayType o2{int(rows), int(cols)};
|
| 643 |
+
VERIFY(o2.rows() == rows);
|
| 644 |
+
VERIFY(o2.cols() == cols);
|
| 645 |
+
|
| 646 |
+
ArrayType2 o3{rows, cols};
|
| 647 |
+
VERIFY(o3(0) == RealScalar(rows) && o3(1) == RealScalar(cols));
|
| 648 |
+
ArrayType2 o4{int(rows), int(cols)};
|
| 649 |
+
VERIFY(o4(0) == RealScalar(rows) && o4(1) == RealScalar(cols));
|
| 650 |
+
}
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
template <typename ArrayType>
|
| 654 |
+
void comparisons(const ArrayType& m) {
|
| 655 |
+
using numext::abs;
|
| 656 |
+
typedef typename ArrayType::Scalar Scalar;
|
| 657 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 658 |
+
|
| 659 |
+
Index rows = m.rows();
|
| 660 |
+
Index cols = m.cols();
|
| 661 |
+
|
| 662 |
+
Index r = internal::random<Index>(0, rows - 1), c = internal::random<Index>(0, cols - 1);
|
| 663 |
+
|
| 664 |
+
ArrayType m1 = ArrayType::Random(rows, cols), m2 = ArrayType::Random(rows, cols), m3(rows, cols), m4 = m1;
|
| 665 |
+
|
| 666 |
+
m4 = (m4.abs() == Scalar(0)).select(1, m4);
|
| 667 |
+
|
| 668 |
+
// use operator overloads with default return type
|
| 669 |
+
|
| 670 |
+
VERIFY(((m1 + Scalar(1)) > m1).all());
|
| 671 |
+
VERIFY(((m1 - Scalar(1)) < m1).all());
|
| 672 |
+
if (rows * cols > 1) {
|
| 673 |
+
m3 = m1;
|
| 674 |
+
m3(r, c) += 1;
|
| 675 |
+
VERIFY(!(m1 < m3).all());
|
| 676 |
+
VERIFY(!(m1 > m3).all());
|
| 677 |
+
}
|
| 678 |
+
VERIFY(!(m1 > m2 && m1 < m2).any());
|
| 679 |
+
VERIFY((m1 <= m2 || m1 >= m2).all());
|
| 680 |
+
|
| 681 |
+
// comparisons array to scalar
|
| 682 |
+
VERIFY((m1 != (m1(r, c) + 1)).any());
|
| 683 |
+
VERIFY((m1 > (m1(r, c) - 1)).any());
|
| 684 |
+
VERIFY((m1 < (m1(r, c) + 1)).any());
|
| 685 |
+
VERIFY((m1 == m1(r, c)).any());
|
| 686 |
+
|
| 687 |
+
// comparisons scalar to array
|
| 688 |
+
VERIFY(((m1(r, c) + 1) != m1).any());
|
| 689 |
+
VERIFY(((m1(r, c) - 1) < m1).any());
|
| 690 |
+
VERIFY(((m1(r, c) + 1) > m1).any());
|
| 691 |
+
VERIFY((m1(r, c) == m1).any());
|
| 692 |
+
|
| 693 |
+
// currently, any() / all() are not vectorized, so use VERIFY_IS_CWISE_EQUAL to test vectorized path
|
| 694 |
+
|
| 695 |
+
// use typed comparisons, regardless of operator overload behavior
|
| 696 |
+
typename ArrayType::ConstantReturnType typed_true = ArrayType::Constant(rows, cols, Scalar(1));
|
| 697 |
+
// (m1 + Scalar(1)) > m1).all()
|
| 698 |
+
VERIFY_IS_CWISE_EQUAL((m1 + Scalar(1)).cwiseTypedGreater(m1), typed_true);
|
| 699 |
+
// (m1 - Scalar(1)) < m1).all()
|
| 700 |
+
VERIFY_IS_CWISE_EQUAL((m1 - Scalar(1)).cwiseTypedLess(m1), typed_true);
|
| 701 |
+
// (m1 + Scalar(1)) == (m1 + Scalar(1))).all()
|
| 702 |
+
VERIFY_IS_CWISE_EQUAL((m1 + Scalar(1)).cwiseTypedEqual(m1 + Scalar(1)), typed_true);
|
| 703 |
+
// (m1 - Scalar(1)) != m1).all()
|
| 704 |
+
VERIFY_IS_CWISE_EQUAL((m1 - Scalar(1)).cwiseTypedNotEqual(m1), typed_true);
|
| 705 |
+
// (m1 <= m2 || m1 >= m2).all()
|
| 706 |
+
VERIFY_IS_CWISE_EQUAL(m1.cwiseTypedGreaterOrEqual(m2) || m1.cwiseTypedLessOrEqual(m2), typed_true);
|
| 707 |
+
|
| 708 |
+
// use boolean comparisons, regardless of operator overload behavior
|
| 709 |
+
ArrayXX<bool>::ConstantReturnType bool_true = ArrayXX<bool>::Constant(rows, cols, true);
|
| 710 |
+
// (m1 + Scalar(1)) > m1).all()
|
| 711 |
+
VERIFY_IS_CWISE_EQUAL((m1 + Scalar(1)).cwiseGreater(m1), bool_true);
|
| 712 |
+
// (m1 - Scalar(1)) < m1).all()
|
| 713 |
+
VERIFY_IS_CWISE_EQUAL((m1 - Scalar(1)).cwiseLess(m1), bool_true);
|
| 714 |
+
// (m1 + Scalar(1)) == (m1 + Scalar(1))).all()
|
| 715 |
+
VERIFY_IS_CWISE_EQUAL((m1 + Scalar(1)).cwiseEqual(m1 + Scalar(1)), bool_true);
|
| 716 |
+
// (m1 - Scalar(1)) != m1).all()
|
| 717 |
+
VERIFY_IS_CWISE_EQUAL((m1 - Scalar(1)).cwiseNotEqual(m1), bool_true);
|
| 718 |
+
// (m1 <= m2 || m1 >= m2).all()
|
| 719 |
+
VERIFY_IS_CWISE_EQUAL(m1.cwiseLessOrEqual(m2) || m1.cwiseGreaterOrEqual(m2), bool_true);
|
| 720 |
+
|
| 721 |
+
// test typed comparisons with scalar argument
|
| 722 |
+
VERIFY_IS_CWISE_EQUAL((m1 - m1).cwiseTypedEqual(Scalar(0)), typed_true);
|
| 723 |
+
VERIFY_IS_CWISE_EQUAL((m1.abs() + Scalar(1)).cwiseTypedNotEqual(Scalar(0)), typed_true);
|
| 724 |
+
VERIFY_IS_CWISE_EQUAL((m1 + Scalar(1)).cwiseTypedGreater(m1.minCoeff()), typed_true);
|
| 725 |
+
VERIFY_IS_CWISE_EQUAL((m1 - Scalar(1)).cwiseTypedLess(m1.maxCoeff()), typed_true);
|
| 726 |
+
VERIFY_IS_CWISE_EQUAL(m1.abs().cwiseTypedLessOrEqual(NumTraits<Scalar>::highest()), typed_true);
|
| 727 |
+
VERIFY_IS_CWISE_EQUAL(m1.abs().cwiseTypedGreaterOrEqual(Scalar(0)), typed_true);
|
| 728 |
+
|
| 729 |
+
// test boolean comparisons with scalar argument
|
| 730 |
+
VERIFY_IS_CWISE_EQUAL((m1 - m1).cwiseEqual(Scalar(0)), bool_true);
|
| 731 |
+
VERIFY_IS_CWISE_EQUAL((m1.abs() + Scalar(1)).cwiseNotEqual(Scalar(0)), bool_true);
|
| 732 |
+
VERIFY_IS_CWISE_EQUAL((m1 + Scalar(1)).cwiseGreater(m1.minCoeff()), bool_true);
|
| 733 |
+
VERIFY_IS_CWISE_EQUAL((m1 - Scalar(1)).cwiseLess(m1.maxCoeff()), bool_true);
|
| 734 |
+
VERIFY_IS_CWISE_EQUAL(m1.abs().cwiseLessOrEqual(NumTraits<Scalar>::highest()), bool_true);
|
| 735 |
+
VERIFY_IS_CWISE_EQUAL(m1.abs().cwiseGreaterOrEqual(Scalar(0)), bool_true);
|
| 736 |
+
|
| 737 |
+
// test select
|
| 738 |
+
VERIFY_IS_APPROX((m1 < m2).select(m1, m2), m1.cwiseMin(m2));
|
| 739 |
+
VERIFY_IS_APPROX((m1 > m2).select(m1, m2), m1.cwiseMax(m2));
|
| 740 |
+
Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff()) / Scalar(2);
|
| 741 |
+
for (int j = 0; j < cols; ++j)
|
| 742 |
+
for (int i = 0; i < rows; ++i) m3(i, j) = abs(m1(i, j)) < mid ? 0 : m1(i, j);
|
| 743 |
+
VERIFY_IS_APPROX((m1.abs() < ArrayType::Constant(rows, cols, mid)).select(ArrayType::Zero(rows, cols), m1), m3);
|
| 744 |
+
// shorter versions:
|
| 745 |
+
VERIFY_IS_APPROX((m1.abs() < ArrayType::Constant(rows, cols, mid)).select(0, m1), m3);
|
| 746 |
+
VERIFY_IS_APPROX((m1.abs() >= ArrayType::Constant(rows, cols, mid)).select(m1, 0), m3);
|
| 747 |
+
// even shorter version:
|
| 748 |
+
VERIFY_IS_APPROX((m1.abs() < mid).select(0, m1), m3);
|
| 749 |
+
|
| 750 |
+
// count
|
| 751 |
+
VERIFY(((m1.abs() + 1) > RealScalar(0.1)).count() == rows * cols);
|
| 752 |
+
|
| 753 |
+
// and/or
|
| 754 |
+
VERIFY((m1 < RealScalar(0) && m1 > RealScalar(0)).count() == 0);
|
| 755 |
+
VERIFY((m1 < RealScalar(0) || m1 >= RealScalar(0)).count() == rows * cols);
|
| 756 |
+
RealScalar a = m1.abs().mean();
|
| 757 |
+
VERIFY((m1 < -a || m1 > a).count() == (m1.abs() > a).count());
|
| 758 |
+
|
| 759 |
+
typedef Array<Index, Dynamic, 1> ArrayOfIndices;
|
| 760 |
+
|
| 761 |
+
// TODO allows colwise/rowwise for array
|
| 762 |
+
VERIFY_IS_APPROX(((m1.abs() + 1) > RealScalar(0.1)).colwise().count(),
|
| 763 |
+
ArrayOfIndices::Constant(cols, rows).transpose());
|
| 764 |
+
VERIFY_IS_APPROX(((m1.abs() + 1) > RealScalar(0.1)).rowwise().count(), ArrayOfIndices::Constant(rows, cols));
|
| 765 |
+
|
| 766 |
+
// simple data type that does not permit implicit conversions
|
| 767 |
+
struct scalar_wrapper {
|
| 768 |
+
Scalar m_data;
|
| 769 |
+
scalar_wrapper() : m_data(0) {}
|
| 770 |
+
explicit scalar_wrapper(Scalar data) : m_data(data) {}
|
| 771 |
+
bool operator==(scalar_wrapper other) const { return m_data == other.m_data; }
|
| 772 |
+
};
|
| 773 |
+
|
| 774 |
+
// test bug2966: select did not support some scalar types that forbade implicit conversions from bool
|
| 775 |
+
ArrayX<scalar_wrapper> m5(10);
|
| 776 |
+
m5 = (m5 == scalar_wrapper(0)).select(m5, m5);
|
| 777 |
+
}
|
| 778 |
+
|
| 779 |
+
template <typename ArrayType>
|
| 780 |
+
void array_real(const ArrayType& m) {
|
| 781 |
+
using numext::abs;
|
| 782 |
+
using std::sqrt;
|
| 783 |
+
typedef typename ArrayType::Scalar Scalar;
|
| 784 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 785 |
+
|
| 786 |
+
Index rows = m.rows();
|
| 787 |
+
Index cols = m.cols();
|
| 788 |
+
|
| 789 |
+
ArrayType m1 = ArrayType::Random(rows, cols), m2 = ArrayType::Random(rows, cols), m3(rows, cols), m4 = m1;
|
| 790 |
+
|
| 791 |
+
// avoid denormalized values so verification doesn't fail on platforms that don't support them
|
| 792 |
+
// denormalized behavior is tested elsewhere (unary_op_test, binary_ops_test)
|
| 793 |
+
const Scalar min = (std::numeric_limits<Scalar>::min)();
|
| 794 |
+
m1 = (m1.abs() < min).select(Scalar(0), m1);
|
| 795 |
+
m2 = (m2.abs() < min).select(Scalar(0), m2);
|
| 796 |
+
m4 = (m4.abs() < min).select(Scalar(1), m4);
|
| 797 |
+
|
| 798 |
+
Scalar s1 = internal::random<Scalar>();
|
| 799 |
+
|
| 800 |
+
// these tests are mostly to check possible compilation issues with free-functions.
|
| 801 |
+
VERIFY_IS_APPROX(m1.sin(), sin(m1));
|
| 802 |
+
VERIFY_IS_APPROX(m1.cos(), cos(m1));
|
| 803 |
+
VERIFY_IS_APPROX(m1.tan(), tan(m1));
|
| 804 |
+
VERIFY_IS_APPROX(m1.asin(), asin(m1));
|
| 805 |
+
VERIFY_IS_APPROX(m1.acos(), acos(m1));
|
| 806 |
+
VERIFY_IS_APPROX(m1.atan(), atan(m1));
|
| 807 |
+
VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
|
| 808 |
+
VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
|
| 809 |
+
VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
|
| 810 |
+
VERIFY_IS_APPROX(m1.atan2(m2), atan2(m1, m2));
|
| 811 |
+
|
| 812 |
+
VERIFY_IS_APPROX(m1.tanh().atanh(), atanh(tanh(m1)));
|
| 813 |
+
VERIFY_IS_APPROX(m1.sinh().asinh(), asinh(sinh(m1)));
|
| 814 |
+
VERIFY_IS_APPROX(m1.cosh().acosh(), acosh(cosh(m1)));
|
| 815 |
+
VERIFY_IS_APPROX(m1.tanh().atanh(), atanh(tanh(m1)));
|
| 816 |
+
VERIFY_IS_APPROX(m1.logistic(), logistic(m1));
|
| 817 |
+
|
| 818 |
+
VERIFY_IS_APPROX(m1.arg(), arg(m1));
|
| 819 |
+
VERIFY_IS_APPROX(m1.round(), round(m1));
|
| 820 |
+
VERIFY_IS_APPROX(m1.rint(), rint(m1));
|
| 821 |
+
VERIFY_IS_APPROX(m1.floor(), floor(m1));
|
| 822 |
+
VERIFY_IS_APPROX(m1.ceil(), ceil(m1));
|
| 823 |
+
VERIFY_IS_APPROX(m1.trunc(), trunc(m1));
|
| 824 |
+
VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
|
| 825 |
+
VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
|
| 826 |
+
VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
|
| 827 |
+
VERIFY_IS_APPROX(m4.inverse(), inverse(m4));
|
| 828 |
+
VERIFY_IS_APPROX(m1.abs(), abs(m1));
|
| 829 |
+
VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
|
| 830 |
+
VERIFY_IS_APPROX(m1.square(), square(m1));
|
| 831 |
+
VERIFY_IS_APPROX(m1.cube(), cube(m1));
|
| 832 |
+
VERIFY_IS_APPROX(cos(m1 + RealScalar(3) * m2), cos((m1 + RealScalar(3) * m2).eval()));
|
| 833 |
+
VERIFY_IS_APPROX(m1.sign(), sign(m1));
|
| 834 |
+
VERIFY((m1.sqrt().sign().isNaN() == (Eigen::isnan)(sign(sqrt(m1)))).all());
|
| 835 |
+
|
| 836 |
+
// avoid inf and NaNs so verification doesn't fail
|
| 837 |
+
m3 = m4.abs();
|
| 838 |
+
|
| 839 |
+
VERIFY_IS_APPROX(m3.sqrt(), sqrt(abs(m3)));
|
| 840 |
+
VERIFY_IS_APPROX(m3.cbrt(), cbrt(m3));
|
| 841 |
+
VERIFY_IS_APPROX(m3.rsqrt(), Scalar(1) / sqrt(abs(m3)));
|
| 842 |
+
VERIFY_IS_APPROX(rsqrt(m3), Scalar(1) / sqrt(abs(m3)));
|
| 843 |
+
VERIFY_IS_APPROX(m3.log(), log(m3));
|
| 844 |
+
VERIFY_IS_APPROX(m3.log1p(), log1p(m3));
|
| 845 |
+
VERIFY_IS_APPROX(m3.log10(), log10(m3));
|
| 846 |
+
VERIFY_IS_APPROX(m3.log2(), log2(m3));
|
| 847 |
+
|
| 848 |
+
VERIFY((!(m1 > m2) == (m1 <= m2)).all());
|
| 849 |
+
|
| 850 |
+
VERIFY_IS_APPROX(sin(m1.asin()), m1);
|
| 851 |
+
VERIFY_IS_APPROX(cos(m1.acos()), m1);
|
| 852 |
+
VERIFY_IS_APPROX(tan(m1.atan()), m1);
|
| 853 |
+
VERIFY_IS_APPROX(sinh(m1), Scalar(0.5) * (exp(m1) - exp(-m1)));
|
| 854 |
+
VERIFY_IS_APPROX(cosh(m1), Scalar(0.5) * (exp(m1) + exp(-m1)));
|
| 855 |
+
VERIFY_IS_APPROX(tanh(m1), (Scalar(0.5) * (exp(m1) - exp(-m1))) / (Scalar(0.5) * (exp(m1) + exp(-m1))));
|
| 856 |
+
VERIFY_IS_APPROX(logistic(m1), (Scalar(1) / (Scalar(1) + exp(-m1))));
|
| 857 |
+
VERIFY_IS_APPROX(arg(m1), ((m1 < Scalar(0)).template cast<Scalar>()) * Scalar(std::acos(Scalar(-1))));
|
| 858 |
+
VERIFY((round(m1) <= ceil(m1) && round(m1) >= floor(m1)).all());
|
| 859 |
+
VERIFY((rint(m1) <= ceil(m1) && rint(m1) >= floor(m1)).all());
|
| 860 |
+
VERIFY(((ceil(m1) - round(m1)) <= Scalar(0.5) || (round(m1) - floor(m1)) <= Scalar(0.5)).all());
|
| 861 |
+
VERIFY(((ceil(m1) - round(m1)) <= Scalar(1.0) && (round(m1) - floor(m1)) <= Scalar(1.0)).all());
|
| 862 |
+
VERIFY(((ceil(m1) - rint(m1)) <= Scalar(0.5) || (rint(m1) - floor(m1)) <= Scalar(0.5)).all());
|
| 863 |
+
VERIFY(((ceil(m1) - rint(m1)) <= Scalar(1.0) && (rint(m1) - floor(m1)) <= Scalar(1.0)).all());
|
| 864 |
+
VERIFY((Eigen::isnan)((m1 * Scalar(0)) / Scalar(0)).all());
|
| 865 |
+
VERIFY((Eigen::isinf)(m4 / Scalar(0)).all());
|
| 866 |
+
VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1 * Scalar(0) / Scalar(0))) &&
|
| 867 |
+
(!(Eigen::isfinite)(m4 / Scalar(0))))
|
| 868 |
+
.all());
|
| 869 |
+
VERIFY_IS_APPROX(inverse(inverse(m4)), m4);
|
| 870 |
+
VERIFY((abs(m1) == m1 || abs(m1) == -m1).all());
|
| 871 |
+
VERIFY_IS_APPROX(m3, sqrt(abs2(m3)));
|
| 872 |
+
VERIFY_IS_APPROX(m1.absolute_difference(m2), (m1 > m2).select(m1 - m2, m2 - m1));
|
| 873 |
+
VERIFY_IS_APPROX(m1.sign(), -(-m1).sign());
|
| 874 |
+
VERIFY_IS_APPROX(m1 * m1.sign(), m1.abs());
|
| 875 |
+
VERIFY_IS_APPROX(m1.sign() * m1.abs(), m1);
|
| 876 |
+
|
| 877 |
+
ArrayType tmp = m1.atan2(m2);
|
| 878 |
+
for (Index i = 0; i < tmp.size(); ++i) {
|
| 879 |
+
Scalar actual = tmp.array()(i);
|
| 880 |
+
Scalar expected = Scalar(std::atan2(m1.array()(i), m2.array()(i)));
|
| 881 |
+
VERIFY_IS_APPROX(actual, expected);
|
| 882 |
+
}
|
| 883 |
+
|
| 884 |
+
VERIFY_IS_APPROX(numext::abs2(numext::real(m1)) + numext::abs2(numext::imag(m1)), numext::abs2(m1));
|
| 885 |
+
VERIFY_IS_APPROX(numext::abs2(Eigen::real(m1)) + numext::abs2(Eigen::imag(m1)), numext::abs2(m1));
|
| 886 |
+
if (!NumTraits<Scalar>::IsComplex) VERIFY_IS_APPROX(numext::real(m1), m1);
|
| 887 |
+
|
| 888 |
+
// shift argument of logarithm so that it is not zero
|
| 889 |
+
Scalar smallNumber = NumTraits<Scalar>::dummy_precision();
|
| 890 |
+
VERIFY_IS_APPROX((m3 + smallNumber).log(), log(abs(m3) + smallNumber));
|
| 891 |
+
VERIFY_IS_APPROX((m3 + smallNumber + Scalar(1)).log(), log1p(abs(m3) + smallNumber));
|
| 892 |
+
|
| 893 |
+
VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1 + m2));
|
| 894 |
+
VERIFY_IS_APPROX(m1.exp(), exp(m1));
|
| 895 |
+
VERIFY_IS_APPROX(m1.exp() / m2.exp(), (m1 - m2).exp());
|
| 896 |
+
|
| 897 |
+
VERIFY_IS_APPROX(m1.expm1(), expm1(m1));
|
| 898 |
+
VERIFY_IS_APPROX((m3 + smallNumber).exp() - Scalar(1), expm1(abs(m3) + smallNumber));
|
| 899 |
+
|
| 900 |
+
VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());
|
| 901 |
+
VERIFY_IS_APPROX(pow(m3, RealScalar(0.5)), m3.sqrt());
|
| 902 |
+
VERIFY_IS_APPROX(m3.pow(RealScalar(1.0 / 3.0)), m3.cbrt());
|
| 903 |
+
VERIFY_IS_APPROX(pow(m3, RealScalar(1.0 / 3.0)), m3.cbrt());
|
| 904 |
+
|
| 905 |
+
VERIFY_IS_APPROX(m3.pow(RealScalar(-0.5)), m3.rsqrt());
|
| 906 |
+
VERIFY_IS_APPROX(pow(m3, RealScalar(-0.5)), m3.rsqrt());
|
| 907 |
+
|
| 908 |
+
// Avoid inf and NaN.
|
| 909 |
+
m3 = (m1.square() < NumTraits<Scalar>::epsilon()).select(Scalar(1), m3);
|
| 910 |
+
VERIFY_IS_APPROX(m3.pow(RealScalar(-2)), m3.square().inverse());
|
| 911 |
+
|
| 912 |
+
// Test pow and atan2 on special IEEE values.
|
| 913 |
+
unary_ops_test<Scalar>();
|
| 914 |
+
binary_ops_test<Scalar>();
|
| 915 |
+
|
| 916 |
+
VERIFY_IS_APPROX(log10(m3), log(m3) / numext::log(Scalar(10)));
|
| 917 |
+
VERIFY_IS_APPROX(log2(m3), log(m3) / numext::log(Scalar(2)));
|
| 918 |
+
|
| 919 |
+
// scalar by array division
|
| 920 |
+
const RealScalar tiny = sqrt(std::numeric_limits<RealScalar>::epsilon());
|
| 921 |
+
s1 += Scalar(tiny);
|
| 922 |
+
m1 += ArrayType::Constant(rows, cols, Scalar(tiny));
|
| 923 |
+
VERIFY_IS_CWISE_APPROX(s1 / m1, s1 * m1.inverse());
|
| 924 |
+
|
| 925 |
+
// check inplace transpose
|
| 926 |
+
m3 = m1;
|
| 927 |
+
m3.transposeInPlace();
|
| 928 |
+
VERIFY_IS_APPROX(m3, m1.transpose());
|
| 929 |
+
m3.transposeInPlace();
|
| 930 |
+
VERIFY_IS_APPROX(m3, m1);
|
| 931 |
+
}
|
| 932 |
+
|
| 933 |
+
template <typename ArrayType>
|
| 934 |
+
void array_complex(const ArrayType& m) {
|
| 935 |
+
typedef typename ArrayType::Scalar Scalar;
|
| 936 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 937 |
+
|
| 938 |
+
Index rows = m.rows();
|
| 939 |
+
Index cols = m.cols();
|
| 940 |
+
|
| 941 |
+
ArrayType m1 = ArrayType::Random(rows, cols), m2(rows, cols), m4 = m1;
|
| 942 |
+
|
| 943 |
+
m4.real() = (m4.real().abs() == RealScalar(0)).select(RealScalar(1), m4.real());
|
| 944 |
+
m4.imag() = (m4.imag().abs() == RealScalar(0)).select(RealScalar(1), m4.imag());
|
| 945 |
+
|
| 946 |
+
Array<RealScalar, -1, -1> m3(rows, cols);
|
| 947 |
+
|
| 948 |
+
for (Index i = 0; i < m.rows(); ++i)
|
| 949 |
+
for (Index j = 0; j < m.cols(); ++j) m2(i, j) = sqrt(m1(i, j));
|
| 950 |
+
|
| 951 |
+
// these tests are mostly to check possible compilation issues with free-functions.
|
| 952 |
+
VERIFY_IS_APPROX(m1.sin(), sin(m1));
|
| 953 |
+
VERIFY_IS_APPROX(m1.cos(), cos(m1));
|
| 954 |
+
VERIFY_IS_APPROX(m1.tan(), tan(m1));
|
| 955 |
+
VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
|
| 956 |
+
VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
|
| 957 |
+
VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
|
| 958 |
+
VERIFY_IS_APPROX(m1.logistic(), logistic(m1));
|
| 959 |
+
VERIFY_IS_APPROX(m1.arg(), arg(m1));
|
| 960 |
+
VERIFY_IS_APPROX(m1.carg(), carg(m1));
|
| 961 |
+
VERIFY_IS_APPROX(arg(m1), carg(m1));
|
| 962 |
+
VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
|
| 963 |
+
VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
|
| 964 |
+
VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
|
| 965 |
+
VERIFY_IS_APPROX(m4.inverse(), inverse(m4));
|
| 966 |
+
VERIFY_IS_APPROX(m1.log(), log(m1));
|
| 967 |
+
VERIFY_IS_APPROX(m1.log10(), log10(m1));
|
| 968 |
+
VERIFY_IS_APPROX(m1.log2(), log2(m1));
|
| 969 |
+
VERIFY_IS_APPROX(m1.abs(), abs(m1));
|
| 970 |
+
VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
|
| 971 |
+
VERIFY_IS_APPROX(m1.sqrt(), sqrt(m1));
|
| 972 |
+
VERIFY_IS_APPROX(m1.square(), square(m1));
|
| 973 |
+
VERIFY_IS_APPROX(m1.cube(), cube(m1));
|
| 974 |
+
VERIFY_IS_APPROX(cos(m1 + RealScalar(3) * m2), cos((m1 + RealScalar(3) * m2).eval()));
|
| 975 |
+
VERIFY_IS_APPROX(m1.sign(), sign(m1));
|
| 976 |
+
|
| 977 |
+
VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1 + m2));
|
| 978 |
+
VERIFY_IS_APPROX(m1.exp(), exp(m1));
|
| 979 |
+
VERIFY_IS_APPROX(m1.exp() / m2.exp(), (m1 - m2).exp());
|
| 980 |
+
|
| 981 |
+
VERIFY_IS_APPROX(m1.expm1(), expm1(m1));
|
| 982 |
+
VERIFY_IS_APPROX(expm1(m1), exp(m1) - 1.);
|
| 983 |
+
// Check for larger magnitude complex numbers that expm1 matches exp - 1.
|
| 984 |
+
VERIFY_IS_APPROX(expm1(10. * m1), exp(10. * m1) - 1.);
|
| 985 |
+
|
| 986 |
+
VERIFY_IS_APPROX(sinh(m1), 0.5 * (exp(m1) - exp(-m1)));
|
| 987 |
+
VERIFY_IS_APPROX(cosh(m1), 0.5 * (exp(m1) + exp(-m1)));
|
| 988 |
+
VERIFY_IS_APPROX(tanh(m1), (0.5 * (exp(m1) - exp(-m1))) / (0.5 * (exp(m1) + exp(-m1))));
|
| 989 |
+
VERIFY_IS_APPROX(logistic(m1), (1.0 / (1.0 + exp(-m1))));
|
| 990 |
+
if (m1.size() > 0) {
|
| 991 |
+
// Complex exponential overflow edge-case.
|
| 992 |
+
Scalar old_m1_val = m1(0, 0);
|
| 993 |
+
m1(0, 0) = std::complex<RealScalar>(1000.0, 1000.0);
|
| 994 |
+
VERIFY_IS_APPROX(logistic(m1), (1.0 / (1.0 + exp(-m1))));
|
| 995 |
+
m1(0, 0) = old_m1_val; // Restore value for future tests.
|
| 996 |
+
}
|
| 997 |
+
|
| 998 |
+
for (Index i = 0; i < m.rows(); ++i)
|
| 999 |
+
for (Index j = 0; j < m.cols(); ++j) m3(i, j) = std::atan2(m1(i, j).imag(), m1(i, j).real());
|
| 1000 |
+
VERIFY_IS_APPROX(arg(m1), m3);
|
| 1001 |
+
VERIFY_IS_APPROX(carg(m1), m3);
|
| 1002 |
+
|
| 1003 |
+
std::complex<RealScalar> zero(0.0, 0.0);
|
| 1004 |
+
VERIFY((Eigen::isnan)(m1 * zero / zero).all());
|
| 1005 |
+
#if EIGEN_COMP_MSVC
|
| 1006 |
+
// msvc complex division is not robust
|
| 1007 |
+
VERIFY((Eigen::isinf)(m4 / RealScalar(0)).all());
|
| 1008 |
+
#else
|
| 1009 |
+
#if EIGEN_COMP_CLANG
|
| 1010 |
+
// clang's complex division is notoriously broken too
|
| 1011 |
+
if ((numext::isinf)(m4(0, 0) / RealScalar(0))) {
|
| 1012 |
+
#endif
|
| 1013 |
+
VERIFY((Eigen::isinf)(m4 / zero).all());
|
| 1014 |
+
#if EIGEN_COMP_CLANG
|
| 1015 |
+
} else {
|
| 1016 |
+
VERIFY((Eigen::isinf)(m4.real() / zero.real()).all());
|
| 1017 |
+
}
|
| 1018 |
+
#endif
|
| 1019 |
+
#endif // MSVC
|
| 1020 |
+
|
| 1021 |
+
VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1 * zero / zero)) && (!(Eigen::isfinite)(m1 / zero))).all());
|
| 1022 |
+
|
| 1023 |
+
VERIFY_IS_APPROX(inverse(inverse(m4)), m4);
|
| 1024 |
+
VERIFY_IS_APPROX(conj(m1.conjugate()), m1);
|
| 1025 |
+
VERIFY_IS_APPROX(abs(m1), sqrt(square(m1.real()) + square(m1.imag())));
|
| 1026 |
+
VERIFY_IS_APPROX(abs(m1), sqrt(abs2(m1)));
|
| 1027 |
+
VERIFY_IS_APPROX(log10(m1), log(m1) / log(10));
|
| 1028 |
+
VERIFY_IS_APPROX(log2(m1), log(m1) / log(2));
|
| 1029 |
+
|
| 1030 |
+
VERIFY_IS_APPROX(m1.sign(), -(-m1).sign());
|
| 1031 |
+
VERIFY_IS_APPROX(m1.sign() * m1.abs(), m1);
|
| 1032 |
+
|
| 1033 |
+
// scalar by array division
|
| 1034 |
+
Scalar s1 = internal::random<Scalar>();
|
| 1035 |
+
const RealScalar tiny = std::sqrt(std::numeric_limits<RealScalar>::epsilon());
|
| 1036 |
+
s1 += Scalar(tiny);
|
| 1037 |
+
m1 += ArrayType::Constant(rows, cols, Scalar(tiny));
|
| 1038 |
+
VERIFY_IS_APPROX(s1 / m1, s1 * m1.inverse());
|
| 1039 |
+
|
| 1040 |
+
// check inplace transpose
|
| 1041 |
+
m2 = m1;
|
| 1042 |
+
m2.transposeInPlace();
|
| 1043 |
+
VERIFY_IS_APPROX(m2, m1.transpose());
|
| 1044 |
+
m2.transposeInPlace();
|
| 1045 |
+
VERIFY_IS_APPROX(m2, m1);
|
| 1046 |
+
// Check vectorized inplace transpose.
|
| 1047 |
+
ArrayType m5 = ArrayType::Random(131, 131);
|
| 1048 |
+
ArrayType m6 = m5;
|
| 1049 |
+
m6.transposeInPlace();
|
| 1050 |
+
VERIFY_IS_APPROX(m6, m5.transpose());
|
| 1051 |
+
}
|
| 1052 |
+
|
| 1053 |
+
template <typename ArrayType>
|
| 1054 |
+
void min_max(const ArrayType& m) {
|
| 1055 |
+
typedef typename ArrayType::Scalar Scalar;
|
| 1056 |
+
|
| 1057 |
+
Index rows = m.rows();
|
| 1058 |
+
Index cols = m.cols();
|
| 1059 |
+
|
| 1060 |
+
ArrayType m1 = ArrayType::Random(rows, cols);
|
| 1061 |
+
|
| 1062 |
+
// min/max with array
|
| 1063 |
+
Scalar maxM1 = m1.maxCoeff();
|
| 1064 |
+
Scalar minM1 = m1.minCoeff();
|
| 1065 |
+
|
| 1066 |
+
VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, minM1), (m1.min)(ArrayType::Constant(rows, cols, minM1)));
|
| 1067 |
+
VERIFY_IS_APPROX(m1, (m1.min)(ArrayType::Constant(rows, cols, maxM1)));
|
| 1068 |
+
|
| 1069 |
+
VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, maxM1), (m1.max)(ArrayType::Constant(rows, cols, maxM1)));
|
| 1070 |
+
VERIFY_IS_APPROX(m1, (m1.max)(ArrayType::Constant(rows, cols, minM1)));
|
| 1071 |
+
|
| 1072 |
+
// min/max with scalar input
|
| 1073 |
+
VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, minM1), (m1.min)(minM1));
|
| 1074 |
+
VERIFY_IS_APPROX(m1, (m1.min)(maxM1));
|
| 1075 |
+
|
| 1076 |
+
VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, maxM1), (m1.max)(maxM1));
|
| 1077 |
+
VERIFY_IS_APPROX(m1, (m1.max)(minM1));
|
| 1078 |
+
|
| 1079 |
+
// min/max with various NaN propagation options.
|
| 1080 |
+
if (m1.size() > 1 && !NumTraits<Scalar>::IsInteger) {
|
| 1081 |
+
m1(0, 0) = NumTraits<Scalar>::quiet_NaN();
|
| 1082 |
+
maxM1 = m1.template maxCoeff<PropagateNaN>();
|
| 1083 |
+
minM1 = m1.template minCoeff<PropagateNaN>();
|
| 1084 |
+
VERIFY((numext::isnan)(maxM1));
|
| 1085 |
+
VERIFY((numext::isnan)(minM1));
|
| 1086 |
+
|
| 1087 |
+
maxM1 = m1.template maxCoeff<PropagateNumbers>();
|
| 1088 |
+
minM1 = m1.template minCoeff<PropagateNumbers>();
|
| 1089 |
+
VERIFY(!(numext::isnan)(maxM1));
|
| 1090 |
+
VERIFY(!(numext::isnan)(minM1));
|
| 1091 |
+
}
|
| 1092 |
+
}
|
| 1093 |
+
|
| 1094 |
+
template <typename Scalar>
|
| 1095 |
+
struct shift_imm_traits {
|
| 1096 |
+
enum { Cost = 1, PacketAccess = internal::packet_traits<Scalar>::HasShift };
|
| 1097 |
+
};
|
| 1098 |
+
|
| 1099 |
+
template <int N, typename Scalar>
|
| 1100 |
+
struct logical_left_shift_op {
|
| 1101 |
+
Scalar operator()(const Scalar& v) const { return numext::logical_shift_left(v, N); }
|
| 1102 |
+
template <typename Packet>
|
| 1103 |
+
Packet packetOp(const Packet& v) const {
|
| 1104 |
+
return internal::plogical_shift_left<N>(v);
|
| 1105 |
+
}
|
| 1106 |
+
};
|
| 1107 |
+
template <int N, typename Scalar>
|
| 1108 |
+
struct logical_right_shift_op {
|
| 1109 |
+
Scalar operator()(const Scalar& v) const { return numext::logical_shift_right(v, N); }
|
| 1110 |
+
template <typename Packet>
|
| 1111 |
+
Packet packetOp(const Packet& v) const {
|
| 1112 |
+
return internal::plogical_shift_right<N>(v);
|
| 1113 |
+
}
|
| 1114 |
+
};
|
| 1115 |
+
template <int N, typename Scalar>
|
| 1116 |
+
struct arithmetic_right_shift_op {
|
| 1117 |
+
Scalar operator()(const Scalar& v) const { return numext::arithmetic_shift_right(v, N); }
|
| 1118 |
+
template <typename Packet>
|
| 1119 |
+
Packet packetOp(const Packet& v) const {
|
| 1120 |
+
return internal::parithmetic_shift_right<N>(v);
|
| 1121 |
+
}
|
| 1122 |
+
};
|
| 1123 |
+
|
| 1124 |
+
namespace Eigen {
|
| 1125 |
+
namespace internal {
|
| 1126 |
+
template <int N, typename Scalar>
|
| 1127 |
+
struct functor_traits<logical_left_shift_op<N, Scalar>> : shift_imm_traits<Scalar> {};
|
| 1128 |
+
template <int N, typename Scalar>
|
| 1129 |
+
struct functor_traits<logical_right_shift_op<N, Scalar>> : shift_imm_traits<Scalar> {};
|
| 1130 |
+
template <int N, typename Scalar>
|
| 1131 |
+
struct functor_traits<arithmetic_right_shift_op<N, Scalar>> : shift_imm_traits<Scalar> {};
|
| 1132 |
+
} // namespace internal
|
| 1133 |
+
} // namespace Eigen
|
| 1134 |
+
|
| 1135 |
+
template <typename ArrayType>
|
| 1136 |
+
struct shift_test_impl {
|
| 1137 |
+
typedef typename ArrayType::Scalar Scalar;
|
| 1138 |
+
static constexpr size_t Size = sizeof(Scalar);
|
| 1139 |
+
static constexpr size_t MaxShift = (CHAR_BIT * Size) - 1;
|
| 1140 |
+
|
| 1141 |
+
template <size_t N = 1>
|
| 1142 |
+
static inline std::enable_if_t<(N > MaxShift), void> run(const ArrayType&) {}
|
| 1143 |
+
template <size_t N = 1>
|
| 1144 |
+
static inline std::enable_if_t<(N <= MaxShift), void> run(const ArrayType& m) {
|
| 1145 |
+
const Index rows = m.rows();
|
| 1146 |
+
const Index cols = m.cols();
|
| 1147 |
+
|
| 1148 |
+
ArrayType m1 = ArrayType::Random(rows, cols), m2(rows, cols), m3(rows, cols);
|
| 1149 |
+
|
| 1150 |
+
m2 = m1.unaryExpr([](const Scalar& v) { return numext::logical_shift_left(v, N); });
|
| 1151 |
+
m3 = m1.unaryExpr(logical_left_shift_op<N, Scalar>());
|
| 1152 |
+
VERIFY_IS_CWISE_EQUAL(m2, m3);
|
| 1153 |
+
|
| 1154 |
+
m2 = m1.unaryExpr([](const Scalar& v) { return numext::logical_shift_right(v, N); });
|
| 1155 |
+
m3 = m1.unaryExpr(logical_right_shift_op<N, Scalar>());
|
| 1156 |
+
VERIFY_IS_CWISE_EQUAL(m2, m3);
|
| 1157 |
+
|
| 1158 |
+
m2 = m1.unaryExpr([](const Scalar& v) { return numext::arithmetic_shift_right(v, N); });
|
| 1159 |
+
m3 = m1.unaryExpr(arithmetic_right_shift_op<N, Scalar>());
|
| 1160 |
+
VERIFY_IS_CWISE_EQUAL(m2, m3);
|
| 1161 |
+
|
| 1162 |
+
run<N + 1>(m);
|
| 1163 |
+
}
|
| 1164 |
+
};
|
| 1165 |
+
template <typename ArrayType>
|
| 1166 |
+
void shift_test(const ArrayType& m) {
|
| 1167 |
+
shift_test_impl<ArrayType>::run(m);
|
| 1168 |
+
}
|
| 1169 |
+
|
| 1170 |
+
template <typename ArrayType>
|
| 1171 |
+
struct typed_logicals_test_impl {
|
| 1172 |
+
using Scalar = typename ArrayType::Scalar;
|
| 1173 |
+
|
| 1174 |
+
static bool scalar_to_bool(const Scalar& x) { return x != Scalar(0); }
|
| 1175 |
+
static Scalar bool_to_scalar(bool x) { return x ? Scalar(1) : Scalar(0); }
|
| 1176 |
+
|
| 1177 |
+
static Scalar eval_bool_and(const Scalar& x, const Scalar& y) {
|
| 1178 |
+
return bool_to_scalar(scalar_to_bool(x) && scalar_to_bool(y));
|
| 1179 |
+
}
|
| 1180 |
+
static Scalar eval_bool_or(const Scalar& x, const Scalar& y) {
|
| 1181 |
+
return bool_to_scalar(scalar_to_bool(x) || scalar_to_bool(y));
|
| 1182 |
+
}
|
| 1183 |
+
static Scalar eval_bool_xor(const Scalar& x, const Scalar& y) {
|
| 1184 |
+
return bool_to_scalar(scalar_to_bool(x) != scalar_to_bool(y));
|
| 1185 |
+
}
|
| 1186 |
+
static Scalar eval_bool_not(const Scalar& x) { return bool_to_scalar(!scalar_to_bool(x)); }
|
| 1187 |
+
|
| 1188 |
+
static void run(const ArrayType& m) {
|
| 1189 |
+
Index rows = m.rows();
|
| 1190 |
+
Index cols = m.cols();
|
| 1191 |
+
|
| 1192 |
+
ArrayType m1(rows, cols), m2(rows, cols), m3(rows, cols), m4(rows, cols);
|
| 1193 |
+
|
| 1194 |
+
m1.setRandom();
|
| 1195 |
+
m2.setRandom();
|
| 1196 |
+
m1 *= ArrayX<bool>::Random(rows, cols).cast<Scalar>();
|
| 1197 |
+
m2 *= ArrayX<bool>::Random(rows, cols).cast<Scalar>();
|
| 1198 |
+
|
| 1199 |
+
// test boolean and
|
| 1200 |
+
m3 = m1 && m2;
|
| 1201 |
+
m4 = m1.binaryExpr(m2, [](const Scalar& x, const Scalar& y) { return eval_bool_and(x, y); });
|
| 1202 |
+
VERIFY_IS_CWISE_EQUAL(m3, m4);
|
| 1203 |
+
for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));
|
| 1204 |
+
|
| 1205 |
+
// test boolean or
|
| 1206 |
+
m3 = m1 || m2;
|
| 1207 |
+
m4 = m1.binaryExpr(m2, [](const Scalar& x, const Scalar& y) { return eval_bool_or(x, y); });
|
| 1208 |
+
VERIFY_IS_CWISE_EQUAL(m3, m4);
|
| 1209 |
+
for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));
|
| 1210 |
+
|
| 1211 |
+
// test boolean xor
|
| 1212 |
+
m3 = m1.binaryExpr(m2, internal::scalar_boolean_xor_op<Scalar>());
|
| 1213 |
+
m4 = m1.binaryExpr(m2, [](const Scalar& x, const Scalar& y) { return eval_bool_xor(x, y); });
|
| 1214 |
+
VERIFY_IS_CWISE_EQUAL(m3, m4);
|
| 1215 |
+
for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));
|
| 1216 |
+
|
| 1217 |
+
// test boolean not
|
| 1218 |
+
m3 = !m1;
|
| 1219 |
+
m4 = m1.unaryExpr([](const Scalar& x) { return eval_bool_not(x); });
|
| 1220 |
+
VERIFY_IS_CWISE_EQUAL(m3, m4);
|
| 1221 |
+
for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));
|
| 1222 |
+
|
| 1223 |
+
// test something more complicated
|
| 1224 |
+
m3 = m1 && m2;
|
| 1225 |
+
m4 = !(!m1 || !m2);
|
| 1226 |
+
VERIFY_IS_CWISE_EQUAL(m3, m4);
|
| 1227 |
+
|
| 1228 |
+
m3 = m1.binaryExpr(m2, internal::scalar_boolean_xor_op<Scalar>());
|
| 1229 |
+
m4 = (!m1).binaryExpr((!m2), internal::scalar_boolean_xor_op<Scalar>());
|
| 1230 |
+
VERIFY_IS_CWISE_EQUAL(m3, m4);
|
| 1231 |
+
|
| 1232 |
+
const size_t bytes = size_t(rows) * size_t(cols) * sizeof(Scalar);
|
| 1233 |
+
|
| 1234 |
+
std::vector<uint8_t> m1_buffer(bytes), m2_buffer(bytes), m3_buffer(bytes), m4_buffer(bytes);
|
| 1235 |
+
|
| 1236 |
+
std::memcpy(m1_buffer.data(), m1.data(), bytes);
|
| 1237 |
+
std::memcpy(m2_buffer.data(), m2.data(), bytes);
|
| 1238 |
+
|
| 1239 |
+
// test bitwise and
|
| 1240 |
+
m3 = m1 & m2;
|
| 1241 |
+
std::memcpy(m3_buffer.data(), m3.data(), bytes);
|
| 1242 |
+
for (size_t i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_buffer[i], uint8_t(m1_buffer[i] & m2_buffer[i]));
|
| 1243 |
+
|
| 1244 |
+
// test bitwise or
|
| 1245 |
+
m3 = m1 | m2;
|
| 1246 |
+
std::memcpy(m3_buffer.data(), m3.data(), bytes);
|
| 1247 |
+
for (size_t i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_buffer[i], uint8_t(m1_buffer[i] | m2_buffer[i]));
|
| 1248 |
+
|
| 1249 |
+
// test bitwise xor
|
| 1250 |
+
m3 = m1 ^ m2;
|
| 1251 |
+
std::memcpy(m3_buffer.data(), m3.data(), bytes);
|
| 1252 |
+
for (size_t i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_buffer[i], uint8_t(m1_buffer[i] ^ m2_buffer[i]));
|
| 1253 |
+
|
| 1254 |
+
// test bitwise not
|
| 1255 |
+
m3 = ~m1;
|
| 1256 |
+
std::memcpy(m3_buffer.data(), m3.data(), bytes);
|
| 1257 |
+
for (size_t i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_buffer[i], uint8_t(~m1_buffer[i]));
|
| 1258 |
+
|
| 1259 |
+
// test something more complicated
|
| 1260 |
+
m3 = m1 & m2;
|
| 1261 |
+
m4 = ~(~m1 | ~m2);
|
| 1262 |
+
std::memcpy(m3_buffer.data(), m3.data(), bytes);
|
| 1263 |
+
std::memcpy(m4_buffer.data(), m4.data(), bytes);
|
| 1264 |
+
for (size_t i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_buffer[i], m4_buffer[i]);
|
| 1265 |
+
|
| 1266 |
+
m3 = m1 ^ m2;
|
| 1267 |
+
m4 = (~m1) ^ (~m2);
|
| 1268 |
+
std::memcpy(m3_buffer.data(), m3.data(), bytes);
|
| 1269 |
+
std::memcpy(m4_buffer.data(), m4.data(), bytes);
|
| 1270 |
+
for (size_t i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_buffer[i], m4_buffer[i]);
|
| 1271 |
+
}
|
| 1272 |
+
};
|
| 1273 |
+
template <typename ArrayType>
|
| 1274 |
+
void typed_logicals_test(const ArrayType& m) {
|
| 1275 |
+
typed_logicals_test_impl<ArrayType>::run(m);
|
| 1276 |
+
}
|
| 1277 |
+
|
| 1278 |
+
template <typename SrcType, typename DstType, int RowsAtCompileTime, int ColsAtCompileTime>
|
| 1279 |
+
struct cast_test_impl {
|
| 1280 |
+
using SrcArray = Array<SrcType, RowsAtCompileTime, ColsAtCompileTime>;
|
| 1281 |
+
using DstArray = Array<DstType, RowsAtCompileTime, ColsAtCompileTime>;
|
| 1282 |
+
struct RandomOp {
|
| 1283 |
+
inline SrcType operator()(const SrcType&) const {
|
| 1284 |
+
return internal::random_without_cast_overflow<SrcType, DstType>::value();
|
| 1285 |
+
}
|
| 1286 |
+
};
|
| 1287 |
+
|
| 1288 |
+
static constexpr int SrcPacketSize = internal::packet_traits<SrcType>::size;
|
| 1289 |
+
static constexpr int DstPacketSize = internal::packet_traits<DstType>::size;
|
| 1290 |
+
static constexpr int MaxPacketSize = internal::plain_enum_max(SrcPacketSize, DstPacketSize);
|
| 1291 |
+
|
| 1292 |
+
static void run() {
|
| 1293 |
+
const Index testRows = RowsAtCompileTime == Dynamic ? ((10 * MaxPacketSize) + 1) : RowsAtCompileTime;
|
| 1294 |
+
const Index testCols = ColsAtCompileTime == Dynamic ? ((10 * MaxPacketSize) + 1) : ColsAtCompileTime;
|
| 1295 |
+
const Index testSize = testRows * testCols;
|
| 1296 |
+
const Index minTestSize = 100;
|
| 1297 |
+
const Index repeats = numext::div_ceil(minTestSize, testSize);
|
| 1298 |
+
|
| 1299 |
+
SrcArray src(testRows, testCols);
|
| 1300 |
+
DstArray dst(testRows, testCols);
|
| 1301 |
+
|
| 1302 |
+
for (Index repeat = 0; repeat < repeats; repeat++) {
|
| 1303 |
+
src = src.unaryExpr(RandomOp());
|
| 1304 |
+
dst = src.template cast<DstType>();
|
| 1305 |
+
|
| 1306 |
+
for (Index j = 0; j < testCols; j++)
|
| 1307 |
+
for (Index i = 0; i < testRows; i++) {
|
| 1308 |
+
SrcType srcVal = src(i, j);
|
| 1309 |
+
DstType refVal = internal::cast_impl<SrcType, DstType>::run(srcVal);
|
| 1310 |
+
DstType dstVal = dst(i, j);
|
| 1311 |
+
bool isApprox = verifyIsApprox(dstVal, refVal);
|
| 1312 |
+
if (!isApprox)
|
| 1313 |
+
std::cout << type_name(srcVal) << ": [" << +srcVal << "] to " << type_name(dstVal) << ": [" << +dstVal
|
| 1314 |
+
<< "] != [" << +refVal << "]\n";
|
| 1315 |
+
VERIFY(isApprox);
|
| 1316 |
+
}
|
| 1317 |
+
}
|
| 1318 |
+
}
|
| 1319 |
+
};
|
| 1320 |
+
|
| 1321 |
+
template <int RowsAtCompileTime, int ColsAtCompileTime, typename... ScalarTypes>
|
| 1322 |
+
struct cast_tests_impl {
|
| 1323 |
+
using ScalarTuple = std::tuple<ScalarTypes...>;
|
| 1324 |
+
static constexpr size_t ScalarTupleSize = std::tuple_size<ScalarTuple>::value;
|
| 1325 |
+
|
| 1326 |
+
template <size_t i = 0, size_t j = i + 1, bool Done = (i >= ScalarTupleSize - 1) || (j >= ScalarTupleSize)>
|
| 1327 |
+
static std::enable_if_t<Done> run() {}
|
| 1328 |
+
|
| 1329 |
+
template <size_t i = 0, size_t j = i + 1, bool Done = (i >= ScalarTupleSize - 1) || (j >= ScalarTupleSize)>
|
| 1330 |
+
static std::enable_if_t<!Done> run() {
|
| 1331 |
+
using Type1 = typename std::tuple_element<i, ScalarTuple>::type;
|
| 1332 |
+
using Type2 = typename std::tuple_element<j, ScalarTuple>::type;
|
| 1333 |
+
cast_test_impl<Type1, Type2, RowsAtCompileTime, ColsAtCompileTime>::run();
|
| 1334 |
+
cast_test_impl<Type2, Type1, RowsAtCompileTime, ColsAtCompileTime>::run();
|
| 1335 |
+
static constexpr size_t next_i = (j == ScalarTupleSize - 1) ? (i + 1) : (i + 0);
|
| 1336 |
+
static constexpr size_t next_j = (j == ScalarTupleSize - 1) ? (i + 2) : (j + 1);
|
| 1337 |
+
run<next_i, next_j>();
|
| 1338 |
+
}
|
| 1339 |
+
};
|
| 1340 |
+
|
| 1341 |
+
// for now, remove all references to 'long double' until test passes on all platforms
|
| 1342 |
+
template <int RowsAtCompileTime, int ColsAtCompileTime>
|
| 1343 |
+
void cast_test() {
|
| 1344 |
+
cast_tests_impl<RowsAtCompileTime, ColsAtCompileTime, bool, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t,
|
| 1345 |
+
uint32_t, uint64_t, float, double, /*long double, */ half, bfloat16>::run();
|
| 1346 |
+
}
|
| 1347 |
+
|
| 1348 |
+
EIGEN_DECLARE_TEST(array_cwise) {
|
| 1349 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1350 |
+
CALL_SUBTEST_1(array_generic(Array<float, 1, 1>()));
|
| 1351 |
+
CALL_SUBTEST_2(array_generic(Array22f()));
|
| 1352 |
+
CALL_SUBTEST_3(array_generic(Array44d()));
|
| 1353 |
+
CALL_SUBTEST_4(array_generic(
|
| 1354 |
+
ArrayXXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1355 |
+
CALL_SUBTEST_5(array_generic(
|
| 1356 |
+
ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1357 |
+
CALL_SUBTEST_8(array_generic(
|
| 1358 |
+
ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1359 |
+
CALL_SUBTEST_7(array_generic(Array<Index, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
| 1360 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1361 |
+
CALL_SUBTEST_8(shift_test(
|
| 1362 |
+
ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1363 |
+
CALL_SUBTEST_9(shift_test(Array<Index, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
| 1364 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1365 |
+
CALL_SUBTEST_10(array_generic(Array<uint32_t, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
| 1366 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1367 |
+
CALL_SUBTEST_11(array_generic(Array<uint64_t, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
| 1368 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1369 |
+
}
|
| 1370 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1371 |
+
CALL_SUBTEST_1(comparisons(Array<float, 1, 1>()));
|
| 1372 |
+
CALL_SUBTEST_2(comparisons(Array22f()));
|
| 1373 |
+
CALL_SUBTEST_3(comparisons(Array44d()));
|
| 1374 |
+
CALL_SUBTEST_7(comparisons(
|
| 1375 |
+
ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1376 |
+
CALL_SUBTEST_8(comparisons(
|
| 1377 |
+
ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1378 |
+
}
|
| 1379 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1380 |
+
CALL_SUBTEST_6(min_max(Array<float, 1, 1>()));
|
| 1381 |
+
CALL_SUBTEST_7(min_max(Array22f()));
|
| 1382 |
+
CALL_SUBTEST_8(min_max(Array44d()));
|
| 1383 |
+
CALL_SUBTEST_9(min_max(
|
| 1384 |
+
ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1385 |
+
CALL_SUBTEST_10(min_max(
|
| 1386 |
+
ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1387 |
+
}
|
| 1388 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1389 |
+
CALL_SUBTEST_11(array_real(Array<float, 1, 1>()));
|
| 1390 |
+
CALL_SUBTEST_12(array_real(Array22f()));
|
| 1391 |
+
CALL_SUBTEST_13(array_real(Array44d()));
|
| 1392 |
+
CALL_SUBTEST_14(array_real(
|
| 1393 |
+
ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1394 |
+
CALL_SUBTEST_15(array_real(Array<Eigen::half, 32, 32>()));
|
| 1395 |
+
CALL_SUBTEST_16(array_real(Array<Eigen::bfloat16, 32, 32>()));
|
| 1396 |
+
}
|
| 1397 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1398 |
+
CALL_SUBTEST_17(array_complex(
|
| 1399 |
+
ArrayXXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1400 |
+
CALL_SUBTEST_18(array_complex(
|
| 1401 |
+
ArrayXXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1402 |
+
}
|
| 1403 |
+
|
| 1404 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1405 |
+
CALL_SUBTEST_19(float_pow_test());
|
| 1406 |
+
CALL_SUBTEST_20(int_pow_test());
|
| 1407 |
+
CALL_SUBTEST_21(mixed_pow_test());
|
| 1408 |
+
CALL_SUBTEST_22(signbit_tests());
|
| 1409 |
+
}
|
| 1410 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1411 |
+
CALL_SUBTEST_23(typed_logicals_test(ArrayX<int>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1412 |
+
CALL_SUBTEST_24(typed_logicals_test(ArrayX<float>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1413 |
+
CALL_SUBTEST_25(typed_logicals_test(ArrayX<double>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1414 |
+
CALL_SUBTEST_26(typed_logicals_test(ArrayX<std::complex<float>>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1415 |
+
CALL_SUBTEST_27(typed_logicals_test(ArrayX<std::complex<double>>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 1416 |
+
}
|
| 1417 |
+
|
| 1418 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 1419 |
+
CALL_SUBTEST_28((cast_test<1, 1>()));
|
| 1420 |
+
CALL_SUBTEST_29((cast_test<3, 1>()));
|
| 1421 |
+
CALL_SUBTEST_30((cast_test<5, 1>()));
|
| 1422 |
+
CALL_SUBTEST_31((cast_test<9, 1>()));
|
| 1423 |
+
CALL_SUBTEST_32((cast_test<17, 1>()));
|
| 1424 |
+
CALL_SUBTEST_33((cast_test<Dynamic, 1>()));
|
| 1425 |
+
}
|
| 1426 |
+
|
| 1427 |
+
VERIFY((internal::is_same<internal::global_math_functions_filtering_base<int>::type, int>::value));
|
| 1428 |
+
VERIFY((internal::is_same<internal::global_math_functions_filtering_base<float>::type, float>::value));
|
| 1429 |
+
VERIFY((internal::is_same<internal::global_math_functions_filtering_base<Array2i>::type, ArrayBase<Array2i>>::value));
|
| 1430 |
+
typedef CwiseUnaryOp<internal::scalar_abs_op<double>, ArrayXd> Xpr;
|
| 1431 |
+
VERIFY((internal::is_same<internal::global_math_functions_filtering_base<Xpr>::type, ArrayBase<Xpr>>::value));
|
| 1432 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_for_matrix.cpp
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <typename MatrixType>
|
| 13 |
+
void array_for_matrix(const MatrixType& m) {
|
| 14 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 15 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
|
| 16 |
+
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
|
| 17 |
+
|
| 18 |
+
Index rows = m.rows();
|
| 19 |
+
Index cols = m.cols();
|
| 20 |
+
|
| 21 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols);
|
| 22 |
+
ColVectorType cv1 = ColVectorType::Random(rows);
|
| 23 |
+
RowVectorType rv1 = RowVectorType::Random(cols);
|
| 24 |
+
|
| 25 |
+
Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>();
|
| 26 |
+
|
| 27 |
+
// Prevent overflows for integer types.
|
| 28 |
+
if (Eigen::NumTraits<Scalar>::IsInteger) {
|
| 29 |
+
Scalar kMaxVal = Scalar(1000);
|
| 30 |
+
m1.array() = m1.array() - kMaxVal * (m1.array() / kMaxVal);
|
| 31 |
+
m2.array() = m2.array() - kMaxVal * (m2.array() / kMaxVal);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// scalar addition
|
| 35 |
+
VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array());
|
| 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));
|
| 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
|
| 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());
|
| 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>()));
|
| 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);
|
| 63 |
+
|
| 64 |
+
// empty objects
|
| 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));
|
| 69 |
+
|
| 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));
|
| 74 |
+
|
| 75 |
+
// verify the const accessors exist
|
| 76 |
+
const Scalar& ref_m1 = m.matrix().array().coeffRef(0);
|
| 77 |
+
const Scalar& ref_m2 = m.matrix().array().coeffRef(0, 0);
|
| 78 |
+
const Scalar& ref_a1 = m.array().matrix().coeffRef(0);
|
| 79 |
+
const Scalar& ref_a2 = m.array().matrix().coeffRef(0, 0);
|
| 80 |
+
VERIFY(&ref_a1 == &ref_m1);
|
| 81 |
+
VERIFY(&ref_a2 == &ref_m2);
|
| 82 |
+
|
| 83 |
+
// Check write accessors:
|
| 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));
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
template <typename MatrixType>
|
| 95 |
+
void comparisons(const MatrixType& m) {
|
| 96 |
+
using std::abs;
|
| 97 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 98 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 99 |
+
|
| 100 |
+
Index rows = m.rows();
|
| 101 |
+
Index cols = m.cols();
|
| 102 |
+
|
| 103 |
+
Index r = internal::random<Index>(0, rows - 1), c = internal::random<Index>(0, cols - 1);
|
| 104 |
+
|
| 105 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols);
|
| 106 |
+
|
| 107 |
+
VERIFY(((m1.array() + Scalar(1)) > m1.array()).all());
|
| 108 |
+
VERIFY(((m1.array() - Scalar(1)) < m1.array()).all());
|
| 109 |
+
if (rows * cols > 1) {
|
| 110 |
+
m3 = m1;
|
| 111 |
+
m3(r, c) += 1;
|
| 112 |
+
VERIFY(!(m1.array() < m3.array()).all());
|
| 113 |
+
VERIFY(!(m1.array() > m3.array()).all());
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
// comparisons to scalar
|
| 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());
|
| 122 |
+
|
| 123 |
+
// test select
|
| 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));
|
| 126 |
+
Scalar mid = m1.cwiseAbs().minCoeff() / Scalar(2) + m1.cwiseAbs().maxCoeff() / Scalar(2);
|
| 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);
|
| 131 |
+
// shorter versions:
|
| 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);
|
| 134 |
+
// even shorter version:
|
| 135 |
+
VERIFY_IS_APPROX((m1.array().abs() < mid).select(0, m1), m3);
|
| 136 |
+
|
| 137 |
+
// count
|
| 138 |
+
VERIFY(((m1.array().abs() + 1) > RealScalar(0.1)).count() == rows * cols);
|
| 139 |
+
|
| 140 |
+
// and/or
|
| 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);
|
| 143 |
+
VERIFY(((m1.array() < -mid).matrix() || (m1.array() > mid).matrix()).count() ==
|
| 144 |
+
(m1.cwiseAbs().array() > mid).count());
|
| 145 |
+
|
| 146 |
+
typedef Matrix<Index, Dynamic, 1> VectorOfIndices;
|
| 147 |
+
|
| 148 |
+
// TODO allows colwise/rowwise for array
|
| 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));
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
template <typename VectorType>
|
| 156 |
+
void lpNorm(const VectorType& v) {
|
| 157 |
+
using std::sqrt;
|
| 158 |
+
typedef typename VectorType::RealScalar RealScalar;
|
| 159 |
+
VectorType u = VectorType::Random(v.size());
|
| 160 |
+
|
| 161 |
+
if (v.size() == 0) {
|
| 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));
|
| 166 |
+
} else {
|
| 167 |
+
VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
|
| 171 |
+
VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));
|
| 172 |
+
VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)),
|
| 173 |
+
u.array().abs().pow(5).sum());
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
template <typename MatrixType>
|
| 177 |
+
void cwise_min_max(const MatrixType& m) {
|
| 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 |
+
|
| 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)));
|
| 191 |
+
|
| 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)));
|
| 194 |
+
|
| 195 |
+
// min/max with scalar input
|
| 196 |
+
VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1), m1.cwiseMin(minM1));
|
| 197 |
+
VERIFY_IS_APPROX(m1, m1.cwiseMin(maxM1));
|
| 198 |
+
VERIFY_IS_APPROX(-m1, (-m1).cwiseMin(-minM1));
|
| 199 |
+
VERIFY_IS_APPROX(-m1.array(), ((-m1).array().min)(-minM1));
|
| 200 |
+
|
| 201 |
+
VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1), m1.cwiseMax(maxM1));
|
| 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));
|
| 205 |
+
|
| 206 |
+
VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1).array(), (m1.array().min)(minM1));
|
| 207 |
+
VERIFY_IS_APPROX(m1.array(), (m1.array().min)(maxM1));
|
| 208 |
+
|
| 209 |
+
VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1).array(), (m1.array().max)(maxM1));
|
| 210 |
+
VERIFY_IS_APPROX(m1.array(), (m1.array().max)(minM1));
|
| 211 |
+
|
| 212 |
+
// Test NaN propagation for min/max.
|
| 213 |
+
if (!NumTraits<Scalar>::IsInteger) {
|
| 214 |
+
m1(0, 0) = NumTraits<Scalar>::quiet_NaN();
|
| 215 |
+
// Elementwise.
|
| 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)));
|
| 224 |
+
|
| 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)));
|
| 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 |
+
}
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
template <typename MatrixTraits>
|
| 252 |
+
void resize(const MatrixTraits& t) {
|
| 253 |
+
typedef typename MatrixTraits::Scalar Scalar;
|
| 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;
|
| 258 |
+
|
| 259 |
+
Index rows = t.rows(), cols = t.cols();
|
| 260 |
+
|
| 261 |
+
MatrixType m(rows, cols);
|
| 262 |
+
VectorType v(rows);
|
| 263 |
+
Array2DType a2(rows, cols);
|
| 264 |
+
Array1DType a1(rows);
|
| 265 |
+
|
| 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);
|
| 270 |
+
v.array().resize(cols);
|
| 271 |
+
VERIFY(v.size() == cols);
|
| 272 |
+
a1.matrix().resize(cols);
|
| 273 |
+
VERIFY(a1.size() == cols);
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
template <int>
|
| 277 |
+
void regression_bug_654() {
|
| 278 |
+
ArrayXf a = RowVectorXf(3);
|
| 279 |
+
VectorXf v = Array<float, 1, Dynamic>(3);
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
// Check propagation of LvalueBit through Array/Matrix-Wrapper
|
| 283 |
+
template <int>
|
| 284 |
+
void regrrssion_bug_1410() {
|
| 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 |
+
|
| 292 |
+
VERIFY((internal::traits<ArrayWrapper<const Matrix4i> >::Flags & LvalueBit) == 0);
|
| 293 |
+
VERIFY((internal::traits<MatrixWrapper<const Array4i> >::Flags & LvalueBit) == 0);
|
| 294 |
+
|
| 295 |
+
VERIFY((internal::traits<ArrayWrapper<Matrix4i> >::Flags & LvalueBit) == LvalueBit);
|
| 296 |
+
VERIFY((internal::traits<MatrixWrapper<Array4i> >::Flags & LvalueBit) == LvalueBit);
|
| 297 |
+
}
|
| 298 |
+
|
| 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))));
|
| 310 |
+
}
|
| 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))));
|
| 319 |
+
}
|
| 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))));
|
| 328 |
+
}
|
| 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))));
|
| 336 |
+
}
|
| 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))));
|
| 346 |
+
}
|
| 347 |
+
CALL_SUBTEST_6(regression_bug_654<0>());
|
| 348 |
+
CALL_SUBTEST_6(regrrssion_bug_1410<0>());
|
| 349 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_of_string.cpp
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
EIGEN_DECLARE_TEST(array_of_string) {
|
| 13 |
+
typedef Array<std::string, 1, Dynamic> ArrayXs;
|
| 14 |
+
ArrayXs a1(3), a2(3), a3(3), a3ref(3);
|
| 15 |
+
a1 << "one", "two", "three";
|
| 16 |
+
a2 << "1", "2", "3";
|
| 17 |
+
a3ref << "one (1)", "two (2)", "three (3)";
|
| 18 |
+
std::stringstream s1;
|
| 19 |
+
s1 << a1;
|
| 20 |
+
VERIFY_IS_EQUAL(s1.str(), std::string(" one two three"));
|
| 21 |
+
a3 = a1 + std::string(" (") + a2 + std::string(")");
|
| 22 |
+
VERIFY((a3 == a3ref).all());
|
| 23 |
+
|
| 24 |
+
a3 = a1;
|
| 25 |
+
a3 += std::string(" (") + a2 + std::string(")");
|
| 26 |
+
VERIFY((a3 == a3ref).all());
|
| 27 |
+
|
| 28 |
+
a1.swap(a3);
|
| 29 |
+
VERIFY((a1 == a3ref).all());
|
| 30 |
+
VERIFY((a3 != a3ref).all());
|
| 31 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_replicate.cpp
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <typename MatrixType>
|
| 13 |
+
void replicate(const MatrixType& m) {
|
| 14 |
+
/* this test covers the following files:
|
| 15 |
+
Replicate.cpp
|
| 16 |
+
*/
|
| 17 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 18 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 19 |
+
typedef Matrix<Scalar, Dynamic, Dynamic> MatrixX;
|
| 20 |
+
typedef Matrix<Scalar, Dynamic, 1> VectorX;
|
| 21 |
+
|
| 22 |
+
Index rows = m.rows();
|
| 23 |
+
Index cols = m.cols();
|
| 24 |
+
|
| 25 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols);
|
| 26 |
+
|
| 27 |
+
VectorType v1 = VectorType::Random(rows);
|
| 28 |
+
|
| 29 |
+
MatrixX x1, x2;
|
| 30 |
+
VectorX vx1;
|
| 31 |
+
|
| 32 |
+
int f1 = internal::random<int>(1, 10), f2 = internal::random<int>(1, 10);
|
| 33 |
+
|
| 34 |
+
x1.resize(rows * f1, cols * f2);
|
| 35 |
+
for (int j = 0; j < f2; j++)
|
| 36 |
+
for (int i = 0; i < f1; i++) x1.block(i * rows, j * cols, rows, cols) = m1;
|
| 37 |
+
VERIFY_IS_APPROX(x1, m1.replicate(f1, f2));
|
| 38 |
+
|
| 39 |
+
x2.resize(2 * rows, 3 * cols);
|
| 40 |
+
x2 << m2, m2, m2, m2, m2, m2;
|
| 41 |
+
VERIFY_IS_APPROX(x2, (m2.template replicate<2, 3>()));
|
| 42 |
+
|
| 43 |
+
x2.resize(rows, 3 * cols);
|
| 44 |
+
x2 << m2, m2, m2;
|
| 45 |
+
VERIFY_IS_APPROX(x2, (m2.template replicate<1, 3>()));
|
| 46 |
+
|
| 47 |
+
vx1.resize(3 * rows, cols);
|
| 48 |
+
vx1 << m2, m2, m2;
|
| 49 |
+
VERIFY_IS_APPROX(vx1 + vx1, vx1 + (m2.template replicate<3, 1>()));
|
| 50 |
+
|
| 51 |
+
vx1 = m2 + (m2.colwise().replicate(1));
|
| 52 |
+
|
| 53 |
+
if (m2.cols() == 1) VERIFY_IS_APPROX(m2.coeff(0), (m2.template replicate<3, 1>().coeff(m2.rows())));
|
| 54 |
+
|
| 55 |
+
x2.resize(rows, f1);
|
| 56 |
+
for (int j = 0; j < f1; ++j) x2.col(j) = v1;
|
| 57 |
+
VERIFY_IS_APPROX(x2, v1.rowwise().replicate(f1));
|
| 58 |
+
|
| 59 |
+
vx1.resize(rows * f2);
|
| 60 |
+
for (int j = 0; j < f2; ++j) vx1.segment(j * rows, rows) = v1;
|
| 61 |
+
VERIFY_IS_APPROX(vx1, v1.colwise().replicate(f2));
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
EIGEN_DECLARE_TEST(array_replicate) {
|
| 65 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 66 |
+
CALL_SUBTEST_1(replicate(Matrix<float, 1, 1>()));
|
| 67 |
+
CALL_SUBTEST_2(replicate(Vector2f()));
|
| 68 |
+
CALL_SUBTEST_3(replicate(Vector3d()));
|
| 69 |
+
CALL_SUBTEST_4(replicate(Vector4f()));
|
| 70 |
+
CALL_SUBTEST_5(replicate(VectorXf(16)));
|
| 71 |
+
CALL_SUBTEST_6(replicate(VectorXcd(10)));
|
| 72 |
+
}
|
| 73 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/array_reverse.cpp
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
| 5 |
+
// Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com>
|
| 6 |
+
//
|
| 7 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 8 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 9 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 10 |
+
|
| 11 |
+
#include "main.h"
|
| 12 |
+
#include <iostream>
|
| 13 |
+
|
| 14 |
+
using namespace std;
|
| 15 |
+
|
| 16 |
+
template <typename MatrixType>
|
| 17 |
+
void reverse(const MatrixType& m) {
|
| 18 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 19 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 20 |
+
|
| 21 |
+
Index rows = m.rows();
|
| 22 |
+
Index cols = m.cols();
|
| 23 |
+
|
| 24 |
+
// this test relies a lot on Random.h, and there's not much more that we can do
|
| 25 |
+
// to test it, hence I consider that we will have tested Random.h
|
| 26 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2;
|
| 27 |
+
VectorType v1 = VectorType::Random(rows);
|
| 28 |
+
|
| 29 |
+
MatrixType m1_r = m1.reverse();
|
| 30 |
+
// Verify that MatrixBase::reverse() works
|
| 31 |
+
for (int i = 0; i < rows; i++) {
|
| 32 |
+
for (int j = 0; j < cols; j++) {
|
| 33 |
+
VERIFY_IS_APPROX(m1_r(i, j), m1(rows - 1 - i, cols - 1 - j));
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
Reverse<MatrixType> m1_rd(m1);
|
| 38 |
+
// Verify that a Reverse default (in both directions) of an expression works
|
| 39 |
+
for (int i = 0; i < rows; i++) {
|
| 40 |
+
for (int j = 0; j < cols; j++) {
|
| 41 |
+
VERIFY_IS_APPROX(m1_rd(i, j), m1(rows - 1 - i, cols - 1 - j));
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
Reverse<MatrixType, BothDirections> m1_rb(m1);
|
| 46 |
+
// Verify that a Reverse in both directions of an expression works
|
| 47 |
+
for (int i = 0; i < rows; i++) {
|
| 48 |
+
for (int j = 0; j < cols; j++) {
|
| 49 |
+
VERIFY_IS_APPROX(m1_rb(i, j), m1(rows - 1 - i, cols - 1 - j));
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
Reverse<MatrixType, Vertical> m1_rv(m1);
|
| 54 |
+
// Verify that a Reverse in the vertical directions of an expression works
|
| 55 |
+
for (int i = 0; i < rows; i++) {
|
| 56 |
+
for (int j = 0; j < cols; j++) {
|
| 57 |
+
VERIFY_IS_APPROX(m1_rv(i, j), m1(rows - 1 - i, j));
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
Reverse<MatrixType, Horizontal> m1_rh(m1);
|
| 62 |
+
// Verify that a Reverse in the horizontal directions of an expression works
|
| 63 |
+
for (int i = 0; i < rows; i++) {
|
| 64 |
+
for (int j = 0; j < cols; j++) {
|
| 65 |
+
VERIFY_IS_APPROX(m1_rh(i, j), m1(i, cols - 1 - j));
|
| 66 |
+
}
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
VectorType v1_r = v1.reverse();
|
| 70 |
+
// Verify that a VectorType::reverse() of an expression works
|
| 71 |
+
for (int i = 0; i < rows; i++) {
|
| 72 |
+
VERIFY_IS_APPROX(v1_r(i), v1(rows - 1 - i));
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
MatrixType m1_cr = m1.colwise().reverse();
|
| 76 |
+
// Verify that PartialRedux::reverse() works (for colwise())
|
| 77 |
+
for (int i = 0; i < rows; i++) {
|
| 78 |
+
for (int j = 0; j < cols; j++) {
|
| 79 |
+
VERIFY_IS_APPROX(m1_cr(i, j), m1(rows - 1 - i, j));
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
MatrixType m1_rr = m1.rowwise().reverse();
|
| 84 |
+
// Verify that PartialRedux::reverse() works (for rowwise())
|
| 85 |
+
for (int i = 0; i < rows; i++) {
|
| 86 |
+
for (int j = 0; j < cols; j++) {
|
| 87 |
+
VERIFY_IS_APPROX(m1_rr(i, j), m1(i, cols - 1 - j));
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
Scalar x = internal::random<Scalar>();
|
| 92 |
+
|
| 93 |
+
Index r = internal::random<Index>(0, rows - 1), c = internal::random<Index>(0, cols - 1);
|
| 94 |
+
|
| 95 |
+
m1.reverse()(r, c) = x;
|
| 96 |
+
VERIFY_IS_APPROX(x, m1(rows - 1 - r, cols - 1 - c));
|
| 97 |
+
|
| 98 |
+
m2 = m1;
|
| 99 |
+
m2.reverseInPlace();
|
| 100 |
+
VERIFY_IS_APPROX(m2, m1.reverse().eval());
|
| 101 |
+
|
| 102 |
+
m2 = m1;
|
| 103 |
+
m2.col(0).reverseInPlace();
|
| 104 |
+
VERIFY_IS_APPROX(m2.col(0), m1.col(0).reverse().eval());
|
| 105 |
+
|
| 106 |
+
m2 = m1;
|
| 107 |
+
m2.row(0).reverseInPlace();
|
| 108 |
+
VERIFY_IS_APPROX(m2.row(0), m1.row(0).reverse().eval());
|
| 109 |
+
|
| 110 |
+
m2 = m1;
|
| 111 |
+
m2.rowwise().reverseInPlace();
|
| 112 |
+
VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());
|
| 113 |
+
|
| 114 |
+
m2 = m1;
|
| 115 |
+
m2.colwise().reverseInPlace();
|
| 116 |
+
VERIFY_IS_APPROX(m2, m1.colwise().reverse().eval());
|
| 117 |
+
|
| 118 |
+
m1.colwise().reverse()(r, c) = x;
|
| 119 |
+
VERIFY_IS_APPROX(x, m1(rows - 1 - r, c));
|
| 120 |
+
|
| 121 |
+
m1.rowwise().reverse()(r, c) = x;
|
| 122 |
+
VERIFY_IS_APPROX(x, m1(r, cols - 1 - c));
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
template <int>
|
| 126 |
+
void array_reverse_extra() {
|
| 127 |
+
Vector4f x;
|
| 128 |
+
x << 1, 2, 3, 4;
|
| 129 |
+
Vector4f y;
|
| 130 |
+
y << 4, 3, 2, 1;
|
| 131 |
+
VERIFY(x.reverse()[1] == 3);
|
| 132 |
+
VERIFY(x.reverse() == y);
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
// Simpler version of reverseInPlace leveraging a bug
|
| 136 |
+
// in clang 6/7 with -O2 and AVX or AVX512 enabled.
|
| 137 |
+
// This simpler version ensure that the clang bug is not simply hidden
|
| 138 |
+
// through mis-inlining of reverseInPlace or other minor changes.
|
| 139 |
+
template <typename MatrixType>
|
| 140 |
+
EIGEN_DONT_INLINE void bug1684_job1(MatrixType& m1, MatrixType& m2) {
|
| 141 |
+
m2 = m1;
|
| 142 |
+
m2.col(0).swap(m2.col(3));
|
| 143 |
+
m2.col(1).swap(m2.col(2));
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
template <typename MatrixType>
|
| 147 |
+
EIGEN_DONT_INLINE void bug1684_job2(MatrixType& m1, MatrixType& m2) {
|
| 148 |
+
m2 = m1; // load m1/m2 in AVX registers
|
| 149 |
+
m1.col(0) = m2.col(3); // perform 128 bits moves
|
| 150 |
+
m1.col(1) = m2.col(2);
|
| 151 |
+
m1.col(2) = m2.col(1);
|
| 152 |
+
m1.col(3) = m2.col(0);
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
template <typename MatrixType>
|
| 156 |
+
EIGEN_DONT_INLINE void bug1684_job3(MatrixType& m1, MatrixType& m2) {
|
| 157 |
+
m2 = m1;
|
| 158 |
+
Vector4f tmp;
|
| 159 |
+
tmp = m2.col(0);
|
| 160 |
+
m2.col(0) = m2.col(3);
|
| 161 |
+
m2.col(3) = tmp;
|
| 162 |
+
tmp = m2.col(1);
|
| 163 |
+
m2.col(1) = m2.col(2);
|
| 164 |
+
m2.col(2) = tmp;
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
template <int>
|
| 168 |
+
void bug1684() {
|
| 169 |
+
Matrix4f m1 = Matrix4f::Random();
|
| 170 |
+
Matrix4f m2 = Matrix4f::Random();
|
| 171 |
+
bug1684_job1(m1, m2);
|
| 172 |
+
VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());
|
| 173 |
+
bug1684_job2(m1, m2);
|
| 174 |
+
VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());
|
| 175 |
+
// This one still fail after our swap's workaround,
|
| 176 |
+
// but I expect users not to implement their own swap.
|
| 177 |
+
// bug1684_job3(m1,m2);
|
| 178 |
+
// VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
EIGEN_DECLARE_TEST(array_reverse) {
|
| 182 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 183 |
+
CALL_SUBTEST_1(reverse(Matrix<float, 1, 1>()));
|
| 184 |
+
CALL_SUBTEST_2(reverse(Matrix2f()));
|
| 185 |
+
CALL_SUBTEST_3(reverse(Matrix4f()));
|
| 186 |
+
CALL_SUBTEST_4(reverse(Matrix4d()));
|
| 187 |
+
CALL_SUBTEST_5(reverse(
|
| 188 |
+
MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 189 |
+
CALL_SUBTEST_6(reverse(
|
| 190 |
+
MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 191 |
+
CALL_SUBTEST_7(reverse(
|
| 192 |
+
MatrixXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 193 |
+
CALL_SUBTEST_8(reverse(Matrix<float, 100, 100>()));
|
| 194 |
+
CALL_SUBTEST_9(reverse(Matrix<float, Dynamic, Dynamic, RowMajor>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
| 195 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 196 |
+
CALL_SUBTEST_3(bug1684<0>());
|
| 197 |
+
}
|
| 198 |
+
CALL_SUBTEST_3(array_reverse_extra<0>());
|
| 199 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/assignment_threaded.cpp
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2023 Charlie Schlosser <cs.schlosser@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_USE_THREADS 1
|
| 11 |
+
|
| 12 |
+
#include "main.h"
|
| 13 |
+
#include <Eigen/ThreadPool>
|
| 14 |
+
|
| 15 |
+
namespace Eigen {
|
| 16 |
+
namespace internal {
|
| 17 |
+
// conveniently control vectorization logic
|
| 18 |
+
template <typename Scalar, bool Vectorize>
|
| 19 |
+
struct scalar_dummy_op {
|
| 20 |
+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& a) const { return a; }
|
| 21 |
+
template <typename Packet>
|
| 22 |
+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const {
|
| 23 |
+
return a;
|
| 24 |
+
}
|
| 25 |
+
};
|
| 26 |
+
template <typename Scalar, bool Vectorize>
|
| 27 |
+
struct functor_traits<scalar_dummy_op<Scalar, Vectorize> > {
|
| 28 |
+
enum { Cost = 1'000'000, PacketAccess = Vectorize && packet_traits<Scalar>::Vectorizable };
|
| 29 |
+
};
|
| 30 |
+
} // namespace internal
|
| 31 |
+
} // namespace Eigen
|
| 32 |
+
|
| 33 |
+
template <typename PlainObject>
|
| 34 |
+
void test_threaded_assignment(const PlainObject&, Index rows = PlainObject::RowsAtCompileTime,
|
| 35 |
+
Index cols = PlainObject::ColsAtCompileTime) {
|
| 36 |
+
using Scalar = typename PlainObject::Scalar;
|
| 37 |
+
using VectorizationOff = internal::scalar_dummy_op<Scalar, false>;
|
| 38 |
+
using VectorizationOn = internal::scalar_dummy_op<Scalar, true>;
|
| 39 |
+
|
| 40 |
+
int threads = 4;
|
| 41 |
+
ThreadPool pool(threads);
|
| 42 |
+
CoreThreadPoolDevice threadPoolDevice(pool);
|
| 43 |
+
|
| 44 |
+
PlainObject dst(rows, cols), ref(rows, cols), rhs(rows, cols);
|
| 45 |
+
rhs.setRandom();
|
| 46 |
+
const auto rhs_xpr = rhs.cwiseAbs2();
|
| 47 |
+
|
| 48 |
+
// linear access
|
| 49 |
+
dst.setRandom();
|
| 50 |
+
ref.setRandom();
|
| 51 |
+
ref = rhs_xpr.unaryExpr(VectorizationOff());
|
| 52 |
+
dst.device(threadPoolDevice) = rhs_xpr.unaryExpr(VectorizationOff());
|
| 53 |
+
VERIFY_IS_CWISE_EQUAL(ref, dst);
|
| 54 |
+
|
| 55 |
+
ref = rhs_xpr.unaryExpr(VectorizationOn());
|
| 56 |
+
dst.device(threadPoolDevice) = rhs_xpr.unaryExpr(VectorizationOn());
|
| 57 |
+
VERIFY_IS_CWISE_EQUAL(ref, dst);
|
| 58 |
+
|
| 59 |
+
// outer-inner access
|
| 60 |
+
Index blockRows = numext::maxi(Index(1), rows - 1);
|
| 61 |
+
Index blockCols = numext::maxi(Index(1), cols - 1);
|
| 62 |
+
dst.setRandom();
|
| 63 |
+
ref.setRandom();
|
| 64 |
+
ref.bottomRightCorner(blockRows, blockCols) =
|
| 65 |
+
rhs_xpr.bottomRightCorner(blockRows, blockCols).unaryExpr(VectorizationOff());
|
| 66 |
+
dst.bottomRightCorner(blockRows, blockCols).device(threadPoolDevice) =
|
| 67 |
+
rhs_xpr.bottomRightCorner(blockRows, blockCols).unaryExpr(VectorizationOff());
|
| 68 |
+
VERIFY_IS_CWISE_EQUAL(ref.bottomRightCorner(blockRows, blockCols), dst.bottomRightCorner(blockRows, blockCols));
|
| 69 |
+
|
| 70 |
+
ref.setZero();
|
| 71 |
+
dst.setZero();
|
| 72 |
+
ref.bottomRightCorner(blockRows, blockCols) =
|
| 73 |
+
rhs_xpr.bottomRightCorner(blockRows, blockCols).unaryExpr(VectorizationOn());
|
| 74 |
+
dst.bottomRightCorner(blockRows, blockCols).device(threadPoolDevice) =
|
| 75 |
+
rhs_xpr.bottomRightCorner(blockRows, blockCols).unaryExpr(VectorizationOn());
|
| 76 |
+
VERIFY_IS_CWISE_EQUAL(ref.bottomRightCorner(blockRows, blockCols), dst.bottomRightCorner(blockRows, blockCols));
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
EIGEN_DECLARE_TEST(test) {
|
| 80 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 81 |
+
CALL_SUBTEST(test_threaded_assignment(MatrixXd(), 123, 123));
|
| 82 |
+
CALL_SUBTEST(test_threaded_assignment(Matrix<float, 16, 16>()));
|
| 83 |
+
}
|
| 84 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bandmatrix.cpp
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is triangularView of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <typename MatrixType>
|
| 13 |
+
void bandmatrix(const MatrixType& _m) {
|
| 14 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 15 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 16 |
+
typedef Matrix<Scalar, Dynamic, Dynamic> DenseMatrixType;
|
| 17 |
+
|
| 18 |
+
Index rows = _m.rows();
|
| 19 |
+
Index cols = _m.cols();
|
| 20 |
+
Index supers = _m.supers();
|
| 21 |
+
Index subs = _m.subs();
|
| 22 |
+
|
| 23 |
+
MatrixType m(rows, cols, supers, subs);
|
| 24 |
+
|
| 25 |
+
DenseMatrixType dm1(rows, cols);
|
| 26 |
+
dm1.setZero();
|
| 27 |
+
|
| 28 |
+
m.diagonal().setConstant(123);
|
| 29 |
+
dm1.diagonal().setConstant(123);
|
| 30 |
+
for (int i = 1; i <= m.supers(); ++i) {
|
| 31 |
+
m.diagonal(i).setConstant(static_cast<RealScalar>(i));
|
| 32 |
+
dm1.diagonal(i).setConstant(static_cast<RealScalar>(i));
|
| 33 |
+
}
|
| 34 |
+
for (int i = 1; i <= m.subs(); ++i) {
|
| 35 |
+
m.diagonal(-i).setConstant(-static_cast<RealScalar>(i));
|
| 36 |
+
dm1.diagonal(-i).setConstant(-static_cast<RealScalar>(i));
|
| 37 |
+
}
|
| 38 |
+
// std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n\n\n";
|
| 39 |
+
VERIFY_IS_APPROX(dm1, m.toDenseMatrix());
|
| 40 |
+
|
| 41 |
+
for (int i = 0; i < cols; ++i) {
|
| 42 |
+
m.col(i).setConstant(static_cast<RealScalar>(i + 1));
|
| 43 |
+
dm1.col(i).setConstant(static_cast<RealScalar>(i + 1));
|
| 44 |
+
}
|
| 45 |
+
Index d = (std::min)(rows, cols);
|
| 46 |
+
Index a = std::max<Index>(0, cols - d - supers);
|
| 47 |
+
Index b = std::max<Index>(0, rows - d - subs);
|
| 48 |
+
if (a > 0) dm1.block(0, d + supers, rows, a).setZero();
|
| 49 |
+
dm1.block(0, supers + 1, cols - supers - 1 - a, cols - supers - 1 - a).template triangularView<Upper>().setZero();
|
| 50 |
+
dm1.block(subs + 1, 0, rows - subs - 1 - b, rows - subs - 1 - b).template triangularView<Lower>().setZero();
|
| 51 |
+
if (b > 0) dm1.block(d + subs, 0, b, cols).setZero();
|
| 52 |
+
// std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n";
|
| 53 |
+
VERIFY_IS_APPROX(dm1, m.toDenseMatrix());
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
using Eigen::internal::BandMatrix;
|
| 57 |
+
|
| 58 |
+
EIGEN_DECLARE_TEST(bandmatrix) {
|
| 59 |
+
for (int i = 0; i < 10 * g_repeat; i++) {
|
| 60 |
+
Index rows = internal::random<Index>(1, 10);
|
| 61 |
+
Index cols = internal::random<Index>(1, 10);
|
| 62 |
+
Index sups = internal::random<Index>(0, cols - 1);
|
| 63 |
+
Index subs = internal::random<Index>(0, rows - 1);
|
| 64 |
+
CALL_SUBTEST(bandmatrix(BandMatrix<float>(rows, cols, sups, subs)));
|
| 65 |
+
}
|
| 66 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/basicstuff.cpp
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2006-2008 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 |
+
#include "main.h"
|
| 11 |
+
#include "random_without_cast_overflow.h"
|
| 12 |
+
|
| 13 |
+
template <typename MatrixType>
|
| 14 |
+
std::enable_if_t<(MatrixType::RowsAtCompileTime == 1 || MatrixType::ColsAtCompileTime == 1), void> check_index(
|
| 15 |
+
const MatrixType& m) {
|
| 16 |
+
VERIFY_RAISES_ASSERT(m[0]);
|
| 17 |
+
VERIFY_RAISES_ASSERT((m + m)[0]);
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
template <typename MatrixType>
|
| 21 |
+
std::enable_if_t<!(MatrixType::RowsAtCompileTime == 1 || MatrixType::ColsAtCompileTime == 1), void> check_index(
|
| 22 |
+
const MatrixType& /*unused*/) {}
|
| 23 |
+
|
| 24 |
+
template <typename MatrixType>
|
| 25 |
+
void basicStuff(const MatrixType& m) {
|
| 26 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 27 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 28 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
|
| 29 |
+
|
| 30 |
+
Index rows = m.rows();
|
| 31 |
+
Index cols = m.cols();
|
| 32 |
+
|
| 33 |
+
// this test relies a lot on Random.h, and there's not much more that we can do
|
| 34 |
+
// to test it, hence I consider that we will have tested Random.h
|
| 35 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols),
|
| 36 |
+
mzero = MatrixType::Zero(rows, cols),
|
| 37 |
+
square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows);
|
| 38 |
+
VectorType v1 = VectorType::Random(rows), vzero = VectorType::Zero(rows);
|
| 39 |
+
SquareMatrixType sm1 = SquareMatrixType::Random(rows, rows), sm2(rows, rows);
|
| 40 |
+
|
| 41 |
+
Scalar x = 0;
|
| 42 |
+
while (x == Scalar(0)) x = internal::random<Scalar>();
|
| 43 |
+
|
| 44 |
+
Index r = internal::random<Index>(0, rows - 1), c = internal::random<Index>(0, cols - 1);
|
| 45 |
+
|
| 46 |
+
m1.coeffRef(r, c) = x;
|
| 47 |
+
VERIFY_IS_APPROX(x, m1.coeff(r, c));
|
| 48 |
+
m1(r, c) = x;
|
| 49 |
+
VERIFY_IS_APPROX(x, m1(r, c));
|
| 50 |
+
v1.coeffRef(r) = x;
|
| 51 |
+
VERIFY_IS_APPROX(x, v1.coeff(r));
|
| 52 |
+
v1(r) = x;
|
| 53 |
+
VERIFY_IS_APPROX(x, v1(r));
|
| 54 |
+
v1[r] = x;
|
| 55 |
+
VERIFY_IS_APPROX(x, v1[r]);
|
| 56 |
+
|
| 57 |
+
// test fetching with various index types.
|
| 58 |
+
Index r1 = internal::random<Index>(0, numext::mini(Index(127), rows - 1));
|
| 59 |
+
x = v1(static_cast<char>(r1));
|
| 60 |
+
x = v1(static_cast<signed char>(r1));
|
| 61 |
+
x = v1(static_cast<unsigned char>(r1));
|
| 62 |
+
x = v1(static_cast<signed short>(r1));
|
| 63 |
+
x = v1(static_cast<unsigned short>(r1));
|
| 64 |
+
x = v1(static_cast<signed int>(r1));
|
| 65 |
+
x = v1(static_cast<unsigned int>(r1));
|
| 66 |
+
x = v1(static_cast<signed long>(r1));
|
| 67 |
+
x = v1(static_cast<unsigned long>(r1));
|
| 68 |
+
if (sizeof(Index) >= sizeof(long long int)) x = v1(static_cast<long long int>(r1));
|
| 69 |
+
if (sizeof(Index) >= sizeof(unsigned long long int)) x = v1(static_cast<unsigned long long int>(r1));
|
| 70 |
+
|
| 71 |
+
VERIFY_IS_APPROX(v1, v1);
|
| 72 |
+
VERIFY_IS_NOT_APPROX(v1, 2 * v1);
|
| 73 |
+
VERIFY_IS_MUCH_SMALLER_THAN(vzero, v1);
|
| 74 |
+
VERIFY_IS_MUCH_SMALLER_THAN(vzero, v1.squaredNorm());
|
| 75 |
+
VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1, v1);
|
| 76 |
+
VERIFY_IS_APPROX(vzero, v1 - v1);
|
| 77 |
+
VERIFY_IS_APPROX(m1, m1);
|
| 78 |
+
VERIFY_IS_NOT_APPROX(m1, 2 * m1);
|
| 79 |
+
VERIFY_IS_MUCH_SMALLER_THAN(mzero, m1);
|
| 80 |
+
VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1, m1);
|
| 81 |
+
VERIFY_IS_APPROX(mzero, m1 - m1);
|
| 82 |
+
|
| 83 |
+
// always test operator() on each read-only expression class,
|
| 84 |
+
// in order to check const-qualifiers.
|
| 85 |
+
// indeed, if an expression class (here Zero) is meant to be read-only,
|
| 86 |
+
// hence has no _write() method, the corresponding MatrixBase method (here zero())
|
| 87 |
+
// should return a const-qualified object so that it is the const-qualified
|
| 88 |
+
// operator() that gets called, which in turn calls _read().
|
| 89 |
+
VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols)(r, c), static_cast<Scalar>(1));
|
| 90 |
+
|
| 91 |
+
// now test copying a row-vector into a (column-)vector and conversely.
|
| 92 |
+
square.col(r) = square.row(r).eval();
|
| 93 |
+
Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows);
|
| 94 |
+
Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows);
|
| 95 |
+
rv = square.row(r);
|
| 96 |
+
cv = square.col(r);
|
| 97 |
+
|
| 98 |
+
VERIFY_IS_APPROX(rv, cv.transpose());
|
| 99 |
+
|
| 100 |
+
if (cols != 1 && rows != 1 && MatrixType::SizeAtCompileTime != Dynamic) {
|
| 101 |
+
VERIFY_RAISES_ASSERT(m1 = (m2.block(0, 0, rows - 1, cols - 1)));
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
if (cols != 1 && rows != 1) {
|
| 105 |
+
check_index(m1);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
VERIFY_IS_APPROX(m3 = m1, m1);
|
| 109 |
+
MatrixType m4;
|
| 110 |
+
VERIFY_IS_APPROX(m4 = m1, m1);
|
| 111 |
+
|
| 112 |
+
m3.real() = m1.real();
|
| 113 |
+
VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());
|
| 114 |
+
VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());
|
| 115 |
+
|
| 116 |
+
// check == / != operators
|
| 117 |
+
VERIFY(m1 == m1);
|
| 118 |
+
VERIFY(m1 != m2);
|
| 119 |
+
VERIFY(!(m1 == m2));
|
| 120 |
+
VERIFY(!(m1 != m1));
|
| 121 |
+
m1 = m2;
|
| 122 |
+
VERIFY(m1 == m2);
|
| 123 |
+
VERIFY(!(m1 != m2));
|
| 124 |
+
|
| 125 |
+
// check automatic transposition
|
| 126 |
+
sm2.setZero();
|
| 127 |
+
for (Index i = 0; i < rows; ++i) sm2.col(i) = sm1.row(i);
|
| 128 |
+
VERIFY_IS_APPROX(sm2, sm1.transpose());
|
| 129 |
+
|
| 130 |
+
sm2.setZero();
|
| 131 |
+
for (Index i = 0; i < rows; ++i) sm2.col(i).noalias() = sm1.row(i);
|
| 132 |
+
VERIFY_IS_APPROX(sm2, sm1.transpose());
|
| 133 |
+
|
| 134 |
+
sm2.setZero();
|
| 135 |
+
for (Index i = 0; i < rows; ++i) sm2.col(i).noalias() += sm1.row(i);
|
| 136 |
+
VERIFY_IS_APPROX(sm2, sm1.transpose());
|
| 137 |
+
|
| 138 |
+
sm2.setZero();
|
| 139 |
+
for (Index i = 0; i < rows; ++i) sm2.col(i).noalias() -= sm1.row(i);
|
| 140 |
+
VERIFY_IS_APPROX(sm2, -sm1.transpose());
|
| 141 |
+
|
| 142 |
+
// check ternary usage
|
| 143 |
+
{
|
| 144 |
+
bool b = internal::random<int>(0, 10) > 5;
|
| 145 |
+
m3 = b ? m1 : m2;
|
| 146 |
+
if (b)
|
| 147 |
+
VERIFY_IS_APPROX(m3, m1);
|
| 148 |
+
else
|
| 149 |
+
VERIFY_IS_APPROX(m3, m2);
|
| 150 |
+
m3 = b ? -m1 : m2;
|
| 151 |
+
if (b)
|
| 152 |
+
VERIFY_IS_APPROX(m3, -m1);
|
| 153 |
+
else
|
| 154 |
+
VERIFY_IS_APPROX(m3, m2);
|
| 155 |
+
m3 = b ? m1 : -m2;
|
| 156 |
+
if (b)
|
| 157 |
+
VERIFY_IS_APPROX(m3, m1);
|
| 158 |
+
else
|
| 159 |
+
VERIFY_IS_APPROX(m3, -m2);
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
template <typename MatrixType>
|
| 164 |
+
void basicStuffComplex(const MatrixType& m) {
|
| 165 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 166 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 167 |
+
typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> RealMatrixType;
|
| 168 |
+
|
| 169 |
+
Index rows = m.rows();
|
| 170 |
+
Index cols = m.cols();
|
| 171 |
+
|
| 172 |
+
Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>();
|
| 173 |
+
|
| 174 |
+
VERIFY(numext::real(s1) == numext::real_ref(s1));
|
| 175 |
+
VERIFY(numext::imag(s1) == numext::imag_ref(s1));
|
| 176 |
+
numext::real_ref(s1) = numext::real(s2);
|
| 177 |
+
numext::imag_ref(s1) = numext::imag(s2);
|
| 178 |
+
VERIFY(internal::isApprox(s1, s2, NumTraits<RealScalar>::epsilon()));
|
| 179 |
+
// extended precision in Intel FPUs means that s1 == s2 in the line above is not guaranteed.
|
| 180 |
+
|
| 181 |
+
RealMatrixType rm1 = RealMatrixType::Random(rows, cols), rm2 = RealMatrixType::Random(rows, cols);
|
| 182 |
+
MatrixType cm(rows, cols);
|
| 183 |
+
cm.real() = rm1;
|
| 184 |
+
cm.imag() = rm2;
|
| 185 |
+
VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).real(), rm1);
|
| 186 |
+
VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).imag(), rm2);
|
| 187 |
+
rm1.setZero();
|
| 188 |
+
rm2.setZero();
|
| 189 |
+
rm1 = cm.real();
|
| 190 |
+
rm2 = cm.imag();
|
| 191 |
+
VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).real(), rm1);
|
| 192 |
+
VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).imag(), rm2);
|
| 193 |
+
cm.real().setZero();
|
| 194 |
+
VERIFY(static_cast<const MatrixType&>(cm).real().isZero());
|
| 195 |
+
VERIFY(!static_cast<const MatrixType&>(cm).imag().isZero());
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
template <typename SrcScalar, typename TgtScalar>
|
| 199 |
+
struct casting_test {
|
| 200 |
+
static void run() {
|
| 201 |
+
Matrix<SrcScalar, 4, 4> m;
|
| 202 |
+
for (int i = 0; i < m.rows(); ++i) {
|
| 203 |
+
for (int j = 0; j < m.cols(); ++j) {
|
| 204 |
+
m(i, j) = internal::random_without_cast_overflow<SrcScalar, TgtScalar>::value();
|
| 205 |
+
}
|
| 206 |
+
}
|
| 207 |
+
Matrix<TgtScalar, 4, 4> n = m.template cast<TgtScalar>();
|
| 208 |
+
for (int i = 0; i < m.rows(); ++i) {
|
| 209 |
+
for (int j = 0; j < m.cols(); ++j) {
|
| 210 |
+
VERIFY_IS_APPROX(n(i, j), (internal::cast<SrcScalar, TgtScalar>(m(i, j))));
|
| 211 |
+
}
|
| 212 |
+
}
|
| 213 |
+
}
|
| 214 |
+
};
|
| 215 |
+
|
| 216 |
+
template <typename SrcScalar, typename EnableIf = void>
|
| 217 |
+
struct casting_test_runner {
|
| 218 |
+
static void run() {
|
| 219 |
+
casting_test<SrcScalar, bool>::run();
|
| 220 |
+
casting_test<SrcScalar, int8_t>::run();
|
| 221 |
+
casting_test<SrcScalar, uint8_t>::run();
|
| 222 |
+
casting_test<SrcScalar, int16_t>::run();
|
| 223 |
+
casting_test<SrcScalar, uint16_t>::run();
|
| 224 |
+
casting_test<SrcScalar, int32_t>::run();
|
| 225 |
+
casting_test<SrcScalar, uint32_t>::run();
|
| 226 |
+
casting_test<SrcScalar, int64_t>::run();
|
| 227 |
+
casting_test<SrcScalar, uint64_t>::run();
|
| 228 |
+
casting_test<SrcScalar, half>::run();
|
| 229 |
+
casting_test<SrcScalar, bfloat16>::run();
|
| 230 |
+
casting_test<SrcScalar, float>::run();
|
| 231 |
+
casting_test<SrcScalar, double>::run();
|
| 232 |
+
casting_test<SrcScalar, std::complex<float>>::run();
|
| 233 |
+
casting_test<SrcScalar, std::complex<double>>::run();
|
| 234 |
+
}
|
| 235 |
+
};
|
| 236 |
+
|
| 237 |
+
template <typename SrcScalar>
|
| 238 |
+
struct casting_test_runner<SrcScalar, std::enable_if_t<(NumTraits<SrcScalar>::IsComplex)>> {
|
| 239 |
+
static void run() {
|
| 240 |
+
// Only a few casts from std::complex<T> are defined.
|
| 241 |
+
casting_test<SrcScalar, half>::run();
|
| 242 |
+
casting_test<SrcScalar, bfloat16>::run();
|
| 243 |
+
casting_test<SrcScalar, std::complex<float>>::run();
|
| 244 |
+
casting_test<SrcScalar, std::complex<double>>::run();
|
| 245 |
+
}
|
| 246 |
+
};
|
| 247 |
+
|
| 248 |
+
void casting_all() {
|
| 249 |
+
casting_test_runner<bool>::run();
|
| 250 |
+
casting_test_runner<int8_t>::run();
|
| 251 |
+
casting_test_runner<uint8_t>::run();
|
| 252 |
+
casting_test_runner<int16_t>::run();
|
| 253 |
+
casting_test_runner<uint16_t>::run();
|
| 254 |
+
casting_test_runner<int32_t>::run();
|
| 255 |
+
casting_test_runner<uint32_t>::run();
|
| 256 |
+
casting_test_runner<int64_t>::run();
|
| 257 |
+
casting_test_runner<uint64_t>::run();
|
| 258 |
+
casting_test_runner<half>::run();
|
| 259 |
+
casting_test_runner<bfloat16>::run();
|
| 260 |
+
casting_test_runner<float>::run();
|
| 261 |
+
casting_test_runner<double>::run();
|
| 262 |
+
casting_test_runner<std::complex<float>>::run();
|
| 263 |
+
casting_test_runner<std::complex<double>>::run();
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
template <typename Scalar>
|
| 267 |
+
void fixedSizeMatrixConstruction() {
|
| 268 |
+
Scalar raw[4];
|
| 269 |
+
for (int k = 0; k < 4; ++k) raw[k] = internal::random<Scalar>();
|
| 270 |
+
|
| 271 |
+
{
|
| 272 |
+
Matrix<Scalar, 4, 1> m(raw);
|
| 273 |
+
Array<Scalar, 4, 1> a(raw);
|
| 274 |
+
for (int k = 0; k < 4; ++k) VERIFY(m(k) == raw[k]);
|
| 275 |
+
for (int k = 0; k < 4; ++k) VERIFY(a(k) == raw[k]);
|
| 276 |
+
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 4, 1>(raw[0], raw[1], raw[2], raw[3])));
|
| 277 |
+
VERIFY((a == (Array<Scalar, 4, 1>(raw[0], raw[1], raw[2], raw[3]))).all());
|
| 278 |
+
}
|
| 279 |
+
{
|
| 280 |
+
Matrix<Scalar, 3, 1> m(raw);
|
| 281 |
+
Array<Scalar, 3, 1> a(raw);
|
| 282 |
+
for (int k = 0; k < 3; ++k) VERIFY(m(k) == raw[k]);
|
| 283 |
+
for (int k = 0; k < 3; ++k) VERIFY(a(k) == raw[k]);
|
| 284 |
+
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 3, 1>(raw[0], raw[1], raw[2])));
|
| 285 |
+
VERIFY((a == Array<Scalar, 3, 1>(raw[0], raw[1], raw[2])).all());
|
| 286 |
+
}
|
| 287 |
+
{
|
| 288 |
+
Matrix<Scalar, 2, 1> m(raw), m2((DenseIndex(raw[0])), (DenseIndex(raw[1])));
|
| 289 |
+
Array<Scalar, 2, 1> a(raw), a2((DenseIndex(raw[0])), (DenseIndex(raw[1])));
|
| 290 |
+
for (int k = 0; k < 2; ++k) VERIFY(m(k) == raw[k]);
|
| 291 |
+
for (int k = 0; k < 2; ++k) VERIFY(a(k) == raw[k]);
|
| 292 |
+
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 2, 1>(raw[0], raw[1])));
|
| 293 |
+
VERIFY((a == Array<Scalar, 2, 1>(raw[0], raw[1])).all());
|
| 294 |
+
for (int k = 0; k < 2; ++k) VERIFY(m2(k) == DenseIndex(raw[k]));
|
| 295 |
+
for (int k = 0; k < 2; ++k) VERIFY(a2(k) == DenseIndex(raw[k]));
|
| 296 |
+
}
|
| 297 |
+
{
|
| 298 |
+
Matrix<Scalar, 1, 2> m(raw), m2((DenseIndex(raw[0])), (DenseIndex(raw[1]))), m3((int(raw[0])), (int(raw[1]))),
|
| 299 |
+
m4((float(raw[0])), (float(raw[1])));
|
| 300 |
+
Array<Scalar, 1, 2> a(raw), a2((DenseIndex(raw[0])), (DenseIndex(raw[1])));
|
| 301 |
+
for (int k = 0; k < 2; ++k) VERIFY(m(k) == raw[k]);
|
| 302 |
+
for (int k = 0; k < 2; ++k) VERIFY(a(k) == raw[k]);
|
| 303 |
+
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 1, 2>(raw[0], raw[1])));
|
| 304 |
+
VERIFY((a == Array<Scalar, 1, 2>(raw[0], raw[1])).all());
|
| 305 |
+
for (int k = 0; k < 2; ++k) VERIFY(m2(k) == DenseIndex(raw[k]));
|
| 306 |
+
for (int k = 0; k < 2; ++k) VERIFY(a2(k) == DenseIndex(raw[k]));
|
| 307 |
+
for (int k = 0; k < 2; ++k) VERIFY(m3(k) == int(raw[k]));
|
| 308 |
+
for (int k = 0; k < 2; ++k) VERIFY((m4(k)) == Scalar(float(raw[k])));
|
| 309 |
+
}
|
| 310 |
+
{
|
| 311 |
+
Matrix<Scalar, 1, 1> m(raw), m1(raw[0]), m2((DenseIndex(raw[0]))), m3((int(raw[0])));
|
| 312 |
+
Array<Scalar, 1, 1> a(raw), a1(raw[0]), a2((DenseIndex(raw[0])));
|
| 313 |
+
VERIFY(m(0) == raw[0]);
|
| 314 |
+
VERIFY(a(0) == raw[0]);
|
| 315 |
+
VERIFY(m1(0) == raw[0]);
|
| 316 |
+
VERIFY(a1(0) == raw[0]);
|
| 317 |
+
VERIFY(m2(0) == DenseIndex(raw[0]));
|
| 318 |
+
VERIFY(a2(0) == DenseIndex(raw[0]));
|
| 319 |
+
VERIFY(m3(0) == int(raw[0]));
|
| 320 |
+
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 1, 1>(raw[0])));
|
| 321 |
+
VERIFY((a == Array<Scalar, 1, 1>(raw[0])).all());
|
| 322 |
+
}
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
EIGEN_DECLARE_TEST(basicstuff) {
|
| 326 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 327 |
+
CALL_SUBTEST_1(basicStuff(Matrix<float, 1, 1>()));
|
| 328 |
+
CALL_SUBTEST_2(basicStuff(Matrix4d()));
|
| 329 |
+
CALL_SUBTEST_3(basicStuff(
|
| 330 |
+
MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 331 |
+
CALL_SUBTEST_4(basicStuff(
|
| 332 |
+
MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 333 |
+
CALL_SUBTEST_5(basicStuff(
|
| 334 |
+
MatrixXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 335 |
+
CALL_SUBTEST_6(basicStuff(Matrix<float, 100, 100>()));
|
| 336 |
+
CALL_SUBTEST_7(basicStuff(Matrix<long double, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
|
| 337 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 338 |
+
CALL_SUBTEST_8(casting_all());
|
| 339 |
+
|
| 340 |
+
CALL_SUBTEST_3(basicStuffComplex(
|
| 341 |
+
MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 342 |
+
CALL_SUBTEST_5(basicStuffComplex(
|
| 343 |
+
MatrixXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
CALL_SUBTEST_1(fixedSizeMatrixConstruction<unsigned char>());
|
| 347 |
+
CALL_SUBTEST_1(fixedSizeMatrixConstruction<float>());
|
| 348 |
+
CALL_SUBTEST_1(fixedSizeMatrixConstruction<double>());
|
| 349 |
+
CALL_SUBTEST_1(fixedSizeMatrixConstruction<int>());
|
| 350 |
+
CALL_SUBTEST_1(fixedSizeMatrixConstruction<long int>());
|
| 351 |
+
CALL_SUBTEST_1(fixedSizeMatrixConstruction<std::ptrdiff_t>());
|
| 352 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bdcsvd.cpp
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
|
| 5 |
+
// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
|
| 6 |
+
// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
|
| 7 |
+
// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
|
| 8 |
+
//
|
| 9 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 10 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 11 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/
|
| 12 |
+
|
| 13 |
+
// discard stack allocation as that too bypasses malloc
|
| 14 |
+
#define EIGEN_STACK_ALLOCATION_LIMIT 0
|
| 15 |
+
#define EIGEN_RUNTIME_NO_MALLOC
|
| 16 |
+
|
| 17 |
+
#include "main.h"
|
| 18 |
+
#include <Eigen/SVD>
|
| 19 |
+
|
| 20 |
+
#define SVD_DEFAULT(M) BDCSVD<M>
|
| 21 |
+
#define SVD_FOR_MIN_NORM(M) BDCSVD<M>
|
| 22 |
+
#define SVD_STATIC_OPTIONS(M, O) BDCSVD<M, O>
|
| 23 |
+
#include "svd_common.h"
|
| 24 |
+
|
| 25 |
+
template <typename MatrixType>
|
| 26 |
+
void bdcsvd_method() {
|
| 27 |
+
enum { Size = MatrixType::RowsAtCompileTime };
|
| 28 |
+
typedef typename MatrixType::RealScalar RealScalar;
|
| 29 |
+
typedef Matrix<RealScalar, Size, 1> RealVecType;
|
| 30 |
+
MatrixType m = MatrixType::Identity();
|
| 31 |
+
VERIFY_IS_APPROX(m.bdcSvd().singularValues(), RealVecType::Ones());
|
| 32 |
+
VERIFY_RAISES_ASSERT(m.bdcSvd().matrixU());
|
| 33 |
+
VERIFY_RAISES_ASSERT(m.bdcSvd().matrixV());
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
// compare the Singular values returned with Jacobi and Bdc
|
| 37 |
+
template <typename MatrixType>
|
| 38 |
+
void compare_bdc_jacobi(const MatrixType& a = MatrixType(), int algoswap = 16, bool random = true) {
|
| 39 |
+
MatrixType m = random ? MatrixType::Random(a.rows(), a.cols()) : a;
|
| 40 |
+
|
| 41 |
+
BDCSVD<MatrixType> bdc_svd(m.rows(), m.cols());
|
| 42 |
+
bdc_svd.setSwitchSize(algoswap);
|
| 43 |
+
bdc_svd.compute(m);
|
| 44 |
+
|
| 45 |
+
JacobiSVD<MatrixType> jacobi_svd(m);
|
| 46 |
+
VERIFY_IS_APPROX(bdc_svd.singularValues(), jacobi_svd.singularValues());
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// Verifies total deflation is **not** triggered.
|
| 50 |
+
void compare_bdc_jacobi_instance(bool structure_as_m, int algoswap = 16) {
|
| 51 |
+
MatrixXd m(4, 3);
|
| 52 |
+
if (structure_as_m) {
|
| 53 |
+
// The first 3 rows are the reduced form of Matrix 1 as shown below, and it
|
| 54 |
+
// has nonzero elements in the first column and diagonals only.
|
| 55 |
+
m << 1.056293, 0, 0, -0.336468, 0.907359, 0, -1.566245, 0, 0.149150, -0.1, 0, 0;
|
| 56 |
+
} else {
|
| 57 |
+
// Matrix 1.
|
| 58 |
+
m << 0.882336, 18.3914, -26.7921, -5.58135, 17.1931, -24.0892, -20.794, 8.68496, -4.83103, -8.4981, -10.5451,
|
| 59 |
+
23.9072;
|
| 60 |
+
}
|
| 61 |
+
compare_bdc_jacobi(m, algoswap, false);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
template <typename MatrixType>
|
| 65 |
+
void bdcsvd_thin_options(const MatrixType& input = MatrixType()) {
|
| 66 |
+
svd_thin_option_checks<MatrixType, 0>(input);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
template <typename MatrixType>
|
| 70 |
+
void bdcsvd_full_options(const MatrixType& input = MatrixType()) {
|
| 71 |
+
svd_option_checks_full_only<MatrixType, 0>(input);
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
template <typename MatrixType>
|
| 75 |
+
void bdcsvd_verify_assert(const MatrixType& input = MatrixType()) {
|
| 76 |
+
svd_verify_assert<MatrixType>(input);
|
| 77 |
+
svd_verify_constructor_options_assert<BDCSVD<MatrixType>>(input);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
template <typename MatrixType>
|
| 81 |
+
void bdcsvd_check_convergence(const MatrixType& input) {
|
| 82 |
+
BDCSVD<MatrixType, Eigen::ComputeThinU | Eigen::ComputeThinV> svd(input);
|
| 83 |
+
VERIFY(svd.info() == Eigen::Success);
|
| 84 |
+
MatrixType D = svd.matrixU() * svd.singularValues().asDiagonal() * svd.matrixV().transpose();
|
| 85 |
+
VERIFY_IS_APPROX(input, D);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
EIGEN_DECLARE_TEST(bdcsvd) {
|
| 89 |
+
CALL_SUBTEST_1((bdcsvd_verify_assert<Matrix3f>()));
|
| 90 |
+
CALL_SUBTEST_2((bdcsvd_verify_assert<Matrix4d>()));
|
| 91 |
+
CALL_SUBTEST_3((bdcsvd_verify_assert<Matrix<float, 10, 7>>()));
|
| 92 |
+
CALL_SUBTEST_4((bdcsvd_verify_assert<Matrix<float, 7, 10>>()));
|
| 93 |
+
CALL_SUBTEST_5((bdcsvd_verify_assert<Matrix<std::complex<double>, 6, 9>>()));
|
| 94 |
+
|
| 95 |
+
CALL_SUBTEST_6((svd_all_trivial_2x2(bdcsvd_thin_options<Matrix2cd>)));
|
| 96 |
+
CALL_SUBTEST_7((svd_all_trivial_2x2(bdcsvd_full_options<Matrix2cd>)));
|
| 97 |
+
CALL_SUBTEST_8((svd_all_trivial_2x2(bdcsvd_thin_options<Matrix2d>)));
|
| 98 |
+
CALL_SUBTEST_9((svd_all_trivial_2x2(bdcsvd_full_options<Matrix2d>)));
|
| 99 |
+
|
| 100 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 101 |
+
int r = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 2), c = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 2);
|
| 102 |
+
|
| 103 |
+
TEST_SET_BUT_UNUSED_VARIABLE(r)
|
| 104 |
+
TEST_SET_BUT_UNUSED_VARIABLE(c)
|
| 105 |
+
|
| 106 |
+
CALL_SUBTEST_10((compare_bdc_jacobi<MatrixXf>(MatrixXf(r, c))));
|
| 107 |
+
CALL_SUBTEST_11((compare_bdc_jacobi<MatrixXd>(MatrixXd(r, c))));
|
| 108 |
+
CALL_SUBTEST_12((compare_bdc_jacobi<MatrixXcd>(MatrixXcd(r, c))));
|
| 109 |
+
// Test on inf/nan matrix
|
| 110 |
+
CALL_SUBTEST_13((svd_inf_nan<MatrixXf>()));
|
| 111 |
+
CALL_SUBTEST_14((svd_inf_nan<MatrixXd>()));
|
| 112 |
+
|
| 113 |
+
// Verify some computations using all combinations of the Options template parameter.
|
| 114 |
+
CALL_SUBTEST_15((bdcsvd_thin_options<Matrix3f>()));
|
| 115 |
+
CALL_SUBTEST_16((bdcsvd_full_options<Matrix3f>()));
|
| 116 |
+
CALL_SUBTEST_17((bdcsvd_thin_options<Matrix<float, 2, 3>>()));
|
| 117 |
+
CALL_SUBTEST_18((bdcsvd_full_options<Matrix<float, 2, 3>>()));
|
| 118 |
+
CALL_SUBTEST_19((bdcsvd_thin_options<MatrixXd>(MatrixXd(20, 17))));
|
| 119 |
+
CALL_SUBTEST_20((bdcsvd_full_options<MatrixXd>(MatrixXd(20, 17))));
|
| 120 |
+
CALL_SUBTEST_21((bdcsvd_thin_options<MatrixXd>(MatrixXd(17, 20))));
|
| 121 |
+
CALL_SUBTEST_22((bdcsvd_full_options<MatrixXd>(MatrixXd(17, 20))));
|
| 122 |
+
CALL_SUBTEST_23((bdcsvd_thin_options<Matrix<double, Dynamic, 15>>(Matrix<double, Dynamic, 15>(r, 15))));
|
| 123 |
+
CALL_SUBTEST_24((bdcsvd_full_options<Matrix<double, Dynamic, 15>>(Matrix<double, Dynamic, 15>(r, 15))));
|
| 124 |
+
CALL_SUBTEST_25((bdcsvd_thin_options<Matrix<double, 13, Dynamic>>(Matrix<double, 13, Dynamic>(13, c))));
|
| 125 |
+
CALL_SUBTEST_26((bdcsvd_full_options<Matrix<double, 13, Dynamic>>(Matrix<double, 13, Dynamic>(13, c))));
|
| 126 |
+
CALL_SUBTEST_27((bdcsvd_thin_options<MatrixXf>(MatrixXf(r, c))));
|
| 127 |
+
CALL_SUBTEST_28((bdcsvd_full_options<MatrixXf>(MatrixXf(r, c))));
|
| 128 |
+
CALL_SUBTEST_29((bdcsvd_thin_options<MatrixXcd>(MatrixXcd(r, c))));
|
| 129 |
+
CALL_SUBTEST_30((bdcsvd_full_options<MatrixXcd>(MatrixXcd(r, c))));
|
| 130 |
+
CALL_SUBTEST_31((bdcsvd_thin_options<MatrixXd>(MatrixXd(r, c))));
|
| 131 |
+
CALL_SUBTEST_32((bdcsvd_full_options<MatrixXd>(MatrixXd(r, c))));
|
| 132 |
+
CALL_SUBTEST_33((bdcsvd_thin_options<Matrix<double, Dynamic, Dynamic, RowMajor>>(
|
| 133 |
+
Matrix<double, Dynamic, Dynamic, RowMajor>(20, 27))));
|
| 134 |
+
CALL_SUBTEST_34((bdcsvd_full_options<Matrix<double, Dynamic, Dynamic, RowMajor>>(
|
| 135 |
+
Matrix<double, Dynamic, Dynamic, RowMajor>(20, 27))));
|
| 136 |
+
CALL_SUBTEST_35((bdcsvd_thin_options<Matrix<double, Dynamic, Dynamic, RowMajor>>(
|
| 137 |
+
Matrix<double, Dynamic, Dynamic, RowMajor>(27, 20))));
|
| 138 |
+
CALL_SUBTEST_36((bdcsvd_full_options<Matrix<double, Dynamic, Dynamic, RowMajor>>(
|
| 139 |
+
Matrix<double, Dynamic, Dynamic, RowMajor>(27, 20))));
|
| 140 |
+
CALL_SUBTEST_37((
|
| 141 |
+
svd_check_max_size_matrix<Matrix<float, Dynamic, Dynamic, ColMajor, 20, 35>, ColPivHouseholderQRPreconditioner>(
|
| 142 |
+
r, c)));
|
| 143 |
+
CALL_SUBTEST_38(
|
| 144 |
+
(svd_check_max_size_matrix<Matrix<float, Dynamic, Dynamic, ColMajor, 35, 20>, HouseholderQRPreconditioner>(r,
|
| 145 |
+
c)));
|
| 146 |
+
CALL_SUBTEST_39((
|
| 147 |
+
svd_check_max_size_matrix<Matrix<float, Dynamic, Dynamic, RowMajor, 20, 35>, ColPivHouseholderQRPreconditioner>(
|
| 148 |
+
r, c)));
|
| 149 |
+
CALL_SUBTEST_40(
|
| 150 |
+
(svd_check_max_size_matrix<Matrix<float, Dynamic, Dynamic, RowMajor, 35, 20>, HouseholderQRPreconditioner>(r,
|
| 151 |
+
c)));
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
// test matrixbase method
|
| 155 |
+
CALL_SUBTEST_41((bdcsvd_method<Matrix2cd>()));
|
| 156 |
+
CALL_SUBTEST_42((bdcsvd_method<Matrix3f>()));
|
| 157 |
+
|
| 158 |
+
// Test problem size constructors
|
| 159 |
+
CALL_SUBTEST_43(BDCSVD<MatrixXf>(10, 10));
|
| 160 |
+
|
| 161 |
+
// Check that preallocation avoids subsequent mallocs
|
| 162 |
+
// Disabled because not supported by BDCSVD
|
| 163 |
+
// CALL_SUBTEST_9( svd_preallocate<void>() );
|
| 164 |
+
|
| 165 |
+
CALL_SUBTEST_44(svd_underoverflow<void>());
|
| 166 |
+
|
| 167 |
+
// Without total deflation issues.
|
| 168 |
+
CALL_SUBTEST_45((compare_bdc_jacobi_instance(true)));
|
| 169 |
+
CALL_SUBTEST_46((compare_bdc_jacobi_instance(false)));
|
| 170 |
+
|
| 171 |
+
// With total deflation issues before, when it shouldn't be triggered.
|
| 172 |
+
CALL_SUBTEST_47((compare_bdc_jacobi_instance(true, 3)));
|
| 173 |
+
CALL_SUBTEST_48((compare_bdc_jacobi_instance(false, 3)));
|
| 174 |
+
|
| 175 |
+
// Convergence for large constant matrix (https://gitlab.com/libeigen/eigen/-/issues/2491)
|
| 176 |
+
CALL_SUBTEST_49(bdcsvd_check_convergence<MatrixXf>(MatrixXf::Constant(500, 500, 1)));
|
| 177 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bfloat16_float.cpp
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 5 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 6 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 7 |
+
|
| 8 |
+
#include <sstream>
|
| 9 |
+
#include <memory>
|
| 10 |
+
#include <math.h>
|
| 11 |
+
|
| 12 |
+
#include "main.h"
|
| 13 |
+
|
| 14 |
+
#define VERIFY_BFLOAT16_BITS_EQUAL(h, bits) \
|
| 15 |
+
VERIFY_IS_EQUAL((numext::bit_cast<numext::uint16_t>(h)), (static_cast<numext::uint16_t>(bits)))
|
| 16 |
+
|
| 17 |
+
// Make sure it's possible to forward declare Eigen::bfloat16
|
| 18 |
+
namespace Eigen {
|
| 19 |
+
struct bfloat16;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
using Eigen::bfloat16;
|
| 23 |
+
|
| 24 |
+
float BinaryToFloat(uint32_t sign, uint32_t exponent, uint32_t high_mantissa, uint32_t low_mantissa) {
|
| 25 |
+
float dest;
|
| 26 |
+
uint32_t src = (sign << 31) + (exponent << 23) + (high_mantissa << 16) + low_mantissa;
|
| 27 |
+
memcpy(static_cast<void*>(&dest), static_cast<const void*>(&src), sizeof(dest));
|
| 28 |
+
return dest;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
template <typename T>
|
| 32 |
+
void test_roundtrip() {
|
| 33 |
+
// Representable T round trip via bfloat16
|
| 34 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(-std::numeric_limits<T>::infinity()))),
|
| 35 |
+
-std::numeric_limits<T>::infinity());
|
| 36 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(std::numeric_limits<T>::infinity()))),
|
| 37 |
+
std::numeric_limits<T>::infinity());
|
| 38 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(T(-1.0)))), T(-1.0));
|
| 39 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(T(-0.5)))), T(-0.5));
|
| 40 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(T(-0.0)))), T(-0.0));
|
| 41 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(T(1.0)))), T(1.0));
|
| 42 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(T(0.5)))), T(0.5));
|
| 43 |
+
VERIFY_IS_EQUAL((internal::cast<bfloat16, T>(internal::cast<T, bfloat16>(T(0.0)))), T(0.0));
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
void test_conversion() {
|
| 47 |
+
using Eigen::bfloat16_impl::__bfloat16_raw;
|
| 48 |
+
|
| 49 |
+
// Round-trip casts
|
| 50 |
+
VERIFY_IS_EQUAL(numext::bit_cast<bfloat16>(numext::bit_cast<numext::uint16_t>(bfloat16(1.0f))), bfloat16(1.0f));
|
| 51 |
+
VERIFY_IS_EQUAL(numext::bit_cast<bfloat16>(numext::bit_cast<numext::uint16_t>(bfloat16(0.5f))), bfloat16(0.5f));
|
| 52 |
+
VERIFY_IS_EQUAL(numext::bit_cast<bfloat16>(numext::bit_cast<numext::uint16_t>(bfloat16(-0.33333f))),
|
| 53 |
+
bfloat16(-0.33333f));
|
| 54 |
+
VERIFY_IS_EQUAL(numext::bit_cast<bfloat16>(numext::bit_cast<numext::uint16_t>(bfloat16(0.0f))), bfloat16(0.0f));
|
| 55 |
+
|
| 56 |
+
// Conversion from float.
|
| 57 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(1.0f), 0x3f80);
|
| 58 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(0.5f), 0x3f00);
|
| 59 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(0.33333f), 0x3eab);
|
| 60 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(3.38e38f), 0x7f7e);
|
| 61 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(3.40e38f), 0x7f80); // Becomes infinity.
|
| 62 |
+
|
| 63 |
+
// Verify round-to-nearest-even behavior.
|
| 64 |
+
float val1 = static_cast<float>(bfloat16(__bfloat16_raw(0x3c00)));
|
| 65 |
+
float val2 = static_cast<float>(bfloat16(__bfloat16_raw(0x3c01)));
|
| 66 |
+
float val3 = static_cast<float>(bfloat16(__bfloat16_raw(0x3c02)));
|
| 67 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(0.5f * (val1 + val2)), 0x3c00);
|
| 68 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(0.5f * (val2 + val3)), 0x3c02);
|
| 69 |
+
|
| 70 |
+
// Conversion from int.
|
| 71 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(-1), 0xbf80);
|
| 72 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(0), 0x0000);
|
| 73 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(1), 0x3f80);
|
| 74 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(2), 0x4000);
|
| 75 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(3), 0x4040);
|
| 76 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(12), 0x4140);
|
| 77 |
+
|
| 78 |
+
// Conversion from bool.
|
| 79 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(false), 0x0000);
|
| 80 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(true), 0x3f80);
|
| 81 |
+
|
| 82 |
+
// Conversion to bool
|
| 83 |
+
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(3)), true);
|
| 84 |
+
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(0.33333f)), true);
|
| 85 |
+
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(-0.0)), false);
|
| 86 |
+
VERIFY_IS_EQUAL(static_cast<bool>(bfloat16(0.0)), false);
|
| 87 |
+
|
| 88 |
+
// Explicit conversion to float.
|
| 89 |
+
VERIFY_IS_EQUAL(static_cast<float>(bfloat16(__bfloat16_raw(0x0000))), 0.0f);
|
| 90 |
+
VERIFY_IS_EQUAL(static_cast<float>(bfloat16(__bfloat16_raw(0x3f80))), 1.0f);
|
| 91 |
+
|
| 92 |
+
// Implicit conversion to float
|
| 93 |
+
VERIFY_IS_EQUAL(bfloat16(__bfloat16_raw(0x0000)), 0.0f);
|
| 94 |
+
VERIFY_IS_EQUAL(bfloat16(__bfloat16_raw(0x3f80)), 1.0f);
|
| 95 |
+
|
| 96 |
+
// Zero representations
|
| 97 |
+
VERIFY_IS_EQUAL(bfloat16(0.0f), bfloat16(0.0f));
|
| 98 |
+
VERIFY_IS_EQUAL(bfloat16(-0.0f), bfloat16(0.0f));
|
| 99 |
+
VERIFY_IS_EQUAL(bfloat16(-0.0f), bfloat16(-0.0f));
|
| 100 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(0.0f), 0x0000);
|
| 101 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(-0.0f), 0x8000);
|
| 102 |
+
|
| 103 |
+
// Default is zero
|
| 104 |
+
VERIFY_IS_EQUAL(static_cast<float>(bfloat16()), 0.0f);
|
| 105 |
+
|
| 106 |
+
// Representable floats round trip via bfloat16
|
| 107 |
+
test_roundtrip<float>();
|
| 108 |
+
test_roundtrip<double>();
|
| 109 |
+
test_roundtrip<std::complex<float> >();
|
| 110 |
+
test_roundtrip<std::complex<double> >();
|
| 111 |
+
|
| 112 |
+
// Conversion
|
| 113 |
+
Array<float, 1, 100> a;
|
| 114 |
+
for (int i = 0; i < 100; i++) a(i) = i + 1.25;
|
| 115 |
+
Array<bfloat16, 1, 100> b = a.cast<bfloat16>();
|
| 116 |
+
Array<float, 1, 100> c = b.cast<float>();
|
| 117 |
+
for (int i = 0; i < 100; ++i) {
|
| 118 |
+
VERIFY_LE(numext::abs(c(i) - a(i)), a(i) / 128);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
// Epsilon
|
| 122 |
+
VERIFY_LE(1.0f, static_cast<float>((std::numeric_limits<bfloat16>::epsilon)() + bfloat16(1.0f)));
|
| 123 |
+
VERIFY_IS_EQUAL(1.0f,
|
| 124 |
+
static_cast<float>((std::numeric_limits<bfloat16>::epsilon)() / bfloat16(2.0f) + bfloat16(1.0f)));
|
| 125 |
+
|
| 126 |
+
// Negate
|
| 127 |
+
VERIFY_IS_EQUAL(static_cast<float>(-bfloat16(3.0f)), -3.0f);
|
| 128 |
+
VERIFY_IS_EQUAL(static_cast<float>(-bfloat16(-4.5f)), 4.5f);
|
| 129 |
+
|
| 130 |
+
#if !EIGEN_COMP_MSVC
|
| 131 |
+
// Visual Studio errors out on divisions by 0
|
| 132 |
+
VERIFY((numext::isnan)(static_cast<float>(bfloat16(0.0 / 0.0))));
|
| 133 |
+
VERIFY((numext::isinf)(static_cast<float>(bfloat16(1.0 / 0.0))));
|
| 134 |
+
VERIFY((numext::isinf)(static_cast<float>(bfloat16(-1.0 / 0.0))));
|
| 135 |
+
|
| 136 |
+
// Visual Studio errors out on divisions by 0
|
| 137 |
+
VERIFY((numext::isnan)(bfloat16(0.0 / 0.0)));
|
| 138 |
+
VERIFY((numext::isinf)(bfloat16(1.0 / 0.0)));
|
| 139 |
+
VERIFY((numext::isinf)(bfloat16(-1.0 / 0.0)));
|
| 140 |
+
#endif
|
| 141 |
+
|
| 142 |
+
// NaNs and infinities.
|
| 143 |
+
VERIFY(!(numext::isinf)(static_cast<float>(bfloat16(3.38e38f)))); // Largest finite number.
|
| 144 |
+
VERIFY(!(numext::isnan)(static_cast<float>(bfloat16(0.0f))));
|
| 145 |
+
VERIFY((numext::isinf)(static_cast<float>(bfloat16(__bfloat16_raw(0xff80)))));
|
| 146 |
+
VERIFY((numext::isnan)(static_cast<float>(bfloat16(__bfloat16_raw(0xffc0)))));
|
| 147 |
+
VERIFY((numext::isinf)(static_cast<float>(bfloat16(__bfloat16_raw(0x7f80)))));
|
| 148 |
+
VERIFY((numext::isnan)(static_cast<float>(bfloat16(__bfloat16_raw(0x7fc0)))));
|
| 149 |
+
|
| 150 |
+
// Exactly same checks as above, just directly on the bfloat16 representation.
|
| 151 |
+
VERIFY(!(numext::isinf)(bfloat16(__bfloat16_raw(0x7bff))));
|
| 152 |
+
VERIFY(!(numext::isnan)(bfloat16(__bfloat16_raw(0x0000))));
|
| 153 |
+
VERIFY((numext::isinf)(bfloat16(__bfloat16_raw(0xff80))));
|
| 154 |
+
VERIFY((numext::isnan)(bfloat16(__bfloat16_raw(0xffc0))));
|
| 155 |
+
VERIFY((numext::isinf)(bfloat16(__bfloat16_raw(0x7f80))));
|
| 156 |
+
VERIFY((numext::isnan)(bfloat16(__bfloat16_raw(0x7fc0))));
|
| 157 |
+
|
| 158 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(BinaryToFloat(0x0, 0xff, 0x40, 0x0)), 0x7fc0);
|
| 159 |
+
VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(BinaryToFloat(0x1, 0xff, 0x40, 0x0)), 0xffc0);
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
void test_numtraits() {
|
| 163 |
+
std::cout << "epsilon = " << NumTraits<bfloat16>::epsilon() << " (0x" << std::hex
|
| 164 |
+
<< numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::epsilon()) << ")" << std::endl;
|
| 165 |
+
std::cout << "highest = " << NumTraits<bfloat16>::highest() << " (0x" << std::hex
|
| 166 |
+
<< numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::highest()) << ")" << std::endl;
|
| 167 |
+
std::cout << "lowest = " << NumTraits<bfloat16>::lowest() << " (0x" << std::hex
|
| 168 |
+
<< numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::lowest()) << ")" << std::endl;
|
| 169 |
+
std::cout << "min = " << (std::numeric_limits<bfloat16>::min)() << " (0x" << std::hex
|
| 170 |
+
<< numext::bit_cast<numext::uint16_t>((std::numeric_limits<bfloat16>::min)()) << ")" << std::endl;
|
| 171 |
+
std::cout << "denorm min = " << (std::numeric_limits<bfloat16>::denorm_min)() << " (0x" << std::hex
|
| 172 |
+
<< numext::bit_cast<numext::uint16_t>((std::numeric_limits<bfloat16>::denorm_min)()) << ")" << std::endl;
|
| 173 |
+
std::cout << "infinity = " << NumTraits<bfloat16>::infinity() << " (0x" << std::hex
|
| 174 |
+
<< numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::infinity()) << ")" << std::endl;
|
| 175 |
+
std::cout << "quiet nan = " << NumTraits<bfloat16>::quiet_NaN() << " (0x" << std::hex
|
| 176 |
+
<< numext::bit_cast<numext::uint16_t>(NumTraits<bfloat16>::quiet_NaN()) << ")" << std::endl;
|
| 177 |
+
std::cout << "signaling nan = " << std::numeric_limits<bfloat16>::signaling_NaN() << " (0x" << std::hex
|
| 178 |
+
<< numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::signaling_NaN()) << ")" << std::endl;
|
| 179 |
+
|
| 180 |
+
VERIFY(NumTraits<bfloat16>::IsSigned);
|
| 181 |
+
|
| 182 |
+
VERIFY_IS_EQUAL(numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::infinity()),
|
| 183 |
+
numext::bit_cast<numext::uint16_t>(bfloat16(std::numeric_limits<float>::infinity())));
|
| 184 |
+
// There is no guarantee that casting a 32-bit NaN to bfloat16 has a precise
|
| 185 |
+
// bit pattern. We test that it is in fact a NaN, then test the signaling
|
| 186 |
+
// bit (msb of significand is 1 for quiet, 0 for signaling).
|
| 187 |
+
const numext::uint16_t BFLOAT16_QUIET_BIT = 0x0040;
|
| 188 |
+
VERIFY((numext::isnan)(std::numeric_limits<bfloat16>::quiet_NaN()) &&
|
| 189 |
+
(numext::isnan)(bfloat16(std::numeric_limits<float>::quiet_NaN())) &&
|
| 190 |
+
((numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::quiet_NaN()) & BFLOAT16_QUIET_BIT) > 0) &&
|
| 191 |
+
((numext::bit_cast<numext::uint16_t>(bfloat16(std::numeric_limits<float>::quiet_NaN())) & BFLOAT16_QUIET_BIT) >
|
| 192 |
+
0));
|
| 193 |
+
// After a cast to bfloat16, a signaling NaN may become non-signaling. Thus,
|
| 194 |
+
// we check that both are NaN, and that only the `numeric_limits` version is
|
| 195 |
+
// signaling.
|
| 196 |
+
VERIFY(
|
| 197 |
+
(numext::isnan)(std::numeric_limits<bfloat16>::signaling_NaN()) &&
|
| 198 |
+
(numext::isnan)(bfloat16(std::numeric_limits<float>::signaling_NaN())) &&
|
| 199 |
+
((numext::bit_cast<numext::uint16_t>(std::numeric_limits<bfloat16>::signaling_NaN()) & BFLOAT16_QUIET_BIT) == 0));
|
| 200 |
+
|
| 201 |
+
VERIFY((std::numeric_limits<bfloat16>::min)() > bfloat16(0.f));
|
| 202 |
+
VERIFY((std::numeric_limits<bfloat16>::denorm_min)() > bfloat16(0.f));
|
| 203 |
+
VERIFY_IS_EQUAL((std::numeric_limits<bfloat16>::denorm_min)() / bfloat16(2), bfloat16(0.f));
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
void test_arithmetic() {
|
| 207 |
+
VERIFY_IS_EQUAL(static_cast<float>(bfloat16(2) + bfloat16(2)), 4.f);
|
| 208 |
+
VERIFY_IS_EQUAL(static_cast<float>(bfloat16(2) + bfloat16(-2)), 0.f);
|
| 209 |
+
VERIFY_IS_APPROX(static_cast<float>(bfloat16(0.33333f) + bfloat16(0.66667f)), 1.0f);
|
| 210 |
+
VERIFY_IS_EQUAL(static_cast<float>(bfloat16(2.0f) * bfloat16(-5.5f)), -11.0f);
|
| 211 |
+
VERIFY_IS_APPROX(static_cast<float>(bfloat16(1.0f) / bfloat16(3.0f)), 0.3339f);
|
| 212 |
+
VERIFY_IS_EQUAL(static_cast<float>(-bfloat16(4096.0f)), -4096.0f);
|
| 213 |
+
VERIFY_IS_EQUAL(static_cast<float>(-bfloat16(-4096.0f)), 4096.0f);
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
void test_comparison() {
|
| 217 |
+
VERIFY(bfloat16(1.0f) > bfloat16(0.5f));
|
| 218 |
+
VERIFY(bfloat16(0.5f) < bfloat16(1.0f));
|
| 219 |
+
VERIFY(!(bfloat16(1.0f) < bfloat16(0.5f)));
|
| 220 |
+
VERIFY(!(bfloat16(0.5f) > bfloat16(1.0f)));
|
| 221 |
+
|
| 222 |
+
VERIFY(!(bfloat16(4.0f) > bfloat16(4.0f)));
|
| 223 |
+
VERIFY(!(bfloat16(4.0f) < bfloat16(4.0f)));
|
| 224 |
+
|
| 225 |
+
VERIFY(!(bfloat16(0.0f) < bfloat16(-0.0f)));
|
| 226 |
+
VERIFY(!(bfloat16(-0.0f) < bfloat16(0.0f)));
|
| 227 |
+
VERIFY(!(bfloat16(0.0f) > bfloat16(-0.0f)));
|
| 228 |
+
VERIFY(!(bfloat16(-0.0f) > bfloat16(0.0f)));
|
| 229 |
+
|
| 230 |
+
VERIFY(bfloat16(0.2f) > bfloat16(-1.0f));
|
| 231 |
+
VERIFY(bfloat16(-1.0f) < bfloat16(0.2f));
|
| 232 |
+
VERIFY(bfloat16(-16.0f) < bfloat16(-15.0f));
|
| 233 |
+
|
| 234 |
+
VERIFY(bfloat16(1.0f) == bfloat16(1.0f));
|
| 235 |
+
VERIFY(bfloat16(1.0f) != bfloat16(2.0f));
|
| 236 |
+
|
| 237 |
+
// Comparisons with NaNs and infinities.
|
| 238 |
+
#if !EIGEN_COMP_MSVC
|
| 239 |
+
// Visual Studio errors out on divisions by 0
|
| 240 |
+
VERIFY(!(bfloat16(0.0 / 0.0) == bfloat16(0.0 / 0.0)));
|
| 241 |
+
VERIFY(bfloat16(0.0 / 0.0) != bfloat16(0.0 / 0.0));
|
| 242 |
+
|
| 243 |
+
VERIFY(!(bfloat16(1.0) == bfloat16(0.0 / 0.0)));
|
| 244 |
+
VERIFY(!(bfloat16(1.0) < bfloat16(0.0 / 0.0)));
|
| 245 |
+
VERIFY(!(bfloat16(1.0) > bfloat16(0.0 / 0.0)));
|
| 246 |
+
VERIFY(bfloat16(1.0) != bfloat16(0.0 / 0.0));
|
| 247 |
+
|
| 248 |
+
VERIFY(bfloat16(1.0) < bfloat16(1.0 / 0.0));
|
| 249 |
+
VERIFY(bfloat16(1.0) > bfloat16(-1.0 / 0.0));
|
| 250 |
+
#endif
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
void test_basic_functions() {
|
| 254 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::abs(bfloat16(3.5f))), 3.5f);
|
| 255 |
+
VERIFY_IS_EQUAL(static_cast<float>(abs(bfloat16(3.5f))), 3.5f);
|
| 256 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::abs(bfloat16(-3.5f))), 3.5f);
|
| 257 |
+
VERIFY_IS_EQUAL(static_cast<float>(abs(bfloat16(-3.5f))), 3.5f);
|
| 258 |
+
|
| 259 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::floor(bfloat16(3.5f))), 3.0f);
|
| 260 |
+
VERIFY_IS_EQUAL(static_cast<float>(floor(bfloat16(3.5f))), 3.0f);
|
| 261 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::floor(bfloat16(-3.5f))), -4.0f);
|
| 262 |
+
VERIFY_IS_EQUAL(static_cast<float>(floor(bfloat16(-3.5f))), -4.0f);
|
| 263 |
+
|
| 264 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::ceil(bfloat16(3.5f))), 4.0f);
|
| 265 |
+
VERIFY_IS_EQUAL(static_cast<float>(ceil(bfloat16(3.5f))), 4.0f);
|
| 266 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::ceil(bfloat16(-3.5f))), -3.0f);
|
| 267 |
+
VERIFY_IS_EQUAL(static_cast<float>(ceil(bfloat16(-3.5f))), -3.0f);
|
| 268 |
+
|
| 269 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::sqrt(bfloat16(0.0f))), 0.0f);
|
| 270 |
+
VERIFY_IS_APPROX(static_cast<float>(sqrt(bfloat16(0.0f))), 0.0f);
|
| 271 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::sqrt(bfloat16(4.0f))), 2.0f);
|
| 272 |
+
VERIFY_IS_APPROX(static_cast<float>(sqrt(bfloat16(4.0f))), 2.0f);
|
| 273 |
+
|
| 274 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::pow(bfloat16(0.0f), bfloat16(1.0f))), 0.0f);
|
| 275 |
+
VERIFY_IS_APPROX(static_cast<float>(pow(bfloat16(0.0f), bfloat16(1.0f))), 0.0f);
|
| 276 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::pow(bfloat16(2.0f), bfloat16(2.0f))), 4.0f);
|
| 277 |
+
VERIFY_IS_APPROX(static_cast<float>(pow(bfloat16(2.0f), bfloat16(2.0f))), 4.0f);
|
| 278 |
+
|
| 279 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::exp(bfloat16(0.0f))), 1.0f);
|
| 280 |
+
VERIFY_IS_EQUAL(static_cast<float>(exp(bfloat16(0.0f))), 1.0f);
|
| 281 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::exp(bfloat16(EIGEN_PI))), 20.f + static_cast<float>(EIGEN_PI));
|
| 282 |
+
VERIFY_IS_APPROX(static_cast<float>(exp(bfloat16(EIGEN_PI))), 20.f + static_cast<float>(EIGEN_PI));
|
| 283 |
+
|
| 284 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::expm1(bfloat16(0.0f))), 0.0f);
|
| 285 |
+
VERIFY_IS_EQUAL(static_cast<float>(expm1(bfloat16(0.0f))), 0.0f);
|
| 286 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::expm1(bfloat16(2.0f))), 6.375f);
|
| 287 |
+
VERIFY_IS_APPROX(static_cast<float>(expm1(bfloat16(2.0f))), 6.375f);
|
| 288 |
+
|
| 289 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::log(bfloat16(1.0f))), 0.0f);
|
| 290 |
+
VERIFY_IS_EQUAL(static_cast<float>(log(bfloat16(1.0f))), 0.0f);
|
| 291 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::log(bfloat16(10.0f))), 2.296875f);
|
| 292 |
+
VERIFY_IS_APPROX(static_cast<float>(log(bfloat16(10.0f))), 2.296875f);
|
| 293 |
+
|
| 294 |
+
VERIFY_IS_EQUAL(static_cast<float>(numext::log1p(bfloat16(0.0f))), 0.0f);
|
| 295 |
+
VERIFY_IS_EQUAL(static_cast<float>(log1p(bfloat16(0.0f))), 0.0f);
|
| 296 |
+
VERIFY_IS_APPROX(static_cast<float>(numext::log1p(bfloat16(10.0f))), 2.390625f);
|
| 297 |
+
VERIFY_IS_APPROX(static_cast<float>(log1p(bfloat16(10.0f))), 2.390625f);
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
void test_trigonometric_functions() {
|
| 301 |
+
VERIFY_IS_APPROX(numext::cos(bfloat16(0.0f)), bfloat16(cosf(0.0f)));
|
| 302 |
+
VERIFY_IS_APPROX(cos(bfloat16(0.0f)), bfloat16(cosf(0.0f)));
|
| 303 |
+
VERIFY_IS_APPROX(numext::cos(bfloat16(EIGEN_PI)), bfloat16(cosf(EIGEN_PI)));
|
| 304 |
+
// VERIFY_IS_APPROX(numext::cos(bfloat16(EIGEN_PI/2)), bfloat16(cosf(EIGEN_PI/2)));
|
| 305 |
+
// VERIFY_IS_APPROX(numext::cos(bfloat16(3*EIGEN_PI/2)), bfloat16(cosf(3*EIGEN_PI/2)));
|
| 306 |
+
VERIFY_IS_APPROX(numext::cos(bfloat16(3.5f)), bfloat16(cosf(3.5f)));
|
| 307 |
+
|
| 308 |
+
VERIFY_IS_APPROX(numext::sin(bfloat16(0.0f)), bfloat16(sinf(0.0f)));
|
| 309 |
+
VERIFY_IS_APPROX(sin(bfloat16(0.0f)), bfloat16(sinf(0.0f)));
|
| 310 |
+
// VERIFY_IS_APPROX(numext::sin(bfloat16(EIGEN_PI)), bfloat16(sinf(EIGEN_PI)));
|
| 311 |
+
VERIFY_IS_APPROX(numext::sin(bfloat16(EIGEN_PI / 2)), bfloat16(sinf(EIGEN_PI / 2)));
|
| 312 |
+
VERIFY_IS_APPROX(numext::sin(bfloat16(3 * EIGEN_PI / 2)), bfloat16(sinf(3 * EIGEN_PI / 2)));
|
| 313 |
+
VERIFY_IS_APPROX(numext::sin(bfloat16(3.5f)), bfloat16(sinf(3.5f)));
|
| 314 |
+
|
| 315 |
+
VERIFY_IS_APPROX(numext::tan(bfloat16(0.0f)), bfloat16(tanf(0.0f)));
|
| 316 |
+
VERIFY_IS_APPROX(tan(bfloat16(0.0f)), bfloat16(tanf(0.0f)));
|
| 317 |
+
// VERIFY_IS_APPROX(numext::tan(bfloat16(EIGEN_PI)), bfloat16(tanf(EIGEN_PI)));
|
| 318 |
+
// VERIFY_IS_APPROX(numext::tan(bfloat16(EIGEN_PI/2)), bfloat16(tanf(EIGEN_PI/2)));
|
| 319 |
+
// VERIFY_IS_APPROX(numext::tan(bfloat16(3*EIGEN_PI/2)), bfloat16(tanf(3*EIGEN_PI/2)));
|
| 320 |
+
VERIFY_IS_APPROX(numext::tan(bfloat16(3.5f)), bfloat16(tanf(3.5f)));
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
void test_array() {
|
| 324 |
+
typedef Array<bfloat16, 1, Dynamic> ArrayXh;
|
| 325 |
+
Index size = internal::random<Index>(1, 10);
|
| 326 |
+
Index i = internal::random<Index>(0, size - 1);
|
| 327 |
+
ArrayXh a1 = ArrayXh::Random(size), a2 = ArrayXh::Random(size);
|
| 328 |
+
VERIFY_IS_APPROX(a1 + a1, bfloat16(2) * a1);
|
| 329 |
+
VERIFY((a1.abs() >= bfloat16(0)).all());
|
| 330 |
+
VERIFY_IS_APPROX((a1 * a1).sqrt(), a1.abs());
|
| 331 |
+
|
| 332 |
+
VERIFY(((a1.min)(a2) <= (a1.max)(a2)).all());
|
| 333 |
+
a1(i) = bfloat16(-10.);
|
| 334 |
+
VERIFY_IS_EQUAL(a1.minCoeff(), bfloat16(-10.));
|
| 335 |
+
a1(i) = bfloat16(10.);
|
| 336 |
+
VERIFY_IS_EQUAL(a1.maxCoeff(), bfloat16(10.));
|
| 337 |
+
|
| 338 |
+
std::stringstream ss;
|
| 339 |
+
ss << a1;
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
void test_product() {
|
| 343 |
+
typedef Matrix<bfloat16, Dynamic, Dynamic> MatrixXh;
|
| 344 |
+
Index rows = internal::random<Index>(1, EIGEN_TEST_MAX_SIZE);
|
| 345 |
+
Index cols = internal::random<Index>(1, EIGEN_TEST_MAX_SIZE);
|
| 346 |
+
Index depth = internal::random<Index>(1, EIGEN_TEST_MAX_SIZE);
|
| 347 |
+
MatrixXh Ah = MatrixXh::Random(rows, depth);
|
| 348 |
+
MatrixXh Bh = MatrixXh::Random(depth, cols);
|
| 349 |
+
MatrixXh Ch = MatrixXh::Random(rows, cols);
|
| 350 |
+
MatrixXf Af = Ah.cast<float>();
|
| 351 |
+
MatrixXf Bf = Bh.cast<float>();
|
| 352 |
+
MatrixXf Cf = Ch.cast<float>();
|
| 353 |
+
VERIFY_IS_APPROX(Ch.noalias() += Ah * Bh, (Cf.noalias() += Af * Bf).cast<bfloat16>());
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
void test_nextafter() {
|
| 357 |
+
VERIFY((numext::isnan)(numext::nextafter(std::numeric_limits<bfloat16>::quiet_NaN(), bfloat16(1.0f))));
|
| 358 |
+
VERIFY((numext::isnan)(numext::nextafter(bfloat16(1.0f), std::numeric_limits<bfloat16>::quiet_NaN())));
|
| 359 |
+
VERIFY(numext::nextafter(bfloat16(0.0f), bfloat16(0.0f)) == bfloat16(0.0f));
|
| 360 |
+
VERIFY(numext::nextafter(bfloat16(1.0f), bfloat16(1.0f)) == bfloat16(1.0f));
|
| 361 |
+
VERIFY(numext::nextafter(bfloat16(-1.0f), bfloat16(-1.0f)) == bfloat16(-1.0f));
|
| 362 |
+
VERIFY(numext::nextafter(std::numeric_limits<bfloat16>::infinity(), std::numeric_limits<bfloat16>::infinity()) ==
|
| 363 |
+
std::numeric_limits<bfloat16>::infinity());
|
| 364 |
+
VERIFY(numext::nextafter(std::numeric_limits<bfloat16>::infinity(), bfloat16(0.0f)) ==
|
| 365 |
+
(std::numeric_limits<bfloat16>::max)());
|
| 366 |
+
VERIFY(numext::nextafter(-std::numeric_limits<bfloat16>::infinity(), bfloat16(0.0f)) ==
|
| 367 |
+
-(std::numeric_limits<bfloat16>::max)());
|
| 368 |
+
VERIFY(numext::nextafter(bfloat16(1.0f), std::numeric_limits<bfloat16>::infinity()) ==
|
| 369 |
+
bfloat16(1.0f) + std::numeric_limits<bfloat16>::epsilon());
|
| 370 |
+
VERIFY(numext::nextafter(bfloat16(1.0f), -std::numeric_limits<bfloat16>::infinity()) ==
|
| 371 |
+
bfloat16(1.0f) - std::numeric_limits<bfloat16>::epsilon() / bfloat16(2.0f));
|
| 372 |
+
VERIFY(numext::nextafter(bfloat16(-1.0f), -std::numeric_limits<bfloat16>::infinity()) ==
|
| 373 |
+
bfloat16(-1.0f) - std::numeric_limits<bfloat16>::epsilon());
|
| 374 |
+
VERIFY(numext::nextafter(bfloat16(-1.0f), std::numeric_limits<bfloat16>::infinity()) ==
|
| 375 |
+
bfloat16(-1.0f) + std::numeric_limits<bfloat16>::epsilon() / bfloat16(2.0f));
|
| 376 |
+
VERIFY(numext::nextafter((std::numeric_limits<bfloat16>::max)(), std::numeric_limits<bfloat16>::infinity()) ==
|
| 377 |
+
std::numeric_limits<bfloat16>::infinity());
|
| 378 |
+
VERIFY(numext::nextafter(-(std::numeric_limits<bfloat16>::max)(), -std::numeric_limits<bfloat16>::infinity()) ==
|
| 379 |
+
-std::numeric_limits<bfloat16>::infinity());
|
| 380 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(1.0f)), 0x0001);
|
| 381 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(1.0f)), 0x0000);
|
| 382 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(-1.0f)), 0x8000);
|
| 383 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(-1.0f)), 0x8001);
|
| 384 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(-0.0f)), 0x8000);
|
| 385 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(0.0f)), 0x0000);
|
| 386 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(0.0f)), 0x0000);
|
| 387 |
+
VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(-0.0f)), 0x8000);
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
EIGEN_DECLARE_TEST(bfloat16_float) {
|
| 391 |
+
CALL_SUBTEST(test_numtraits());
|
| 392 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 393 |
+
CALL_SUBTEST(test_conversion());
|
| 394 |
+
CALL_SUBTEST(test_arithmetic());
|
| 395 |
+
CALL_SUBTEST(test_comparison());
|
| 396 |
+
CALL_SUBTEST(test_basic_functions());
|
| 397 |
+
CALL_SUBTEST(test_trigonometric_functions());
|
| 398 |
+
CALL_SUBTEST(test_array());
|
| 399 |
+
CALL_SUBTEST(test_product());
|
| 400 |
+
CALL_SUBTEST(test_nextafter());
|
| 401 |
+
}
|
| 402 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bicgstab.cpp
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
|
| 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 |
+
#include "sparse_solver.h"
|
| 11 |
+
#include <Eigen/IterativeLinearSolvers>
|
| 12 |
+
|
| 13 |
+
template <typename T, typename I_>
|
| 14 |
+
void test_bicgstab_T() {
|
| 15 |
+
BiCGSTAB<SparseMatrix<T, 0, I_>, DiagonalPreconditioner<T> > bicgstab_colmajor_diag;
|
| 16 |
+
BiCGSTAB<SparseMatrix<T, 0, I_>, IdentityPreconditioner> bicgstab_colmajor_I;
|
| 17 |
+
BiCGSTAB<SparseMatrix<T, 0, I_>, IncompleteLUT<T, I_> > bicgstab_colmajor_ilut;
|
| 18 |
+
// BiCGSTAB<SparseMatrix<T>, SSORPreconditioner<T> > bicgstab_colmajor_ssor;
|
| 19 |
+
|
| 20 |
+
bicgstab_colmajor_diag.setTolerance(NumTraits<T>::epsilon() * 4);
|
| 21 |
+
bicgstab_colmajor_ilut.setTolerance(NumTraits<T>::epsilon() * 4);
|
| 22 |
+
|
| 23 |
+
CALL_SUBTEST(check_sparse_square_solving(bicgstab_colmajor_diag));
|
| 24 |
+
// CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_I) );
|
| 25 |
+
CALL_SUBTEST(check_sparse_square_solving(bicgstab_colmajor_ilut));
|
| 26 |
+
// CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ssor) );
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
// https://gitlab.com/libeigen/eigen/-/issues/2856
|
| 30 |
+
void test_2856() {
|
| 31 |
+
Eigen::MatrixXd D = Eigen::MatrixXd::Identity(14, 14);
|
| 32 |
+
D(6, 13) = 1;
|
| 33 |
+
D(13, 12) = 1;
|
| 34 |
+
using CSRMatrix = Eigen::SparseMatrix<double, Eigen::RowMajor>;
|
| 35 |
+
CSRMatrix A = D.sparseView();
|
| 36 |
+
|
| 37 |
+
Eigen::VectorXd b = Eigen::VectorXd::Zero(14);
|
| 38 |
+
b(12) = -1001;
|
| 39 |
+
|
| 40 |
+
Eigen::BiCGSTAB<CSRMatrix> solver;
|
| 41 |
+
solver.compute(A);
|
| 42 |
+
Eigen::VectorXd x = solver.solve(b);
|
| 43 |
+
Eigen::VectorXd expected = Eigen::VectorXd::Zero(14);
|
| 44 |
+
expected(6) = -1001;
|
| 45 |
+
expected(12) = -1001;
|
| 46 |
+
expected(13) = 1001;
|
| 47 |
+
VERIFY_IS_EQUAL(x, expected);
|
| 48 |
+
|
| 49 |
+
Eigen::VectorXd residual = b - A * x;
|
| 50 |
+
VERIFY(residual.isZero());
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// https://gitlab.com/libeigen/eigen/-/issues/2899
|
| 54 |
+
void test_2899() {
|
| 55 |
+
Eigen::MatrixXd A = Eigen::MatrixXd::Zero(4, 4);
|
| 56 |
+
A(0, 0) = 1;
|
| 57 |
+
A(1, 0) = -1.0 / 6;
|
| 58 |
+
A(1, 1) = 2.0 / 3;
|
| 59 |
+
A(1, 2) = -1.0 / 6;
|
| 60 |
+
A(1, 3) = -1.0 / 3;
|
| 61 |
+
A(2, 1) = -1.0 / 3;
|
| 62 |
+
A(2, 2) = 1;
|
| 63 |
+
A(2, 3) = -2.0 / 3;
|
| 64 |
+
A(3, 1) = -1.0 / 3;
|
| 65 |
+
A(3, 2) = -1.0 / 3;
|
| 66 |
+
A(3, 3) = 2.0 / 3;
|
| 67 |
+
Eigen::VectorXd b = Eigen::VectorXd::Zero(4);
|
| 68 |
+
b(0) = 0;
|
| 69 |
+
b(1) = 1;
|
| 70 |
+
b(2) = 1;
|
| 71 |
+
b(3) = 1;
|
| 72 |
+
Eigen::BiCGSTAB<Eigen::MatrixXd> solver;
|
| 73 |
+
solver.compute(A);
|
| 74 |
+
Eigen::VectorXd x = solver.solve(b);
|
| 75 |
+
Eigen::VectorXd expected(4);
|
| 76 |
+
expected << 0, 15, 18, 18;
|
| 77 |
+
VERIFY_IS_APPROX(x, expected);
|
| 78 |
+
Eigen::VectorXd residual = b - A * x;
|
| 79 |
+
VERIFY(residual.isZero());
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
EIGEN_DECLARE_TEST(bicgstab) {
|
| 83 |
+
CALL_SUBTEST_1((test_bicgstab_T<double, int>()));
|
| 84 |
+
CALL_SUBTEST_2((test_bicgstab_T<std::complex<double>, int>()));
|
| 85 |
+
CALL_SUBTEST_3((test_bicgstab_T<double, long int>()));
|
| 86 |
+
CALL_SUBTEST_4(test_2856());
|
| 87 |
+
CALL_SUBTEST_5(test_2899());
|
| 88 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/blasutil.cpp
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2020 Everton Constantino <everton.constantino@ibm.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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
// Disable "ignoring attributes on template argument"
|
| 13 |
+
// for packet_traits<Packet*>
|
| 14 |
+
// => The only workaround would be to wrap _m128 and the likes
|
| 15 |
+
// within wrappers.
|
| 16 |
+
#if EIGEN_GNUC_STRICT_AT_LEAST(6, 0, 0)
|
| 17 |
+
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
| 18 |
+
#endif
|
| 19 |
+
|
| 20 |
+
#define GET(i, j) (StorageOrder == RowMajor ? (i) * stride + (j) : (i) + (j) * stride)
|
| 21 |
+
#define SCATTER(i, j, k) (StorageOrder == RowMajor ? ((i) + (k)) * stride + (j) : (i) + ((j) + (k)) * stride)
|
| 22 |
+
|
| 23 |
+
template <typename Scalar, typename Packet>
|
| 24 |
+
void compare(const Packet& a, const Packet& b) {
|
| 25 |
+
int pktsz = internal::packet_traits<Scalar>::size;
|
| 26 |
+
Scalar* buffA = new Scalar[pktsz];
|
| 27 |
+
Scalar* buffB = new Scalar[pktsz];
|
| 28 |
+
|
| 29 |
+
internal::pstoreu<Scalar, Packet>(buffA, a);
|
| 30 |
+
internal::pstoreu<Scalar, Packet>(buffB, b);
|
| 31 |
+
|
| 32 |
+
for (int i = 0; i < pktsz; i++) {
|
| 33 |
+
VERIFY_IS_EQUAL(buffA[i], buffB[i]);
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
delete[] buffA;
|
| 37 |
+
delete[] buffB;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
template <typename Scalar, int StorageOrder, int n>
|
| 41 |
+
struct PacketBlockSet {
|
| 42 |
+
typedef typename internal::packet_traits<Scalar>::type Packet;
|
| 43 |
+
|
| 44 |
+
void setPacketBlock(internal::PacketBlock<Packet, n>& block, Scalar value) {
|
| 45 |
+
for (int idx = 0; idx < n; idx++) {
|
| 46 |
+
block.packet[idx] = internal::pset1<Packet>(value);
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
void comparePacketBlock(Scalar* data, int i, int j, int stride, internal::PacketBlock<Packet, n>& block) {
|
| 51 |
+
for (int idx = 0; idx < n; idx++) {
|
| 52 |
+
Packet line = internal::ploadu<Packet>(data + SCATTER(i, j, idx));
|
| 53 |
+
compare<Scalar, Packet>(block.packet[idx], line);
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
template <typename Scalar, int StorageOrder, int BlockSize>
|
| 59 |
+
void run_bdmp_spec_1() {
|
| 60 |
+
typedef internal::blas_data_mapper<Scalar, int, StorageOrder> BlasDataMapper;
|
| 61 |
+
int packetSize = internal::packet_traits<Scalar>::size;
|
| 62 |
+
int minSize = std::max<int>(packetSize, BlockSize);
|
| 63 |
+
typedef typename internal::packet_traits<Scalar>::type Packet;
|
| 64 |
+
|
| 65 |
+
int szm = internal::random<int>(minSize, 500), szn = internal::random<int>(minSize, 500);
|
| 66 |
+
int stride = StorageOrder == RowMajor ? szn : szm;
|
| 67 |
+
Scalar* d = new Scalar[szn * szm];
|
| 68 |
+
|
| 69 |
+
// Initializing with random entries
|
| 70 |
+
for (int i = 0; i < szm * szn; i++) {
|
| 71 |
+
d[i] = internal::random<Scalar>(static_cast<Scalar>(3), static_cast<Scalar>(10));
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
BlasDataMapper bdm(d, stride);
|
| 75 |
+
|
| 76 |
+
// Testing operator()
|
| 77 |
+
for (int i = 0; i < szm; i++) {
|
| 78 |
+
for (int j = 0; j < szn; j++) {
|
| 79 |
+
VERIFY_IS_EQUAL(d[GET(i, j)], bdm(i, j));
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
// Testing getSubMapper and getLinearMapper
|
| 84 |
+
int i0 = internal::random<int>(0, szm - 2);
|
| 85 |
+
int j0 = internal::random<int>(0, szn - 2);
|
| 86 |
+
for (int i = i0; i < szm; i++) {
|
| 87 |
+
for (int j = j0; j < szn; j++) {
|
| 88 |
+
const BlasDataMapper& bdmSM = bdm.getSubMapper(i0, j0);
|
| 89 |
+
const internal::BlasLinearMapper<Scalar, int, 0>& bdmLM = bdm.getLinearMapper(i0, j0);
|
| 90 |
+
|
| 91 |
+
Scalar v = bdmSM(i - i0, j - j0);
|
| 92 |
+
Scalar vd = d[GET(i, j)];
|
| 93 |
+
VERIFY_IS_EQUAL(vd, v);
|
| 94 |
+
VERIFY_IS_EQUAL(vd, bdmLM(GET(i - i0, j - j0)));
|
| 95 |
+
}
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
// Testing loadPacket
|
| 99 |
+
for (int i = 0; i < szm - minSize; i++) {
|
| 100 |
+
for (int j = 0; j < szn - minSize; j++) {
|
| 101 |
+
Packet pktBDM = bdm.template loadPacket<Packet>(i, j);
|
| 102 |
+
Packet pktD = internal::ploadu<Packet>(d + GET(i, j));
|
| 103 |
+
|
| 104 |
+
compare<Scalar, Packet>(pktBDM, pktD);
|
| 105 |
+
}
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
// Testing gatherPacket
|
| 109 |
+
Scalar* buff = new Scalar[packetSize];
|
| 110 |
+
for (int i = 0; i < szm - minSize; i++) {
|
| 111 |
+
for (int j = 0; j < szn - minSize; j++) {
|
| 112 |
+
Packet p = bdm.template gatherPacket<Packet>(i, j);
|
| 113 |
+
internal::pstoreu<Scalar, Packet>(buff, p);
|
| 114 |
+
|
| 115 |
+
for (int k = 0; k < packetSize; k++) {
|
| 116 |
+
VERIFY_IS_EQUAL(d[SCATTER(i, j, k)], buff[k]);
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
delete[] buff;
|
| 121 |
+
|
| 122 |
+
// Testing scatterPacket
|
| 123 |
+
for (int i = 0; i < szm - minSize; i++) {
|
| 124 |
+
for (int j = 0; j < szn - minSize; j++) {
|
| 125 |
+
Packet p = internal::pset1<Packet>(static_cast<Scalar>(1));
|
| 126 |
+
bdm.template scatterPacket<Packet>(i, j, p);
|
| 127 |
+
for (int k = 0; k < packetSize; k++) {
|
| 128 |
+
VERIFY_IS_EQUAL(d[SCATTER(i, j, k)], static_cast<Scalar>(1));
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
// Testing storePacketBlock
|
| 134 |
+
internal::PacketBlock<Packet, BlockSize> block;
|
| 135 |
+
|
| 136 |
+
PacketBlockSet<Scalar, StorageOrder, BlockSize> pbs;
|
| 137 |
+
pbs.setPacketBlock(block, static_cast<Scalar>(2));
|
| 138 |
+
|
| 139 |
+
for (int i = 0; i < szm - minSize; i++) {
|
| 140 |
+
for (int j = 0; j < szn - minSize; j++) {
|
| 141 |
+
bdm.template storePacketBlock<Packet, BlockSize>(i, j, block);
|
| 142 |
+
|
| 143 |
+
pbs.comparePacketBlock(d, i, j, stride, block);
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
delete[] d;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
template <typename Scalar>
|
| 151 |
+
void run_test() {
|
| 152 |
+
run_bdmp_spec_1<Scalar, RowMajor, 1>();
|
| 153 |
+
run_bdmp_spec_1<Scalar, ColMajor, 1>();
|
| 154 |
+
run_bdmp_spec_1<Scalar, RowMajor, 2>();
|
| 155 |
+
run_bdmp_spec_1<Scalar, ColMajor, 2>();
|
| 156 |
+
run_bdmp_spec_1<Scalar, RowMajor, 4>();
|
| 157 |
+
run_bdmp_spec_1<Scalar, ColMajor, 4>();
|
| 158 |
+
run_bdmp_spec_1<Scalar, RowMajor, 8>();
|
| 159 |
+
run_bdmp_spec_1<Scalar, ColMajor, 8>();
|
| 160 |
+
run_bdmp_spec_1<Scalar, RowMajor, 16>();
|
| 161 |
+
run_bdmp_spec_1<Scalar, ColMajor, 16>();
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
EIGEN_DECLARE_TEST(blasutil) {
|
| 165 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 166 |
+
CALL_SUBTEST_1(run_test<numext::int8_t>());
|
| 167 |
+
CALL_SUBTEST_2(run_test<numext::int16_t>());
|
| 168 |
+
CALL_SUBTEST_3(run_test<numext::int32_t>());
|
| 169 |
+
|
| 170 |
+
// TODO: Replace this by a call to numext::int64_t as soon as we have a way to
|
| 171 |
+
// detect the typedef for int64_t on all platforms
|
| 172 |
+
CALL_SUBTEST_4(run_test<signed long long>());
|
| 173 |
+
CALL_SUBTEST_5(run_test<float_t>());
|
| 174 |
+
CALL_SUBTEST_6(run_test<double_t>());
|
| 175 |
+
CALL_SUBTEST_7(run_test<std::complex<float> >());
|
| 176 |
+
CALL_SUBTEST_8(run_test<std::complex<double> >());
|
| 177 |
+
}
|
| 178 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/block.cpp
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2006-2010 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <typename MatrixType, typename Index, typename Scalar>
|
| 13 |
+
std::enable_if_t<!NumTraits<typename MatrixType::Scalar>::IsComplex, typename MatrixType::Scalar> block_real_only(
|
| 14 |
+
const MatrixType& m1, Index r1, Index r2, Index c1, Index c2, const Scalar& s1) {
|
| 15 |
+
// check cwise-Functions:
|
| 16 |
+
VERIFY_IS_APPROX(m1.row(r1).cwiseMax(s1), m1.cwiseMax(s1).row(r1));
|
| 17 |
+
VERIFY_IS_APPROX(m1.col(c1).cwiseMin(s1), m1.cwiseMin(s1).col(c1));
|
| 18 |
+
|
| 19 |
+
VERIFY_IS_APPROX(m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).cwiseMin(s1),
|
| 20 |
+
m1.cwiseMin(s1).block(r1, c1, r2 - r1 + 1, c2 - c1 + 1));
|
| 21 |
+
VERIFY_IS_APPROX(m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).cwiseMax(s1),
|
| 22 |
+
m1.cwiseMax(s1).block(r1, c1, r2 - r1 + 1, c2 - c1 + 1));
|
| 23 |
+
|
| 24 |
+
return Scalar(0);
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
template <typename MatrixType, typename Index, typename Scalar>
|
| 28 |
+
std::enable_if_t<NumTraits<typename MatrixType::Scalar>::IsComplex, typename MatrixType::Scalar> block_real_only(
|
| 29 |
+
const MatrixType&, Index, Index, Index, Index, const Scalar&) {
|
| 30 |
+
return Scalar(0);
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
// Check at compile-time that T1==T2, and at runtime-time that a==b
|
| 34 |
+
template <typename T1, typename T2>
|
| 35 |
+
std::enable_if_t<internal::is_same<T1, T2>::value, bool> is_same_block(const T1& a, const T2& b) {
|
| 36 |
+
return a.isApprox(b);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
template <typename MatrixType>
|
| 40 |
+
std::enable_if_t<((MatrixType::Flags & RowMajorBit) == 0), void> check_left_top(const MatrixType& m, Index r, Index c,
|
| 41 |
+
Index rows, Index /*unused*/) {
|
| 42 |
+
if (c > 0) VERIFY_IS_EQUAL(m.leftCols(c).coeff(r + c * rows), m(r, c));
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
template <typename MatrixType>
|
| 46 |
+
std::enable_if_t<((MatrixType::Flags & RowMajorBit) != 0), void> check_left_top(const MatrixType& m, Index r, Index c,
|
| 47 |
+
Index /*unused*/, Index cols) {
|
| 48 |
+
if (r > 0) VERIFY_IS_EQUAL(m.topRows(r).coeff(c + r * cols), m(r, c));
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
template <typename MatrixType>
|
| 52 |
+
void block(const MatrixType& m) {
|
| 53 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 54 |
+
typedef typename MatrixType::RealScalar RealScalar;
|
| 55 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 56 |
+
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
|
| 57 |
+
typedef Matrix<Scalar, Dynamic, Dynamic, MatrixType::IsRowMajor ? RowMajor : ColMajor> DynamicMatrixType;
|
| 58 |
+
typedef Matrix<Scalar, Dynamic, 1> DynamicVectorType;
|
| 59 |
+
|
| 60 |
+
Index rows = m.rows();
|
| 61 |
+
Index cols = m.cols();
|
| 62 |
+
|
| 63 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m1_copy = m1, m2 = MatrixType::Random(rows, cols), m3(rows, cols),
|
| 64 |
+
ones = MatrixType::Ones(rows, cols);
|
| 65 |
+
VectorType v1 = VectorType::Random(rows);
|
| 66 |
+
|
| 67 |
+
Scalar s1 = internal::random<Scalar>();
|
| 68 |
+
|
| 69 |
+
Index r1 = internal::random<Index>(0, rows - 1);
|
| 70 |
+
Index r2 = internal::random<Index>(r1, rows - 1);
|
| 71 |
+
Index c1 = internal::random<Index>(0, cols - 1);
|
| 72 |
+
Index c2 = internal::random<Index>(c1, cols - 1);
|
| 73 |
+
|
| 74 |
+
block_real_only(m1, r1, r2, c1, c1, s1);
|
| 75 |
+
|
| 76 |
+
// test fill logic with innerpanel and non-innerpanel blocks
|
| 77 |
+
m1.row(r1).setConstant(s1);
|
| 78 |
+
VERIFY_IS_CWISE_EQUAL(m1.row(r1), DynamicVectorType::Constant(cols, s1).transpose());
|
| 79 |
+
m1 = m1_copy;
|
| 80 |
+
m1.col(c1).setConstant(s1);
|
| 81 |
+
VERIFY_IS_CWISE_EQUAL(m1.col(c1), DynamicVectorType::Constant(rows, s1));
|
| 82 |
+
m1 = m1_copy;
|
| 83 |
+
// test setZero logic with innerpanel and non-innerpanel blocks
|
| 84 |
+
m1.row(r1).setZero();
|
| 85 |
+
VERIFY_IS_CWISE_EQUAL(m1.row(r1), DynamicVectorType::Zero(cols).transpose());
|
| 86 |
+
m1 = m1_copy;
|
| 87 |
+
m1.col(c1).setZero();
|
| 88 |
+
VERIFY_IS_CWISE_EQUAL(m1.col(c1), DynamicVectorType::Zero(rows));
|
| 89 |
+
m1 = m1_copy;
|
| 90 |
+
|
| 91 |
+
// check row() and col()
|
| 92 |
+
VERIFY_IS_EQUAL(m1.col(c1).transpose(), m1.transpose().row(c1));
|
| 93 |
+
// check operator(), both constant and non-constant, on row() and col()
|
| 94 |
+
m1 = m1_copy;
|
| 95 |
+
m1.row(r1) += s1 * m1_copy.row(r2);
|
| 96 |
+
VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + s1 * m1_copy.row(r2));
|
| 97 |
+
// check nested block xpr on lhs
|
| 98 |
+
m1.row(r1).row(0) += s1 * m1_copy.row(r2);
|
| 99 |
+
VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + Scalar(2) * s1 * m1_copy.row(r2));
|
| 100 |
+
m1 = m1_copy;
|
| 101 |
+
m1.col(c1) += s1 * m1_copy.col(c2);
|
| 102 |
+
VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + s1 * m1_copy.col(c2));
|
| 103 |
+
m1.col(c1).col(0) += s1 * m1_copy.col(c2);
|
| 104 |
+
VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + Scalar(2) * s1 * m1_copy.col(c2));
|
| 105 |
+
|
| 106 |
+
check_left_top(m1, r1, c1, rows, cols);
|
| 107 |
+
|
| 108 |
+
// check block()
|
| 109 |
+
Matrix<Scalar, Dynamic, Dynamic> b1(1, 1);
|
| 110 |
+
b1(0, 0) = m1(r1, c1);
|
| 111 |
+
|
| 112 |
+
RowVectorType br1(m1.block(r1, 0, 1, cols));
|
| 113 |
+
VectorType bc1(m1.block(0, c1, rows, 1));
|
| 114 |
+
VERIFY_IS_EQUAL(b1, m1.block(r1, c1, 1, 1));
|
| 115 |
+
VERIFY_IS_EQUAL(m1.row(r1), br1);
|
| 116 |
+
VERIFY_IS_EQUAL(m1.col(c1), bc1);
|
| 117 |
+
// check operator(), both constant and non-constant, on block()
|
| 118 |
+
m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1) = s1 * m2.block(0, 0, r2 - r1 + 1, c2 - c1 + 1);
|
| 119 |
+
m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1)(r2 - r1, c2 - c1) = m2.block(0, 0, r2 - r1 + 1, c2 - c1 + 1)(0, 0);
|
| 120 |
+
|
| 121 |
+
const Index BlockRows = 2;
|
| 122 |
+
const Index BlockCols = 5;
|
| 123 |
+
|
| 124 |
+
if (rows >= 5 && cols >= 8) {
|
| 125 |
+
// test fixed block() as lvalue
|
| 126 |
+
m1.template block<BlockRows, BlockCols>(1, 1) *= s1;
|
| 127 |
+
// test operator() on fixed block() both as constant and non-constant
|
| 128 |
+
m1.template block<BlockRows, BlockCols>(1, 1)(0, 3) = m1.template block<2, 5>(1, 1)(1, 2);
|
| 129 |
+
// check that fixed block() and block() agree
|
| 130 |
+
Matrix<Scalar, Dynamic, Dynamic> b = m1.template block<BlockRows, BlockCols>(3, 3);
|
| 131 |
+
VERIFY_IS_EQUAL(b, m1.block(3, 3, BlockRows, BlockCols));
|
| 132 |
+
|
| 133 |
+
// same tests with mixed fixed/dynamic size
|
| 134 |
+
m1.template block<BlockRows, Dynamic>(1, 1, BlockRows, BlockCols) *= s1;
|
| 135 |
+
m1.template block<BlockRows, Dynamic>(1, 1, BlockRows, BlockCols)(0, 3) = m1.template block<2, 5>(1, 1)(1, 2);
|
| 136 |
+
Matrix<Scalar, Dynamic, Dynamic> b2 = m1.template block<Dynamic, BlockCols>(3, 3, 2, 5);
|
| 137 |
+
VERIFY_IS_EQUAL(b2, m1.block(3, 3, BlockRows, BlockCols));
|
| 138 |
+
|
| 139 |
+
VERIFY(is_same_block(m1.block(3, 3, BlockRows, BlockCols),
|
| 140 |
+
m1.block(3, 3, fix<Dynamic>(BlockRows), fix<Dynamic>(BlockCols))));
|
| 141 |
+
VERIFY(is_same_block(m1.template block<BlockRows, Dynamic>(1, 1, BlockRows, BlockCols),
|
| 142 |
+
m1.block(1, 1, fix<BlockRows>, BlockCols)));
|
| 143 |
+
VERIFY(is_same_block(m1.template block<BlockRows, BlockCols>(1, 1, BlockRows, BlockCols),
|
| 144 |
+
m1.block(1, 1, fix<BlockRows>(), fix<BlockCols>)));
|
| 145 |
+
VERIFY(is_same_block(m1.template block<BlockRows, BlockCols>(1, 1, BlockRows, BlockCols),
|
| 146 |
+
m1.block(1, 1, fix<BlockRows>, fix<BlockCols>(BlockCols))));
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
if (rows > 2) {
|
| 150 |
+
// test sub vectors
|
| 151 |
+
VERIFY_IS_EQUAL(v1.template head<2>(), v1.block(0, 0, 2, 1));
|
| 152 |
+
VERIFY_IS_EQUAL(v1.template head<2>(), v1.head(2));
|
| 153 |
+
VERIFY_IS_EQUAL(v1.template head<2>(), v1.segment(0, 2));
|
| 154 |
+
VERIFY_IS_EQUAL(v1.template head<2>(), v1.template segment<2>(0));
|
| 155 |
+
Index i = rows - 2;
|
| 156 |
+
VERIFY_IS_EQUAL(v1.template tail<2>(), v1.block(i, 0, 2, 1));
|
| 157 |
+
VERIFY_IS_EQUAL(v1.template tail<2>(), v1.tail(2));
|
| 158 |
+
VERIFY_IS_EQUAL(v1.template tail<2>(), v1.segment(i, 2));
|
| 159 |
+
VERIFY_IS_EQUAL(v1.template tail<2>(), v1.template segment<2>(i));
|
| 160 |
+
i = internal::random<Index>(0, rows - 2);
|
| 161 |
+
VERIFY_IS_EQUAL(v1.segment(i, 2), v1.template segment<2>(i));
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
// stress some basic stuffs with block matrices
|
| 165 |
+
VERIFY_IS_EQUAL(numext::real(ones.col(c1).sum()), RealScalar(rows));
|
| 166 |
+
VERIFY_IS_EQUAL(numext::real(ones.row(r1).sum()), RealScalar(cols));
|
| 167 |
+
|
| 168 |
+
VERIFY_IS_EQUAL(numext::real(ones.col(c1).dot(ones.col(c2))), RealScalar(rows));
|
| 169 |
+
VERIFY_IS_EQUAL(numext::real(ones.row(r1).dot(ones.row(r2))), RealScalar(cols));
|
| 170 |
+
|
| 171 |
+
// check that linear accessors works on blocks
|
| 172 |
+
m1 = m1_copy;
|
| 173 |
+
|
| 174 |
+
// now test some block-inside-of-block.
|
| 175 |
+
|
| 176 |
+
// expressions with direct access
|
| 177 |
+
VERIFY_IS_EQUAL((m1.block(r1, c1, rows - r1, cols - c1).block(r2 - r1, c2 - c1, rows - r2, cols - c2)),
|
| 178 |
+
(m1.block(r2, c2, rows - r2, cols - c2)));
|
| 179 |
+
VERIFY_IS_EQUAL((m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).row(0)), (m1.row(r1).segment(c1, c2 - c1 + 1)));
|
| 180 |
+
VERIFY_IS_EQUAL((m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).col(0)), (m1.col(c1).segment(r1, r2 - r1 + 1)));
|
| 181 |
+
VERIFY_IS_EQUAL((m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).transpose().col(0)),
|
| 182 |
+
(m1.row(r1).segment(c1, c2 - c1 + 1)).transpose());
|
| 183 |
+
VERIFY_IS_EQUAL((m1.transpose().block(c1, r1, c2 - c1 + 1, r2 - r1 + 1).col(0)),
|
| 184 |
+
(m1.row(r1).segment(c1, c2 - c1 + 1)).transpose());
|
| 185 |
+
|
| 186 |
+
// expressions without direct access
|
| 187 |
+
VERIFY_IS_APPROX(((m1 + m2).block(r1, c1, rows - r1, cols - c1).block(r2 - r1, c2 - c1, rows - r2, cols - c2)),
|
| 188 |
+
((m1 + m2).block(r2, c2, rows - r2, cols - c2)));
|
| 189 |
+
VERIFY_IS_APPROX(((m1 + m2).block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).row(0)),
|
| 190 |
+
((m1 + m2).row(r1).segment(c1, c2 - c1 + 1)));
|
| 191 |
+
VERIFY_IS_APPROX(((m1 + m2).block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).row(0)),
|
| 192 |
+
((m1 + m2).eval().row(r1).segment(c1, c2 - c1 + 1)));
|
| 193 |
+
VERIFY_IS_APPROX(((m1 + m2).block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).col(0)),
|
| 194 |
+
((m1 + m2).col(c1).segment(r1, r2 - r1 + 1)));
|
| 195 |
+
VERIFY_IS_APPROX(((m1 + m2).block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).transpose().col(0)),
|
| 196 |
+
((m1 + m2).row(r1).segment(c1, c2 - c1 + 1)).transpose());
|
| 197 |
+
VERIFY_IS_APPROX(((m1 + m2).transpose().block(c1, r1, c2 - c1 + 1, r2 - r1 + 1).col(0)),
|
| 198 |
+
((m1 + m2).row(r1).segment(c1, c2 - c1 + 1)).transpose());
|
| 199 |
+
VERIFY_IS_APPROX(((m1 + m2).template block<Dynamic, 1>(r1, c1, r2 - r1 + 1, 1)),
|
| 200 |
+
((m1 + m2).eval().col(c1).eval().segment(r1, r2 - r1 + 1)));
|
| 201 |
+
VERIFY_IS_APPROX(((m1 + m2).template block<1, Dynamic>(r1, c1, 1, c2 - c1 + 1)),
|
| 202 |
+
((m1 + m2).eval().row(r1).eval().segment(c1, c2 - c1 + 1)));
|
| 203 |
+
VERIFY_IS_APPROX(((m1 + m2).transpose().template block<1, Dynamic>(c1, r1, 1, r2 - r1 + 1)),
|
| 204 |
+
((m1 + m2).eval().col(c1).eval().segment(r1, r2 - r1 + 1)).transpose());
|
| 205 |
+
VERIFY_IS_APPROX((m1 + m2).row(r1).eval(), (m1 + m2).eval().row(r1));
|
| 206 |
+
VERIFY_IS_APPROX((m1 + m2).adjoint().col(r1).eval(), (m1 + m2).adjoint().eval().col(r1));
|
| 207 |
+
VERIFY_IS_APPROX((m1 + m2).adjoint().row(c1).eval(), (m1 + m2).adjoint().eval().row(c1));
|
| 208 |
+
VERIFY_IS_APPROX((m1 * 1).row(r1).segment(c1, c2 - c1 + 1).eval(), m1.row(r1).eval().segment(c1, c2 - c1 + 1).eval());
|
| 209 |
+
VERIFY_IS_APPROX(m1.col(c1).reverse().segment(r1, r2 - r1 + 1).eval(),
|
| 210 |
+
m1.col(c1).reverse().eval().segment(r1, r2 - r1 + 1).eval());
|
| 211 |
+
|
| 212 |
+
VERIFY_IS_APPROX((m1 * 1).topRows(r1), m1.topRows(r1));
|
| 213 |
+
VERIFY_IS_APPROX((m1 * 1).leftCols(c1), m1.leftCols(c1));
|
| 214 |
+
VERIFY_IS_APPROX((m1 * 1).transpose().topRows(c1), m1.transpose().topRows(c1));
|
| 215 |
+
VERIFY_IS_APPROX((m1 * 1).transpose().leftCols(r1), m1.transpose().leftCols(r1));
|
| 216 |
+
VERIFY_IS_APPROX((m1 * 1).transpose().middleRows(c1, c2 - c1 + 1), m1.transpose().middleRows(c1, c2 - c1 + 1));
|
| 217 |
+
VERIFY_IS_APPROX((m1 * 1).transpose().middleCols(r1, r2 - r1 + 1), m1.transpose().middleCols(r1, r2 - r1 + 1));
|
| 218 |
+
|
| 219 |
+
// evaluation into plain matrices from expressions with direct access (stress MapBase)
|
| 220 |
+
DynamicMatrixType dm;
|
| 221 |
+
DynamicVectorType dv;
|
| 222 |
+
dm.setZero();
|
| 223 |
+
dm = m1.block(r1, c1, rows - r1, cols - c1).block(r2 - r1, c2 - c1, rows - r2, cols - c2);
|
| 224 |
+
VERIFY_IS_EQUAL(dm, (m1.block(r2, c2, rows - r2, cols - c2)));
|
| 225 |
+
dm.setZero();
|
| 226 |
+
dv.setZero();
|
| 227 |
+
dm = m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).row(0).transpose();
|
| 228 |
+
dv = m1.row(r1).segment(c1, c2 - c1 + 1);
|
| 229 |
+
VERIFY_IS_EQUAL(dv, dm);
|
| 230 |
+
dm.setZero();
|
| 231 |
+
dv.setZero();
|
| 232 |
+
dm = m1.col(c1).segment(r1, r2 - r1 + 1);
|
| 233 |
+
dv = m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).col(0);
|
| 234 |
+
VERIFY_IS_EQUAL(dv, dm);
|
| 235 |
+
dm.setZero();
|
| 236 |
+
dv.setZero();
|
| 237 |
+
dm = m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1).transpose().col(0);
|
| 238 |
+
dv = m1.row(r1).segment(c1, c2 - c1 + 1);
|
| 239 |
+
VERIFY_IS_EQUAL(dv, dm);
|
| 240 |
+
dm.setZero();
|
| 241 |
+
dv.setZero();
|
| 242 |
+
dm = m1.row(r1).segment(c1, c2 - c1 + 1).transpose();
|
| 243 |
+
dv = m1.transpose().block(c1, r1, c2 - c1 + 1, r2 - r1 + 1).col(0);
|
| 244 |
+
VERIFY_IS_EQUAL(dv, dm);
|
| 245 |
+
|
| 246 |
+
VERIFY_IS_EQUAL((m1.template block<Dynamic, 1>(1, 0, 0, 1)), m1.block(1, 0, 0, 1));
|
| 247 |
+
VERIFY_IS_EQUAL((m1.template block<1, Dynamic>(0, 1, 1, 0)), m1.block(0, 1, 1, 0));
|
| 248 |
+
VERIFY_IS_EQUAL(((m1 * 1).template block<Dynamic, 1>(1, 0, 0, 1)), m1.block(1, 0, 0, 1));
|
| 249 |
+
VERIFY_IS_EQUAL(((m1 * 1).template block<1, Dynamic>(0, 1, 1, 0)), m1.block(0, 1, 1, 0));
|
| 250 |
+
|
| 251 |
+
VERIFY_IS_EQUAL(m1.template subVector<Horizontal>(r1), m1.row(r1));
|
| 252 |
+
VERIFY_IS_APPROX((m1 + m1).template subVector<Horizontal>(r1), (m1 + m1).row(r1));
|
| 253 |
+
VERIFY_IS_EQUAL(m1.template subVector<Vertical>(c1), m1.col(c1));
|
| 254 |
+
VERIFY_IS_APPROX((m1 + m1).template subVector<Vertical>(c1), (m1 + m1).col(c1));
|
| 255 |
+
VERIFY_IS_EQUAL(m1.template subVectors<Horizontal>(), m1.rows());
|
| 256 |
+
VERIFY_IS_EQUAL(m1.template subVectors<Vertical>(), m1.cols());
|
| 257 |
+
|
| 258 |
+
if (rows >= 2 || cols >= 2) {
|
| 259 |
+
VERIFY_IS_EQUAL(int(m1.middleCols(0, 0).IsRowMajor), int(m1.IsRowMajor));
|
| 260 |
+
VERIFY_IS_EQUAL(m1.middleCols(0, 0).outerSize(), m1.IsRowMajor ? rows : 0);
|
| 261 |
+
VERIFY_IS_EQUAL(m1.middleCols(0, 0).innerSize(), m1.IsRowMajor ? 0 : rows);
|
| 262 |
+
|
| 263 |
+
VERIFY_IS_EQUAL(int(m1.middleRows(0, 0).IsRowMajor), int(m1.IsRowMajor));
|
| 264 |
+
VERIFY_IS_EQUAL(m1.middleRows(0, 0).outerSize(), m1.IsRowMajor ? 0 : cols);
|
| 265 |
+
VERIFY_IS_EQUAL(m1.middleRows(0, 0).innerSize(), m1.IsRowMajor ? cols : 0);
|
| 266 |
+
}
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
template <typename MatrixType>
|
| 270 |
+
std::enable_if_t<MatrixType::IsVectorAtCompileTime, void> compare_using_data_and_stride(const MatrixType& m) {
|
| 271 |
+
Index rows = m.rows();
|
| 272 |
+
Index cols = m.cols();
|
| 273 |
+
Index size = m.size();
|
| 274 |
+
Index innerStride = m.innerStride();
|
| 275 |
+
Index rowStride = m.rowStride();
|
| 276 |
+
Index colStride = m.colStride();
|
| 277 |
+
const typename MatrixType::Scalar* data = m.data();
|
| 278 |
+
|
| 279 |
+
for (int j = 0; j < cols; ++j)
|
| 280 |
+
for (int i = 0; i < rows; ++i) VERIFY(m.coeff(i, j) == data[i * rowStride + j * colStride]);
|
| 281 |
+
|
| 282 |
+
VERIFY(innerStride == int((&m.coeff(1)) - (&m.coeff(0))));
|
| 283 |
+
for (int i = 0; i < size; ++i) VERIFY(m.coeff(i) == data[i * innerStride]);
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
template <typename MatrixType>
|
| 287 |
+
std::enable_if_t<!MatrixType::IsVectorAtCompileTime, void> compare_using_data_and_stride(const MatrixType& m) {
|
| 288 |
+
Index rows = m.rows();
|
| 289 |
+
Index cols = m.cols();
|
| 290 |
+
Index innerStride = m.innerStride();
|
| 291 |
+
Index outerStride = m.outerStride();
|
| 292 |
+
Index rowStride = m.rowStride();
|
| 293 |
+
Index colStride = m.colStride();
|
| 294 |
+
const typename MatrixType::Scalar* data = m.data();
|
| 295 |
+
|
| 296 |
+
for (int j = 0; j < cols; ++j)
|
| 297 |
+
for (int i = 0; i < rows; ++i) VERIFY(m.coeff(i, j) == data[i * rowStride + j * colStride]);
|
| 298 |
+
|
| 299 |
+
for (int j = 0; j < cols; ++j)
|
| 300 |
+
for (int i = 0; i < rows; ++i)
|
| 301 |
+
VERIFY(m.coeff(i, j) == data[(MatrixType::Flags & RowMajorBit) ? i * outerStride + j * innerStride
|
| 302 |
+
: j * outerStride + i * innerStride]);
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
template <typename MatrixType>
|
| 306 |
+
void data_and_stride(const MatrixType& m) {
|
| 307 |
+
Index rows = m.rows();
|
| 308 |
+
Index cols = m.cols();
|
| 309 |
+
|
| 310 |
+
Index r1 = internal::random<Index>(0, rows - 1);
|
| 311 |
+
Index r2 = internal::random<Index>(r1, rows - 1);
|
| 312 |
+
Index c1 = internal::random<Index>(0, cols - 1);
|
| 313 |
+
Index c2 = internal::random<Index>(c1, cols - 1);
|
| 314 |
+
|
| 315 |
+
MatrixType m1 = MatrixType::Random(rows, cols);
|
| 316 |
+
compare_using_data_and_stride(m1.block(r1, c1, r2 - r1 + 1, c2 - c1 + 1));
|
| 317 |
+
compare_using_data_and_stride(m1.transpose().block(c1, r1, c2 - c1 + 1, r2 - r1 + 1));
|
| 318 |
+
compare_using_data_and_stride(m1.row(r1));
|
| 319 |
+
compare_using_data_and_stride(m1.col(c1));
|
| 320 |
+
compare_using_data_and_stride(m1.row(r1).transpose());
|
| 321 |
+
compare_using_data_and_stride(m1.col(c1).transpose());
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
template <typename BaseXpr, typename Xpr = BaseXpr, int Depth = 0>
|
| 325 |
+
struct unwind_test_impl {
|
| 326 |
+
static void run(Xpr& xpr) {
|
| 327 |
+
Index startRow = internal::random<Index>(0, xpr.rows() / 5);
|
| 328 |
+
Index startCol = internal::random<Index>(0, xpr.cols() / 6);
|
| 329 |
+
Index rows = xpr.rows() / 3;
|
| 330 |
+
Index cols = xpr.cols() / 2;
|
| 331 |
+
// test equivalence of const expressions
|
| 332 |
+
const Block<const Xpr> constNestedBlock(xpr, startRow, startCol, rows, cols);
|
| 333 |
+
const Block<const BaseXpr> constUnwoundBlock = constNestedBlock.unwind();
|
| 334 |
+
VERIFY_IS_CWISE_EQUAL(constNestedBlock, constUnwoundBlock);
|
| 335 |
+
// modify a random element in each representation and test equivalence of non-const expressions
|
| 336 |
+
Block<Xpr> nestedBlock(xpr, startRow, startCol, rows, cols);
|
| 337 |
+
Block<BaseXpr> unwoundBlock = nestedBlock.unwind();
|
| 338 |
+
Index r1 = internal::random<Index>(0, rows - 1);
|
| 339 |
+
Index c1 = internal::random<Index>(0, cols - 1);
|
| 340 |
+
Index r2 = internal::random<Index>(0, rows - 1);
|
| 341 |
+
Index c2 = internal::random<Index>(0, cols - 1);
|
| 342 |
+
nestedBlock.coeffRef(r1, c1) = internal::random<typename DenseBase<Xpr>::Scalar>();
|
| 343 |
+
unwoundBlock.coeffRef(r2, c2) = internal::random<typename DenseBase<Xpr>::Scalar>();
|
| 344 |
+
VERIFY_IS_CWISE_EQUAL(nestedBlock, unwoundBlock);
|
| 345 |
+
unwind_test_impl<BaseXpr, Block<Xpr>, Depth + 1>::run(nestedBlock);
|
| 346 |
+
}
|
| 347 |
+
};
|
| 348 |
+
|
| 349 |
+
template <typename BaseXpr, typename Xpr>
|
| 350 |
+
struct unwind_test_impl<BaseXpr, Xpr, 4> {
|
| 351 |
+
static void run(const Xpr&) {}
|
| 352 |
+
};
|
| 353 |
+
|
| 354 |
+
template <typename BaseXpr>
|
| 355 |
+
void unwind_test(const BaseXpr&) {
|
| 356 |
+
BaseXpr xpr = BaseXpr::Random(100, 100);
|
| 357 |
+
unwind_test_impl<BaseXpr>::run(xpr);
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
EIGEN_DECLARE_TEST(block) {
|
| 361 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 362 |
+
CALL_SUBTEST_1(block(Matrix<float, 1, 1>()));
|
| 363 |
+
CALL_SUBTEST_1(block(Matrix<float, 1, Dynamic>(internal::random(2, 50))));
|
| 364 |
+
CALL_SUBTEST_1(block(Matrix<float, Dynamic, 1>(internal::random(2, 50))));
|
| 365 |
+
CALL_SUBTEST_2(block(Matrix4d()));
|
| 366 |
+
CALL_SUBTEST_3(block(MatrixXcf(internal::random(2, 50), internal::random(2, 50))));
|
| 367 |
+
CALL_SUBTEST_4(block(MatrixXi(internal::random(2, 50), internal::random(2, 50))));
|
| 368 |
+
CALL_SUBTEST_5(block(MatrixXcd(internal::random(2, 50), internal::random(2, 50))));
|
| 369 |
+
CALL_SUBTEST_6(block(MatrixXf(internal::random(2, 50), internal::random(2, 50))));
|
| 370 |
+
CALL_SUBTEST_7(block(Matrix<int, Dynamic, Dynamic, RowMajor>(internal::random(2, 50), internal::random(2, 50))));
|
| 371 |
+
|
| 372 |
+
CALL_SUBTEST_8(block(Matrix<float, Dynamic, 4>(3, 4)));
|
| 373 |
+
CALL_SUBTEST_9(unwind_test(MatrixXf()));
|
| 374 |
+
|
| 375 |
+
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
|
| 376 |
+
CALL_SUBTEST_6(data_and_stride(MatrixXf(internal::random(5, 50), internal::random(5, 50))));
|
| 377 |
+
CALL_SUBTEST_7(
|
| 378 |
+
data_and_stride(Matrix<int, Dynamic, Dynamic, RowMajor>(internal::random(5, 50), internal::random(5, 50))));
|
| 379 |
+
#endif
|
| 380 |
+
}
|
| 381 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/boostmultiprec.cpp
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include <sstream>
|
| 11 |
+
|
| 12 |
+
#ifdef EIGEN_TEST_MAX_SIZE
|
| 13 |
+
#undef EIGEN_TEST_MAX_SIZE
|
| 14 |
+
#endif
|
| 15 |
+
|
| 16 |
+
#define EIGEN_TEST_MAX_SIZE 50
|
| 17 |
+
|
| 18 |
+
#ifdef EIGEN_TEST_PART_1
|
| 19 |
+
#include "cholesky.cpp"
|
| 20 |
+
#endif
|
| 21 |
+
|
| 22 |
+
#ifdef EIGEN_TEST_PART_2
|
| 23 |
+
#include "lu.cpp"
|
| 24 |
+
#endif
|
| 25 |
+
|
| 26 |
+
#ifdef EIGEN_TEST_PART_3
|
| 27 |
+
#include "qr.cpp"
|
| 28 |
+
#endif
|
| 29 |
+
|
| 30 |
+
#ifdef EIGEN_TEST_PART_4
|
| 31 |
+
#include "qr_colpivoting.cpp"
|
| 32 |
+
#endif
|
| 33 |
+
|
| 34 |
+
#ifdef EIGEN_TEST_PART_5
|
| 35 |
+
#include "qr_fullpivoting.cpp"
|
| 36 |
+
#endif
|
| 37 |
+
|
| 38 |
+
#ifdef EIGEN_TEST_PART_6
|
| 39 |
+
#include "eigensolver_selfadjoint.cpp"
|
| 40 |
+
#endif
|
| 41 |
+
|
| 42 |
+
#ifdef EIGEN_TEST_PART_7
|
| 43 |
+
#include "eigensolver_generic.cpp"
|
| 44 |
+
#endif
|
| 45 |
+
|
| 46 |
+
#ifdef EIGEN_TEST_PART_8
|
| 47 |
+
#include "eigensolver_generalized_real.cpp"
|
| 48 |
+
#endif
|
| 49 |
+
|
| 50 |
+
#ifdef EIGEN_TEST_PART_9
|
| 51 |
+
#include "jacobisvd.cpp"
|
| 52 |
+
#endif
|
| 53 |
+
|
| 54 |
+
#ifdef EIGEN_TEST_PART_10
|
| 55 |
+
#include "bdcsvd.cpp"
|
| 56 |
+
#endif
|
| 57 |
+
|
| 58 |
+
#ifdef EIGEN_TEST_PART_11
|
| 59 |
+
#include "simplicial_cholesky.cpp"
|
| 60 |
+
#endif
|
| 61 |
+
|
| 62 |
+
#include <Eigen/Dense>
|
| 63 |
+
|
| 64 |
+
#undef min
|
| 65 |
+
#undef max
|
| 66 |
+
#undef isnan
|
| 67 |
+
#undef isinf
|
| 68 |
+
#undef isfinite
|
| 69 |
+
#undef I
|
| 70 |
+
|
| 71 |
+
#include <boost/serialization/nvp.hpp>
|
| 72 |
+
#include <boost/multiprecision/cpp_dec_float.hpp>
|
| 73 |
+
#include <boost/multiprecision/number.hpp>
|
| 74 |
+
#include <boost/math/special_functions.hpp>
|
| 75 |
+
#include <boost/math/complex.hpp>
|
| 76 |
+
|
| 77 |
+
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<100>, boost::multiprecision::et_on> Real;
|
| 78 |
+
|
| 79 |
+
namespace Eigen {
|
| 80 |
+
template <>
|
| 81 |
+
struct NumTraits<Real> : GenericNumTraits<Real> {
|
| 82 |
+
static inline Real dummy_precision() { return 1e-50; }
|
| 83 |
+
};
|
| 84 |
+
|
| 85 |
+
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
| 86 |
+
struct NumTraits<boost::multiprecision::detail::expression<T1, T2, T3, T4, T5> > : NumTraits<Real> {};
|
| 87 |
+
|
| 88 |
+
template <>
|
| 89 |
+
Real test_precision<Real>() {
|
| 90 |
+
return 1e-50;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// needed in C++93 mode where number does not support explicit cast.
|
| 94 |
+
namespace internal {
|
| 95 |
+
template <typename NewType>
|
| 96 |
+
struct cast_impl<Real, NewType> {
|
| 97 |
+
static inline NewType run(const Real& x) { return x.template convert_to<NewType>(); }
|
| 98 |
+
};
|
| 99 |
+
|
| 100 |
+
template <>
|
| 101 |
+
struct cast_impl<Real, std::complex<Real> > {
|
| 102 |
+
static inline std::complex<Real> run(const Real& x) { return std::complex<Real>(x); }
|
| 103 |
+
};
|
| 104 |
+
} // namespace internal
|
| 105 |
+
} // namespace Eigen
|
| 106 |
+
|
| 107 |
+
namespace boost {
|
| 108 |
+
namespace multiprecision {
|
| 109 |
+
// to make ADL works as expected:
|
| 110 |
+
using boost::math::copysign;
|
| 111 |
+
using boost::math::hypot;
|
| 112 |
+
using boost::math::isfinite;
|
| 113 |
+
using boost::math::isinf;
|
| 114 |
+
using boost::math::isnan;
|
| 115 |
+
|
| 116 |
+
// The following is needed for std::complex<Real>:
|
| 117 |
+
Real fabs(const Real& a) { return abs EIGEN_NOT_A_MACRO(a); }
|
| 118 |
+
Real fmax(const Real& a, const Real& b) {
|
| 119 |
+
using std::max;
|
| 120 |
+
return max(a, b);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
// some specialization for the unit tests:
|
| 124 |
+
inline bool test_isMuchSmallerThan(const Real& a, const Real& b) {
|
| 125 |
+
return internal::isMuchSmallerThan(a, b, test_precision<Real>());
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
inline bool test_isApprox(const Real& a, const Real& b) { return internal::isApprox(a, b, test_precision<Real>()); }
|
| 129 |
+
|
| 130 |
+
inline bool test_isApproxOrLessThan(const Real& a, const Real& b) {
|
| 131 |
+
return internal::isApproxOrLessThan(a, b, test_precision<Real>());
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
Real get_test_precision(const Real&) { return test_precision<Real>(); }
|
| 135 |
+
|
| 136 |
+
Real test_relative_error(const Real& a, const Real& b) {
|
| 137 |
+
using Eigen::numext::abs2;
|
| 138 |
+
return sqrt(abs2<Real>(a - b) / Eigen::numext::mini<Real>(abs2(a), abs2(b)));
|
| 139 |
+
}
|
| 140 |
+
} // namespace multiprecision
|
| 141 |
+
} // namespace boost
|
| 142 |
+
|
| 143 |
+
namespace Eigen {}
|
| 144 |
+
|
| 145 |
+
EIGEN_DECLARE_TEST(boostmultiprec) {
|
| 146 |
+
typedef Matrix<Real, Dynamic, Dynamic> Mat;
|
| 147 |
+
typedef Matrix<std::complex<Real>, Dynamic, Dynamic> MatC;
|
| 148 |
+
|
| 149 |
+
std::cout << "NumTraits<Real>::epsilon() = " << NumTraits<Real>::epsilon() << std::endl;
|
| 150 |
+
std::cout << "NumTraits<Real>::dummy_precision() = " << NumTraits<Real>::dummy_precision() << std::endl;
|
| 151 |
+
std::cout << "NumTraits<Real>::lowest() = " << NumTraits<Real>::lowest() << std::endl;
|
| 152 |
+
std::cout << "NumTraits<Real>::highest() = " << NumTraits<Real>::highest() << std::endl;
|
| 153 |
+
std::cout << "NumTraits<Real>::digits10() = " << NumTraits<Real>::digits10() << std::endl;
|
| 154 |
+
std::cout << "NumTraits<Real>::max_digits10() = " << NumTraits<Real>::max_digits10() << std::endl;
|
| 155 |
+
|
| 156 |
+
// check stream output
|
| 157 |
+
{
|
| 158 |
+
Mat A(10, 10);
|
| 159 |
+
A.setRandom();
|
| 160 |
+
std::stringstream ss;
|
| 161 |
+
ss << A;
|
| 162 |
+
}
|
| 163 |
+
{
|
| 164 |
+
MatC A(10, 10);
|
| 165 |
+
A.setRandom();
|
| 166 |
+
std::stringstream ss;
|
| 167 |
+
ss << A;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 171 |
+
int s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE);
|
| 172 |
+
|
| 173 |
+
CALL_SUBTEST_1(cholesky(Mat(s, s)));
|
| 174 |
+
|
| 175 |
+
CALL_SUBTEST_2(lu_non_invertible<Mat>());
|
| 176 |
+
CALL_SUBTEST_2(lu_invertible<Mat>());
|
| 177 |
+
CALL_SUBTEST_2(lu_non_invertible<MatC>());
|
| 178 |
+
CALL_SUBTEST_2(lu_invertible<MatC>());
|
| 179 |
+
|
| 180 |
+
CALL_SUBTEST_3(
|
| 181 |
+
qr(Mat(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 182 |
+
CALL_SUBTEST_3(qr_invertible<Mat>());
|
| 183 |
+
|
| 184 |
+
CALL_SUBTEST_4(qr<Mat>());
|
| 185 |
+
CALL_SUBTEST_4(cod<Mat>());
|
| 186 |
+
CALL_SUBTEST_4(qr_invertible<Mat>());
|
| 187 |
+
|
| 188 |
+
CALL_SUBTEST_5(qr<Mat>());
|
| 189 |
+
CALL_SUBTEST_5(qr_invertible<Mat>());
|
| 190 |
+
|
| 191 |
+
CALL_SUBTEST_6(selfadjointeigensolver(Mat(s, s)));
|
| 192 |
+
|
| 193 |
+
CALL_SUBTEST_7(eigensolver(Mat(s, s)));
|
| 194 |
+
|
| 195 |
+
CALL_SUBTEST_8(generalized_eigensolver_real(Mat(s, s)));
|
| 196 |
+
|
| 197 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
CALL_SUBTEST_9(
|
| 201 |
+
(jacobisvd_thin_options(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE),
|
| 202 |
+
internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE / 2)))));
|
| 203 |
+
CALL_SUBTEST_9(
|
| 204 |
+
(jacobisvd_full_options(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE),
|
| 205 |
+
internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE / 2)))));
|
| 206 |
+
CALL_SUBTEST_10((bdcsvd_thin_options(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE),
|
| 207 |
+
internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE / 2)))));
|
| 208 |
+
CALL_SUBTEST_10((bdcsvd_full_options(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE),
|
| 209 |
+
internal::random<int>(EIGEN_TEST_MAX_SIZE / 4, EIGEN_TEST_MAX_SIZE / 2)))));
|
| 210 |
+
|
| 211 |
+
CALL_SUBTEST_11((test_simplicial_cholesky_T<Real, int, ColMajor>()));
|
| 212 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bug1213.cpp
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
// This anonymous enum is essential to trigger the linking issue
|
| 3 |
+
enum { Foo };
|
| 4 |
+
|
| 5 |
+
#include "bug1213.h"
|
| 6 |
+
|
| 7 |
+
bool bug1213_1(const Eigen::Vector3f& x) { return bug1213_2(x); }
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bug1213.h
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
#include <Eigen/Core>
|
| 3 |
+
|
| 4 |
+
template <typename T, int dim>
|
| 5 |
+
bool bug1213_2(const Eigen::Matrix<T, dim, 1>& x);
|
| 6 |
+
|
| 7 |
+
bool bug1213_1(const Eigen::Vector3f& x);
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/bug1213_main.cpp
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
// This is a regression unit regarding a weird linking issue with gcc.
|
| 3 |
+
|
| 4 |
+
#include "bug1213.h"
|
| 5 |
+
|
| 6 |
+
int main() { return 0; }
|
| 7 |
+
|
| 8 |
+
template <typename T, int dim>
|
| 9 |
+
bool bug1213_2(const Eigen::Matrix<T, dim, 1>&) {
|
| 10 |
+
return true;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
template bool bug1213_2<float, 3>(const Eigen::Vector3f&);
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/cholesky.cpp
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 TEST_ENABLE_TEMPORARY_TRACKING
|
| 11 |
+
|
| 12 |
+
#include "main.h"
|
| 13 |
+
#include <Eigen/Cholesky>
|
| 14 |
+
#include <Eigen/QR>
|
| 15 |
+
#include "solverbase.h"
|
| 16 |
+
|
| 17 |
+
template <typename MatrixType, int UpLo>
|
| 18 |
+
typename MatrixType::RealScalar matrix_l1_norm(const MatrixType& m) {
|
| 19 |
+
if (m.cols() == 0) return typename MatrixType::RealScalar(0);
|
| 20 |
+
MatrixType symm = m.template selfadjointView<UpLo>();
|
| 21 |
+
return symm.cwiseAbs().colwise().sum().maxCoeff();
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
template <typename MatrixType, template <typename, int> class CholType>
|
| 25 |
+
void test_chol_update(const MatrixType& symm) {
|
| 26 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 27 |
+
typedef typename MatrixType::RealScalar RealScalar;
|
| 28 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 29 |
+
|
| 30 |
+
MatrixType symmLo = symm.template triangularView<Lower>();
|
| 31 |
+
MatrixType symmUp = symm.template triangularView<Upper>();
|
| 32 |
+
MatrixType symmCpy = symm;
|
| 33 |
+
|
| 34 |
+
CholType<MatrixType, Lower> chollo(symmLo);
|
| 35 |
+
CholType<MatrixType, Upper> cholup(symmUp);
|
| 36 |
+
|
| 37 |
+
for (int k = 0; k < 10; ++k) {
|
| 38 |
+
VectorType vec = VectorType::Random(symm.rows());
|
| 39 |
+
RealScalar sigma = internal::random<RealScalar>();
|
| 40 |
+
symmCpy += sigma * vec * vec.adjoint();
|
| 41 |
+
|
| 42 |
+
// we are doing some downdates, so it might be the case that the matrix is not SPD anymore
|
| 43 |
+
CholType<MatrixType, Lower> chol(symmCpy);
|
| 44 |
+
if (chol.info() != Success) break;
|
| 45 |
+
|
| 46 |
+
chollo.rankUpdate(vec, sigma);
|
| 47 |
+
VERIFY_IS_APPROX(symmCpy, chollo.reconstructedMatrix());
|
| 48 |
+
|
| 49 |
+
cholup.rankUpdate(vec, sigma);
|
| 50 |
+
VERIFY_IS_APPROX(symmCpy, cholup.reconstructedMatrix());
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
template <typename MatrixType>
|
| 55 |
+
void cholesky(const MatrixType& m) {
|
| 56 |
+
/* this test covers the following files:
|
| 57 |
+
LLT.h LDLT.h
|
| 58 |
+
*/
|
| 59 |
+
Index rows = m.rows();
|
| 60 |
+
Index cols = m.cols();
|
| 61 |
+
|
| 62 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 63 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 64 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
|
| 65 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 66 |
+
|
| 67 |
+
MatrixType a0 = MatrixType::Random(rows, cols);
|
| 68 |
+
VectorType vecB = VectorType::Random(rows), vecX(rows);
|
| 69 |
+
MatrixType matB = MatrixType::Random(rows, cols), matX(rows, cols);
|
| 70 |
+
SquareMatrixType symm = a0 * a0.adjoint();
|
| 71 |
+
// let's make sure the matrix is not singular or near singular
|
| 72 |
+
for (int k = 0; k < 3; ++k) {
|
| 73 |
+
MatrixType a1 = MatrixType::Random(rows, cols);
|
| 74 |
+
symm += a1 * a1.adjoint();
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
{
|
| 78 |
+
STATIC_CHECK((internal::is_same<typename LLT<MatrixType, Lower>::StorageIndex, int>::value));
|
| 79 |
+
STATIC_CHECK((internal::is_same<typename LLT<MatrixType, Upper>::StorageIndex, int>::value));
|
| 80 |
+
|
| 81 |
+
SquareMatrixType symmUp = symm.template triangularView<Upper>();
|
| 82 |
+
SquareMatrixType symmLo = symm.template triangularView<Lower>();
|
| 83 |
+
|
| 84 |
+
LLT<SquareMatrixType, Lower> chollo(symmLo);
|
| 85 |
+
VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
|
| 86 |
+
|
| 87 |
+
check_solverbase<VectorType, VectorType>(symm, chollo, rows, rows, 1);
|
| 88 |
+
check_solverbase<MatrixType, MatrixType>(symm, chollo, rows, cols, rows);
|
| 89 |
+
|
| 90 |
+
const MatrixType symmLo_inverse = chollo.solve(MatrixType::Identity(rows, cols));
|
| 91 |
+
RealScalar rcond =
|
| 92 |
+
(RealScalar(1) / matrix_l1_norm<MatrixType, Lower>(symmLo)) / matrix_l1_norm<MatrixType, Lower>(symmLo_inverse);
|
| 93 |
+
RealScalar rcond_est = chollo.rcond();
|
| 94 |
+
// Verify that the estimated condition number is within a factor of 10 of the
|
| 95 |
+
// truth.
|
| 96 |
+
VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
|
| 97 |
+
|
| 98 |
+
// test the upper mode
|
| 99 |
+
LLT<SquareMatrixType, Upper> cholup(symmUp);
|
| 100 |
+
VERIFY_IS_APPROX(symm, cholup.reconstructedMatrix());
|
| 101 |
+
vecX = cholup.solve(vecB);
|
| 102 |
+
VERIFY_IS_APPROX(symm * vecX, vecB);
|
| 103 |
+
matX = cholup.solve(matB);
|
| 104 |
+
VERIFY_IS_APPROX(symm * matX, matB);
|
| 105 |
+
|
| 106 |
+
// Verify that the estimated condition number is within a factor of 10 of the
|
| 107 |
+
// truth.
|
| 108 |
+
const MatrixType symmUp_inverse = cholup.solve(MatrixType::Identity(rows, cols));
|
| 109 |
+
rcond =
|
| 110 |
+
(RealScalar(1) / matrix_l1_norm<MatrixType, Upper>(symmUp)) / matrix_l1_norm<MatrixType, Upper>(symmUp_inverse);
|
| 111 |
+
rcond_est = cholup.rcond();
|
| 112 |
+
VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
|
| 113 |
+
|
| 114 |
+
MatrixType neg = -symmLo;
|
| 115 |
+
chollo.compute(neg);
|
| 116 |
+
VERIFY(neg.size() == 0 || chollo.info() == NumericalIssue);
|
| 117 |
+
|
| 118 |
+
VERIFY_IS_APPROX(MatrixType(chollo.matrixL().transpose().conjugate()), MatrixType(chollo.matrixU()));
|
| 119 |
+
VERIFY_IS_APPROX(MatrixType(chollo.matrixU().transpose().conjugate()), MatrixType(chollo.matrixL()));
|
| 120 |
+
VERIFY_IS_APPROX(MatrixType(cholup.matrixL().transpose().conjugate()), MatrixType(cholup.matrixU()));
|
| 121 |
+
VERIFY_IS_APPROX(MatrixType(cholup.matrixU().transpose().conjugate()), MatrixType(cholup.matrixL()));
|
| 122 |
+
|
| 123 |
+
// test some special use cases of SelfCwiseBinaryOp:
|
| 124 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2(rows, cols);
|
| 125 |
+
m2 = m1;
|
| 126 |
+
m2 += symmLo.template selfadjointView<Lower>().llt().solve(matB);
|
| 127 |
+
VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
|
| 128 |
+
m2 = m1;
|
| 129 |
+
m2 -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
|
| 130 |
+
VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
|
| 131 |
+
m2 = m1;
|
| 132 |
+
m2.noalias() += symmLo.template selfadjointView<Lower>().llt().solve(matB);
|
| 133 |
+
VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));
|
| 134 |
+
m2 = m1;
|
| 135 |
+
m2.noalias() -= symmLo.template selfadjointView<Lower>().llt().solve(matB);
|
| 136 |
+
VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
// LDLT
|
| 140 |
+
{
|
| 141 |
+
STATIC_CHECK((internal::is_same<typename LDLT<MatrixType, Lower>::StorageIndex, int>::value));
|
| 142 |
+
STATIC_CHECK((internal::is_same<typename LDLT<MatrixType, Upper>::StorageIndex, int>::value));
|
| 143 |
+
|
| 144 |
+
int sign = internal::random<int>() % 2 ? 1 : -1;
|
| 145 |
+
|
| 146 |
+
if (sign == -1) {
|
| 147 |
+
symm = -symm; // test a negative matrix
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
SquareMatrixType symmUp = symm.template triangularView<Upper>();
|
| 151 |
+
SquareMatrixType symmLo = symm.template triangularView<Lower>();
|
| 152 |
+
|
| 153 |
+
LDLT<SquareMatrixType, Lower> ldltlo(symmLo);
|
| 154 |
+
VERIFY(ldltlo.info() == Success);
|
| 155 |
+
VERIFY_IS_APPROX(symm, ldltlo.reconstructedMatrix());
|
| 156 |
+
|
| 157 |
+
check_solverbase<VectorType, VectorType>(symm, ldltlo, rows, rows, 1);
|
| 158 |
+
check_solverbase<MatrixType, MatrixType>(symm, ldltlo, rows, cols, rows);
|
| 159 |
+
|
| 160 |
+
const MatrixType symmLo_inverse = ldltlo.solve(MatrixType::Identity(rows, cols));
|
| 161 |
+
RealScalar rcond =
|
| 162 |
+
(RealScalar(1) / matrix_l1_norm<MatrixType, Lower>(symmLo)) / matrix_l1_norm<MatrixType, Lower>(symmLo_inverse);
|
| 163 |
+
RealScalar rcond_est = ldltlo.rcond();
|
| 164 |
+
// Verify that the estimated condition number is within a factor of 10 of the
|
| 165 |
+
// truth.
|
| 166 |
+
VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
|
| 167 |
+
|
| 168 |
+
LDLT<SquareMatrixType, Upper> ldltup(symmUp);
|
| 169 |
+
VERIFY(ldltup.info() == Success);
|
| 170 |
+
VERIFY_IS_APPROX(symm, ldltup.reconstructedMatrix());
|
| 171 |
+
vecX = ldltup.solve(vecB);
|
| 172 |
+
VERIFY_IS_APPROX(symm * vecX, vecB);
|
| 173 |
+
matX = ldltup.solve(matB);
|
| 174 |
+
VERIFY_IS_APPROX(symm * matX, matB);
|
| 175 |
+
|
| 176 |
+
// Verify that the estimated condition number is within a factor of 10 of the
|
| 177 |
+
// truth.
|
| 178 |
+
const MatrixType symmUp_inverse = ldltup.solve(MatrixType::Identity(rows, cols));
|
| 179 |
+
rcond =
|
| 180 |
+
(RealScalar(1) / matrix_l1_norm<MatrixType, Upper>(symmUp)) / matrix_l1_norm<MatrixType, Upper>(symmUp_inverse);
|
| 181 |
+
rcond_est = ldltup.rcond();
|
| 182 |
+
VERIFY(rcond_est >= rcond / 10 && rcond_est <= rcond * 10);
|
| 183 |
+
|
| 184 |
+
VERIFY_IS_APPROX(MatrixType(ldltlo.matrixL().transpose().conjugate()), MatrixType(ldltlo.matrixU()));
|
| 185 |
+
VERIFY_IS_APPROX(MatrixType(ldltlo.matrixU().transpose().conjugate()), MatrixType(ldltlo.matrixL()));
|
| 186 |
+
VERIFY_IS_APPROX(MatrixType(ldltup.matrixL().transpose().conjugate()), MatrixType(ldltup.matrixU()));
|
| 187 |
+
VERIFY_IS_APPROX(MatrixType(ldltup.matrixU().transpose().conjugate()), MatrixType(ldltup.matrixL()));
|
| 188 |
+
|
| 189 |
+
if (MatrixType::RowsAtCompileTime == Dynamic) {
|
| 190 |
+
// note : each inplace permutation requires a small temporary vector (mask)
|
| 191 |
+
|
| 192 |
+
// check inplace solve
|
| 193 |
+
matX = matB;
|
| 194 |
+
VERIFY_EVALUATION_COUNT(matX = ldltlo.solve(matX), 0);
|
| 195 |
+
VERIFY_IS_APPROX(matX, ldltlo.solve(matB).eval());
|
| 196 |
+
|
| 197 |
+
matX = matB;
|
| 198 |
+
VERIFY_EVALUATION_COUNT(matX = ldltup.solve(matX), 0);
|
| 199 |
+
VERIFY_IS_APPROX(matX, ldltup.solve(matB).eval());
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
// restore
|
| 203 |
+
if (sign == -1) symm = -symm;
|
| 204 |
+
|
| 205 |
+
// check matrices coming from linear constraints with Lagrange multipliers
|
| 206 |
+
if (rows >= 3) {
|
| 207 |
+
SquareMatrixType A = symm;
|
| 208 |
+
Index c = internal::random<Index>(0, rows - 2);
|
| 209 |
+
A.bottomRightCorner(c, c).setZero();
|
| 210 |
+
// Make sure a solution exists:
|
| 211 |
+
vecX.setRandom();
|
| 212 |
+
vecB = A * vecX;
|
| 213 |
+
vecX.setZero();
|
| 214 |
+
ldltlo.compute(A);
|
| 215 |
+
VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());
|
| 216 |
+
vecX = ldltlo.solve(vecB);
|
| 217 |
+
VERIFY_IS_APPROX(A * vecX, vecB);
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
// check non-full rank matrices
|
| 221 |
+
if (rows >= 3) {
|
| 222 |
+
Index r = internal::random<Index>(1, rows - 1);
|
| 223 |
+
Matrix<Scalar, Dynamic, Dynamic> a = Matrix<Scalar, Dynamic, Dynamic>::Random(rows, r);
|
| 224 |
+
SquareMatrixType A = a * a.adjoint();
|
| 225 |
+
// Make sure a solution exists:
|
| 226 |
+
vecX.setRandom();
|
| 227 |
+
vecB = A * vecX;
|
| 228 |
+
vecX.setZero();
|
| 229 |
+
ldltlo.compute(A);
|
| 230 |
+
VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());
|
| 231 |
+
vecX = ldltlo.solve(vecB);
|
| 232 |
+
VERIFY_IS_APPROX(A * vecX, vecB);
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
// check matrices with a wide spectrum
|
| 236 |
+
if (rows >= 3) {
|
| 237 |
+
using std::pow;
|
| 238 |
+
using std::sqrt;
|
| 239 |
+
RealScalar s = (std::min)(16, std::numeric_limits<RealScalar>::max_exponent10 / 8);
|
| 240 |
+
Matrix<Scalar, Dynamic, Dynamic> a = Matrix<Scalar, Dynamic, Dynamic>::Random(rows, rows);
|
| 241 |
+
Matrix<RealScalar, Dynamic, 1> d = Matrix<RealScalar, Dynamic, 1>::Random(rows);
|
| 242 |
+
for (Index k = 0; k < rows; ++k) d(k) = d(k) * pow(RealScalar(10), internal::random<RealScalar>(-s, s));
|
| 243 |
+
SquareMatrixType A = a * d.asDiagonal() * a.adjoint();
|
| 244 |
+
// Make sure a solution exists:
|
| 245 |
+
vecX.setRandom();
|
| 246 |
+
vecB = A * vecX;
|
| 247 |
+
vecX.setZero();
|
| 248 |
+
ldltlo.compute(A);
|
| 249 |
+
VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());
|
| 250 |
+
vecX = ldltlo.solve(vecB);
|
| 251 |
+
|
| 252 |
+
if (ldltlo.vectorD().real().cwiseAbs().minCoeff() > RealScalar(0)) {
|
| 253 |
+
VERIFY_IS_APPROX(A * vecX, vecB);
|
| 254 |
+
} else {
|
| 255 |
+
RealScalar large_tol = sqrt(test_precision<RealScalar>());
|
| 256 |
+
VERIFY((A * vecX).isApprox(vecB, large_tol));
|
| 257 |
+
|
| 258 |
+
++g_test_level;
|
| 259 |
+
VERIFY_IS_APPROX(A * vecX, vecB);
|
| 260 |
+
--g_test_level;
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
// update/downdate
|
| 266 |
+
CALL_SUBTEST((test_chol_update<SquareMatrixType, LLT>(symm)));
|
| 267 |
+
CALL_SUBTEST((test_chol_update<SquareMatrixType, LDLT>(symm)));
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
template <typename MatrixType>
|
| 271 |
+
void cholesky_cplx(const MatrixType& m) {
|
| 272 |
+
// classic test
|
| 273 |
+
cholesky(m);
|
| 274 |
+
|
| 275 |
+
// test mixing real/scalar types
|
| 276 |
+
|
| 277 |
+
Index rows = m.rows();
|
| 278 |
+
Index cols = m.cols();
|
| 279 |
+
|
| 280 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 281 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 282 |
+
typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RealMatrixType;
|
| 283 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 284 |
+
|
| 285 |
+
RealMatrixType a0 = RealMatrixType::Random(rows, cols);
|
| 286 |
+
VectorType vecB = VectorType::Random(rows), vecX(rows);
|
| 287 |
+
MatrixType matB = MatrixType::Random(rows, cols), matX(rows, cols);
|
| 288 |
+
RealMatrixType symm = a0 * a0.adjoint();
|
| 289 |
+
// let's make sure the matrix is not singular or near singular
|
| 290 |
+
for (int k = 0; k < 3; ++k) {
|
| 291 |
+
RealMatrixType a1 = RealMatrixType::Random(rows, cols);
|
| 292 |
+
symm += a1 * a1.adjoint();
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
{
|
| 296 |
+
RealMatrixType symmLo = symm.template triangularView<Lower>();
|
| 297 |
+
|
| 298 |
+
LLT<RealMatrixType, Lower> chollo(symmLo);
|
| 299 |
+
VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
|
| 300 |
+
|
| 301 |
+
check_solverbase<VectorType, VectorType>(symm, chollo, rows, rows, 1);
|
| 302 |
+
// check_solverbase<MatrixType, MatrixType>(symm, chollo, rows, cols, rows);
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
// LDLT
|
| 306 |
+
{
|
| 307 |
+
int sign = internal::random<int>() % 2 ? 1 : -1;
|
| 308 |
+
|
| 309 |
+
if (sign == -1) {
|
| 310 |
+
symm = -symm; // test a negative matrix
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
RealMatrixType symmLo = symm.template triangularView<Lower>();
|
| 314 |
+
|
| 315 |
+
LDLT<RealMatrixType, Lower> ldltlo(symmLo);
|
| 316 |
+
VERIFY(ldltlo.info() == Success);
|
| 317 |
+
VERIFY_IS_APPROX(symm, ldltlo.reconstructedMatrix());
|
| 318 |
+
|
| 319 |
+
check_solverbase<VectorType, VectorType>(symm, ldltlo, rows, rows, 1);
|
| 320 |
+
// check_solverbase<MatrixType, MatrixType>(symm, ldltlo, rows, cols, rows);
|
| 321 |
+
}
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
// regression test for bug 241
|
| 325 |
+
template <typename MatrixType>
|
| 326 |
+
void cholesky_bug241(const MatrixType& m) {
|
| 327 |
+
eigen_assert(m.rows() == 2 && m.cols() == 2);
|
| 328 |
+
|
| 329 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 330 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 331 |
+
|
| 332 |
+
MatrixType matA;
|
| 333 |
+
matA << 1, 1, 1, 1;
|
| 334 |
+
VectorType vecB;
|
| 335 |
+
vecB << 1, 1;
|
| 336 |
+
VectorType vecX = matA.ldlt().solve(vecB);
|
| 337 |
+
VERIFY_IS_APPROX(matA * vecX, vecB);
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
// LDLT is not guaranteed to work for indefinite matrices, but happens to work fine if matrix is diagonal.
|
| 341 |
+
// This test checks that LDLT reports correctly that matrix is indefinite.
|
| 342 |
+
// See http://forum.kde.org/viewtopic.php?f=74&t=106942 and bug 736
|
| 343 |
+
template <typename MatrixType>
|
| 344 |
+
void cholesky_definiteness(const MatrixType& m) {
|
| 345 |
+
eigen_assert(m.rows() == 2 && m.cols() == 2);
|
| 346 |
+
MatrixType mat;
|
| 347 |
+
LDLT<MatrixType> ldlt(2);
|
| 348 |
+
|
| 349 |
+
{
|
| 350 |
+
mat << 1, 0, 0, -1;
|
| 351 |
+
ldlt.compute(mat);
|
| 352 |
+
VERIFY(ldlt.info() == Success);
|
| 353 |
+
VERIFY(!ldlt.isNegative());
|
| 354 |
+
VERIFY(!ldlt.isPositive());
|
| 355 |
+
VERIFY_IS_APPROX(mat, ldlt.reconstructedMatrix());
|
| 356 |
+
}
|
| 357 |
+
{
|
| 358 |
+
mat << 1, 2, 2, 1;
|
| 359 |
+
ldlt.compute(mat);
|
| 360 |
+
VERIFY(ldlt.info() == Success);
|
| 361 |
+
VERIFY(!ldlt.isNegative());
|
| 362 |
+
VERIFY(!ldlt.isPositive());
|
| 363 |
+
VERIFY_IS_APPROX(mat, ldlt.reconstructedMatrix());
|
| 364 |
+
}
|
| 365 |
+
{
|
| 366 |
+
mat << 0, 0, 0, 0;
|
| 367 |
+
ldlt.compute(mat);
|
| 368 |
+
VERIFY(ldlt.info() == Success);
|
| 369 |
+
VERIFY(ldlt.isNegative());
|
| 370 |
+
VERIFY(ldlt.isPositive());
|
| 371 |
+
VERIFY_IS_APPROX(mat, ldlt.reconstructedMatrix());
|
| 372 |
+
}
|
| 373 |
+
{
|
| 374 |
+
mat << 0, 0, 0, 1;
|
| 375 |
+
ldlt.compute(mat);
|
| 376 |
+
VERIFY(ldlt.info() == Success);
|
| 377 |
+
VERIFY(!ldlt.isNegative());
|
| 378 |
+
VERIFY(ldlt.isPositive());
|
| 379 |
+
VERIFY_IS_APPROX(mat, ldlt.reconstructedMatrix());
|
| 380 |
+
}
|
| 381 |
+
{
|
| 382 |
+
mat << -1, 0, 0, 0;
|
| 383 |
+
ldlt.compute(mat);
|
| 384 |
+
VERIFY(ldlt.info() == Success);
|
| 385 |
+
VERIFY(ldlt.isNegative());
|
| 386 |
+
VERIFY(!ldlt.isPositive());
|
| 387 |
+
VERIFY_IS_APPROX(mat, ldlt.reconstructedMatrix());
|
| 388 |
+
}
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
template <typename>
|
| 392 |
+
void cholesky_faillure_cases() {
|
| 393 |
+
MatrixXd mat;
|
| 394 |
+
LDLT<MatrixXd> ldlt;
|
| 395 |
+
|
| 396 |
+
{
|
| 397 |
+
mat.resize(2, 2);
|
| 398 |
+
mat << 0, 1, 1, 0;
|
| 399 |
+
ldlt.compute(mat);
|
| 400 |
+
VERIFY_IS_NOT_APPROX(mat, ldlt.reconstructedMatrix());
|
| 401 |
+
VERIFY(ldlt.info() == NumericalIssue);
|
| 402 |
+
}
|
| 403 |
+
#if (!EIGEN_ARCH_i386) || defined(EIGEN_VECTORIZE_SSE2)
|
| 404 |
+
{
|
| 405 |
+
mat.resize(3, 3);
|
| 406 |
+
mat << -1, -3, 3, -3, -8.9999999999999999999, 1, 3, 1, 0;
|
| 407 |
+
ldlt.compute(mat);
|
| 408 |
+
VERIFY(ldlt.info() == NumericalIssue);
|
| 409 |
+
VERIFY_IS_NOT_APPROX(mat, ldlt.reconstructedMatrix());
|
| 410 |
+
}
|
| 411 |
+
#endif
|
| 412 |
+
{
|
| 413 |
+
mat.resize(3, 3);
|
| 414 |
+
mat << 1, 2, 3, 2, 4, 1, 3, 1, 0;
|
| 415 |
+
ldlt.compute(mat);
|
| 416 |
+
VERIFY(ldlt.info() == NumericalIssue);
|
| 417 |
+
VERIFY_IS_NOT_APPROX(mat, ldlt.reconstructedMatrix());
|
| 418 |
+
}
|
| 419 |
+
|
| 420 |
+
{
|
| 421 |
+
mat.resize(8, 8);
|
| 422 |
+
mat << 0.1, 0, -0.1, 0, 0, 0, 1, 0, 0, 4.24667, 0, 2.00333, 0, 0, 0, 0, -0.1, 0, 0.2, 0, -0.1, 0, 0, 0, 0, 2.00333,
|
| 423 |
+
0, 8.49333, 0, 2.00333, 0, 0, 0, 0, -0.1, 0, 0.1, 0, 0, 1, 0, 0, 0, 2.00333, 0, 4.24667, 0, 0, 1, 0, 0, 0, 0, 0,
|
| 424 |
+
0, 0, 0, 0, 0, 0, 1, 0, 0, 0;
|
| 425 |
+
ldlt.compute(mat);
|
| 426 |
+
VERIFY(ldlt.info() == NumericalIssue);
|
| 427 |
+
VERIFY_IS_NOT_APPROX(mat, ldlt.reconstructedMatrix());
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
// bug 1479
|
| 431 |
+
{
|
| 432 |
+
mat.resize(4, 4);
|
| 433 |
+
mat << 1, 2, 0, 1, 2, 4, 0, 2, 0, 0, 0, 1, 1, 2, 1, 1;
|
| 434 |
+
ldlt.compute(mat);
|
| 435 |
+
VERIFY(ldlt.info() == NumericalIssue);
|
| 436 |
+
VERIFY_IS_NOT_APPROX(mat, ldlt.reconstructedMatrix());
|
| 437 |
+
}
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
template <typename MatrixType>
|
| 441 |
+
void cholesky_verify_assert() {
|
| 442 |
+
MatrixType tmp;
|
| 443 |
+
|
| 444 |
+
LLT<MatrixType> llt;
|
| 445 |
+
VERIFY_RAISES_ASSERT(llt.matrixL())
|
| 446 |
+
VERIFY_RAISES_ASSERT(llt.matrixU())
|
| 447 |
+
VERIFY_RAISES_ASSERT(llt.solve(tmp))
|
| 448 |
+
VERIFY_RAISES_ASSERT(llt.transpose().solve(tmp))
|
| 449 |
+
VERIFY_RAISES_ASSERT(llt.adjoint().solve(tmp))
|
| 450 |
+
VERIFY_RAISES_ASSERT(llt.solveInPlace(tmp))
|
| 451 |
+
|
| 452 |
+
LDLT<MatrixType> ldlt;
|
| 453 |
+
VERIFY_RAISES_ASSERT(ldlt.matrixL())
|
| 454 |
+
VERIFY_RAISES_ASSERT(ldlt.transpositionsP())
|
| 455 |
+
VERIFY_RAISES_ASSERT(ldlt.vectorD())
|
| 456 |
+
VERIFY_RAISES_ASSERT(ldlt.isPositive())
|
| 457 |
+
VERIFY_RAISES_ASSERT(ldlt.isNegative())
|
| 458 |
+
VERIFY_RAISES_ASSERT(ldlt.solve(tmp))
|
| 459 |
+
VERIFY_RAISES_ASSERT(ldlt.transpose().solve(tmp))
|
| 460 |
+
VERIFY_RAISES_ASSERT(ldlt.adjoint().solve(tmp))
|
| 461 |
+
VERIFY_RAISES_ASSERT(ldlt.solveInPlace(tmp))
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
EIGEN_DECLARE_TEST(cholesky) {
|
| 465 |
+
int s = 0;
|
| 466 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 467 |
+
CALL_SUBTEST_1(cholesky(Matrix<double, 1, 1>()));
|
| 468 |
+
CALL_SUBTEST_3(cholesky(Matrix2d()));
|
| 469 |
+
CALL_SUBTEST_3(cholesky_bug241(Matrix2d()));
|
| 470 |
+
CALL_SUBTEST_3(cholesky_definiteness(Matrix2d()));
|
| 471 |
+
CALL_SUBTEST_4(cholesky(Matrix3f()));
|
| 472 |
+
CALL_SUBTEST_5(cholesky(Matrix4d()));
|
| 473 |
+
|
| 474 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE);
|
| 475 |
+
CALL_SUBTEST_2(cholesky(MatrixXd(s, s)));
|
| 476 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 477 |
+
|
| 478 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 2);
|
| 479 |
+
CALL_SUBTEST_6(cholesky_cplx(MatrixXcd(s, s)));
|
| 480 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 481 |
+
}
|
| 482 |
+
// empty matrix, regression test for Bug 785:
|
| 483 |
+
CALL_SUBTEST_2(cholesky(MatrixXd(0, 0)));
|
| 484 |
+
|
| 485 |
+
// This does not work yet:
|
| 486 |
+
// CALL_SUBTEST_2( cholesky(Matrix<double,0,0>()) );
|
| 487 |
+
|
| 488 |
+
CALL_SUBTEST_4(cholesky_verify_assert<Matrix3f>());
|
| 489 |
+
CALL_SUBTEST_7(cholesky_verify_assert<Matrix3d>());
|
| 490 |
+
CALL_SUBTEST_8(cholesky_verify_assert<MatrixXf>());
|
| 491 |
+
CALL_SUBTEST_2(cholesky_verify_assert<MatrixXd>());
|
| 492 |
+
|
| 493 |
+
// Test problem size constructors
|
| 494 |
+
CALL_SUBTEST_9(LLT<MatrixXf>(10));
|
| 495 |
+
CALL_SUBTEST_9(LDLT<MatrixXf>(10));
|
| 496 |
+
|
| 497 |
+
CALL_SUBTEST_2(cholesky_faillure_cases<void>());
|
| 498 |
+
|
| 499 |
+
TEST_SET_BUT_UNUSED_VARIABLE(nb_temporaries)
|
| 500 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/cholmod_support.cpp
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
|
| 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_DEBUG_SMALL_PRODUCT_BLOCKS
|
| 11 |
+
#include "sparse_solver.h"
|
| 12 |
+
|
| 13 |
+
#include <Eigen/CholmodSupport>
|
| 14 |
+
|
| 15 |
+
template <typename SparseType>
|
| 16 |
+
void test_cholmod_ST() {
|
| 17 |
+
CholmodDecomposition<SparseType, Lower> g_chol_colmajor_lower;
|
| 18 |
+
g_chol_colmajor_lower.setMode(CholmodSupernodalLLt);
|
| 19 |
+
CholmodDecomposition<SparseType, Upper> g_chol_colmajor_upper;
|
| 20 |
+
g_chol_colmajor_upper.setMode(CholmodSupernodalLLt);
|
| 21 |
+
CholmodDecomposition<SparseType, Lower> g_llt_colmajor_lower;
|
| 22 |
+
g_llt_colmajor_lower.setMode(CholmodSimplicialLLt);
|
| 23 |
+
CholmodDecomposition<SparseType, Upper> g_llt_colmajor_upper;
|
| 24 |
+
g_llt_colmajor_upper.setMode(CholmodSimplicialLLt);
|
| 25 |
+
CholmodDecomposition<SparseType, Lower> g_ldlt_colmajor_lower;
|
| 26 |
+
g_ldlt_colmajor_lower.setMode(CholmodLDLt);
|
| 27 |
+
CholmodDecomposition<SparseType, Upper> g_ldlt_colmajor_upper;
|
| 28 |
+
g_ldlt_colmajor_upper.setMode(CholmodLDLt);
|
| 29 |
+
|
| 30 |
+
CholmodSupernodalLLT<SparseType, Lower> chol_colmajor_lower;
|
| 31 |
+
CholmodSupernodalLLT<SparseType, Upper> chol_colmajor_upper;
|
| 32 |
+
CholmodSimplicialLLT<SparseType, Lower> llt_colmajor_lower;
|
| 33 |
+
CholmodSimplicialLLT<SparseType, Upper> llt_colmajor_upper;
|
| 34 |
+
CholmodSimplicialLDLT<SparseType, Lower> ldlt_colmajor_lower;
|
| 35 |
+
CholmodSimplicialLDLT<SparseType, Upper> ldlt_colmajor_upper;
|
| 36 |
+
|
| 37 |
+
check_sparse_spd_solving(g_chol_colmajor_lower);
|
| 38 |
+
check_sparse_spd_solving(g_chol_colmajor_upper);
|
| 39 |
+
check_sparse_spd_solving(g_llt_colmajor_lower);
|
| 40 |
+
check_sparse_spd_solving(g_llt_colmajor_upper);
|
| 41 |
+
check_sparse_spd_solving(g_ldlt_colmajor_lower);
|
| 42 |
+
check_sparse_spd_solving(g_ldlt_colmajor_upper);
|
| 43 |
+
|
| 44 |
+
check_sparse_spd_solving(chol_colmajor_lower);
|
| 45 |
+
check_sparse_spd_solving(chol_colmajor_upper);
|
| 46 |
+
check_sparse_spd_solving(llt_colmajor_lower);
|
| 47 |
+
check_sparse_spd_solving(llt_colmajor_upper);
|
| 48 |
+
check_sparse_spd_solving(ldlt_colmajor_lower);
|
| 49 |
+
check_sparse_spd_solving(ldlt_colmajor_upper);
|
| 50 |
+
|
| 51 |
+
check_sparse_spd_determinant(chol_colmajor_lower);
|
| 52 |
+
check_sparse_spd_determinant(chol_colmajor_upper);
|
| 53 |
+
check_sparse_spd_determinant(llt_colmajor_lower);
|
| 54 |
+
check_sparse_spd_determinant(llt_colmajor_upper);
|
| 55 |
+
check_sparse_spd_determinant(ldlt_colmajor_lower);
|
| 56 |
+
check_sparse_spd_determinant(ldlt_colmajor_upper);
|
| 57 |
+
|
| 58 |
+
check_sparse_zero_matrix(chol_colmajor_lower);
|
| 59 |
+
check_sparse_zero_matrix(chol_colmajor_upper);
|
| 60 |
+
check_sparse_zero_matrix(llt_colmajor_lower);
|
| 61 |
+
check_sparse_zero_matrix(llt_colmajor_upper);
|
| 62 |
+
check_sparse_zero_matrix(ldlt_colmajor_lower);
|
| 63 |
+
check_sparse_zero_matrix(ldlt_colmajor_upper);
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
template <typename T, int flags, typename IdxType>
|
| 67 |
+
void test_cholmod_T() {
|
| 68 |
+
test_cholmod_ST<SparseMatrix<T, flags, IdxType> >();
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
EIGEN_DECLARE_TEST(cholmod_support) {
|
| 72 |
+
CALL_SUBTEST_11((test_cholmod_T<double, ColMajor, int>()));
|
| 73 |
+
CALL_SUBTEST_12((test_cholmod_T<double, ColMajor, long>()));
|
| 74 |
+
CALL_SUBTEST_13((test_cholmod_T<double, RowMajor, int>()));
|
| 75 |
+
CALL_SUBTEST_14((test_cholmod_T<double, RowMajor, long>()));
|
| 76 |
+
CALL_SUBTEST_21((test_cholmod_T<std::complex<double>, ColMajor, int>()));
|
| 77 |
+
CALL_SUBTEST_22((test_cholmod_T<std::complex<double>, ColMajor, long>()));
|
| 78 |
+
// TODO complex row-major matrices do not work at the moment:
|
| 79 |
+
// CALL_SUBTEST_23( (test_cholmod_T<std::complex<double>, RowMajor, int >()) );
|
| 80 |
+
// CALL_SUBTEST_24( (test_cholmod_T<std::complex<double>, RowMajor, long>()) );
|
| 81 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/clz.cpp
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2023 The Eigen Authors
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <typename T>
|
| 13 |
+
int ref_clz(T val) {
|
| 14 |
+
constexpr int kNumBits = sizeof(T) * CHAR_BIT;
|
| 15 |
+
T kMsbMask = T(1) << (kNumBits - 1);
|
| 16 |
+
int z = 0;
|
| 17 |
+
for (; z < kNumBits && ((val & kMsbMask) == 0); ++z) {
|
| 18 |
+
val <<= 1;
|
| 19 |
+
}
|
| 20 |
+
return z;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
template <typename T>
|
| 24 |
+
int ref_ctz(T val) {
|
| 25 |
+
constexpr int kNumBits = sizeof(T) * CHAR_BIT;
|
| 26 |
+
T kLsbMask = T(1);
|
| 27 |
+
int z = 0;
|
| 28 |
+
for (; z < kNumBits && ((val & kLsbMask) == 0); ++z) {
|
| 29 |
+
val >>= 1;
|
| 30 |
+
}
|
| 31 |
+
return z;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
template <typename T>
|
| 35 |
+
void test_clz_ctz() {
|
| 36 |
+
T step = sizeof(T) <= 2 ? 1 : (Eigen::NumTraits<T>::highest() / (T(1) << 16));
|
| 37 |
+
T iters = Eigen::NumTraits<T>::highest() / step;
|
| 38 |
+
for (T i = 0; i < iters; ++i) {
|
| 39 |
+
T val = i * step;
|
| 40 |
+
int expected_clz = ref_clz(val);
|
| 41 |
+
int actual_clz = Eigen::internal::clz(val);
|
| 42 |
+
VERIFY(expected_clz == actual_clz);
|
| 43 |
+
|
| 44 |
+
int expected_ctz = ref_ctz(val);
|
| 45 |
+
int actual_ctz = Eigen::internal::ctz(val);
|
| 46 |
+
VERIFY(expected_ctz == actual_ctz);
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
template <typename T>
|
| 51 |
+
void test_clz_ctz_random() {
|
| 52 |
+
for (int i = 0; i < 1024 * 1024; ++i) {
|
| 53 |
+
T val = Eigen::internal::random<T>();
|
| 54 |
+
int expected_clz = ref_clz(val);
|
| 55 |
+
int actual_clz = Eigen::internal::clz(val);
|
| 56 |
+
VERIFY(expected_clz == actual_clz);
|
| 57 |
+
|
| 58 |
+
int expected_ctz = ref_ctz(val);
|
| 59 |
+
int actual_ctz = Eigen::internal::ctz(val);
|
| 60 |
+
VERIFY(expected_ctz == actual_ctz);
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
EIGEN_DECLARE_TEST(clz) {
|
| 65 |
+
CALL_SUBTEST_1(test_clz_ctz<uint8_t>());
|
| 66 |
+
CALL_SUBTEST_2(test_clz_ctz<uint16_t>());
|
| 67 |
+
CALL_SUBTEST_3(test_clz_ctz<uint32_t>());
|
| 68 |
+
CALL_SUBTEST_4(test_clz_ctz<uint64_t>());
|
| 69 |
+
|
| 70 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 71 |
+
test_clz_ctz_random<uint32_t>();
|
| 72 |
+
test_clz_ctz_random<uint64_t>();
|
| 73 |
+
}
|
| 74 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/commainitializer.cpp
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <int M1, int M2, int N1, int N2>
|
| 13 |
+
void test_blocks() {
|
| 14 |
+
Matrix<int, M1 + M2, N1 + N2> m_fixed;
|
| 15 |
+
MatrixXi m_dynamic(M1 + M2, N1 + N2);
|
| 16 |
+
|
| 17 |
+
Matrix<int, M1, N1> mat11;
|
| 18 |
+
mat11.setRandom();
|
| 19 |
+
Matrix<int, M1, N2> mat12;
|
| 20 |
+
mat12.setRandom();
|
| 21 |
+
Matrix<int, M2, N1> mat21;
|
| 22 |
+
mat21.setRandom();
|
| 23 |
+
Matrix<int, M2, N2> mat22;
|
| 24 |
+
mat22.setRandom();
|
| 25 |
+
|
| 26 |
+
MatrixXi matx11 = mat11, matx12 = mat12, matx21 = mat21, matx22 = mat22;
|
| 27 |
+
|
| 28 |
+
{
|
| 29 |
+
VERIFY_IS_EQUAL((m_fixed << mat11, mat12, mat21, matx22).finished(),
|
| 30 |
+
(m_dynamic << mat11, matx12, mat21, matx22).finished());
|
| 31 |
+
VERIFY_IS_EQUAL((m_fixed.template topLeftCorner<M1, N1>()), mat11);
|
| 32 |
+
VERIFY_IS_EQUAL((m_fixed.template topRightCorner<M1, N2>()), mat12);
|
| 33 |
+
VERIFY_IS_EQUAL((m_fixed.template bottomLeftCorner<M2, N1>()), mat21);
|
| 34 |
+
VERIFY_IS_EQUAL((m_fixed.template bottomRightCorner<M2, N2>()), mat22);
|
| 35 |
+
VERIFY_IS_EQUAL((m_fixed << mat12, mat11, matx21, mat22).finished(),
|
| 36 |
+
(m_dynamic << mat12, matx11, matx21, mat22).finished());
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
if (N1 > 0) {
|
| 40 |
+
if (M1 > 0) {
|
| 41 |
+
VERIFY_RAISES_ASSERT((m_fixed << mat11, mat12, mat11, mat21, mat22));
|
| 42 |
+
}
|
| 43 |
+
if (M2 > 0) {
|
| 44 |
+
VERIFY_RAISES_ASSERT((m_fixed << mat11, mat12, mat21, mat21, mat22));
|
| 45 |
+
}
|
| 46 |
+
} else {
|
| 47 |
+
// allow insertion of zero-column blocks:
|
| 48 |
+
VERIFY_IS_EQUAL((m_fixed << mat11, mat12, mat11, mat11, mat21, mat21, mat22).finished(),
|
| 49 |
+
(m_dynamic << mat12, mat22).finished());
|
| 50 |
+
}
|
| 51 |
+
if (M1 != M2) {
|
| 52 |
+
VERIFY_RAISES_ASSERT((m_fixed << mat11, mat21, mat12, mat22));
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
template <int depth, int N = 0>
|
| 57 |
+
struct test_block_recursion {
|
| 58 |
+
static void run() {
|
| 59 |
+
test_block_recursion<depth - 1, N>::run();
|
| 60 |
+
test_block_recursion<depth - 1, N + (1 << (depth - 1))>::run();
|
| 61 |
+
}
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
+
template <int N>
|
| 65 |
+
struct test_block_recursion<0, N> {
|
| 66 |
+
static void run() { test_blocks<(N >> 6) & 3, (N >> 4) & 3, (N >> 2) & 3, N & 3>(); }
|
| 67 |
+
};
|
| 68 |
+
|
| 69 |
+
void test_basics() {
|
| 70 |
+
Matrix3d m3;
|
| 71 |
+
Matrix4d m4;
|
| 72 |
+
|
| 73 |
+
VERIFY_RAISES_ASSERT((m3 << 1, 2, 3, 4, 5, 6, 7, 8));
|
| 74 |
+
|
| 75 |
+
#ifndef _MSC_VER
|
| 76 |
+
VERIFY_RAISES_ASSERT((m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
|
| 77 |
+
#endif
|
| 78 |
+
|
| 79 |
+
double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
| 80 |
+
Matrix3d ref = Map<Matrix<double, 3, 3, RowMajor> >(data);
|
| 81 |
+
|
| 82 |
+
m3 = Matrix3d::Random();
|
| 83 |
+
m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9;
|
| 84 |
+
VERIFY_IS_APPROX(m3, ref);
|
| 85 |
+
|
| 86 |
+
Vector3d vec[3];
|
| 87 |
+
vec[0] << 1, 4, 7;
|
| 88 |
+
vec[1] << 2, 5, 8;
|
| 89 |
+
vec[2] << 3, 6, 9;
|
| 90 |
+
m3 = Matrix3d::Random();
|
| 91 |
+
m3 << vec[0], vec[1], vec[2];
|
| 92 |
+
VERIFY_IS_APPROX(m3, ref);
|
| 93 |
+
|
| 94 |
+
vec[0] << 1, 2, 3;
|
| 95 |
+
vec[1] << 4, 5, 6;
|
| 96 |
+
vec[2] << 7, 8, 9;
|
| 97 |
+
m3 = Matrix3d::Random();
|
| 98 |
+
m3 << vec[0].transpose(), 4, 5, 6, vec[2].transpose();
|
| 99 |
+
VERIFY_IS_APPROX(m3, ref);
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
EIGEN_DECLARE_TEST(commainitializer) {
|
| 103 |
+
CALL_SUBTEST_1(test_basics());
|
| 104 |
+
|
| 105 |
+
// recursively test all block-sizes from 0 to 3:
|
| 106 |
+
CALL_SUBTEST_2(test_block_recursion<8>::run());
|
| 107 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/complex_qz.cpp
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2012 The Eigen Authors
|
| 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_RUNTIME_NO_MALLOC
|
| 11 |
+
#include "main.h"
|
| 12 |
+
|
| 13 |
+
#include <Eigen/Eigenvalues>
|
| 14 |
+
|
| 15 |
+
/* this test covers the following files:
|
| 16 |
+
ComplexQZ.h
|
| 17 |
+
*/
|
| 18 |
+
|
| 19 |
+
template <typename MatrixType>
|
| 20 |
+
void generate_random_matrix_pair(const Index dim, MatrixType& A, MatrixType& B) {
|
| 21 |
+
A.setRandom(dim, dim);
|
| 22 |
+
B.setRandom(dim, dim);
|
| 23 |
+
// Zero out each row of B to with a probability of 10%.
|
| 24 |
+
for (int i = 0; i < dim; i++) {
|
| 25 |
+
if (internal::random<int>(0, 10) == 0) B.row(i).setZero();
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
template <typename MatrixType>
|
| 30 |
+
void complex_qz(const MatrixType& A, const MatrixType& B) {
|
| 31 |
+
using std::abs;
|
| 32 |
+
const Index dim = A.rows();
|
| 33 |
+
ComplexQZ<MatrixType> qz(A, B);
|
| 34 |
+
VERIFY_IS_EQUAL(qz.info(), Success);
|
| 35 |
+
auto T = qz.matrixT(), S = qz.matrixS();
|
| 36 |
+
bool is_all_zero_T = true, is_all_zero_S = true;
|
| 37 |
+
using RealScalar = typename MatrixType::RealScalar;
|
| 38 |
+
RealScalar tol = dim * 10 * NumTraits<RealScalar>::epsilon();
|
| 39 |
+
for (Index j = 0; j < dim; j++) {
|
| 40 |
+
for (Index i = j + 1; i < dim; i++) {
|
| 41 |
+
if (std::abs(T(i, j)) > tol) {
|
| 42 |
+
std::cerr << std::abs(T(i, j)) << std::endl;
|
| 43 |
+
is_all_zero_T = false;
|
| 44 |
+
}
|
| 45 |
+
if (std::abs(S(i, j)) > tol) {
|
| 46 |
+
std::cerr << std::abs(S(i, j)) << std::endl;
|
| 47 |
+
is_all_zero_S = false;
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
}
|
| 51 |
+
VERIFY_IS_EQUAL(is_all_zero_T, true);
|
| 52 |
+
VERIFY_IS_EQUAL(is_all_zero_S, true);
|
| 53 |
+
VERIFY_IS_APPROX(qz.matrixQ() * qz.matrixS() * qz.matrixZ(), A);
|
| 54 |
+
VERIFY_IS_APPROX(qz.matrixQ() * qz.matrixT() * qz.matrixZ(), B);
|
| 55 |
+
VERIFY_IS_APPROX(qz.matrixQ() * qz.matrixQ().adjoint(), MatrixType::Identity(dim, dim));
|
| 56 |
+
VERIFY_IS_APPROX(qz.matrixZ() * qz.matrixZ().adjoint(), MatrixType::Identity(dim, dim));
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
EIGEN_DECLARE_TEST(complex_qz) {
|
| 60 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 61 |
+
// Check for very small, fixed-sized double- and float complex matrices
|
| 62 |
+
Eigen::Matrix2cd A_2x2, B_2x2;
|
| 63 |
+
A_2x2.setRandom();
|
| 64 |
+
B_2x2.setRandom();
|
| 65 |
+
B_2x2.row(1).setZero();
|
| 66 |
+
Eigen::Matrix3cf A_3x3, B_3x3;
|
| 67 |
+
A_3x3.setRandom();
|
| 68 |
+
B_3x3.setRandom();
|
| 69 |
+
B_3x3.col(i % 3).setRandom();
|
| 70 |
+
CALL_SUBTEST_1(complex_qz(A_2x2, B_2x2));
|
| 71 |
+
CALL_SUBTEST_2(complex_qz(A_3x3, B_3x3));
|
| 72 |
+
|
| 73 |
+
// Test for float complex matrices
|
| 74 |
+
const Index dim = internal::random<Index>(15, 80);
|
| 75 |
+
Eigen::MatrixXcf A_float, B_float;
|
| 76 |
+
generate_random_matrix_pair(dim, A_float, B_float);
|
| 77 |
+
CALL_SUBTEST_3(complex_qz(A_float, B_float));
|
| 78 |
+
|
| 79 |
+
// Test for double complex matrices
|
| 80 |
+
Eigen::MatrixXcd A_double, B_double;
|
| 81 |
+
generate_random_matrix_pair(dim, A_double, B_double);
|
| 82 |
+
CALL_SUBTEST_4(complex_qz(A_double, B_double));
|
| 83 |
+
}
|
| 84 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/conjugate_gradient.cpp
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>
|
| 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 |
+
#include "sparse_solver.h"
|
| 11 |
+
#include <Eigen/IterativeLinearSolvers>
|
| 12 |
+
|
| 13 |
+
template <typename T, typename I_>
|
| 14 |
+
void test_conjugate_gradient_T() {
|
| 15 |
+
typedef SparseMatrix<T, 0, I_> SparseMatrixType;
|
| 16 |
+
ConjugateGradient<SparseMatrixType, Lower> cg_colmajor_lower_diag;
|
| 17 |
+
ConjugateGradient<SparseMatrixType, Upper> cg_colmajor_upper_diag;
|
| 18 |
+
ConjugateGradient<SparseMatrixType, Lower | Upper> cg_colmajor_loup_diag;
|
| 19 |
+
ConjugateGradient<SparseMatrixType, Lower, IdentityPreconditioner> cg_colmajor_lower_I;
|
| 20 |
+
ConjugateGradient<SparseMatrixType, Upper, IdentityPreconditioner> cg_colmajor_upper_I;
|
| 21 |
+
|
| 22 |
+
CALL_SUBTEST(check_sparse_spd_solving(cg_colmajor_lower_diag));
|
| 23 |
+
CALL_SUBTEST(check_sparse_spd_solving(cg_colmajor_upper_diag));
|
| 24 |
+
CALL_SUBTEST(check_sparse_spd_solving(cg_colmajor_loup_diag));
|
| 25 |
+
CALL_SUBTEST(check_sparse_spd_solving(cg_colmajor_lower_I));
|
| 26 |
+
CALL_SUBTEST(check_sparse_spd_solving(cg_colmajor_upper_I));
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
EIGEN_DECLARE_TEST(conjugate_gradient) {
|
| 30 |
+
CALL_SUBTEST_1((test_conjugate_gradient_T<double, int>()));
|
| 31 |
+
CALL_SUBTEST_2((test_conjugate_gradient_T<std::complex<double>, int>()));
|
| 32 |
+
CALL_SUBTEST_3((test_conjugate_gradient_T<double, long int>()));
|
| 33 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/conservative_resize.cpp
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
#include <Eigen/Core>
|
| 13 |
+
#include "AnnoyingScalar.h"
|
| 14 |
+
|
| 15 |
+
using namespace Eigen;
|
| 16 |
+
|
| 17 |
+
template <typename Scalar, int Storage>
|
| 18 |
+
void run_matrix_tests() {
|
| 19 |
+
typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Storage> MatrixType;
|
| 20 |
+
|
| 21 |
+
MatrixType m, n;
|
| 22 |
+
|
| 23 |
+
// boundary cases ...
|
| 24 |
+
m = n = MatrixType::Random(50, 50);
|
| 25 |
+
m.conservativeResize(1, 50);
|
| 26 |
+
VERIFY_IS_APPROX(m, n.block(0, 0, 1, 50));
|
| 27 |
+
|
| 28 |
+
m = n = MatrixType::Random(50, 50);
|
| 29 |
+
m.conservativeResize(50, 1);
|
| 30 |
+
VERIFY_IS_APPROX(m, n.block(0, 0, 50, 1));
|
| 31 |
+
|
| 32 |
+
m = n = MatrixType::Random(50, 50);
|
| 33 |
+
m.conservativeResize(50, 50);
|
| 34 |
+
VERIFY_IS_APPROX(m, n.block(0, 0, 50, 50));
|
| 35 |
+
|
| 36 |
+
// random shrinking ...
|
| 37 |
+
for (int i = 0; i < 25; ++i) {
|
| 38 |
+
const Index rows = internal::random<Index>(1, 50);
|
| 39 |
+
const Index cols = internal::random<Index>(1, 50);
|
| 40 |
+
m = n = MatrixType::Random(50, 50);
|
| 41 |
+
m.conservativeResize(rows, cols);
|
| 42 |
+
VERIFY_IS_APPROX(m, n.block(0, 0, rows, cols));
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
// random growing with zeroing ...
|
| 46 |
+
for (int i = 0; i < 25; ++i) {
|
| 47 |
+
const Index rows = internal::random<Index>(50, 75);
|
| 48 |
+
const Index cols = internal::random<Index>(50, 75);
|
| 49 |
+
m = n = MatrixType::Random(50, 50);
|
| 50 |
+
m.conservativeResizeLike(MatrixType::Zero(rows, cols));
|
| 51 |
+
VERIFY_IS_APPROX(m.block(0, 0, n.rows(), n.cols()), n);
|
| 52 |
+
VERIFY(rows <= 50 || m.block(50, 0, rows - 50, cols).sum() == Scalar(0));
|
| 53 |
+
VERIFY(cols <= 50 || m.block(0, 50, rows, cols - 50).sum() == Scalar(0));
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
template <typename Scalar>
|
| 58 |
+
void run_vector_tests() {
|
| 59 |
+
typedef Matrix<Scalar, 1, Eigen::Dynamic> VectorType;
|
| 60 |
+
|
| 61 |
+
VectorType m, n;
|
| 62 |
+
|
| 63 |
+
// boundary cases ...
|
| 64 |
+
m = n = VectorType::Random(50);
|
| 65 |
+
m.conservativeResize(1);
|
| 66 |
+
VERIFY_IS_APPROX(m, n.segment(0, 1));
|
| 67 |
+
|
| 68 |
+
m = n = VectorType::Random(50);
|
| 69 |
+
m.conservativeResize(50);
|
| 70 |
+
VERIFY_IS_APPROX(m, n.segment(0, 50));
|
| 71 |
+
|
| 72 |
+
m = n = VectorType::Random(50);
|
| 73 |
+
m.conservativeResize(m.rows(), 1);
|
| 74 |
+
VERIFY_IS_APPROX(m, n.segment(0, 1));
|
| 75 |
+
|
| 76 |
+
m = n = VectorType::Random(50);
|
| 77 |
+
m.conservativeResize(m.rows(), 50);
|
| 78 |
+
VERIFY_IS_APPROX(m, n.segment(0, 50));
|
| 79 |
+
|
| 80 |
+
// random shrinking ...
|
| 81 |
+
for (int i = 0; i < 50; ++i) {
|
| 82 |
+
const int size = internal::random<int>(1, 50);
|
| 83 |
+
m = n = VectorType::Random(50);
|
| 84 |
+
m.conservativeResize(size);
|
| 85 |
+
VERIFY_IS_APPROX(m, n.segment(0, size));
|
| 86 |
+
|
| 87 |
+
m = n = VectorType::Random(50);
|
| 88 |
+
m.conservativeResize(m.rows(), size);
|
| 89 |
+
VERIFY_IS_APPROX(m, n.segment(0, size));
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
// random growing with zeroing ...
|
| 93 |
+
for (int i = 0; i < 50; ++i) {
|
| 94 |
+
const int size = internal::random<int>(50, 100);
|
| 95 |
+
m = n = VectorType::Random(50);
|
| 96 |
+
m.conservativeResizeLike(VectorType::Zero(size));
|
| 97 |
+
VERIFY_IS_APPROX(m.segment(0, 50), n);
|
| 98 |
+
VERIFY(size <= 50 || m.segment(50, size - 50).sum() == Scalar(0));
|
| 99 |
+
|
| 100 |
+
m = n = VectorType::Random(50);
|
| 101 |
+
m.conservativeResizeLike(Matrix<Scalar, Dynamic, Dynamic>::Zero(1, size));
|
| 102 |
+
VERIFY_IS_APPROX(m.segment(0, 50), n);
|
| 103 |
+
VERIFY(size <= 50 || m.segment(50, size - 50).sum() == Scalar(0));
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
// Basic memory leak check with a non-copyable scalar type
|
| 108 |
+
template <int>
|
| 109 |
+
void noncopyable() {
|
| 110 |
+
typedef Eigen::Matrix<AnnoyingScalar, Dynamic, 1> VectorType;
|
| 111 |
+
typedef Eigen::Matrix<AnnoyingScalar, Dynamic, Dynamic> MatrixType;
|
| 112 |
+
|
| 113 |
+
{
|
| 114 |
+
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
|
| 115 |
+
AnnoyingScalar::dont_throw = true;
|
| 116 |
+
#endif
|
| 117 |
+
int n = 50;
|
| 118 |
+
VectorType v0(n), v1(n);
|
| 119 |
+
MatrixType m0(n, n), m1(n, n), m2(n, n);
|
| 120 |
+
v0.setOnes();
|
| 121 |
+
v1.setOnes();
|
| 122 |
+
m0.setOnes();
|
| 123 |
+
m1.setOnes();
|
| 124 |
+
m2.setOnes();
|
| 125 |
+
VERIFY(m0 == m1);
|
| 126 |
+
m0.conservativeResize(2 * n, 2 * n);
|
| 127 |
+
VERIFY(m0.topLeftCorner(n, n) == m1);
|
| 128 |
+
|
| 129 |
+
VERIFY(v0.head(n) == v1);
|
| 130 |
+
v0.conservativeResize(2 * n);
|
| 131 |
+
VERIFY(v0.head(n) == v1);
|
| 132 |
+
}
|
| 133 |
+
VERIFY(AnnoyingScalar::instances == 0 && "global memory leak detected in noncopyable");
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
EIGEN_DECLARE_TEST(conservative_resize) {
|
| 137 |
+
for (int i = 0; i < g_repeat; ++i) {
|
| 138 |
+
CALL_SUBTEST_1((run_matrix_tests<int, Eigen::RowMajor>()));
|
| 139 |
+
CALL_SUBTEST_1((run_matrix_tests<int, Eigen::ColMajor>()));
|
| 140 |
+
CALL_SUBTEST_2((run_matrix_tests<float, Eigen::RowMajor>()));
|
| 141 |
+
CALL_SUBTEST_2((run_matrix_tests<float, Eigen::ColMajor>()));
|
| 142 |
+
CALL_SUBTEST_3((run_matrix_tests<double, Eigen::RowMajor>()));
|
| 143 |
+
CALL_SUBTEST_3((run_matrix_tests<double, Eigen::ColMajor>()));
|
| 144 |
+
CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::RowMajor>()));
|
| 145 |
+
CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::ColMajor>()));
|
| 146 |
+
CALL_SUBTEST_5((run_matrix_tests<std::complex<double>, Eigen::RowMajor>()));
|
| 147 |
+
CALL_SUBTEST_5((run_matrix_tests<std::complex<double>, Eigen::ColMajor>()));
|
| 148 |
+
CALL_SUBTEST_1((run_matrix_tests<int, Eigen::RowMajor | Eigen::DontAlign>()));
|
| 149 |
+
|
| 150 |
+
CALL_SUBTEST_1((run_vector_tests<int>()));
|
| 151 |
+
CALL_SUBTEST_2((run_vector_tests<float>()));
|
| 152 |
+
CALL_SUBTEST_3((run_vector_tests<double>()));
|
| 153 |
+
CALL_SUBTEST_4((run_vector_tests<std::complex<float> >()));
|
| 154 |
+
CALL_SUBTEST_5((run_vector_tests<std::complex<double> >()));
|
| 155 |
+
|
| 156 |
+
#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
|
| 157 |
+
AnnoyingScalar::dont_throw = true;
|
| 158 |
+
#endif
|
| 159 |
+
CALL_SUBTEST_6((run_vector_tests<AnnoyingScalar>()));
|
| 160 |
+
CALL_SUBTEST_6((noncopyable<0>()));
|
| 161 |
+
}
|
| 162 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/constexpr.cpp
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2022 Alex Richardson <alexrichardson@google.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_TESTING_CONSTEXPR
|
| 11 |
+
#include "main.h"
|
| 12 |
+
|
| 13 |
+
template <typename Scalar, int Rows>
|
| 14 |
+
struct ConstexprTest {
|
| 15 |
+
constexpr ConstexprTest(const Matrix<Scalar, Rows, Rows>& B) { A = B; }
|
| 16 |
+
|
| 17 |
+
Matrix<Scalar, Rows, Rows> A;
|
| 18 |
+
};
|
| 19 |
+
|
| 20 |
+
EIGEN_DECLARE_TEST(constexpr) {
|
| 21 |
+
// Clang accepts (some of) this code when using C++14/C++17, but GCC does not like
|
| 22 |
+
// the fact that `T array[Size]` inside Eigen::internal::plain_array is not initialized
|
| 23 |
+
// until after the constructor returns:
|
| 24 |
+
// error: member ‘Eigen::internal::plain_array<int, 9, 0, 0>::array’ must be initialized by mem-initializer in
|
| 25 |
+
// ‘constexpr’ constructor
|
| 26 |
+
#if __cpp_constexpr >= 201907L
|
| 27 |
+
constexpr Matrix3i mat({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
| 28 |
+
VERIFY_IS_EQUAL(mat.size(), 9);
|
| 29 |
+
static_assert(mat(0, 0) == 1);
|
| 30 |
+
static_assert(mat(0) == 1);
|
| 31 |
+
static_assert(mat.coeff(0, 1) == 2);
|
| 32 |
+
constexpr Array33i arr({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
| 33 |
+
static_assert(arr(0, 0) == 1);
|
| 34 |
+
static_assert(arr(0) == 1);
|
| 35 |
+
VERIFY_IS_EQUAL(arr.size(), 9);
|
| 36 |
+
static_assert(arr.coeff(0, 1) == 2);
|
| 37 |
+
constexpr RowVector3i vec{{1, 2, 3}};
|
| 38 |
+
static_assert(vec(0, 0) == 1);
|
| 39 |
+
static_assert(vec[0] == 1);
|
| 40 |
+
VERIFY_IS_EQUAL(vec.size(), 3);
|
| 41 |
+
static_assert(vec.coeff(0, 1) == 2);
|
| 42 |
+
|
| 43 |
+
// Check assignment. A wrapper struct is used to avoid copy ellision.
|
| 44 |
+
constexpr ConstexprTest<double, 2> obj1(Matrix2d({{1, 2}, {3, 4}}));
|
| 45 |
+
VERIFY_IS_EQUAL(obj1.A.size(), 4);
|
| 46 |
+
static_assert(obj1.A(0, 0) == 1);
|
| 47 |
+
static_assert(obj1.A(0) == 1);
|
| 48 |
+
static_assert(obj1.A.coeff(0, 1) == 2);
|
| 49 |
+
constexpr ConstexprTest<double, 3> obj2(Matrix3d({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}));
|
| 50 |
+
VERIFY_IS_EQUAL(obj2.A.size(), 9);
|
| 51 |
+
static_assert(obj2.A(0, 0) == 1);
|
| 52 |
+
static_assert(obj2.A(0) == 1);
|
| 53 |
+
static_assert(obj2.A.coeff(0, 1) == 2);
|
| 54 |
+
|
| 55 |
+
// Also check dynamic size arrays/matrices with fixed-size storage (currently
|
| 56 |
+
// only works if all elements are initialized, since otherwise the compiler
|
| 57 |
+
// complains about uninitialized trailing elements.
|
| 58 |
+
constexpr Matrix<int, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> dyn_mat({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
| 59 |
+
VERIFY_IS_EQUAL(dyn_mat.size(), 9);
|
| 60 |
+
static_assert(dyn_mat(0, 0) == 1);
|
| 61 |
+
static_assert(dyn_mat.coeff(0, 1) == 2);
|
| 62 |
+
constexpr Array<int, Eigen::Dynamic, Eigen::Dynamic, 0, 3, 3> dyn_arr({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
|
| 63 |
+
static_assert(dyn_arr(0, 0) == 1);
|
| 64 |
+
static_assert(dyn_arr(0) == 1);
|
| 65 |
+
VERIFY_IS_EQUAL(dyn_arr.size(), 9);
|
| 66 |
+
static_assert(dyn_arr.coeff(0, 1) == 2);
|
| 67 |
+
#endif // __cpp_constexpr >= 201907L
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
// Check that we can use the std::initializer_list constructor for constexpr variables.
|
| 71 |
+
#if __cpp_constexpr >= 201907L
|
| 72 |
+
// EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT() will fail constexpr evaluation unless
|
| 73 |
+
// we have std::is_constant_evaluated().
|
| 74 |
+
constexpr Matrix<int, 2, 2> global_mat({{1, 2}, {3, 4}});
|
| 75 |
+
|
| 76 |
+
EIGEN_DECLARE_TEST(constexpr_global) {
|
| 77 |
+
VERIFY_IS_EQUAL(global_mat.size(), 4);
|
| 78 |
+
static_assert(global_mat(0, 0) == 1);
|
| 79 |
+
static_assert(global_mat(0) == 1);
|
| 80 |
+
static_assert(global_mat.coeff(0, 0) == 1);
|
| 81 |
+
}
|
| 82 |
+
#endif // __cpp_constexpr >= 201907L
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/constructor.cpp
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 TEST_ENABLE_TEMPORARY_TRACKING
|
| 11 |
+
|
| 12 |
+
#include "main.h"
|
| 13 |
+
|
| 14 |
+
template <typename MatrixType>
|
| 15 |
+
struct Wrapper {
|
| 16 |
+
MatrixType m_mat;
|
| 17 |
+
inline Wrapper(const MatrixType& x) : m_mat(x) {}
|
| 18 |
+
inline operator const MatrixType&() const { return m_mat; }
|
| 19 |
+
inline operator MatrixType&() { return m_mat; }
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
enum my_sizes { M = 12, N = 7 };
|
| 23 |
+
|
| 24 |
+
template <typename MatrixType>
|
| 25 |
+
void ctor_init1(const MatrixType& m) {
|
| 26 |
+
// Check logic in PlainObjectBase::_init1
|
| 27 |
+
Index rows = m.rows();
|
| 28 |
+
Index cols = m.cols();
|
| 29 |
+
|
| 30 |
+
MatrixType m0 = MatrixType::Random(rows, cols);
|
| 31 |
+
|
| 32 |
+
VERIFY_EVALUATION_COUNT(MatrixType m1(m0), 1);
|
| 33 |
+
VERIFY_EVALUATION_COUNT(MatrixType m2(m0 + m0), 1);
|
| 34 |
+
VERIFY_EVALUATION_COUNT(MatrixType m2(m0.block(0, 0, rows, cols)), 1);
|
| 35 |
+
|
| 36 |
+
Wrapper<MatrixType> wrapper(m0);
|
| 37 |
+
VERIFY_EVALUATION_COUNT(MatrixType m3(wrapper), 1);
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
EIGEN_DECLARE_TEST(constructor) {
|
| 41 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 42 |
+
CALL_SUBTEST_1(ctor_init1(Matrix<float, 1, 1>()));
|
| 43 |
+
CALL_SUBTEST_1(ctor_init1(Matrix4d()));
|
| 44 |
+
CALL_SUBTEST_1(ctor_init1(
|
| 45 |
+
MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 46 |
+
CALL_SUBTEST_1(ctor_init1(
|
| 47 |
+
MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 48 |
+
}
|
| 49 |
+
{
|
| 50 |
+
Matrix<Index, 1, 1> a(123);
|
| 51 |
+
VERIFY_IS_EQUAL(a[0], 123);
|
| 52 |
+
}
|
| 53 |
+
{
|
| 54 |
+
Matrix<Index, 1, 1> a(123.0);
|
| 55 |
+
VERIFY_IS_EQUAL(a[0], 123);
|
| 56 |
+
}
|
| 57 |
+
{
|
| 58 |
+
Matrix<float, 1, 1> a(123);
|
| 59 |
+
VERIFY_IS_EQUAL(a[0], 123.f);
|
| 60 |
+
}
|
| 61 |
+
{
|
| 62 |
+
Array<Index, 1, 1> a(123);
|
| 63 |
+
VERIFY_IS_EQUAL(a[0], 123);
|
| 64 |
+
}
|
| 65 |
+
{
|
| 66 |
+
Array<Index, 1, 1> a(123.0);
|
| 67 |
+
VERIFY_IS_EQUAL(a[0], 123);
|
| 68 |
+
}
|
| 69 |
+
{
|
| 70 |
+
Array<float, 1, 1> a(123);
|
| 71 |
+
VERIFY_IS_EQUAL(a[0], 123.f);
|
| 72 |
+
}
|
| 73 |
+
{
|
| 74 |
+
Array<Index, 3, 3> a(123);
|
| 75 |
+
VERIFY_IS_EQUAL(a(4), 123);
|
| 76 |
+
}
|
| 77 |
+
{
|
| 78 |
+
Array<Index, 3, 3> a(123.0);
|
| 79 |
+
VERIFY_IS_EQUAL(a(4), 123);
|
| 80 |
+
}
|
| 81 |
+
{
|
| 82 |
+
Array<float, 3, 3> a(123);
|
| 83 |
+
VERIFY_IS_EQUAL(a(4), 123.f);
|
| 84 |
+
}
|
| 85 |
+
{
|
| 86 |
+
MatrixXi m1(M, N);
|
| 87 |
+
VERIFY_IS_EQUAL(m1.rows(), M);
|
| 88 |
+
VERIFY_IS_EQUAL(m1.cols(), N);
|
| 89 |
+
ArrayXXi a1(M, N);
|
| 90 |
+
VERIFY_IS_EQUAL(a1.rows(), M);
|
| 91 |
+
VERIFY_IS_EQUAL(a1.cols(), N);
|
| 92 |
+
VectorXi v1(M);
|
| 93 |
+
VERIFY_IS_EQUAL(v1.size(), M);
|
| 94 |
+
ArrayXi a2(M);
|
| 95 |
+
VERIFY_IS_EQUAL(a2.size(), M);
|
| 96 |
+
}
|
| 97 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/corners.cpp
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2006-2010 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
#define COMPARE_CORNER(A, B) \
|
| 13 |
+
VERIFY_IS_EQUAL(matrix.A, matrix.B); \
|
| 14 |
+
VERIFY_IS_EQUAL(const_matrix.A, const_matrix.B);
|
| 15 |
+
|
| 16 |
+
template <typename MatrixType>
|
| 17 |
+
void corners(const MatrixType& m) {
|
| 18 |
+
Index rows = m.rows();
|
| 19 |
+
Index cols = m.cols();
|
| 20 |
+
|
| 21 |
+
Index r = internal::random<Index>(1, rows);
|
| 22 |
+
Index c = internal::random<Index>(1, cols);
|
| 23 |
+
|
| 24 |
+
MatrixType matrix = MatrixType::Random(rows, cols);
|
| 25 |
+
const MatrixType const_matrix = MatrixType::Random(rows, cols);
|
| 26 |
+
|
| 27 |
+
COMPARE_CORNER(topLeftCorner(r, c), block(0, 0, r, c));
|
| 28 |
+
COMPARE_CORNER(topRightCorner(r, c), block(0, cols - c, r, c));
|
| 29 |
+
COMPARE_CORNER(bottomLeftCorner(r, c), block(rows - r, 0, r, c));
|
| 30 |
+
COMPARE_CORNER(bottomRightCorner(r, c), block(rows - r, cols - c, r, c));
|
| 31 |
+
|
| 32 |
+
Index sr = internal::random<Index>(1, rows) - 1;
|
| 33 |
+
Index nr = internal::random<Index>(1, rows - sr);
|
| 34 |
+
Index sc = internal::random<Index>(1, cols) - 1;
|
| 35 |
+
Index nc = internal::random<Index>(1, cols - sc);
|
| 36 |
+
|
| 37 |
+
COMPARE_CORNER(topRows(r), block(0, 0, r, cols));
|
| 38 |
+
COMPARE_CORNER(middleRows(sr, nr), block(sr, 0, nr, cols));
|
| 39 |
+
COMPARE_CORNER(bottomRows(r), block(rows - r, 0, r, cols));
|
| 40 |
+
COMPARE_CORNER(leftCols(c), block(0, 0, rows, c));
|
| 41 |
+
COMPARE_CORNER(middleCols(sc, nc), block(0, sc, rows, nc));
|
| 42 |
+
COMPARE_CORNER(rightCols(c), block(0, cols - c, rows, c));
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
template <typename MatrixType, int CRows, int CCols, int SRows, int SCols>
|
| 46 |
+
void corners_fixedsize() {
|
| 47 |
+
MatrixType matrix = MatrixType::Random();
|
| 48 |
+
const MatrixType const_matrix = MatrixType::Random();
|
| 49 |
+
|
| 50 |
+
enum {
|
| 51 |
+
rows = MatrixType::RowsAtCompileTime,
|
| 52 |
+
cols = MatrixType::ColsAtCompileTime,
|
| 53 |
+
r = CRows,
|
| 54 |
+
c = CCols,
|
| 55 |
+
sr = SRows,
|
| 56 |
+
sc = SCols
|
| 57 |
+
};
|
| 58 |
+
|
| 59 |
+
VERIFY_IS_EQUAL((matrix.template topLeftCorner<r, c>()), (matrix.template block<r, c>(0, 0)));
|
| 60 |
+
VERIFY_IS_EQUAL((matrix.template topRightCorner<r, c>()), (matrix.template block<r, c>(0, cols - c)));
|
| 61 |
+
VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r, c>()), (matrix.template block<r, c>(rows - r, 0)));
|
| 62 |
+
VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r, c>()), (matrix.template block<r, c>(rows - r, cols - c)));
|
| 63 |
+
|
| 64 |
+
VERIFY_IS_EQUAL((matrix.template topLeftCorner<r, c>()), (matrix.template topLeftCorner<r, Dynamic>(r, c)));
|
| 65 |
+
VERIFY_IS_EQUAL((matrix.template topRightCorner<r, c>()), (matrix.template topRightCorner<r, Dynamic>(r, c)));
|
| 66 |
+
VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r, c>()), (matrix.template bottomLeftCorner<r, Dynamic>(r, c)));
|
| 67 |
+
VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r, c>()), (matrix.template bottomRightCorner<r, Dynamic>(r, c)));
|
| 68 |
+
|
| 69 |
+
VERIFY_IS_EQUAL((matrix.template topLeftCorner<r, c>()), (matrix.template topLeftCorner<Dynamic, c>(r, c)));
|
| 70 |
+
VERIFY_IS_EQUAL((matrix.template topRightCorner<r, c>()), (matrix.template topRightCorner<Dynamic, c>(r, c)));
|
| 71 |
+
VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r, c>()), (matrix.template bottomLeftCorner<Dynamic, c>(r, c)));
|
| 72 |
+
VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r, c>()), (matrix.template bottomRightCorner<Dynamic, c>(r, c)));
|
| 73 |
+
|
| 74 |
+
VERIFY_IS_EQUAL((matrix.template topRows<r>()), (matrix.template block<r, cols>(0, 0)));
|
| 75 |
+
VERIFY_IS_EQUAL((matrix.template middleRows<r>(sr)), (matrix.template block<r, cols>(sr, 0)));
|
| 76 |
+
VERIFY_IS_EQUAL((matrix.template bottomRows<r>()), (matrix.template block<r, cols>(rows - r, 0)));
|
| 77 |
+
VERIFY_IS_EQUAL((matrix.template leftCols<c>()), (matrix.template block<rows, c>(0, 0)));
|
| 78 |
+
VERIFY_IS_EQUAL((matrix.template middleCols<c>(sc)), (matrix.template block<rows, c>(0, sc)));
|
| 79 |
+
VERIFY_IS_EQUAL((matrix.template rightCols<c>()), (matrix.template block<rows, c>(0, cols - c)));
|
| 80 |
+
|
| 81 |
+
VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r, c>()), (const_matrix.template block<r, c>(0, 0)));
|
| 82 |
+
VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r, c>()), (const_matrix.template block<r, c>(0, cols - c)));
|
| 83 |
+
VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r, c>()), (const_matrix.template block<r, c>(rows - r, 0)));
|
| 84 |
+
VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r, c>()),
|
| 85 |
+
(const_matrix.template block<r, c>(rows - r, cols - c)));
|
| 86 |
+
|
| 87 |
+
VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r, c>()),
|
| 88 |
+
(const_matrix.template topLeftCorner<r, Dynamic>(r, c)));
|
| 89 |
+
VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r, c>()),
|
| 90 |
+
(const_matrix.template topRightCorner<r, Dynamic>(r, c)));
|
| 91 |
+
VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r, c>()),
|
| 92 |
+
(const_matrix.template bottomLeftCorner<r, Dynamic>(r, c)));
|
| 93 |
+
VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r, c>()),
|
| 94 |
+
(const_matrix.template bottomRightCorner<r, Dynamic>(r, c)));
|
| 95 |
+
|
| 96 |
+
VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r, c>()),
|
| 97 |
+
(const_matrix.template topLeftCorner<Dynamic, c>(r, c)));
|
| 98 |
+
VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r, c>()),
|
| 99 |
+
(const_matrix.template topRightCorner<Dynamic, c>(r, c)));
|
| 100 |
+
VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r, c>()),
|
| 101 |
+
(const_matrix.template bottomLeftCorner<Dynamic, c>(r, c)));
|
| 102 |
+
VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r, c>()),
|
| 103 |
+
(const_matrix.template bottomRightCorner<Dynamic, c>(r, c)));
|
| 104 |
+
|
| 105 |
+
VERIFY_IS_EQUAL((const_matrix.template topRows<r>()), (const_matrix.template block<r, cols>(0, 0)));
|
| 106 |
+
VERIFY_IS_EQUAL((const_matrix.template middleRows<r>(sr)), (const_matrix.template block<r, cols>(sr, 0)));
|
| 107 |
+
VERIFY_IS_EQUAL((const_matrix.template bottomRows<r>()), (const_matrix.template block<r, cols>(rows - r, 0)));
|
| 108 |
+
VERIFY_IS_EQUAL((const_matrix.template leftCols<c>()), (const_matrix.template block<rows, c>(0, 0)));
|
| 109 |
+
VERIFY_IS_EQUAL((const_matrix.template middleCols<c>(sc)), (const_matrix.template block<rows, c>(0, sc)));
|
| 110 |
+
VERIFY_IS_EQUAL((const_matrix.template rightCols<c>()), (const_matrix.template block<rows, c>(0, cols - c)));
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
EIGEN_DECLARE_TEST(corners) {
|
| 114 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 115 |
+
CALL_SUBTEST_1(corners(Matrix<float, 1, 1>()));
|
| 116 |
+
CALL_SUBTEST_2(corners(Matrix4d()));
|
| 117 |
+
CALL_SUBTEST_3(corners(Matrix<int, 10, 12>()));
|
| 118 |
+
CALL_SUBTEST_4(corners(MatrixXcf(5, 7)));
|
| 119 |
+
CALL_SUBTEST_5(corners(MatrixXf(21, 20)));
|
| 120 |
+
|
| 121 |
+
CALL_SUBTEST_1((corners_fixedsize<Matrix<float, 1, 1>, 1, 1, 0, 0>()));
|
| 122 |
+
CALL_SUBTEST_2((corners_fixedsize<Matrix4d, 2, 2, 1, 1>()));
|
| 123 |
+
CALL_SUBTEST_3((corners_fixedsize<Matrix<int, 10, 12>, 4, 7, 5, 2>()));
|
| 124 |
+
}
|
| 125 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/ctorleak.cpp
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "main.h"
|
| 2 |
+
|
| 3 |
+
#include <exception> // std::exception
|
| 4 |
+
|
| 5 |
+
struct Foo {
|
| 6 |
+
static Index object_count;
|
| 7 |
+
static Index object_limit;
|
| 8 |
+
int dummy;
|
| 9 |
+
|
| 10 |
+
Foo() : dummy(0) {
|
| 11 |
+
#ifdef EIGEN_EXCEPTIONS
|
| 12 |
+
// TODO: Is this the correct way to handle this?
|
| 13 |
+
if (Foo::object_count > Foo::object_limit) {
|
| 14 |
+
std::cout << "\nThrow!\n";
|
| 15 |
+
throw Foo::Fail();
|
| 16 |
+
}
|
| 17 |
+
#endif
|
| 18 |
+
std::cout << '+';
|
| 19 |
+
++Foo::object_count;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
~Foo() {
|
| 23 |
+
std::cout << '-';
|
| 24 |
+
--Foo::object_count;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
class Fail : public std::exception {};
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
Index Foo::object_count = 0;
|
| 31 |
+
Index Foo::object_limit = 0;
|
| 32 |
+
|
| 33 |
+
#undef EIGEN_TEST_MAX_SIZE
|
| 34 |
+
#define EIGEN_TEST_MAX_SIZE 3
|
| 35 |
+
|
| 36 |
+
EIGEN_DECLARE_TEST(ctorleak) {
|
| 37 |
+
typedef Matrix<Foo, Dynamic, Dynamic> MatrixX;
|
| 38 |
+
typedef Matrix<Foo, Dynamic, 1> VectorX;
|
| 39 |
+
|
| 40 |
+
Foo::object_count = 0;
|
| 41 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 42 |
+
Index rows = internal::random<Index>(2, EIGEN_TEST_MAX_SIZE),
|
| 43 |
+
cols = internal::random<Index>(2, EIGEN_TEST_MAX_SIZE);
|
| 44 |
+
Foo::object_limit = rows * cols;
|
| 45 |
+
{
|
| 46 |
+
MatrixX r(rows, cols);
|
| 47 |
+
Foo::object_limit = r.size() + internal::random<Index>(0, rows * cols - 2);
|
| 48 |
+
std::cout << "object_limit =" << Foo::object_limit << std::endl;
|
| 49 |
+
#ifdef EIGEN_EXCEPTIONS
|
| 50 |
+
try {
|
| 51 |
+
#endif
|
| 52 |
+
if (internal::random<bool>()) {
|
| 53 |
+
std::cout << "\nMatrixX m(" << rows << ", " << cols << ");\n";
|
| 54 |
+
MatrixX m(rows, cols);
|
| 55 |
+
} else {
|
| 56 |
+
std::cout << "\nMatrixX m(r);\n";
|
| 57 |
+
MatrixX m(r);
|
| 58 |
+
}
|
| 59 |
+
#ifdef EIGEN_EXCEPTIONS
|
| 60 |
+
VERIFY(false); // not reached if exceptions are enabled
|
| 61 |
+
} catch (const Foo::Fail&) { /* ignore */
|
| 62 |
+
}
|
| 63 |
+
#endif
|
| 64 |
+
}
|
| 65 |
+
VERIFY_IS_EQUAL(Index(0), Foo::object_count);
|
| 66 |
+
|
| 67 |
+
{
|
| 68 |
+
Foo::object_limit = (rows + 1) * (cols + 1);
|
| 69 |
+
MatrixX A(rows, cols);
|
| 70 |
+
VERIFY_IS_EQUAL(Foo::object_count, rows * cols);
|
| 71 |
+
VectorX v = A.row(0);
|
| 72 |
+
VERIFY_IS_EQUAL(Foo::object_count, (rows + 1) * cols);
|
| 73 |
+
v = A.col(0);
|
| 74 |
+
VERIFY_IS_EQUAL(Foo::object_count, rows * (cols + 1));
|
| 75 |
+
}
|
| 76 |
+
VERIFY_IS_EQUAL(Index(0), Foo::object_count);
|
| 77 |
+
}
|
| 78 |
+
std::cout << "\n";
|
| 79 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/denseLM.cpp
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
|
| 5 |
+
// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 6 |
+
//
|
| 7 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 8 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 9 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 10 |
+
|
| 11 |
+
#include <iostream>
|
| 12 |
+
#include <fstream>
|
| 13 |
+
#include <iomanip>
|
| 14 |
+
|
| 15 |
+
#include "main.h"
|
| 16 |
+
#include <Eigen/LevenbergMarquardt>
|
| 17 |
+
using namespace std;
|
| 18 |
+
using namespace Eigen;
|
| 19 |
+
|
| 20 |
+
template <typename Scalar>
|
| 21 |
+
struct DenseLM : DenseFunctor<Scalar> {
|
| 22 |
+
typedef DenseFunctor<Scalar> Base;
|
| 23 |
+
typedef typename Base::JacobianType JacobianType;
|
| 24 |
+
typedef Matrix<Scalar, Dynamic, 1> VectorType;
|
| 25 |
+
|
| 26 |
+
DenseLM(int n, int m) : DenseFunctor<Scalar>(n, m) {}
|
| 27 |
+
|
| 28 |
+
VectorType model(const VectorType& uv, VectorType& x) {
|
| 29 |
+
VectorType y; // Should change to use expression template
|
| 30 |
+
int m = Base::values();
|
| 31 |
+
int n = Base::inputs();
|
| 32 |
+
eigen_assert(uv.size() % 2 == 0);
|
| 33 |
+
eigen_assert(uv.size() == n);
|
| 34 |
+
eigen_assert(x.size() == m);
|
| 35 |
+
y.setZero(m);
|
| 36 |
+
int half = n / 2;
|
| 37 |
+
VectorBlock<const VectorType> u(uv, 0, half);
|
| 38 |
+
VectorBlock<const VectorType> v(uv, half, half);
|
| 39 |
+
for (int j = 0; j < m; j++) {
|
| 40 |
+
for (int i = 0; i < half; i++) y(j) += u(i) * std::exp(-(x(j) - i) * (x(j) - i) / (v(i) * v(i)));
|
| 41 |
+
}
|
| 42 |
+
return y;
|
| 43 |
+
}
|
| 44 |
+
void initPoints(VectorType& uv_ref, VectorType& x) {
|
| 45 |
+
m_x = x;
|
| 46 |
+
m_y = this->model(uv_ref, x);
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
int operator()(const VectorType& uv, VectorType& fvec) {
|
| 50 |
+
int m = Base::values();
|
| 51 |
+
int n = Base::inputs();
|
| 52 |
+
eigen_assert(uv.size() % 2 == 0);
|
| 53 |
+
eigen_assert(uv.size() == n);
|
| 54 |
+
eigen_assert(fvec.size() == m);
|
| 55 |
+
int half = n / 2;
|
| 56 |
+
VectorBlock<const VectorType> u(uv, 0, half);
|
| 57 |
+
VectorBlock<const VectorType> v(uv, half, half);
|
| 58 |
+
for (int j = 0; j < m; j++) {
|
| 59 |
+
fvec(j) = m_y(j);
|
| 60 |
+
for (int i = 0; i < half; i++) {
|
| 61 |
+
fvec(j) -= u(i) * std::exp(-(m_x(j) - i) * (m_x(j) - i) / (v(i) * v(i)));
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
return 0;
|
| 66 |
+
}
|
| 67 |
+
int df(const VectorType& uv, JacobianType& fjac) {
|
| 68 |
+
int m = Base::values();
|
| 69 |
+
int n = Base::inputs();
|
| 70 |
+
eigen_assert(n == uv.size());
|
| 71 |
+
eigen_assert(fjac.rows() == m);
|
| 72 |
+
eigen_assert(fjac.cols() == n);
|
| 73 |
+
int half = n / 2;
|
| 74 |
+
VectorBlock<const VectorType> u(uv, 0, half);
|
| 75 |
+
VectorBlock<const VectorType> v(uv, half, half);
|
| 76 |
+
for (int j = 0; j < m; j++) {
|
| 77 |
+
for (int i = 0; i < half; i++) {
|
| 78 |
+
fjac.coeffRef(j, i) = -std::exp(-(m_x(j) - i) * (m_x(j) - i) / (v(i) * v(i)));
|
| 79 |
+
fjac.coeffRef(j, i + half) = -2. * u(i) * (m_x(j) - i) * (m_x(j) - i) / (std::pow(v(i), 3)) *
|
| 80 |
+
std::exp(-(m_x(j) - i) * (m_x(j) - i) / (v(i) * v(i)));
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
return 0;
|
| 84 |
+
}
|
| 85 |
+
VectorType m_x, m_y; // Data Points
|
| 86 |
+
};
|
| 87 |
+
|
| 88 |
+
template <typename FunctorType, typename VectorType>
|
| 89 |
+
int test_minimizeLM(FunctorType& functor, VectorType& uv) {
|
| 90 |
+
LevenbergMarquardt<FunctorType> lm(functor);
|
| 91 |
+
LevenbergMarquardtSpace::Status info;
|
| 92 |
+
|
| 93 |
+
info = lm.minimize(uv);
|
| 94 |
+
|
| 95 |
+
VERIFY_IS_EQUAL(info, 1);
|
| 96 |
+
// FIXME Check other parameters
|
| 97 |
+
return info;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
template <typename FunctorType, typename VectorType>
|
| 101 |
+
int test_lmder(FunctorType& functor, VectorType& uv) {
|
| 102 |
+
typedef typename VectorType::Scalar Scalar;
|
| 103 |
+
LevenbergMarquardtSpace::Status info;
|
| 104 |
+
LevenbergMarquardt<FunctorType> lm(functor);
|
| 105 |
+
info = lm.lmder1(uv);
|
| 106 |
+
|
| 107 |
+
VERIFY_IS_EQUAL(info, 1);
|
| 108 |
+
// FIXME Check other parameters
|
| 109 |
+
return info;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
template <typename FunctorType, typename VectorType>
|
| 113 |
+
int test_minimizeSteps(FunctorType& functor, VectorType& uv) {
|
| 114 |
+
LevenbergMarquardtSpace::Status info;
|
| 115 |
+
LevenbergMarquardt<FunctorType> lm(functor);
|
| 116 |
+
info = lm.minimizeInit(uv);
|
| 117 |
+
if (info == LevenbergMarquardtSpace::ImproperInputParameters) return info;
|
| 118 |
+
do {
|
| 119 |
+
info = lm.minimizeOneStep(uv);
|
| 120 |
+
} while (info == LevenbergMarquardtSpace::Running);
|
| 121 |
+
|
| 122 |
+
VERIFY_IS_EQUAL(info, 1);
|
| 123 |
+
// FIXME Check other parameters
|
| 124 |
+
return info;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
template <typename T>
|
| 128 |
+
void test_denseLM_T() {
|
| 129 |
+
typedef Matrix<T, Dynamic, 1> VectorType;
|
| 130 |
+
|
| 131 |
+
int inputs = 10;
|
| 132 |
+
int values = 1000;
|
| 133 |
+
DenseLM<T> dense_gaussian(inputs, values);
|
| 134 |
+
VectorType uv(inputs), uv_ref(inputs);
|
| 135 |
+
VectorType x(values);
|
| 136 |
+
|
| 137 |
+
// Generate the reference solution
|
| 138 |
+
uv_ref << -2, 1, 4, 8, 6, 1.8, 1.2, 1.1, 1.9, 3;
|
| 139 |
+
|
| 140 |
+
// Generate the reference data points
|
| 141 |
+
x.setRandom();
|
| 142 |
+
x = 10 * x;
|
| 143 |
+
x.array() += 10;
|
| 144 |
+
dense_gaussian.initPoints(uv_ref, x);
|
| 145 |
+
|
| 146 |
+
// Generate the initial parameters
|
| 147 |
+
VectorBlock<VectorType> u(uv, 0, inputs / 2);
|
| 148 |
+
VectorBlock<VectorType> v(uv, inputs / 2, inputs / 2);
|
| 149 |
+
|
| 150 |
+
// Solve the optimization problem
|
| 151 |
+
|
| 152 |
+
// Solve in one go
|
| 153 |
+
u.setOnes();
|
| 154 |
+
v.setOnes();
|
| 155 |
+
test_minimizeLM(dense_gaussian, uv);
|
| 156 |
+
|
| 157 |
+
// Solve until the machine precision
|
| 158 |
+
u.setOnes();
|
| 159 |
+
v.setOnes();
|
| 160 |
+
test_lmder(dense_gaussian, uv);
|
| 161 |
+
|
| 162 |
+
// Solve step by step
|
| 163 |
+
v.setOnes();
|
| 164 |
+
u.setOnes();
|
| 165 |
+
test_minimizeSteps(dense_gaussian, uv);
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
EIGEN_DECLARE_TEST(denseLM) {
|
| 169 |
+
CALL_SUBTEST_2(test_denseLM_T<double>());
|
| 170 |
+
|
| 171 |
+
// CALL_SUBTEST_2(test_sparseLM_T<std::complex<double>());
|
| 172 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/dense_storage.cpp
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2013 Hauke Heibel <hauke.heibel@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_TESTING_PLAINOBJECT_CTOR
|
| 11 |
+
|
| 12 |
+
#include "main.h"
|
| 13 |
+
#include "AnnoyingScalar.h"
|
| 14 |
+
#include "MovableScalar.h"
|
| 15 |
+
#include "SafeScalar.h"
|
| 16 |
+
|
| 17 |
+
#include <Eigen/Core>
|
| 18 |
+
|
| 19 |
+
using DenseStorageD3x3 = Eigen::DenseStorage<double, 9, 3, 3, 0>;
|
| 20 |
+
#if !defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
|
| 21 |
+
static_assert(std::is_trivially_copy_constructible<DenseStorageD3x3>::value,
|
| 22 |
+
"DenseStorage not trivially_copy_constructible");
|
| 23 |
+
static_assert(std::is_trivially_move_constructible<DenseStorageD3x3>::value,
|
| 24 |
+
"DenseStorage not trivially_move_constructible");
|
| 25 |
+
static_assert(std::is_trivially_copy_assignable<DenseStorageD3x3>::value, "DenseStorage not trivially_copy_assignable");
|
| 26 |
+
static_assert(std::is_trivially_move_assignable<DenseStorageD3x3>::value, "DenseStorage not trivially_move_assignable");
|
| 27 |
+
#endif
|
| 28 |
+
// all plain object types conform to standard layout
|
| 29 |
+
static_assert(std::is_standard_layout<Matrix4f>::value, "Matrix4f not standard_layout");
|
| 30 |
+
static_assert(std::is_standard_layout<Array4f>::value, "Array4f not standard_layout");
|
| 31 |
+
static_assert(std::is_standard_layout<VectorXf>::value, "VectorXf not standard_layout");
|
| 32 |
+
static_assert(std::is_standard_layout<ArrayXf>::value, "ArrayXf not standard_layout");
|
| 33 |
+
static_assert(std::is_standard_layout<MatrixXf>::value, "MatrixXf not standard_layout");
|
| 34 |
+
static_assert(std::is_standard_layout<ArrayXXf>::value, "ArrayXXf not standard_layout");
|
| 35 |
+
// all fixed-size, fixed-dimension plain object types are trivially default constructible
|
| 36 |
+
static_assert(std::is_trivially_default_constructible<Matrix4f>::value, "Matrix4f not trivially_default_constructible");
|
| 37 |
+
static_assert(std::is_trivially_default_constructible<Array4f>::value, "Array4f not trivially_default_constructible");
|
| 38 |
+
// all fixed-size, fixed-dimension plain object types are trivially move constructible
|
| 39 |
+
static_assert(std::is_trivially_move_constructible<Matrix4f>::value, "Matrix4f not trivially_move_constructible");
|
| 40 |
+
static_assert(std::is_trivially_move_constructible<Array4f>::value, "Array4f not trivially_move_constructible");
|
| 41 |
+
// all statically-allocated plain object types are trivially destructible
|
| 42 |
+
static_assert(std::is_trivially_destructible<Matrix4f>::value, "Matrix4f not trivially_destructible");
|
| 43 |
+
static_assert(std::is_trivially_destructible<Array4f>::value, "Array4f not trivially_destructible");
|
| 44 |
+
static_assert(std::is_trivially_destructible<Matrix<float, 4, Dynamic, 0, 4, 4>>::value,
|
| 45 |
+
"Matrix4X44 not trivially_destructible");
|
| 46 |
+
static_assert(std::is_trivially_destructible<Array<float, 4, Dynamic, 0, 4, 4>>::value,
|
| 47 |
+
"Array4X44 not trivially_destructible");
|
| 48 |
+
#if !defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
|
| 49 |
+
// all fixed-size, fixed-dimension plain object types are trivially copy constructible
|
| 50 |
+
static_assert(std::is_trivially_copy_constructible<Matrix4f>::value, "Matrix4f not trivially_copy_constructible");
|
| 51 |
+
static_assert(std::is_trivially_copy_constructible<Array4f>::value, "Array4f not trivially_copy_constructible");
|
| 52 |
+
#endif
|
| 53 |
+
|
| 54 |
+
template <typename T, int Size, int Rows, int Cols>
|
| 55 |
+
void dense_storage_copy(int rows, int cols) {
|
| 56 |
+
typedef DenseStorage<T, Size, Rows, Cols, 0> DenseStorageType;
|
| 57 |
+
|
| 58 |
+
const int size = rows * cols;
|
| 59 |
+
DenseStorageType reference(size, rows, cols);
|
| 60 |
+
T* raw_reference = reference.data();
|
| 61 |
+
for (int i = 0; i < size; ++i) raw_reference[i] = internal::random<T>();
|
| 62 |
+
|
| 63 |
+
DenseStorageType copied_reference(reference);
|
| 64 |
+
const T* raw_copied_reference = copied_reference.data();
|
| 65 |
+
for (int i = 0; i < size; ++i) VERIFY_IS_EQUAL(raw_reference[i], raw_copied_reference[i]);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
template <typename T, int Size, int Rows, int Cols>
|
| 69 |
+
void dense_storage_assignment(int rows, int cols) {
|
| 70 |
+
typedef DenseStorage<T, Size, Rows, Cols, 0> DenseStorageType;
|
| 71 |
+
|
| 72 |
+
const int size = rows * cols;
|
| 73 |
+
DenseStorageType reference(size, rows, cols);
|
| 74 |
+
T* raw_reference = reference.data();
|
| 75 |
+
for (int i = 0; i < size; ++i) raw_reference[i] = internal::random<T>();
|
| 76 |
+
|
| 77 |
+
DenseStorageType copied_reference;
|
| 78 |
+
copied_reference = reference;
|
| 79 |
+
const T* raw_copied_reference = copied_reference.data();
|
| 80 |
+
for (int i = 0; i < size; ++i) VERIFY_IS_EQUAL(raw_reference[i], raw_copied_reference[i]);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
template <typename T, int Size, int Rows, int Cols>
|
| 84 |
+
void dense_storage_swap(int rowsa, int colsa, int rowsb, int colsb) {
|
| 85 |
+
typedef DenseStorage<T, Size, Rows, Cols, 0> DenseStorageType;
|
| 86 |
+
|
| 87 |
+
const int sizea = rowsa * colsa;
|
| 88 |
+
ArrayX<T> referencea(sizea);
|
| 89 |
+
referencea.setRandom();
|
| 90 |
+
DenseStorageType a(sizea, rowsa, colsa);
|
| 91 |
+
for (int i = 0; i < sizea; ++i) a.data()[i] = referencea(i);
|
| 92 |
+
|
| 93 |
+
const int sizeb = rowsb * colsb;
|
| 94 |
+
ArrayX<T> referenceb(sizeb);
|
| 95 |
+
referenceb.setRandom();
|
| 96 |
+
DenseStorageType b(sizeb, rowsb, colsb);
|
| 97 |
+
for (int i = 0; i < sizeb; ++i) b.data()[i] = referenceb(i);
|
| 98 |
+
|
| 99 |
+
a.swap(b);
|
| 100 |
+
|
| 101 |
+
for (int i = 0; i < sizea; i++) VERIFY_IS_EQUAL(b.data()[i], referencea(i));
|
| 102 |
+
for (int i = 0; i < sizeb; i++) VERIFY_IS_EQUAL(a.data()[i], referenceb(i));
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
template <typename T, int Size, std::size_t Alignment>
|
| 106 |
+
void dense_storage_alignment() {
|
| 107 |
+
struct alignas(Alignment) Empty1 {};
|
| 108 |
+
VERIFY_IS_EQUAL(std::alignment_of<Empty1>::value, Alignment);
|
| 109 |
+
|
| 110 |
+
struct EIGEN_ALIGN_TO_BOUNDARY(Alignment) Empty2 {};
|
| 111 |
+
VERIFY_IS_EQUAL(std::alignment_of<Empty2>::value, Alignment);
|
| 112 |
+
|
| 113 |
+
struct Nested1 {
|
| 114 |
+
EIGEN_ALIGN_TO_BOUNDARY(Alignment) T data[Size];
|
| 115 |
+
};
|
| 116 |
+
VERIFY_IS_EQUAL(std::alignment_of<Nested1>::value, Alignment);
|
| 117 |
+
|
| 118 |
+
VERIFY_IS_EQUAL((std::alignment_of<internal::plain_array<T, Size, AutoAlign, Alignment>>::value), Alignment);
|
| 119 |
+
|
| 120 |
+
const std::size_t default_alignment = internal::compute_default_alignment<T, Size>::value;
|
| 121 |
+
if (default_alignment > 0) {
|
| 122 |
+
VERIFY_IS_EQUAL((std::alignment_of<DenseStorage<T, Size, 1, 1, AutoAlign>>::value), default_alignment);
|
| 123 |
+
VERIFY_IS_EQUAL((std::alignment_of<Matrix<T, Size, 1, AutoAlign>>::value), default_alignment);
|
| 124 |
+
struct Nested2 {
|
| 125 |
+
Matrix<T, Size, 1, AutoAlign> mat;
|
| 126 |
+
};
|
| 127 |
+
VERIFY_IS_EQUAL(std::alignment_of<Nested2>::value, default_alignment);
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
template <typename T>
|
| 132 |
+
void dense_storage_tests() {
|
| 133 |
+
// Dynamic Storage.
|
| 134 |
+
dense_storage_copy<T, Dynamic, Dynamic, Dynamic>(4, 3);
|
| 135 |
+
dense_storage_copy<T, Dynamic, Dynamic, 3>(4, 3);
|
| 136 |
+
dense_storage_copy<T, Dynamic, 4, Dynamic>(4, 3);
|
| 137 |
+
// Fixed Storage.
|
| 138 |
+
dense_storage_copy<T, 12, 4, 3>(4, 3);
|
| 139 |
+
dense_storage_copy<T, 12, Dynamic, Dynamic>(4, 3);
|
| 140 |
+
dense_storage_copy<T, 12, 4, Dynamic>(4, 3);
|
| 141 |
+
dense_storage_copy<T, 12, Dynamic, 3>(4, 3);
|
| 142 |
+
// Fixed Storage with Uninitialized Elements.
|
| 143 |
+
dense_storage_copy<T, 18, Dynamic, Dynamic>(4, 3);
|
| 144 |
+
dense_storage_copy<T, 18, 4, Dynamic>(4, 3);
|
| 145 |
+
dense_storage_copy<T, 18, Dynamic, 3>(4, 3);
|
| 146 |
+
|
| 147 |
+
// Dynamic Storage.
|
| 148 |
+
dense_storage_assignment<T, Dynamic, Dynamic, Dynamic>(4, 3);
|
| 149 |
+
dense_storage_assignment<T, Dynamic, Dynamic, 3>(4, 3);
|
| 150 |
+
dense_storage_assignment<T, Dynamic, 4, Dynamic>(4, 3);
|
| 151 |
+
// Fixed Storage.
|
| 152 |
+
dense_storage_assignment<T, 12, 4, 3>(4, 3);
|
| 153 |
+
dense_storage_assignment<T, 12, Dynamic, Dynamic>(4, 3);
|
| 154 |
+
dense_storage_assignment<T, 12, 4, Dynamic>(4, 3);
|
| 155 |
+
dense_storage_assignment<T, 12, Dynamic, 3>(4, 3);
|
| 156 |
+
// Fixed Storage with Uninitialized Elements.
|
| 157 |
+
dense_storage_assignment<T, 18, Dynamic, Dynamic>(4, 3);
|
| 158 |
+
dense_storage_assignment<T, 18, 4, Dynamic>(4, 3);
|
| 159 |
+
dense_storage_assignment<T, 18, Dynamic, 3>(4, 3);
|
| 160 |
+
|
| 161 |
+
// Dynamic Storage.
|
| 162 |
+
dense_storage_swap<T, Dynamic, Dynamic, Dynamic>(4, 3, 4, 3);
|
| 163 |
+
dense_storage_swap<T, Dynamic, Dynamic, Dynamic>(4, 3, 2, 1);
|
| 164 |
+
dense_storage_swap<T, Dynamic, Dynamic, Dynamic>(2, 1, 4, 3);
|
| 165 |
+
dense_storage_swap<T, Dynamic, Dynamic, 3>(4, 3, 4, 3);
|
| 166 |
+
dense_storage_swap<T, Dynamic, Dynamic, 3>(4, 3, 2, 3);
|
| 167 |
+
dense_storage_swap<T, Dynamic, Dynamic, 3>(2, 3, 4, 3);
|
| 168 |
+
dense_storage_swap<T, Dynamic, 4, Dynamic>(4, 3, 4, 3);
|
| 169 |
+
dense_storage_swap<T, Dynamic, 4, Dynamic>(4, 3, 4, 1);
|
| 170 |
+
dense_storage_swap<T, Dynamic, 4, Dynamic>(4, 1, 4, 3);
|
| 171 |
+
// Fixed Storage.
|
| 172 |
+
dense_storage_swap<T, 12, 4, 3>(4, 3, 4, 3);
|
| 173 |
+
dense_storage_swap<T, 12, Dynamic, Dynamic>(4, 3, 4, 3);
|
| 174 |
+
dense_storage_swap<T, 12, Dynamic, Dynamic>(4, 3, 2, 1);
|
| 175 |
+
dense_storage_swap<T, 12, Dynamic, Dynamic>(2, 1, 4, 3);
|
| 176 |
+
dense_storage_swap<T, 12, 4, Dynamic>(4, 3, 4, 3);
|
| 177 |
+
dense_storage_swap<T, 12, 4, Dynamic>(4, 3, 4, 1);
|
| 178 |
+
dense_storage_swap<T, 12, 4, Dynamic>(4, 1, 4, 3);
|
| 179 |
+
dense_storage_swap<T, 12, Dynamic, 3>(4, 3, 4, 3);
|
| 180 |
+
dense_storage_swap<T, 12, Dynamic, 3>(4, 3, 2, 3);
|
| 181 |
+
dense_storage_swap<T, 12, Dynamic, 3>(2, 3, 4, 3);
|
| 182 |
+
// Fixed Storage with Uninitialized Elements.
|
| 183 |
+
dense_storage_swap<T, 18, Dynamic, Dynamic>(4, 3, 4, 3);
|
| 184 |
+
dense_storage_swap<T, 18, Dynamic, Dynamic>(4, 3, 2, 1);
|
| 185 |
+
dense_storage_swap<T, 18, Dynamic, Dynamic>(2, 1, 4, 3);
|
| 186 |
+
dense_storage_swap<T, 18, 4, Dynamic>(4, 3, 4, 3);
|
| 187 |
+
dense_storage_swap<T, 18, 4, Dynamic>(4, 3, 4, 1);
|
| 188 |
+
dense_storage_swap<T, 18, 4, Dynamic>(4, 1, 4, 3);
|
| 189 |
+
dense_storage_swap<T, 18, Dynamic, 3>(4, 3, 4, 3);
|
| 190 |
+
dense_storage_swap<T, 18, Dynamic, 3>(4, 3, 2, 3);
|
| 191 |
+
dense_storage_swap<T, 18, Dynamic, 3>(2, 3, 4, 3);
|
| 192 |
+
|
| 193 |
+
dense_storage_alignment<T, 16, 8>();
|
| 194 |
+
dense_storage_alignment<T, 16, 16>();
|
| 195 |
+
dense_storage_alignment<T, 16, 32>();
|
| 196 |
+
dense_storage_alignment<T, 16, 64>();
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
template <typename PlainType>
|
| 200 |
+
void plaintype_tests() {
|
| 201 |
+
constexpr int RowsAtCompileTime = PlainType::RowsAtCompileTime;
|
| 202 |
+
constexpr int ColsAtCompileTime = PlainType::ColsAtCompileTime;
|
| 203 |
+
constexpr int MaxRowsAtCompileTime = PlainType::MaxRowsAtCompileTime;
|
| 204 |
+
constexpr int MaxColsAtCompileTime = PlainType::MaxColsAtCompileTime;
|
| 205 |
+
const Index expectedDefaultRows = RowsAtCompileTime == Dynamic ? 0 : RowsAtCompileTime;
|
| 206 |
+
const Index expectedDefaultCols = ColsAtCompileTime == Dynamic ? 0 : ColsAtCompileTime;
|
| 207 |
+
const Index minRows = RowsAtCompileTime == Dynamic ? 0 : RowsAtCompileTime;
|
| 208 |
+
const Index minCols = ColsAtCompileTime == Dynamic ? 0 : ColsAtCompileTime;
|
| 209 |
+
const Index maxRows = MaxRowsAtCompileTime == Dynamic ? 100 : MaxRowsAtCompileTime;
|
| 210 |
+
const Index maxCols = MaxColsAtCompileTime == Dynamic ? 100 : MaxColsAtCompileTime;
|
| 211 |
+
const Index rows = internal::random<Index>(minRows, maxRows);
|
| 212 |
+
const Index cols = internal::random<Index>(minCols, maxCols);
|
| 213 |
+
// default construction
|
| 214 |
+
PlainType m0;
|
| 215 |
+
VERIFY_IS_EQUAL(m0.rows(), expectedDefaultRows);
|
| 216 |
+
VERIFY_IS_EQUAL(m0.cols(), expectedDefaultCols);
|
| 217 |
+
m0.resize(rows, cols);
|
| 218 |
+
m0.setRandom();
|
| 219 |
+
// copy construction
|
| 220 |
+
PlainType m1(m0);
|
| 221 |
+
VERIFY_IS_EQUAL(m1.rows(), m0.rows());
|
| 222 |
+
VERIFY_IS_EQUAL(m1.cols(), m0.cols());
|
| 223 |
+
VERIFY_IS_CWISE_EQUAL(m1, m0);
|
| 224 |
+
// move construction
|
| 225 |
+
PlainType m2(std::move(m1));
|
| 226 |
+
VERIFY_IS_EQUAL(m2.rows(), m0.rows());
|
| 227 |
+
VERIFY_IS_EQUAL(m2.cols(), m0.cols());
|
| 228 |
+
VERIFY_IS_CWISE_EQUAL(m2, m0);
|
| 229 |
+
// check that object is usable after move construction
|
| 230 |
+
m1.resize(minRows, minCols);
|
| 231 |
+
m1.setRandom();
|
| 232 |
+
// copy assignment
|
| 233 |
+
m1 = m0;
|
| 234 |
+
VERIFY_IS_EQUAL(m1.rows(), m0.rows());
|
| 235 |
+
VERIFY_IS_EQUAL(m1.cols(), m0.cols());
|
| 236 |
+
VERIFY_IS_CWISE_EQUAL(m1, m0);
|
| 237 |
+
// move assignment
|
| 238 |
+
m2.resize(minRows, minCols);
|
| 239 |
+
m2.setRandom();
|
| 240 |
+
m2 = std::move(m1);
|
| 241 |
+
VERIFY_IS_EQUAL(m2.rows(), m0.rows());
|
| 242 |
+
VERIFY_IS_EQUAL(m2.cols(), m0.cols());
|
| 243 |
+
VERIFY_IS_CWISE_EQUAL(m2, m0);
|
| 244 |
+
// check that object is usable after move assignment
|
| 245 |
+
m1.resize(minRows, minCols);
|
| 246 |
+
m1.setRandom();
|
| 247 |
+
m1 = m2;
|
| 248 |
+
VERIFY_IS_EQUAL(m1.rows(), m0.rows());
|
| 249 |
+
VERIFY_IS_EQUAL(m1.cols(), m0.cols());
|
| 250 |
+
VERIFY_IS_CWISE_EQUAL(m1, m0);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
EIGEN_DECLARE_TEST(dense_storage) {
|
| 254 |
+
dense_storage_tests<int>();
|
| 255 |
+
dense_storage_tests<float>();
|
| 256 |
+
dense_storage_tests<SafeScalar<float>>();
|
| 257 |
+
dense_storage_tests<MovableScalar<float>>();
|
| 258 |
+
dense_storage_tests<AnnoyingScalar>();
|
| 259 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 260 |
+
plaintype_tests<Matrix<float, 0, 0, ColMajor>>();
|
| 261 |
+
plaintype_tests<Matrix<float, Dynamic, Dynamic, ColMajor, 0, 0>>();
|
| 262 |
+
|
| 263 |
+
plaintype_tests<Matrix<float, 16, 16, ColMajor>>();
|
| 264 |
+
plaintype_tests<Matrix<float, 16, Dynamic, ColMajor>>();
|
| 265 |
+
plaintype_tests<Matrix<float, Dynamic, Dynamic, ColMajor>>();
|
| 266 |
+
plaintype_tests<Matrix<float, Dynamic, Dynamic, ColMajor, 16, 16>>();
|
| 267 |
+
|
| 268 |
+
plaintype_tests<Matrix<SafeScalar<float>, 16, 16, ColMajor>>();
|
| 269 |
+
plaintype_tests<Matrix<SafeScalar<float>, 16, Dynamic, ColMajor>>();
|
| 270 |
+
plaintype_tests<Matrix<SafeScalar<float>, Dynamic, Dynamic, ColMajor>>();
|
| 271 |
+
plaintype_tests<Matrix<SafeScalar<float>, Dynamic, Dynamic, ColMajor, 16, 16>>();
|
| 272 |
+
|
| 273 |
+
plaintype_tests<Matrix<MovableScalar<float>, 16, 16, ColMajor>>();
|
| 274 |
+
plaintype_tests<Matrix<MovableScalar<float>, 16, Dynamic, ColMajor>>();
|
| 275 |
+
plaintype_tests<Matrix<MovableScalar<float>, Dynamic, Dynamic, ColMajor>>();
|
| 276 |
+
plaintype_tests<Matrix<MovableScalar<float>, Dynamic, Dynamic, ColMajor, 16, 16>>();
|
| 277 |
+
|
| 278 |
+
plaintype_tests<Matrix<AnnoyingScalar, 16, 16, ColMajor>>();
|
| 279 |
+
plaintype_tests<Matrix<AnnoyingScalar, 16, Dynamic, ColMajor>>();
|
| 280 |
+
plaintype_tests<Matrix<AnnoyingScalar, Dynamic, Dynamic, ColMajor>>();
|
| 281 |
+
plaintype_tests<Matrix<AnnoyingScalar, Dynamic, Dynamic, ColMajor, 16, 16>>();
|
| 282 |
+
}
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
#undef EIGEN_TESTING_PLAINOBJECT_CTOR
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/determinant.cpp
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
| 5 |
+
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 6 |
+
//
|
| 7 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 8 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 9 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 10 |
+
|
| 11 |
+
#include "main.h"
|
| 12 |
+
#include <Eigen/LU>
|
| 13 |
+
|
| 14 |
+
template <typename MatrixType>
|
| 15 |
+
void determinant(const MatrixType& m) {
|
| 16 |
+
/* this test covers the following files:
|
| 17 |
+
Determinant.h
|
| 18 |
+
*/
|
| 19 |
+
Index size = m.rows();
|
| 20 |
+
|
| 21 |
+
MatrixType m1(size, size), m2(size, size);
|
| 22 |
+
m1.setRandom();
|
| 23 |
+
m2.setRandom();
|
| 24 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 25 |
+
Scalar x = internal::random<Scalar>();
|
| 26 |
+
VERIFY_IS_APPROX(MatrixType::Identity(size, size).determinant(), Scalar(1));
|
| 27 |
+
VERIFY_IS_APPROX((m1 * m2).eval().determinant(), m1.determinant() * m2.determinant());
|
| 28 |
+
if (size == 1) return;
|
| 29 |
+
Index i = internal::random<Index>(0, size - 1);
|
| 30 |
+
Index j;
|
| 31 |
+
do {
|
| 32 |
+
j = internal::random<Index>(0, size - 1);
|
| 33 |
+
} while (j == i);
|
| 34 |
+
m2 = m1;
|
| 35 |
+
m2.row(i).swap(m2.row(j));
|
| 36 |
+
VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());
|
| 37 |
+
m2 = m1;
|
| 38 |
+
m2.col(i).swap(m2.col(j));
|
| 39 |
+
VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());
|
| 40 |
+
VERIFY_IS_APPROX(m2.determinant(), m2.transpose().determinant());
|
| 41 |
+
VERIFY_IS_APPROX(numext::conj(m2.determinant()), m2.adjoint().determinant());
|
| 42 |
+
m2 = m1;
|
| 43 |
+
m2.row(i) += x * m2.row(j);
|
| 44 |
+
VERIFY_IS_APPROX(m2.determinant(), m1.determinant());
|
| 45 |
+
m2 = m1;
|
| 46 |
+
m2.row(i) *= x;
|
| 47 |
+
VERIFY_IS_APPROX(m2.determinant(), m1.determinant() * x);
|
| 48 |
+
|
| 49 |
+
// check empty matrix
|
| 50 |
+
VERIFY_IS_APPROX(m2.block(0, 0, 0, 0).determinant(), Scalar(1));
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
EIGEN_DECLARE_TEST(determinant) {
|
| 54 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 55 |
+
int s = 0;
|
| 56 |
+
CALL_SUBTEST_1(determinant(Matrix<float, 1, 1>()));
|
| 57 |
+
CALL_SUBTEST_2(determinant(Matrix<double, 2, 2>()));
|
| 58 |
+
CALL_SUBTEST_3(determinant(Matrix<double, 3, 3>()));
|
| 59 |
+
CALL_SUBTEST_4(determinant(Matrix<double, 4, 4>()));
|
| 60 |
+
CALL_SUBTEST_5(determinant(Matrix<std::complex<double>, 10, 10>()));
|
| 61 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 62 |
+
CALL_SUBTEST_6(determinant(MatrixXd(s, s)));
|
| 63 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 64 |
+
}
|
| 65 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/diagonal.cpp
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2006-2010 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
template <typename MatrixType>
|
| 13 |
+
void diagonal(const MatrixType& m) {
|
| 14 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 15 |
+
|
| 16 |
+
Index rows = m.rows();
|
| 17 |
+
Index cols = m.cols();
|
| 18 |
+
|
| 19 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols);
|
| 20 |
+
|
| 21 |
+
Scalar s1 = internal::random<Scalar>();
|
| 22 |
+
|
| 23 |
+
// check diagonal()
|
| 24 |
+
VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());
|
| 25 |
+
m2.diagonal() = 2 * m1.diagonal();
|
| 26 |
+
m2.diagonal()[0] *= 3;
|
| 27 |
+
|
| 28 |
+
if (rows > 2) {
|
| 29 |
+
enum { N1 = MatrixType::RowsAtCompileTime > 2 ? 2 : 0, N2 = MatrixType::RowsAtCompileTime > 1 ? -1 : 0 };
|
| 30 |
+
|
| 31 |
+
// check sub/super diagonal
|
| 32 |
+
if (MatrixType::SizeAtCompileTime != Dynamic) {
|
| 33 |
+
VERIFY(m1.template diagonal<N1>().RowsAtCompileTime == m1.diagonal(N1).size());
|
| 34 |
+
VERIFY(m1.template diagonal<N2>().RowsAtCompileTime == m1.diagonal(N2).size());
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
m2.template diagonal<N1>() = 2 * m1.template diagonal<N1>();
|
| 38 |
+
VERIFY_IS_APPROX(m2.template diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));
|
| 39 |
+
m2.template diagonal<N1>()[0] *= 3;
|
| 40 |
+
VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]);
|
| 41 |
+
|
| 42 |
+
m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>();
|
| 43 |
+
m2.template diagonal<N2>()[0] *= 3;
|
| 44 |
+
VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]);
|
| 45 |
+
|
| 46 |
+
m2.diagonal(N1) = 2 * m1.diagonal(N1);
|
| 47 |
+
VERIFY_IS_APPROX(m2.template diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));
|
| 48 |
+
m2.diagonal(N1)[0] *= 3;
|
| 49 |
+
VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]);
|
| 50 |
+
|
| 51 |
+
m2.diagonal(N2) = 2 * m1.diagonal(N2);
|
| 52 |
+
VERIFY_IS_APPROX(m2.template diagonal<N2>(), static_cast<Scalar>(2) * m1.diagonal(N2));
|
| 53 |
+
m2.diagonal(N2)[0] *= 3;
|
| 54 |
+
VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]);
|
| 55 |
+
|
| 56 |
+
m2.diagonal(N2).x() = s1;
|
| 57 |
+
VERIFY_IS_APPROX(m2.diagonal(N2).x(), s1);
|
| 58 |
+
m2.diagonal(N2).coeffRef(0) = Scalar(2) * s1;
|
| 59 |
+
VERIFY_IS_APPROX(m2.diagonal(N2).coeff(0), Scalar(2) * s1);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
VERIFY(m1.diagonal(cols).size() == 0);
|
| 63 |
+
VERIFY(m1.diagonal(-rows).size() == 0);
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
template <typename MatrixType>
|
| 67 |
+
void diagonal_assert(const MatrixType& m) {
|
| 68 |
+
Index rows = m.rows();
|
| 69 |
+
Index cols = m.cols();
|
| 70 |
+
|
| 71 |
+
MatrixType m1 = MatrixType::Random(rows, cols);
|
| 72 |
+
|
| 73 |
+
if (rows >= 2 && cols >= 2) {
|
| 74 |
+
VERIFY_RAISES_ASSERT(m1 += m1.diagonal());
|
| 75 |
+
VERIFY_RAISES_ASSERT(m1 -= m1.diagonal());
|
| 76 |
+
VERIFY_RAISES_ASSERT(m1.array() *= m1.diagonal().array());
|
| 77 |
+
VERIFY_RAISES_ASSERT(m1.array() /= m1.diagonal().array());
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
VERIFY_RAISES_ASSERT(m1.diagonal(cols + 1));
|
| 81 |
+
VERIFY_RAISES_ASSERT(m1.diagonal(-(rows + 1)));
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
EIGEN_DECLARE_TEST(diagonal) {
|
| 85 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 86 |
+
CALL_SUBTEST_1(diagonal(Matrix<float, 1, 1>()));
|
| 87 |
+
CALL_SUBTEST_1(diagonal(Matrix<float, 4, 9>()));
|
| 88 |
+
CALL_SUBTEST_1(diagonal(Matrix<float, 7, 3>()));
|
| 89 |
+
CALL_SUBTEST_2(diagonal(Matrix4d()));
|
| 90 |
+
CALL_SUBTEST_2(diagonal(
|
| 91 |
+
MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 92 |
+
CALL_SUBTEST_2(diagonal(
|
| 93 |
+
MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 94 |
+
CALL_SUBTEST_2(diagonal(
|
| 95 |
+
MatrixXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 96 |
+
CALL_SUBTEST_1(diagonal(
|
| 97 |
+
MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 98 |
+
CALL_SUBTEST_1(diagonal(Matrix<float, Dynamic, 4>(3, 4)));
|
| 99 |
+
CALL_SUBTEST_1(diagonal_assert(
|
| 100 |
+
MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 101 |
+
}
|
| 102 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/diagonal_matrix_variadic_ctor.cpp
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2019 David Tellenbach <david.tellenbach@tellnotes.org>
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
#define VERIFY_IMPLICIT_CONVERSION_3(DIAGTYPE, V0, V1, V2) \
|
| 13 |
+
DIAGTYPE d(V0, V1, V2); \
|
| 14 |
+
DIAGTYPE::DenseMatrixType Dense = d.toDenseMatrix(); \
|
| 15 |
+
VERIFY_IS_APPROX(Dense(0, 0), (Scalar)V0); \
|
| 16 |
+
VERIFY_IS_APPROX(Dense(1, 1), (Scalar)V1); \
|
| 17 |
+
VERIFY_IS_APPROX(Dense(2, 2), (Scalar)V2);
|
| 18 |
+
|
| 19 |
+
#define VERIFY_IMPLICIT_CONVERSION_4(DIAGTYPE, V0, V1, V2, V3) \
|
| 20 |
+
DIAGTYPE d(V0, V1, V2, V3); \
|
| 21 |
+
DIAGTYPE::DenseMatrixType Dense = d.toDenseMatrix(); \
|
| 22 |
+
VERIFY_IS_APPROX(Dense(0, 0), (Scalar)V0); \
|
| 23 |
+
VERIFY_IS_APPROX(Dense(1, 1), (Scalar)V1); \
|
| 24 |
+
VERIFY_IS_APPROX(Dense(2, 2), (Scalar)V2); \
|
| 25 |
+
VERIFY_IS_APPROX(Dense(3, 3), (Scalar)V3);
|
| 26 |
+
|
| 27 |
+
#define VERIFY_IMPLICIT_CONVERSION_5(DIAGTYPE, V0, V1, V2, V3, V4) \
|
| 28 |
+
DIAGTYPE d(V0, V1, V2, V3, V4); \
|
| 29 |
+
DIAGTYPE::DenseMatrixType Dense = d.toDenseMatrix(); \
|
| 30 |
+
VERIFY_IS_APPROX(Dense(0, 0), (Scalar)V0); \
|
| 31 |
+
VERIFY_IS_APPROX(Dense(1, 1), (Scalar)V1); \
|
| 32 |
+
VERIFY_IS_APPROX(Dense(2, 2), (Scalar)V2); \
|
| 33 |
+
VERIFY_IS_APPROX(Dense(3, 3), (Scalar)V3); \
|
| 34 |
+
VERIFY_IS_APPROX(Dense(4, 4), (Scalar)V4);
|
| 35 |
+
|
| 36 |
+
template <typename Scalar>
|
| 37 |
+
void constructorTest() {
|
| 38 |
+
typedef DiagonalMatrix<Scalar, 0> DiagonalMatrix0;
|
| 39 |
+
typedef DiagonalMatrix<Scalar, 3> DiagonalMatrix3;
|
| 40 |
+
typedef DiagonalMatrix<Scalar, 4> DiagonalMatrix4;
|
| 41 |
+
typedef DiagonalMatrix<Scalar, Dynamic> DiagonalMatrixX;
|
| 42 |
+
|
| 43 |
+
Scalar raw[7];
|
| 44 |
+
for (int k = 0; k < 7; ++k) raw[k] = internal::random<Scalar>();
|
| 45 |
+
|
| 46 |
+
// Fixed-sized matrices
|
| 47 |
+
{
|
| 48 |
+
DiagonalMatrix0 a{{}};
|
| 49 |
+
VERIFY(a.rows() == 0);
|
| 50 |
+
VERIFY(a.cols() == 0);
|
| 51 |
+
typename DiagonalMatrix0::DenseMatrixType m = a.toDenseMatrix();
|
| 52 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 53 |
+
}
|
| 54 |
+
{
|
| 55 |
+
DiagonalMatrix3 a{{raw[0], raw[1], raw[2]}};
|
| 56 |
+
VERIFY(a.rows() == 3);
|
| 57 |
+
VERIFY(a.cols() == 3);
|
| 58 |
+
typename DiagonalMatrix3::DenseMatrixType m = a.toDenseMatrix();
|
| 59 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 60 |
+
}
|
| 61 |
+
{
|
| 62 |
+
DiagonalMatrix4 a{{raw[0], raw[1], raw[2], raw[3]}};
|
| 63 |
+
VERIFY(a.rows() == 4);
|
| 64 |
+
VERIFY(a.cols() == 4);
|
| 65 |
+
typename DiagonalMatrix4::DenseMatrixType m = a.toDenseMatrix();
|
| 66 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
// dynamically sized matrices
|
| 70 |
+
{
|
| 71 |
+
DiagonalMatrixX a{{}};
|
| 72 |
+
VERIFY(a.rows() == 0);
|
| 73 |
+
VERIFY(a.rows() == 0);
|
| 74 |
+
typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
|
| 75 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 76 |
+
}
|
| 77 |
+
{
|
| 78 |
+
DiagonalMatrixX a{{raw[0], raw[1], raw[2], raw[3], raw[4], raw[5], raw[6]}};
|
| 79 |
+
VERIFY(a.rows() == 7);
|
| 80 |
+
VERIFY(a.rows() == 7);
|
| 81 |
+
typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
|
| 82 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
template <>
|
| 87 |
+
void constructorTest<float>() {
|
| 88 |
+
typedef float Scalar;
|
| 89 |
+
|
| 90 |
+
typedef DiagonalMatrix<Scalar, 0> DiagonalMatrix0;
|
| 91 |
+
typedef DiagonalMatrix<Scalar, 3> DiagonalMatrix3;
|
| 92 |
+
typedef DiagonalMatrix<Scalar, 4> DiagonalMatrix4;
|
| 93 |
+
typedef DiagonalMatrix<Scalar, 5> DiagonalMatrix5;
|
| 94 |
+
typedef DiagonalMatrix<Scalar, Dynamic> DiagonalMatrixX;
|
| 95 |
+
|
| 96 |
+
Scalar raw[7];
|
| 97 |
+
for (int k = 0; k < 7; ++k) raw[k] = internal::random<Scalar>();
|
| 98 |
+
|
| 99 |
+
// Fixed-sized matrices
|
| 100 |
+
{
|
| 101 |
+
DiagonalMatrix0 a{{}};
|
| 102 |
+
VERIFY(a.rows() == 0);
|
| 103 |
+
VERIFY(a.cols() == 0);
|
| 104 |
+
typename DiagonalMatrix0::DenseMatrixType m = a.toDenseMatrix();
|
| 105 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 106 |
+
}
|
| 107 |
+
{
|
| 108 |
+
DiagonalMatrix3 a{{raw[0], raw[1], raw[2]}};
|
| 109 |
+
VERIFY(a.rows() == 3);
|
| 110 |
+
VERIFY(a.cols() == 3);
|
| 111 |
+
typename DiagonalMatrix3::DenseMatrixType m = a.toDenseMatrix();
|
| 112 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 113 |
+
}
|
| 114 |
+
{
|
| 115 |
+
DiagonalMatrix4 a{{raw[0], raw[1], raw[2], raw[3]}};
|
| 116 |
+
VERIFY(a.rows() == 4);
|
| 117 |
+
VERIFY(a.cols() == 4);
|
| 118 |
+
typename DiagonalMatrix4::DenseMatrixType m = a.toDenseMatrix();
|
| 119 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
// dynamically sized matrices
|
| 123 |
+
{
|
| 124 |
+
DiagonalMatrixX a{{}};
|
| 125 |
+
VERIFY(a.rows() == 0);
|
| 126 |
+
VERIFY(a.rows() == 0);
|
| 127 |
+
typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
|
| 128 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 129 |
+
}
|
| 130 |
+
{
|
| 131 |
+
DiagonalMatrixX a{{raw[0], raw[1], raw[2], raw[3], raw[4], raw[5], raw[6]}};
|
| 132 |
+
VERIFY(a.rows() == 7);
|
| 133 |
+
VERIFY(a.rows() == 7);
|
| 134 |
+
typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
|
| 135 |
+
for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
|
| 136 |
+
}
|
| 137 |
+
{ VERIFY_IMPLICIT_CONVERSION_3(DiagonalMatrix3, 1.2647, 2.56f, -3); }
|
| 138 |
+
{ VERIFY_IMPLICIT_CONVERSION_4(DiagonalMatrix4, 1.2647, 2.56f, -3, 3.23f); }
|
| 139 |
+
{ VERIFY_IMPLICIT_CONVERSION_5(DiagonalMatrix5, 1.2647, 2.56f, -3, 3.23f, 2); }
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
EIGEN_DECLARE_TEST(diagonal_matrix_variadic_ctor) {
|
| 143 |
+
CALL_SUBTEST_2(constructorTest<unsigned char>());
|
| 144 |
+
CALL_SUBTEST_2(constructorTest<float>());
|
| 145 |
+
CALL_SUBTEST_2(constructorTest<Index>());
|
| 146 |
+
CALL_SUBTEST_2(constructorTest<int>());
|
| 147 |
+
CALL_SUBTEST_2(constructorTest<long int>());
|
| 148 |
+
CALL_SUBTEST_2(constructorTest<std::ptrdiff_t>());
|
| 149 |
+
CALL_SUBTEST_2(constructorTest<std::complex<double>>());
|
| 150 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/diagonalmatrices.cpp
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2009 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 |
+
// discard stack allocation as that too bypasses malloc
|
| 11 |
+
#define EIGEN_STACK_ALLOCATION_LIMIT 0
|
| 12 |
+
// heap allocation will raise an assert if enabled at runtime
|
| 13 |
+
#define EIGEN_RUNTIME_NO_MALLOC
|
| 14 |
+
|
| 15 |
+
#include "main.h"
|
| 16 |
+
using namespace std;
|
| 17 |
+
template <typename MatrixType>
|
| 18 |
+
void diagonalmatrices(const MatrixType& m) {
|
| 19 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 20 |
+
enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
|
| 21 |
+
typedef Matrix<Scalar, Rows, 1> VectorType;
|
| 22 |
+
typedef Matrix<Scalar, 1, Cols> RowVectorType;
|
| 23 |
+
typedef Matrix<Scalar, Rows, Rows> SquareMatrixType;
|
| 24 |
+
typedef Matrix<Scalar, Dynamic, Dynamic> DynMatrixType;
|
| 25 |
+
typedef DiagonalMatrix<Scalar, Rows> LeftDiagonalMatrix;
|
| 26 |
+
typedef DiagonalMatrix<Scalar, Cols> RightDiagonalMatrix;
|
| 27 |
+
typedef Matrix<Scalar, Rows == Dynamic ? Dynamic : 2 * Rows, Cols == Dynamic ? Dynamic : 2 * Cols> BigMatrix;
|
| 28 |
+
Index rows = m.rows();
|
| 29 |
+
Index cols = m.cols();
|
| 30 |
+
|
| 31 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols);
|
| 32 |
+
VectorType v1 = VectorType::Random(rows), v2 = VectorType::Random(rows);
|
| 33 |
+
RowVectorType rv1 = RowVectorType::Random(cols), rv2 = RowVectorType::Random(cols);
|
| 34 |
+
|
| 35 |
+
LeftDiagonalMatrix ldm1(v1), ldm2(v2);
|
| 36 |
+
RightDiagonalMatrix rdm1(rv1), rdm2(rv2);
|
| 37 |
+
|
| 38 |
+
Scalar s1 = internal::random<Scalar>();
|
| 39 |
+
|
| 40 |
+
SquareMatrixType sq_m1(v1.asDiagonal());
|
| 41 |
+
VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix());
|
| 42 |
+
sq_m1 = v1.asDiagonal();
|
| 43 |
+
VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix());
|
| 44 |
+
SquareMatrixType sq_m2 = v1.asDiagonal();
|
| 45 |
+
VERIFY_IS_APPROX(sq_m1, sq_m2);
|
| 46 |
+
|
| 47 |
+
ldm1 = v1.asDiagonal();
|
| 48 |
+
LeftDiagonalMatrix ldm3(v1);
|
| 49 |
+
VERIFY_IS_APPROX(ldm1.diagonal(), ldm3.diagonal());
|
| 50 |
+
LeftDiagonalMatrix ldm4 = v1.asDiagonal();
|
| 51 |
+
VERIFY_IS_APPROX(ldm1.diagonal(), ldm4.diagonal());
|
| 52 |
+
|
| 53 |
+
sq_m1.block(0, 0, rows, rows) = ldm1;
|
| 54 |
+
VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix());
|
| 55 |
+
sq_m1.transpose() = ldm1;
|
| 56 |
+
VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix());
|
| 57 |
+
|
| 58 |
+
Index i = internal::random<Index>(0, rows - 1);
|
| 59 |
+
Index j = internal::random<Index>(0, cols - 1);
|
| 60 |
+
|
| 61 |
+
internal::set_is_malloc_allowed(false);
|
| 62 |
+
VERIFY_IS_APPROX(((ldm1 * m1)(i, j)), ldm1.diagonal()(i) * m1(i, j));
|
| 63 |
+
VERIFY_IS_APPROX(((ldm1 * (m1 + m2))(i, j)), ldm1.diagonal()(i) * (m1 + m2)(i, j));
|
| 64 |
+
VERIFY_IS_APPROX(((m1 * rdm1)(i, j)), rdm1.diagonal()(j) * m1(i, j));
|
| 65 |
+
VERIFY_IS_APPROX(((v1.asDiagonal() * m1)(i, j)), v1(i) * m1(i, j));
|
| 66 |
+
VERIFY_IS_APPROX(((m1 * rv1.asDiagonal())(i, j)), rv1(j) * m1(i, j));
|
| 67 |
+
VERIFY_IS_APPROX((((v1 + v2).asDiagonal() * m1)(i, j)), (v1 + v2)(i)*m1(i, j));
|
| 68 |
+
VERIFY_IS_APPROX((((v1 + v2).asDiagonal() * (m1 + m2))(i, j)), (v1 + v2)(i) * (m1 + m2)(i, j));
|
| 69 |
+
VERIFY_IS_APPROX(((m1 * (rv1 + rv2).asDiagonal())(i, j)), (rv1 + rv2)(j)*m1(i, j));
|
| 70 |
+
VERIFY_IS_APPROX((((m1 + m2) * (rv1 + rv2).asDiagonal())(i, j)), (rv1 + rv2)(j) * (m1 + m2)(i, j));
|
| 71 |
+
VERIFY_IS_APPROX((ldm1 * ldm1).diagonal()(i), ldm1.diagonal()(i) * ldm1.diagonal()(i));
|
| 72 |
+
VERIFY_IS_APPROX((ldm1 * ldm1 * m1)(i, j), ldm1.diagonal()(i) * ldm1.diagonal()(i) * m1(i, j));
|
| 73 |
+
VERIFY_IS_APPROX(((v1.asDiagonal() * v1.asDiagonal()).diagonal()(i)), v1(i) * v1(i));
|
| 74 |
+
internal::set_is_malloc_allowed(true);
|
| 75 |
+
|
| 76 |
+
if (rows > 1) {
|
| 77 |
+
DynMatrixType tmp = m1.topRows(rows / 2), res;
|
| 78 |
+
VERIFY_IS_APPROX((res = m1.topRows(rows / 2) * rv1.asDiagonal()), tmp * rv1.asDiagonal());
|
| 79 |
+
VERIFY_IS_APPROX((res = v1.head(rows / 2).asDiagonal() * m1.topRows(rows / 2)),
|
| 80 |
+
v1.head(rows / 2).asDiagonal() * tmp);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
BigMatrix big;
|
| 84 |
+
big.setZero(2 * rows, 2 * cols);
|
| 85 |
+
|
| 86 |
+
big.block(i, j, rows, cols) = m1;
|
| 87 |
+
big.block(i, j, rows, cols) = v1.asDiagonal() * big.block(i, j, rows, cols);
|
| 88 |
+
|
| 89 |
+
VERIFY_IS_APPROX((big.block(i, j, rows, cols)), v1.asDiagonal() * m1);
|
| 90 |
+
|
| 91 |
+
big.block(i, j, rows, cols) = m1;
|
| 92 |
+
big.block(i, j, rows, cols) = big.block(i, j, rows, cols) * rv1.asDiagonal();
|
| 93 |
+
VERIFY_IS_APPROX((big.block(i, j, rows, cols)), m1 * rv1.asDiagonal());
|
| 94 |
+
|
| 95 |
+
// products do not allocate memory
|
| 96 |
+
MatrixType res(rows, cols);
|
| 97 |
+
internal::set_is_malloc_allowed(false);
|
| 98 |
+
res.noalias() = ldm1 * m1;
|
| 99 |
+
res.noalias() = m1 * rdm1;
|
| 100 |
+
res.noalias() = ldm1 * m1 * rdm1;
|
| 101 |
+
res.noalias() = LeftDiagonalMatrix::Identity(rows) * m1 * RightDiagonalMatrix::Zero(cols);
|
| 102 |
+
internal::set_is_malloc_allowed(true);
|
| 103 |
+
|
| 104 |
+
// scalar multiple
|
| 105 |
+
VERIFY_IS_APPROX(LeftDiagonalMatrix(ldm1 * s1).diagonal(), ldm1.diagonal() * s1);
|
| 106 |
+
VERIFY_IS_APPROX(LeftDiagonalMatrix(s1 * ldm1).diagonal(), s1 * ldm1.diagonal());
|
| 107 |
+
|
| 108 |
+
VERIFY_IS_APPROX(m1 * (rdm1 * s1), (m1 * rdm1) * s1);
|
| 109 |
+
VERIFY_IS_APPROX(m1 * (s1 * rdm1), (m1 * rdm1) * s1);
|
| 110 |
+
|
| 111 |
+
// Diagonal to dense
|
| 112 |
+
sq_m1.setRandom();
|
| 113 |
+
sq_m2 = sq_m1;
|
| 114 |
+
VERIFY_IS_APPROX((sq_m1 += (s1 * v1).asDiagonal()), sq_m2 += (s1 * v1).asDiagonal().toDenseMatrix());
|
| 115 |
+
VERIFY_IS_APPROX((sq_m1 -= (s1 * v1).asDiagonal()), sq_m2 -= (s1 * v1).asDiagonal().toDenseMatrix());
|
| 116 |
+
VERIFY_IS_APPROX((sq_m1 = (s1 * v1).asDiagonal()), (s1 * v1).asDiagonal().toDenseMatrix());
|
| 117 |
+
|
| 118 |
+
sq_m1.setRandom();
|
| 119 |
+
sq_m2 = v1.asDiagonal();
|
| 120 |
+
sq_m2 = sq_m1 * sq_m2;
|
| 121 |
+
VERIFY_IS_APPROX((sq_m1 * v1.asDiagonal()).col(i), sq_m2.col(i));
|
| 122 |
+
VERIFY_IS_APPROX((sq_m1 * v1.asDiagonal()).row(i), sq_m2.row(i));
|
| 123 |
+
|
| 124 |
+
sq_m1 = v1.asDiagonal();
|
| 125 |
+
sq_m2 = v2.asDiagonal();
|
| 126 |
+
SquareMatrixType sq_m3 = v1.asDiagonal();
|
| 127 |
+
VERIFY_IS_APPROX(sq_m3 = v1.asDiagonal() + v2.asDiagonal(), sq_m1 + sq_m2);
|
| 128 |
+
VERIFY_IS_APPROX(sq_m3 = v1.asDiagonal() - v2.asDiagonal(), sq_m1 - sq_m2);
|
| 129 |
+
VERIFY_IS_APPROX(sq_m3 = v1.asDiagonal() - 2 * v2.asDiagonal() + v1.asDiagonal(), sq_m1 - 2 * sq_m2 + sq_m1);
|
| 130 |
+
|
| 131 |
+
// Zero and Identity
|
| 132 |
+
LeftDiagonalMatrix zero = LeftDiagonalMatrix::Zero(rows);
|
| 133 |
+
LeftDiagonalMatrix identity = LeftDiagonalMatrix::Identity(rows);
|
| 134 |
+
VERIFY_IS_APPROX(identity.diagonal().sum(), Scalar(rows));
|
| 135 |
+
VERIFY_IS_APPROX(zero.diagonal().sum(), Scalar(0));
|
| 136 |
+
VERIFY_IS_APPROX((zero + 2 * LeftDiagonalMatrix::Identity(rows)).diagonal().sum(), Scalar(2 * rows));
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
template <typename MatrixType>
|
| 140 |
+
void as_scalar_product(const MatrixType& m) {
|
| 141 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 142 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 143 |
+
typedef Matrix<Scalar, Dynamic, Dynamic> DynMatrixType;
|
| 144 |
+
typedef Matrix<Scalar, Dynamic, 1> DynVectorType;
|
| 145 |
+
typedef Matrix<Scalar, 1, Dynamic> DynRowVectorType;
|
| 146 |
+
|
| 147 |
+
Index rows = m.rows();
|
| 148 |
+
Index depth = internal::random<Index>(1, EIGEN_TEST_MAX_SIZE);
|
| 149 |
+
|
| 150 |
+
VectorType v1 = VectorType::Random(rows);
|
| 151 |
+
DynVectorType dv1 = DynVectorType::Random(depth);
|
| 152 |
+
DynRowVectorType drv1 = DynRowVectorType::Random(depth);
|
| 153 |
+
DynMatrixType dm1 = dv1;
|
| 154 |
+
DynMatrixType drm1 = drv1;
|
| 155 |
+
|
| 156 |
+
Scalar s = v1(0);
|
| 157 |
+
|
| 158 |
+
VERIFY_IS_APPROX(v1.asDiagonal() * drv1, s * drv1);
|
| 159 |
+
VERIFY_IS_APPROX(dv1 * v1.asDiagonal(), dv1 * s);
|
| 160 |
+
|
| 161 |
+
VERIFY_IS_APPROX(v1.asDiagonal() * drm1, s * drm1);
|
| 162 |
+
VERIFY_IS_APPROX(dm1 * v1.asDiagonal(), dm1 * s);
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
template <int>
|
| 166 |
+
void bug987() {
|
| 167 |
+
Matrix3Xd points = Matrix3Xd::Random(3, 3);
|
| 168 |
+
Vector2d diag = Vector2d::Random();
|
| 169 |
+
Matrix2Xd tmp1 = points.topRows<2>(), res1, res2;
|
| 170 |
+
VERIFY_IS_APPROX(res1 = diag.asDiagonal() * points.topRows<2>(), res2 = diag.asDiagonal() * tmp1);
|
| 171 |
+
Matrix2d tmp2 = points.topLeftCorner<2, 2>();
|
| 172 |
+
VERIFY_IS_APPROX((res1 = points.topLeftCorner<2, 2>() * diag.asDiagonal()), res2 = tmp2 * diag.asDiagonal());
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
EIGEN_DECLARE_TEST(diagonalmatrices) {
|
| 176 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 177 |
+
CALL_SUBTEST_1(diagonalmatrices(Matrix<float, 1, 1>()));
|
| 178 |
+
CALL_SUBTEST_1(as_scalar_product(Matrix<float, 1, 1>()));
|
| 179 |
+
|
| 180 |
+
CALL_SUBTEST_2(diagonalmatrices(Matrix3f()));
|
| 181 |
+
CALL_SUBTEST_3(diagonalmatrices(Matrix<double, 3, 3, RowMajor>()));
|
| 182 |
+
CALL_SUBTEST_4(diagonalmatrices(Matrix4d()));
|
| 183 |
+
CALL_SUBTEST_5(diagonalmatrices(Matrix<float, 4, 4, RowMajor>()));
|
| 184 |
+
CALL_SUBTEST_6(diagonalmatrices(
|
| 185 |
+
MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 186 |
+
CALL_SUBTEST_6(as_scalar_product(MatrixXcf(1, 1)));
|
| 187 |
+
CALL_SUBTEST_7(diagonalmatrices(
|
| 188 |
+
MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 189 |
+
CALL_SUBTEST_8(diagonalmatrices(Matrix<double, Dynamic, Dynamic, RowMajor>(
|
| 190 |
+
internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 191 |
+
CALL_SUBTEST_9(diagonalmatrices(
|
| 192 |
+
MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
|
| 193 |
+
CALL_SUBTEST_9(diagonalmatrices(MatrixXf(1, 1)));
|
| 194 |
+
CALL_SUBTEST_9(as_scalar_product(MatrixXf(1, 1)));
|
| 195 |
+
}
|
| 196 |
+
CALL_SUBTEST_10(bug987<0>());
|
| 197 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/dontalign.cpp
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
#if defined EIGEN_TEST_PART_1 || defined EIGEN_TEST_PART_2 || defined EIGEN_TEST_PART_3 || defined EIGEN_TEST_PART_4
|
| 11 |
+
#define EIGEN_DONT_ALIGN
|
| 12 |
+
#elif defined EIGEN_TEST_PART_5 || defined EIGEN_TEST_PART_6 || defined EIGEN_TEST_PART_7 || defined EIGEN_TEST_PART_8
|
| 13 |
+
#define EIGEN_DONT_ALIGN_STATICALLY
|
| 14 |
+
#endif
|
| 15 |
+
|
| 16 |
+
#include "main.h"
|
| 17 |
+
#include <Eigen/Dense>
|
| 18 |
+
|
| 19 |
+
template <typename MatrixType>
|
| 20 |
+
void dontalign(const MatrixType& m) {
|
| 21 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 22 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 23 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
|
| 24 |
+
|
| 25 |
+
Index rows = m.rows();
|
| 26 |
+
Index cols = m.cols();
|
| 27 |
+
|
| 28 |
+
MatrixType a = MatrixType::Random(rows, cols);
|
| 29 |
+
SquareMatrixType square = SquareMatrixType::Random(rows, rows);
|
| 30 |
+
VectorType v = VectorType::Random(rows);
|
| 31 |
+
|
| 32 |
+
VERIFY_IS_APPROX(v, square * square.colPivHouseholderQr().solve(v));
|
| 33 |
+
square = square.inverse().eval();
|
| 34 |
+
a = square * a;
|
| 35 |
+
square = square * square;
|
| 36 |
+
v = square * v;
|
| 37 |
+
v = a.adjoint() * v;
|
| 38 |
+
VERIFY(square.determinant() != Scalar(0));
|
| 39 |
+
|
| 40 |
+
// bug 219: MapAligned() was giving an assert with EIGEN_DONT_ALIGN, because Map Flags were miscomputed
|
| 41 |
+
Scalar* array = internal::aligned_new<Scalar>(rows);
|
| 42 |
+
v = VectorType::MapAligned(array, rows);
|
| 43 |
+
internal::aligned_delete(array, rows);
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
EIGEN_DECLARE_TEST(dontalign) {
|
| 47 |
+
#if defined EIGEN_TEST_PART_1 || defined EIGEN_TEST_PART_5
|
| 48 |
+
dontalign(Matrix3d());
|
| 49 |
+
dontalign(Matrix4f());
|
| 50 |
+
#elif defined EIGEN_TEST_PART_2 || defined EIGEN_TEST_PART_6
|
| 51 |
+
dontalign(Matrix3cd());
|
| 52 |
+
dontalign(Matrix4cf());
|
| 53 |
+
#elif defined EIGEN_TEST_PART_3 || defined EIGEN_TEST_PART_7
|
| 54 |
+
dontalign(Matrix<float, 32, 32>());
|
| 55 |
+
dontalign(Matrix<std::complex<float>, 32, 32>());
|
| 56 |
+
#elif defined EIGEN_TEST_PART_4 || defined EIGEN_TEST_PART_8
|
| 57 |
+
dontalign(MatrixXd(32, 32));
|
| 58 |
+
dontalign(MatrixXcf(32, 32));
|
| 59 |
+
#endif
|
| 60 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/dynalloc.cpp
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 |
+
#include "main.h"
|
| 11 |
+
|
| 12 |
+
#if EIGEN_MAX_ALIGN_BYTES > 0
|
| 13 |
+
#define ALIGNMENT EIGEN_MAX_ALIGN_BYTES
|
| 14 |
+
#else
|
| 15 |
+
#define ALIGNMENT 1
|
| 16 |
+
#endif
|
| 17 |
+
|
| 18 |
+
typedef Matrix<float, 16, 1> Vector16f;
|
| 19 |
+
typedef Matrix<float, 8, 1> Vector8f;
|
| 20 |
+
|
| 21 |
+
void check_handmade_aligned_malloc() {
|
| 22 |
+
// Hand-make alignment needs at least sizeof(void*) to store the offset.
|
| 23 |
+
constexpr int alignment = (std::max<int>)(EIGEN_DEFAULT_ALIGN_BYTES, sizeof(void *));
|
| 24 |
+
|
| 25 |
+
for (int i = 1; i < 1000; i++) {
|
| 26 |
+
char *p = (char *)internal::handmade_aligned_malloc(i, alignment);
|
| 27 |
+
VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
|
| 28 |
+
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
| 29 |
+
for (int j = 0; j < i; j++) p[j] = 0;
|
| 30 |
+
internal::handmade_aligned_free(p);
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
void check_aligned_malloc() {
|
| 35 |
+
for (int i = ALIGNMENT; i < 1000; i++) {
|
| 36 |
+
char *p = (char *)internal::aligned_malloc(i);
|
| 37 |
+
VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
|
| 38 |
+
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
| 39 |
+
for (int j = 0; j < i; j++) p[j] = 0;
|
| 40 |
+
internal::aligned_free(p);
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
void check_aligned_new() {
|
| 45 |
+
for (int i = ALIGNMENT; i < 1000; i++) {
|
| 46 |
+
float *p = internal::aligned_new<float>(i);
|
| 47 |
+
VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
|
| 48 |
+
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
| 49 |
+
for (int j = 0; j < i; j++) p[j] = 0;
|
| 50 |
+
internal::aligned_delete(p, i);
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
void check_aligned_stack_alloc() {
|
| 55 |
+
for (int i = ALIGNMENT; i < 400; i++) {
|
| 56 |
+
ei_declare_aligned_stack_constructed_variable(float, p, i, 0);
|
| 57 |
+
VERIFY(std::uintptr_t(p) % ALIGNMENT == 0);
|
| 58 |
+
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
| 59 |
+
for (int j = 0; j < i; j++) p[j] = 0;
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// test compilation with both a struct and a class...
|
| 64 |
+
struct MyStruct {
|
| 65 |
+
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
| 66 |
+
char dummychar;
|
| 67 |
+
Vector16f avec;
|
| 68 |
+
};
|
| 69 |
+
|
| 70 |
+
class MyClassA {
|
| 71 |
+
public:
|
| 72 |
+
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
| 73 |
+
char dummychar;
|
| 74 |
+
Vector16f avec;
|
| 75 |
+
};
|
| 76 |
+
|
| 77 |
+
template <typename T>
|
| 78 |
+
void check_dynaligned() {
|
| 79 |
+
// TODO have to be updated once we support multiple alignment values
|
| 80 |
+
if (T::SizeAtCompileTime % ALIGNMENT == 0) {
|
| 81 |
+
T *obj = new T;
|
| 82 |
+
VERIFY(T::NeedsToAlign == 1);
|
| 83 |
+
VERIFY(std::uintptr_t(obj) % ALIGNMENT == 0);
|
| 84 |
+
delete obj;
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
template <typename T>
|
| 89 |
+
void check_custom_new_delete() {
|
| 90 |
+
{
|
| 91 |
+
T *t = new T;
|
| 92 |
+
delete t;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
{
|
| 96 |
+
std::size_t N = internal::random<std::size_t>(1, 10);
|
| 97 |
+
T *t = new T[N];
|
| 98 |
+
delete[] t;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
#if EIGEN_MAX_ALIGN_BYTES > 0 && (!EIGEN_HAS_CXX17_OVERALIGN)
|
| 102 |
+
{
|
| 103 |
+
T *t = static_cast<T *>((T::operator new)(sizeof(T)));
|
| 104 |
+
(T::operator delete)(t, sizeof(T));
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
{
|
| 108 |
+
T *t = static_cast<T *>((T::operator new)(sizeof(T)));
|
| 109 |
+
(T::operator delete)(t);
|
| 110 |
+
}
|
| 111 |
+
#endif
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
EIGEN_DECLARE_TEST(dynalloc) {
|
| 115 |
+
// low level dynamic memory allocation
|
| 116 |
+
CALL_SUBTEST(check_handmade_aligned_malloc());
|
| 117 |
+
CALL_SUBTEST(check_aligned_malloc());
|
| 118 |
+
CALL_SUBTEST(check_aligned_new());
|
| 119 |
+
CALL_SUBTEST(check_aligned_stack_alloc());
|
| 120 |
+
|
| 121 |
+
for (int i = 0; i < g_repeat * 100; ++i) {
|
| 122 |
+
CALL_SUBTEST(check_custom_new_delete<Vector4f>());
|
| 123 |
+
CALL_SUBTEST(check_custom_new_delete<Vector2f>());
|
| 124 |
+
CALL_SUBTEST(check_custom_new_delete<Matrix4f>());
|
| 125 |
+
CALL_SUBTEST(check_custom_new_delete<MatrixXi>());
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
// check static allocation, who knows ?
|
| 129 |
+
#if EIGEN_MAX_STATIC_ALIGN_BYTES
|
| 130 |
+
for (int i = 0; i < g_repeat * 100; ++i) {
|
| 131 |
+
CALL_SUBTEST(check_dynaligned<Vector4f>());
|
| 132 |
+
CALL_SUBTEST(check_dynaligned<Vector2d>());
|
| 133 |
+
CALL_SUBTEST(check_dynaligned<Matrix4f>());
|
| 134 |
+
CALL_SUBTEST(check_dynaligned<Vector4d>());
|
| 135 |
+
CALL_SUBTEST(check_dynaligned<Vector4i>());
|
| 136 |
+
CALL_SUBTEST(check_dynaligned<Vector8f>());
|
| 137 |
+
CALL_SUBTEST(check_dynaligned<Vector16f>());
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
{
|
| 141 |
+
MyStruct foo0;
|
| 142 |
+
VERIFY(std::uintptr_t(foo0.avec.data()) % ALIGNMENT == 0);
|
| 143 |
+
MyClassA fooA;
|
| 144 |
+
VERIFY(std::uintptr_t(fooA.avec.data()) % ALIGNMENT == 0);
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
// dynamic allocation, single object
|
| 148 |
+
for (int i = 0; i < g_repeat * 100; ++i) {
|
| 149 |
+
MyStruct *foo0 = new MyStruct();
|
| 150 |
+
VERIFY(std::uintptr_t(foo0->avec.data()) % ALIGNMENT == 0);
|
| 151 |
+
MyClassA *fooA = new MyClassA();
|
| 152 |
+
VERIFY(std::uintptr_t(fooA->avec.data()) % ALIGNMENT == 0);
|
| 153 |
+
delete foo0;
|
| 154 |
+
delete fooA;
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
// dynamic allocation, array
|
| 158 |
+
const int N = 10;
|
| 159 |
+
for (int i = 0; i < g_repeat * 100; ++i) {
|
| 160 |
+
MyStruct *foo0 = new MyStruct[N];
|
| 161 |
+
VERIFY(std::uintptr_t(foo0->avec.data()) % ALIGNMENT == 0);
|
| 162 |
+
MyClassA *fooA = new MyClassA[N];
|
| 163 |
+
VERIFY(std::uintptr_t(fooA->avec.data()) % ALIGNMENT == 0);
|
| 164 |
+
delete[] foo0;
|
| 165 |
+
delete[] fooA;
|
| 166 |
+
}
|
| 167 |
+
#endif
|
| 168 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigen2support.cpp
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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 EIGEN2_SUPPORT
|
| 11 |
+
|
| 12 |
+
#include "main.h"
|
| 13 |
+
|
| 14 |
+
template <typename MatrixType>
|
| 15 |
+
void eigen2support(const MatrixType& m) {
|
| 16 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 17 |
+
|
| 18 |
+
Index rows = m.rows();
|
| 19 |
+
Index cols = m.cols();
|
| 20 |
+
|
| 21 |
+
MatrixType m1 = MatrixType::Random(rows, cols), m3(rows, cols);
|
| 22 |
+
|
| 23 |
+
Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>();
|
| 24 |
+
|
| 25 |
+
// scalar addition
|
| 26 |
+
VERIFY_IS_APPROX(m1.cwise() + s1, s1 + m1.cwise());
|
| 27 |
+
VERIFY_IS_APPROX(m1.cwise() + s1, MatrixType::Constant(rows, cols, s1) + m1);
|
| 28 |
+
VERIFY_IS_APPROX((m1 * Scalar(2)).cwise() - s2, (m1 + m1) - MatrixType::Constant(rows, cols, s2));
|
| 29 |
+
m3 = m1;
|
| 30 |
+
m3.cwise() += s2;
|
| 31 |
+
VERIFY_IS_APPROX(m3, m1.cwise() + s2);
|
| 32 |
+
m3 = m1;
|
| 33 |
+
m3.cwise() -= s1;
|
| 34 |
+
VERIFY_IS_APPROX(m3, m1.cwise() - s1);
|
| 35 |
+
|
| 36 |
+
VERIFY_IS_EQUAL((m1.corner(TopLeft, 1, 1)), (m1.block(0, 0, 1, 1)));
|
| 37 |
+
VERIFY_IS_EQUAL((m1.template corner<1, 1>(TopLeft)), (m1.template block<1, 1>(0, 0)));
|
| 38 |
+
VERIFY_IS_EQUAL((m1.col(0).start(1)), (m1.col(0).segment(0, 1)));
|
| 39 |
+
VERIFY_IS_EQUAL((m1.col(0).template start<1>()), (m1.col(0).segment(0, 1)));
|
| 40 |
+
VERIFY_IS_EQUAL((m1.col(0).end(1)), (m1.col(0).segment(rows - 1, 1)));
|
| 41 |
+
VERIFY_IS_EQUAL((m1.col(0).template end<1>()), (m1.col(0).segment(rows - 1, 1)));
|
| 42 |
+
|
| 43 |
+
using numext::abs2;
|
| 44 |
+
using numext::real;
|
| 45 |
+
using std::cos;
|
| 46 |
+
VERIFY_IS_EQUAL(ei_cos(s1), cos(s1));
|
| 47 |
+
VERIFY_IS_EQUAL(ei_real(s1), real(s1));
|
| 48 |
+
VERIFY_IS_EQUAL(ei_abs2(s1), abs2(s1));
|
| 49 |
+
|
| 50 |
+
m1.minor(0, 0);
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
EIGEN_DECLARE_TEST(eigen2support) {
|
| 54 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 55 |
+
CALL_SUBTEST_1(eigen2support(Matrix<double, 1, 1>()));
|
| 56 |
+
CALL_SUBTEST_2(eigen2support(MatrixXd(1, 1)));
|
| 57 |
+
CALL_SUBTEST_4(eigen2support(Matrix3f()));
|
| 58 |
+
CALL_SUBTEST_5(eigen2support(Matrix4d()));
|
| 59 |
+
CALL_SUBTEST_2(eigen2support(MatrixXf(200, 200)));
|
| 60 |
+
CALL_SUBTEST_6(eigen2support(MatrixXcd(100, 100)));
|
| 61 |
+
}
|
| 62 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_complex.cpp
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 5 |
+
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
| 6 |
+
//
|
| 7 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 8 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 9 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 10 |
+
|
| 11 |
+
#include "main.h"
|
| 12 |
+
#include <limits>
|
| 13 |
+
#include <Eigen/Eigenvalues>
|
| 14 |
+
#include <Eigen/LU>
|
| 15 |
+
#include "CustomComplex.h"
|
| 16 |
+
|
| 17 |
+
template <typename MatrixType>
|
| 18 |
+
bool find_pivot(typename MatrixType::Scalar tol, MatrixType& diffs, Index col = 0) {
|
| 19 |
+
bool match = diffs.diagonal().sum() <= tol;
|
| 20 |
+
if (match || col == diffs.cols()) {
|
| 21 |
+
return match;
|
| 22 |
+
} else {
|
| 23 |
+
Index n = diffs.cols();
|
| 24 |
+
std::vector<std::pair<Index, Index> > transpositions;
|
| 25 |
+
for (Index i = col; i < n; ++i) {
|
| 26 |
+
Index best_index(0);
|
| 27 |
+
if (diffs.col(col).segment(col, n - i).minCoeff(&best_index) > tol) break;
|
| 28 |
+
|
| 29 |
+
best_index += col;
|
| 30 |
+
|
| 31 |
+
diffs.row(col).swap(diffs.row(best_index));
|
| 32 |
+
if (find_pivot(tol, diffs, col + 1)) return true;
|
| 33 |
+
diffs.row(col).swap(diffs.row(best_index));
|
| 34 |
+
|
| 35 |
+
// move current pivot to the end
|
| 36 |
+
diffs.row(n - (i - col) - 1).swap(diffs.row(best_index));
|
| 37 |
+
transpositions.push_back(std::pair<Index, Index>(n - (i - col) - 1, best_index));
|
| 38 |
+
}
|
| 39 |
+
// restore
|
| 40 |
+
for (Index k = transpositions.size() - 1; k >= 0; --k)
|
| 41 |
+
diffs.row(transpositions[k].first).swap(diffs.row(transpositions[k].second));
|
| 42 |
+
}
|
| 43 |
+
return false;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
/* Check that two column vectors are approximately equal up to permutations.
|
| 47 |
+
* Initially, this method checked that the k-th power sums are equal for all k = 1, ..., vec1.rows(),
|
| 48 |
+
* however this strategy is numerically inaccurate because of numerical cancellation issues.
|
| 49 |
+
*/
|
| 50 |
+
template <typename VectorType>
|
| 51 |
+
void verify_is_approx_upto_permutation(const VectorType& vec1, const VectorType& vec2) {
|
| 52 |
+
typedef typename VectorType::Scalar Scalar;
|
| 53 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 54 |
+
|
| 55 |
+
VERIFY(vec1.cols() == 1);
|
| 56 |
+
VERIFY(vec2.cols() == 1);
|
| 57 |
+
VERIFY(vec1.rows() == vec2.rows());
|
| 58 |
+
|
| 59 |
+
Index n = vec1.rows();
|
| 60 |
+
RealScalar tol = test_precision<RealScalar>() * test_precision<RealScalar>() *
|
| 61 |
+
numext::maxi(vec1.squaredNorm(), vec2.squaredNorm());
|
| 62 |
+
Matrix<RealScalar, Dynamic, Dynamic> diffs =
|
| 63 |
+
(vec1.rowwise().replicate(n) - vec2.rowwise().replicate(n).transpose()).cwiseAbs2();
|
| 64 |
+
|
| 65 |
+
VERIFY(find_pivot(tol, diffs));
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
template <typename MatrixType>
|
| 69 |
+
void eigensolver(const MatrixType& m) {
|
| 70 |
+
/* this test covers the following files:
|
| 71 |
+
ComplexEigenSolver.h, and indirectly ComplexSchur.h
|
| 72 |
+
*/
|
| 73 |
+
Index rows = m.rows();
|
| 74 |
+
Index cols = m.cols();
|
| 75 |
+
|
| 76 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 77 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 78 |
+
|
| 79 |
+
MatrixType a = MatrixType::Random(rows, cols);
|
| 80 |
+
MatrixType symmA = a.adjoint() * a;
|
| 81 |
+
|
| 82 |
+
ComplexEigenSolver<MatrixType> ei0(symmA);
|
| 83 |
+
VERIFY_IS_EQUAL(ei0.info(), Success);
|
| 84 |
+
VERIFY_IS_APPROX(symmA * ei0.eigenvectors(), ei0.eigenvectors() * ei0.eigenvalues().asDiagonal());
|
| 85 |
+
|
| 86 |
+
ComplexEigenSolver<MatrixType> ei1(a);
|
| 87 |
+
VERIFY_IS_EQUAL(ei1.info(), Success);
|
| 88 |
+
VERIFY_IS_APPROX(a * ei1.eigenvectors(), ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());
|
| 89 |
+
// Note: If MatrixType is real then a.eigenvalues() uses EigenSolver and thus
|
| 90 |
+
// another algorithm so results may differ slightly
|
| 91 |
+
verify_is_approx_upto_permutation(a.eigenvalues(), ei1.eigenvalues());
|
| 92 |
+
|
| 93 |
+
ComplexEigenSolver<MatrixType> ei2;
|
| 94 |
+
ei2.setMaxIterations(ComplexSchur<MatrixType>::m_maxIterationsPerRow * rows).compute(a);
|
| 95 |
+
VERIFY_IS_EQUAL(ei2.info(), Success);
|
| 96 |
+
VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());
|
| 97 |
+
VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());
|
| 98 |
+
if (rows > 2) {
|
| 99 |
+
ei2.setMaxIterations(1).compute(a);
|
| 100 |
+
VERIFY_IS_EQUAL(ei2.info(), NoConvergence);
|
| 101 |
+
VERIFY_IS_EQUAL(ei2.getMaxIterations(), 1);
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
ComplexEigenSolver<MatrixType> eiNoEivecs(a, false);
|
| 105 |
+
VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
|
| 106 |
+
VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
|
| 107 |
+
|
| 108 |
+
// Regression test for issue #66
|
| 109 |
+
MatrixType z = MatrixType::Zero(rows, cols);
|
| 110 |
+
ComplexEigenSolver<MatrixType> eiz(z);
|
| 111 |
+
VERIFY((eiz.eigenvalues().cwiseEqual(0)).all());
|
| 112 |
+
|
| 113 |
+
MatrixType id = MatrixType::Identity(rows, cols);
|
| 114 |
+
VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
|
| 115 |
+
|
| 116 |
+
if (rows > 1 && rows < 20) {
|
| 117 |
+
// Test matrix with NaN
|
| 118 |
+
a(0, 0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
|
| 119 |
+
ComplexEigenSolver<MatrixType> eiNaN(a);
|
| 120 |
+
VERIFY_IS_EQUAL(eiNaN.info(), NoConvergence);
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
// regression test for bug 1098
|
| 124 |
+
{
|
| 125 |
+
ComplexEigenSolver<MatrixType> eig(a.adjoint() * a);
|
| 126 |
+
eig.compute(a.adjoint() * a);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
// regression test for bug 478
|
| 130 |
+
{
|
| 131 |
+
a.setZero();
|
| 132 |
+
ComplexEigenSolver<MatrixType> ei3(a);
|
| 133 |
+
VERIFY_IS_EQUAL(ei3.info(), Success);
|
| 134 |
+
VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(), RealScalar(1));
|
| 135 |
+
VERIFY((ei3.eigenvectors().transpose() * ei3.eigenvectors().transpose()).eval().isIdentity());
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
template <typename MatrixType>
|
| 140 |
+
void eigensolver_verify_assert(const MatrixType& m) {
|
| 141 |
+
ComplexEigenSolver<MatrixType> eig;
|
| 142 |
+
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
| 143 |
+
VERIFY_RAISES_ASSERT(eig.eigenvalues());
|
| 144 |
+
|
| 145 |
+
MatrixType a = MatrixType::Random(m.rows(), m.cols());
|
| 146 |
+
eig.compute(a, false);
|
| 147 |
+
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
EIGEN_DECLARE_TEST(eigensolver_complex) {
|
| 151 |
+
int s = 0;
|
| 152 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 153 |
+
CALL_SUBTEST_1(eigensolver(Matrix4cf()));
|
| 154 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 155 |
+
CALL_SUBTEST_2(eigensolver(MatrixXcd(s, s)));
|
| 156 |
+
CALL_SUBTEST_3(eigensolver(Matrix<std::complex<float>, 1, 1>()));
|
| 157 |
+
CALL_SUBTEST_4(eigensolver(Matrix3f()));
|
| 158 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 159 |
+
}
|
| 160 |
+
CALL_SUBTEST_1(eigensolver_verify_assert(Matrix4cf()));
|
| 161 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 162 |
+
CALL_SUBTEST_2(eigensolver_verify_assert(MatrixXcd(s, s)));
|
| 163 |
+
CALL_SUBTEST_3(eigensolver_verify_assert(Matrix<std::complex<float>, 1, 1>()));
|
| 164 |
+
CALL_SUBTEST_4(eigensolver_verify_assert(Matrix3f()));
|
| 165 |
+
|
| 166 |
+
// Test problem size constructors
|
| 167 |
+
CALL_SUBTEST_5(ComplexEigenSolver<MatrixXf> tmp(s));
|
| 168 |
+
|
| 169 |
+
// Test custom complex scalar type.
|
| 170 |
+
CALL_SUBTEST_6(eigensolver(Matrix<CustomComplex<double>, 5, 5>()));
|
| 171 |
+
|
| 172 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 173 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_generalized_real.cpp
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2012-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 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_RUNTIME_NO_MALLOC
|
| 11 |
+
#include "main.h"
|
| 12 |
+
#include <limits>
|
| 13 |
+
#include <Eigen/Eigenvalues>
|
| 14 |
+
#include <Eigen/LU>
|
| 15 |
+
|
| 16 |
+
template <typename MatrixType>
|
| 17 |
+
void generalized_eigensolver_real(const MatrixType& m) {
|
| 18 |
+
/* this test covers the following files:
|
| 19 |
+
GeneralizedEigenSolver.h
|
| 20 |
+
*/
|
| 21 |
+
Index rows = m.rows();
|
| 22 |
+
Index cols = m.cols();
|
| 23 |
+
|
| 24 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 25 |
+
typedef std::complex<Scalar> ComplexScalar;
|
| 26 |
+
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
| 27 |
+
|
| 28 |
+
MatrixType a = MatrixType::Random(rows, cols);
|
| 29 |
+
MatrixType b = MatrixType::Random(rows, cols);
|
| 30 |
+
MatrixType a1 = MatrixType::Random(rows, cols);
|
| 31 |
+
MatrixType b1 = MatrixType::Random(rows, cols);
|
| 32 |
+
MatrixType spdA = a.adjoint() * a + a1.adjoint() * a1;
|
| 33 |
+
MatrixType spdB = b.adjoint() * b + b1.adjoint() * b1;
|
| 34 |
+
|
| 35 |
+
// lets compare to GeneralizedSelfAdjointEigenSolver
|
| 36 |
+
{
|
| 37 |
+
GeneralizedSelfAdjointEigenSolver<MatrixType> symmEig(spdA, spdB);
|
| 38 |
+
GeneralizedEigenSolver<MatrixType> eig(spdA, spdB);
|
| 39 |
+
|
| 40 |
+
VERIFY_IS_EQUAL(eig.eigenvalues().imag().cwiseAbs().maxCoeff(), 0);
|
| 41 |
+
|
| 42 |
+
VectorType realEigenvalues = eig.eigenvalues().real();
|
| 43 |
+
std::sort(realEigenvalues.data(), realEigenvalues.data() + realEigenvalues.size());
|
| 44 |
+
VERIFY_IS_APPROX(realEigenvalues, symmEig.eigenvalues());
|
| 45 |
+
|
| 46 |
+
// check eigenvectors
|
| 47 |
+
typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType D = eig.eigenvalues().asDiagonal();
|
| 48 |
+
typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType V = eig.eigenvectors();
|
| 49 |
+
VERIFY_IS_APPROX(spdA * V, spdB * V * D);
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
// non symmetric case:
|
| 53 |
+
{
|
| 54 |
+
GeneralizedEigenSolver<MatrixType> eig(rows);
|
| 55 |
+
// TODO enable full-prealocation of required memory, this probably requires an in-place mode for
|
| 56 |
+
// HessenbergDecomposition
|
| 57 |
+
// Eigen::internal::set_is_malloc_allowed(false);
|
| 58 |
+
eig.compute(a, b);
|
| 59 |
+
// Eigen::internal::set_is_malloc_allowed(true);
|
| 60 |
+
for (Index k = 0; k < cols; ++k) {
|
| 61 |
+
Matrix<ComplexScalar, Dynamic, Dynamic> tmp =
|
| 62 |
+
(eig.betas()(k) * a).template cast<ComplexScalar>() - eig.alphas()(k) * b;
|
| 63 |
+
if (tmp.size() > 1 && tmp.norm() > (std::numeric_limits<Scalar>::min)()) tmp /= tmp.norm();
|
| 64 |
+
VERIFY_IS_MUCH_SMALLER_THAN(std::abs(tmp.determinant()), Scalar(1));
|
| 65 |
+
}
|
| 66 |
+
// check eigenvectors
|
| 67 |
+
typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType D = eig.eigenvalues().asDiagonal();
|
| 68 |
+
typename GeneralizedEigenSolver<MatrixType>::EigenvectorsType V = eig.eigenvectors();
|
| 69 |
+
VERIFY_IS_APPROX(a * V, b * V * D);
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
// regression test for bug 1098
|
| 73 |
+
{
|
| 74 |
+
GeneralizedSelfAdjointEigenSolver<MatrixType> eig1(a.adjoint() * a, b.adjoint() * b);
|
| 75 |
+
eig1.compute(a.adjoint() * a, b.adjoint() * b);
|
| 76 |
+
GeneralizedEigenSolver<MatrixType> eig2(a.adjoint() * a, b.adjoint() * b);
|
| 77 |
+
eig2.compute(a.adjoint() * a, b.adjoint() * b);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
// check without eigenvectors
|
| 81 |
+
{
|
| 82 |
+
GeneralizedEigenSolver<MatrixType> eig1(spdA, spdB, true);
|
| 83 |
+
GeneralizedEigenSolver<MatrixType> eig2(spdA, spdB, false);
|
| 84 |
+
VERIFY_IS_APPROX(eig1.eigenvalues(), eig2.eigenvalues());
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
template <typename MatrixType>
|
| 89 |
+
void generalized_eigensolver_assert() {
|
| 90 |
+
GeneralizedEigenSolver<MatrixType> eig;
|
| 91 |
+
// all raise assert if uninitialized
|
| 92 |
+
VERIFY_RAISES_ASSERT(eig.info());
|
| 93 |
+
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
| 94 |
+
VERIFY_RAISES_ASSERT(eig.eigenvalues());
|
| 95 |
+
VERIFY_RAISES_ASSERT(eig.alphas());
|
| 96 |
+
VERIFY_RAISES_ASSERT(eig.betas());
|
| 97 |
+
|
| 98 |
+
// none raise assert after compute called
|
| 99 |
+
eig.compute(MatrixType::Random(20, 20), MatrixType::Random(20, 20));
|
| 100 |
+
VERIFY(eig.info() == Success);
|
| 101 |
+
eig.eigenvectors();
|
| 102 |
+
eig.eigenvalues();
|
| 103 |
+
eig.alphas();
|
| 104 |
+
eig.betas();
|
| 105 |
+
|
| 106 |
+
// eigenvectors() raises assert, if eigenvectors were not requested
|
| 107 |
+
eig.compute(MatrixType::Random(20, 20), MatrixType::Random(20, 20), false);
|
| 108 |
+
VERIFY(eig.info() == Success);
|
| 109 |
+
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
| 110 |
+
eig.eigenvalues();
|
| 111 |
+
eig.alphas();
|
| 112 |
+
eig.betas();
|
| 113 |
+
|
| 114 |
+
// all except info raise assert if realQZ did not converge
|
| 115 |
+
eig.setMaxIterations(0); // force real QZ to fail.
|
| 116 |
+
eig.compute(MatrixType::Random(20, 20), MatrixType::Random(20, 20));
|
| 117 |
+
VERIFY(eig.info() == NoConvergence);
|
| 118 |
+
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
| 119 |
+
VERIFY_RAISES_ASSERT(eig.eigenvalues());
|
| 120 |
+
VERIFY_RAISES_ASSERT(eig.alphas());
|
| 121 |
+
VERIFY_RAISES_ASSERT(eig.betas());
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
EIGEN_DECLARE_TEST(eigensolver_generalized_real) {
|
| 125 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 126 |
+
int s = 0;
|
| 127 |
+
CALL_SUBTEST_1(generalized_eigensolver_real(Matrix4f()));
|
| 128 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 129 |
+
CALL_SUBTEST_2(generalized_eigensolver_real(MatrixXd(s, s)));
|
| 130 |
+
|
| 131 |
+
// some trivial but implementation-wise special cases
|
| 132 |
+
CALL_SUBTEST_2(generalized_eigensolver_real(MatrixXd(1, 1)));
|
| 133 |
+
CALL_SUBTEST_2(generalized_eigensolver_real(MatrixXd(2, 2)));
|
| 134 |
+
CALL_SUBTEST_3(generalized_eigensolver_real(Matrix<double, 1, 1>()));
|
| 135 |
+
CALL_SUBTEST_4(generalized_eigensolver_real(Matrix2d()));
|
| 136 |
+
CALL_SUBTEST_5(generalized_eigensolver_assert<MatrixXd>());
|
| 137 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 138 |
+
}
|
| 139 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_generic.cpp
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 5 |
+
// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
| 6 |
+
//
|
| 7 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 8 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 9 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 10 |
+
|
| 11 |
+
#include "main.h"
|
| 12 |
+
#include <limits>
|
| 13 |
+
#include <Eigen/Eigenvalues>
|
| 14 |
+
|
| 15 |
+
template <typename EigType, typename MatType>
|
| 16 |
+
void check_eigensolver_for_given_mat(const EigType& eig, const MatType& a) {
|
| 17 |
+
typedef typename NumTraits<typename MatType::Scalar>::Real RealScalar;
|
| 18 |
+
typedef Matrix<RealScalar, MatType::RowsAtCompileTime, 1> RealVectorType;
|
| 19 |
+
typedef typename std::complex<RealScalar> Complex;
|
| 20 |
+
Index n = a.rows();
|
| 21 |
+
VERIFY_IS_EQUAL(eig.info(), Success);
|
| 22 |
+
VERIFY_IS_APPROX(a * eig.pseudoEigenvectors(), eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix());
|
| 23 |
+
VERIFY_IS_APPROX(a.template cast<Complex>() * eig.eigenvectors(),
|
| 24 |
+
eig.eigenvectors() * eig.eigenvalues().asDiagonal());
|
| 25 |
+
VERIFY_IS_APPROX(eig.eigenvectors().colwise().norm(), RealVectorType::Ones(n).transpose());
|
| 26 |
+
VERIFY_IS_APPROX(a.eigenvalues(), eig.eigenvalues());
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
template <typename MatrixType>
|
| 30 |
+
void eigensolver(const MatrixType& m) {
|
| 31 |
+
/* this test covers the following files:
|
| 32 |
+
EigenSolver.h
|
| 33 |
+
*/
|
| 34 |
+
Index rows = m.rows();
|
| 35 |
+
Index cols = m.cols();
|
| 36 |
+
|
| 37 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 38 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 39 |
+
typedef typename std::complex<RealScalar> Complex;
|
| 40 |
+
|
| 41 |
+
MatrixType a = MatrixType::Random(rows, cols);
|
| 42 |
+
MatrixType a1 = MatrixType::Random(rows, cols);
|
| 43 |
+
MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;
|
| 44 |
+
|
| 45 |
+
EigenSolver<MatrixType> ei0(symmA);
|
| 46 |
+
VERIFY_IS_EQUAL(ei0.info(), Success);
|
| 47 |
+
VERIFY_IS_APPROX(symmA * ei0.pseudoEigenvectors(), ei0.pseudoEigenvectors() * ei0.pseudoEigenvalueMatrix());
|
| 48 |
+
VERIFY_IS_APPROX((symmA.template cast<Complex>()) * (ei0.pseudoEigenvectors().template cast<Complex>()),
|
| 49 |
+
(ei0.pseudoEigenvectors().template cast<Complex>()) * (ei0.eigenvalues().asDiagonal()));
|
| 50 |
+
|
| 51 |
+
EigenSolver<MatrixType> ei1(a);
|
| 52 |
+
CALL_SUBTEST(check_eigensolver_for_given_mat(ei1, a));
|
| 53 |
+
|
| 54 |
+
EigenSolver<MatrixType> ei2;
|
| 55 |
+
ei2.setMaxIterations(RealSchur<MatrixType>::m_maxIterationsPerRow * rows).compute(a);
|
| 56 |
+
VERIFY_IS_EQUAL(ei2.info(), Success);
|
| 57 |
+
VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());
|
| 58 |
+
VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());
|
| 59 |
+
if (rows > 2) {
|
| 60 |
+
ei2.setMaxIterations(1).compute(a);
|
| 61 |
+
VERIFY_IS_EQUAL(ei2.info(), NoConvergence);
|
| 62 |
+
VERIFY_IS_EQUAL(ei2.getMaxIterations(), 1);
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
EigenSolver<MatrixType> eiNoEivecs(a, false);
|
| 66 |
+
VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);
|
| 67 |
+
VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());
|
| 68 |
+
VERIFY_IS_APPROX(ei1.pseudoEigenvalueMatrix(), eiNoEivecs.pseudoEigenvalueMatrix());
|
| 69 |
+
|
| 70 |
+
MatrixType id = MatrixType::Identity(rows, cols);
|
| 71 |
+
VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));
|
| 72 |
+
|
| 73 |
+
if (rows > 2 && rows < 20) {
|
| 74 |
+
// Test matrix with NaN
|
| 75 |
+
a(0, 0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
|
| 76 |
+
EigenSolver<MatrixType> eiNaN(a);
|
| 77 |
+
VERIFY_IS_NOT_EQUAL(eiNaN.info(), Success);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
// regression test for bug 1098
|
| 81 |
+
{
|
| 82 |
+
EigenSolver<MatrixType> eig(a.adjoint() * a);
|
| 83 |
+
eig.compute(a.adjoint() * a);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
// regression test for bug 478
|
| 87 |
+
{
|
| 88 |
+
a.setZero();
|
| 89 |
+
EigenSolver<MatrixType> ei3(a);
|
| 90 |
+
VERIFY_IS_EQUAL(ei3.info(), Success);
|
| 91 |
+
VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(), RealScalar(1));
|
| 92 |
+
VERIFY((ei3.eigenvectors().transpose() * ei3.eigenvectors().transpose()).eval().isIdentity());
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
template <typename MatrixType>
|
| 97 |
+
void eigensolver_verify_assert(const MatrixType& m) {
|
| 98 |
+
EigenSolver<MatrixType> eig;
|
| 99 |
+
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
| 100 |
+
VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());
|
| 101 |
+
VERIFY_RAISES_ASSERT(eig.pseudoEigenvalueMatrix());
|
| 102 |
+
VERIFY_RAISES_ASSERT(eig.eigenvalues());
|
| 103 |
+
|
| 104 |
+
MatrixType a = MatrixType::Random(m.rows(), m.cols());
|
| 105 |
+
eig.compute(a, false);
|
| 106 |
+
VERIFY_RAISES_ASSERT(eig.eigenvectors());
|
| 107 |
+
VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
template <typename CoeffType>
|
| 111 |
+
Matrix<typename CoeffType::Scalar, Dynamic, Dynamic> make_companion(const CoeffType& coeffs) {
|
| 112 |
+
Index n = coeffs.size() - 1;
|
| 113 |
+
Matrix<typename CoeffType::Scalar, Dynamic, Dynamic> res(n, n);
|
| 114 |
+
res.setZero();
|
| 115 |
+
res.row(0) = -coeffs.tail(n) / coeffs(0);
|
| 116 |
+
res.diagonal(-1).setOnes();
|
| 117 |
+
return res;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
template <int>
|
| 121 |
+
void eigensolver_generic_extra() {
|
| 122 |
+
{
|
| 123 |
+
// regression test for bug 793
|
| 124 |
+
MatrixXd a(3, 3);
|
| 125 |
+
a << 0, 0, 1, 1, 1, 1, 1, 1e+200, 1;
|
| 126 |
+
Eigen::EigenSolver<MatrixXd> eig(a);
|
| 127 |
+
double scale = 1e-200; // scale to avoid overflow during the comparisons
|
| 128 |
+
VERIFY_IS_APPROX(a * eig.pseudoEigenvectors() * scale,
|
| 129 |
+
eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix() * scale);
|
| 130 |
+
VERIFY_IS_APPROX(a * eig.eigenvectors() * scale, eig.eigenvectors() * eig.eigenvalues().asDiagonal() * scale);
|
| 131 |
+
}
|
| 132 |
+
{
|
| 133 |
+
// check a case where all eigenvalues are null.
|
| 134 |
+
MatrixXd a(2, 2);
|
| 135 |
+
a << 1, 1, -1, -1;
|
| 136 |
+
Eigen::EigenSolver<MatrixXd> eig(a);
|
| 137 |
+
VERIFY_IS_APPROX(eig.pseudoEigenvectors().squaredNorm(), 2.);
|
| 138 |
+
VERIFY_IS_APPROX((a * eig.pseudoEigenvectors()).norm() + 1., 1.);
|
| 139 |
+
VERIFY_IS_APPROX((eig.pseudoEigenvectors() * eig.pseudoEigenvalueMatrix()).norm() + 1., 1.);
|
| 140 |
+
VERIFY_IS_APPROX((a * eig.eigenvectors()).norm() + 1., 1.);
|
| 141 |
+
VERIFY_IS_APPROX((eig.eigenvectors() * eig.eigenvalues().asDiagonal()).norm() + 1., 1.);
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
// regression test for bug 933
|
| 145 |
+
{
|
| 146 |
+
{
|
| 147 |
+
VectorXd coeffs(5);
|
| 148 |
+
coeffs << 1, -3, -175, -225, 2250;
|
| 149 |
+
MatrixXd C = make_companion(coeffs);
|
| 150 |
+
EigenSolver<MatrixXd> eig(C);
|
| 151 |
+
CALL_SUBTEST(check_eigensolver_for_given_mat(eig, C));
|
| 152 |
+
}
|
| 153 |
+
{
|
| 154 |
+
// this test is tricky because it requires high accuracy in smallest eigenvalues
|
| 155 |
+
VectorXd coeffs(5);
|
| 156 |
+
coeffs << 6.154671e-15, -1.003870e-10, -9.819570e-01, 3.995715e+03, 2.211511e+08;
|
| 157 |
+
MatrixXd C = make_companion(coeffs);
|
| 158 |
+
EigenSolver<MatrixXd> eig(C);
|
| 159 |
+
CALL_SUBTEST(check_eigensolver_for_given_mat(eig, C));
|
| 160 |
+
Index n = C.rows();
|
| 161 |
+
for (Index i = 0; i < n; ++i) {
|
| 162 |
+
typedef std::complex<double> Complex;
|
| 163 |
+
MatrixXcd ac = C.cast<Complex>();
|
| 164 |
+
ac.diagonal().array() -= eig.eigenvalues()(i);
|
| 165 |
+
VectorXd sv = ac.jacobiSvd().singularValues();
|
| 166 |
+
// comparing to sv(0) is not enough here to catch the "bug",
|
| 167 |
+
// the hard-coded 1.0 is important!
|
| 168 |
+
VERIFY_IS_MUCH_SMALLER_THAN(sv(n - 1), 1.0);
|
| 169 |
+
}
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
// regression test for bug 1557
|
| 173 |
+
{
|
| 174 |
+
// this test is interesting because it contains zeros on the diagonal.
|
| 175 |
+
MatrixXd A_bug1557(3, 3);
|
| 176 |
+
A_bug1557 << 0, 0, 0, 1, 0, 0.5887907064808635127, 0, 1, 0;
|
| 177 |
+
EigenSolver<MatrixXd> eig(A_bug1557);
|
| 178 |
+
CALL_SUBTEST(check_eigensolver_for_given_mat(eig, A_bug1557));
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
// regression test for bug 1174
|
| 182 |
+
{
|
| 183 |
+
Index n = 12;
|
| 184 |
+
MatrixXf A_bug1174(n, n);
|
| 185 |
+
A_bug1174 << 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432, 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0,
|
| 186 |
+
786432, 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0, 786432, 262144, 0, 0, 262144, 786432, 0, 0, 0, 0, 0, 0,
|
| 187 |
+
786432, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0,
|
| 188 |
+
262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144,
|
| 189 |
+
262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144,
|
| 190 |
+
262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144,
|
| 191 |
+
262144, 262144, 262144, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0,
|
| 192 |
+
0, 262144, 262144, 0, 0, 262144, 262144, 262144, 262144, 262144, 262144, 0;
|
| 193 |
+
EigenSolver<MatrixXf> eig(A_bug1174);
|
| 194 |
+
CALL_SUBTEST(check_eigensolver_for_given_mat(eig, A_bug1174));
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
EIGEN_DECLARE_TEST(eigensolver_generic) {
|
| 199 |
+
int s = 0;
|
| 200 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 201 |
+
CALL_SUBTEST_1(eigensolver(Matrix4f()));
|
| 202 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 203 |
+
CALL_SUBTEST_2(eigensolver(MatrixXd(s, s)));
|
| 204 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 205 |
+
|
| 206 |
+
// some trivial but implementation-wise tricky cases
|
| 207 |
+
CALL_SUBTEST_2(eigensolver(MatrixXd(1, 1)));
|
| 208 |
+
CALL_SUBTEST_2(eigensolver(MatrixXd(2, 2)));
|
| 209 |
+
CALL_SUBTEST_3(eigensolver(Matrix<double, 1, 1>()));
|
| 210 |
+
CALL_SUBTEST_4(eigensolver(Matrix2d()));
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
CALL_SUBTEST_1(eigensolver_verify_assert(Matrix4f()));
|
| 214 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 215 |
+
CALL_SUBTEST_2(eigensolver_verify_assert(MatrixXd(s, s)));
|
| 216 |
+
CALL_SUBTEST_3(eigensolver_verify_assert(Matrix<double, 1, 1>()));
|
| 217 |
+
CALL_SUBTEST_4(eigensolver_verify_assert(Matrix2d()));
|
| 218 |
+
|
| 219 |
+
// Test problem size constructors
|
| 220 |
+
CALL_SUBTEST_5(EigenSolver<MatrixXf> tmp(s));
|
| 221 |
+
|
| 222 |
+
// regression test for bug 410
|
| 223 |
+
CALL_SUBTEST_2({
|
| 224 |
+
MatrixXd A(1, 1);
|
| 225 |
+
A(0, 0) = std::sqrt(-1.); // is Not-a-Number
|
| 226 |
+
Eigen::EigenSolver<MatrixXd> solver(A);
|
| 227 |
+
VERIFY_IS_EQUAL(solver.info(), NumericalIssue);
|
| 228 |
+
});
|
| 229 |
+
|
| 230 |
+
CALL_SUBTEST_2(eigensolver_generic_extra<0>());
|
| 231 |
+
|
| 232 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 233 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/eigensolver_selfadjoint.cpp
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// This file is part of Eigen, a lightweight C++ template library
|
| 2 |
+
// for linear algebra.
|
| 3 |
+
//
|
| 4 |
+
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
| 5 |
+
// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
| 6 |
+
//
|
| 7 |
+
// This Source Code Form is subject to the terms of the Mozilla
|
| 8 |
+
// Public License v. 2.0. If a copy of the MPL was not distributed
|
| 9 |
+
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 10 |
+
|
| 11 |
+
#include "main.h"
|
| 12 |
+
#include "svd_fill.h"
|
| 13 |
+
#include <limits>
|
| 14 |
+
#include <Eigen/Eigenvalues>
|
| 15 |
+
#include <Eigen/SparseCore>
|
| 16 |
+
#include <unsupported/Eigen/MatrixFunctions>
|
| 17 |
+
|
| 18 |
+
template <typename MatrixType>
|
| 19 |
+
void selfadjointeigensolver_essential_check(const MatrixType& m) {
|
| 20 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 21 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 22 |
+
RealScalar eival_eps =
|
| 23 |
+
numext::mini<RealScalar>(test_precision<RealScalar>(), NumTraits<Scalar>::dummy_precision() * 20000);
|
| 24 |
+
|
| 25 |
+
SelfAdjointEigenSolver<MatrixType> eiSymm(m);
|
| 26 |
+
VERIFY_IS_EQUAL(eiSymm.info(), Success);
|
| 27 |
+
|
| 28 |
+
RealScalar scaling = m.cwiseAbs().maxCoeff();
|
| 29 |
+
RealScalar unitary_error_factor = RealScalar(16);
|
| 30 |
+
|
| 31 |
+
if (scaling < (std::numeric_limits<RealScalar>::min)()) {
|
| 32 |
+
VERIFY(eiSymm.eigenvalues().cwiseAbs().maxCoeff() <= (std::numeric_limits<RealScalar>::min)());
|
| 33 |
+
} else {
|
| 34 |
+
VERIFY_IS_APPROX((m.template selfadjointView<Lower>() * eiSymm.eigenvectors()) / scaling,
|
| 35 |
+
(eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal()) / scaling);
|
| 36 |
+
}
|
| 37 |
+
VERIFY_IS_APPROX(m.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());
|
| 38 |
+
VERIFY(eiSymm.eigenvectors().isUnitary(test_precision<RealScalar>() * unitary_error_factor));
|
| 39 |
+
|
| 40 |
+
if (m.cols() <= 4) {
|
| 41 |
+
SelfAdjointEigenSolver<MatrixType> eiDirect;
|
| 42 |
+
eiDirect.computeDirect(m);
|
| 43 |
+
VERIFY_IS_EQUAL(eiDirect.info(), Success);
|
| 44 |
+
if (!eiSymm.eigenvalues().isApprox(eiDirect.eigenvalues(), eival_eps)) {
|
| 45 |
+
std::cerr << "reference eigenvalues: " << eiSymm.eigenvalues().transpose() << "\n"
|
| 46 |
+
<< "obtained eigenvalues: " << eiDirect.eigenvalues().transpose() << "\n"
|
| 47 |
+
<< "diff: " << (eiSymm.eigenvalues() - eiDirect.eigenvalues()).transpose() << "\n"
|
| 48 |
+
<< "error (eps): "
|
| 49 |
+
<< (eiSymm.eigenvalues() - eiDirect.eigenvalues()).norm() / eiSymm.eigenvalues().norm() << " ("
|
| 50 |
+
<< eival_eps << ")\n";
|
| 51 |
+
}
|
| 52 |
+
if (scaling < (std::numeric_limits<RealScalar>::min)()) {
|
| 53 |
+
VERIFY(eiDirect.eigenvalues().cwiseAbs().maxCoeff() <= (std::numeric_limits<RealScalar>::min)());
|
| 54 |
+
} else {
|
| 55 |
+
VERIFY_IS_APPROX(eiSymm.eigenvalues() / scaling, eiDirect.eigenvalues() / scaling);
|
| 56 |
+
VERIFY_IS_APPROX((m.template selfadjointView<Lower>() * eiDirect.eigenvectors()) / scaling,
|
| 57 |
+
(eiDirect.eigenvectors() * eiDirect.eigenvalues().asDiagonal()) / scaling);
|
| 58 |
+
VERIFY_IS_APPROX(m.template selfadjointView<Lower>().eigenvalues() / scaling, eiDirect.eigenvalues() / scaling);
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
VERIFY(eiDirect.eigenvectors().isUnitary(test_precision<RealScalar>() * unitary_error_factor));
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
template <typename MatrixType>
|
| 66 |
+
void selfadjointeigensolver(const MatrixType& m) {
|
| 67 |
+
/* this test covers the following files:
|
| 68 |
+
EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)
|
| 69 |
+
*/
|
| 70 |
+
Index rows = m.rows();
|
| 71 |
+
Index cols = m.cols();
|
| 72 |
+
|
| 73 |
+
typedef typename MatrixType::Scalar Scalar;
|
| 74 |
+
typedef typename NumTraits<Scalar>::Real RealScalar;
|
| 75 |
+
|
| 76 |
+
RealScalar largerEps = 10 * test_precision<RealScalar>();
|
| 77 |
+
|
| 78 |
+
MatrixType a = MatrixType::Random(rows, cols);
|
| 79 |
+
MatrixType a1 = MatrixType::Random(rows, cols);
|
| 80 |
+
MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;
|
| 81 |
+
MatrixType symmC = symmA;
|
| 82 |
+
|
| 83 |
+
svd_fill_random(symmA, Symmetric);
|
| 84 |
+
|
| 85 |
+
symmA.template triangularView<StrictlyUpper>().setZero();
|
| 86 |
+
symmC.template triangularView<StrictlyUpper>().setZero();
|
| 87 |
+
|
| 88 |
+
MatrixType b = MatrixType::Random(rows, cols);
|
| 89 |
+
MatrixType b1 = MatrixType::Random(rows, cols);
|
| 90 |
+
MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;
|
| 91 |
+
symmB.template triangularView<StrictlyUpper>().setZero();
|
| 92 |
+
|
| 93 |
+
CALL_SUBTEST(selfadjointeigensolver_essential_check(symmA));
|
| 94 |
+
|
| 95 |
+
SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);
|
| 96 |
+
// generalized eigen pb
|
| 97 |
+
GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmC, symmB);
|
| 98 |
+
|
| 99 |
+
SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);
|
| 100 |
+
VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);
|
| 101 |
+
VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());
|
| 102 |
+
|
| 103 |
+
// generalized eigen problem Ax = lBx
|
| 104 |
+
eiSymmGen.compute(symmC, symmB, Ax_lBx);
|
| 105 |
+
VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
|
| 106 |
+
VERIFY((symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())
|
| 107 |
+
.isApprox(symmB.template selfadjointView<Lower>() *
|
| 108 |
+
(eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()),
|
| 109 |
+
largerEps));
|
| 110 |
+
|
| 111 |
+
// generalized eigen problem BAx = lx
|
| 112 |
+
eiSymmGen.compute(symmC, symmB, BAx_lx);
|
| 113 |
+
VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
|
| 114 |
+
VERIFY(
|
| 115 |
+
(symmB.template selfadjointView<Lower>() * (symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()))
|
| 116 |
+
.isApprox((eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));
|
| 117 |
+
|
| 118 |
+
// generalized eigen problem ABx = lx
|
| 119 |
+
eiSymmGen.compute(symmC, symmB, ABx_lx);
|
| 120 |
+
VERIFY_IS_EQUAL(eiSymmGen.info(), Success);
|
| 121 |
+
VERIFY(
|
| 122 |
+
(symmC.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()))
|
| 123 |
+
.isApprox((eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));
|
| 124 |
+
|
| 125 |
+
eiSymm.compute(symmC);
|
| 126 |
+
MatrixType sqrtSymmA = eiSymm.operatorSqrt();
|
| 127 |
+
VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), sqrtSymmA * sqrtSymmA);
|
| 128 |
+
VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView<Lower>() * eiSymm.operatorInverseSqrt());
|
| 129 |
+
|
| 130 |
+
MatrixType id = MatrixType::Identity(rows, cols);
|
| 131 |
+
VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));
|
| 132 |
+
|
| 133 |
+
SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;
|
| 134 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());
|
| 135 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());
|
| 136 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
|
| 137 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
|
| 138 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());
|
| 139 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorExp());
|
| 140 |
+
|
| 141 |
+
eiSymmUninitialized.compute(symmA, false);
|
| 142 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());
|
| 143 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());
|
| 144 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());
|
| 145 |
+
VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorExp());
|
| 146 |
+
|
| 147 |
+
// test Tridiagonalization's methods
|
| 148 |
+
Tridiagonalization<MatrixType> tridiag(symmC);
|
| 149 |
+
VERIFY_IS_APPROX(tridiag.diagonal(), tridiag.matrixT().diagonal());
|
| 150 |
+
VERIFY_IS_APPROX(tridiag.subDiagonal(), tridiag.matrixT().template diagonal<-1>());
|
| 151 |
+
Matrix<RealScalar, Dynamic, Dynamic> T = tridiag.matrixT();
|
| 152 |
+
if (rows > 1 && cols > 1) {
|
| 153 |
+
// FIXME check that upper and lower part are 0:
|
| 154 |
+
// VERIFY(T.topRightCorner(rows-2, cols-2).template triangularView<Upper>().isZero());
|
| 155 |
+
}
|
| 156 |
+
VERIFY_IS_APPROX(tridiag.diagonal(), T.diagonal());
|
| 157 |
+
VERIFY_IS_APPROX(tridiag.subDiagonal(), T.template diagonal<1>());
|
| 158 |
+
VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()),
|
| 159 |
+
tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());
|
| 160 |
+
VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()),
|
| 161 |
+
tridiag.matrixQ() * tridiag.matrixT() * tridiag.matrixQ().adjoint());
|
| 162 |
+
|
| 163 |
+
// Test computation of eigenvalues from tridiagonal matrix
|
| 164 |
+
if (rows > 1) {
|
| 165 |
+
SelfAdjointEigenSolver<MatrixType> eiSymmTridiag;
|
| 166 |
+
eiSymmTridiag.computeFromTridiagonal(tridiag.matrixT().diagonal(), tridiag.matrixT().diagonal(-1),
|
| 167 |
+
ComputeEigenvectors);
|
| 168 |
+
VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmTridiag.eigenvalues());
|
| 169 |
+
VERIFY_IS_APPROX(tridiag.matrixT(), eiSymmTridiag.eigenvectors().real() * eiSymmTridiag.eigenvalues().asDiagonal() *
|
| 170 |
+
eiSymmTridiag.eigenvectors().real().transpose());
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
// Test matrix expponential from eigendecomposition.
|
| 174 |
+
// First scale to avoid overflow.
|
| 175 |
+
symmB = symmB / symmB.norm();
|
| 176 |
+
eiSymm.compute(symmB);
|
| 177 |
+
MatrixType expSymmB = eiSymm.operatorExp();
|
| 178 |
+
symmB = symmB.template selfadjointView<Lower>();
|
| 179 |
+
VERIFY_IS_APPROX(expSymmB, symmB.exp());
|
| 180 |
+
|
| 181 |
+
if (rows > 1 && rows < 20) {
|
| 182 |
+
// Test matrix with NaN
|
| 183 |
+
symmC(0, 0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();
|
| 184 |
+
SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmC);
|
| 185 |
+
VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
// regression test for bug 1098
|
| 189 |
+
{
|
| 190 |
+
SelfAdjointEigenSolver<MatrixType> eig(a.adjoint() * a);
|
| 191 |
+
eig.compute(a.adjoint() * a);
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
// regression test for bug 478
|
| 195 |
+
{
|
| 196 |
+
a.setZero();
|
| 197 |
+
SelfAdjointEigenSolver<MatrixType> ei3(a);
|
| 198 |
+
VERIFY_IS_EQUAL(ei3.info(), Success);
|
| 199 |
+
VERIFY_IS_MUCH_SMALLER_THAN(ei3.eigenvalues().norm(), RealScalar(1));
|
| 200 |
+
VERIFY((ei3.eigenvectors().transpose() * ei3.eigenvectors().transpose()).eval().isIdentity());
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
template <int>
|
| 205 |
+
void bug_854() {
|
| 206 |
+
Matrix3d m;
|
| 207 |
+
m << 850.961, 51.966, 0, 51.966, 254.841, 0, 0, 0, 0;
|
| 208 |
+
selfadjointeigensolver_essential_check(m);
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
template <int>
|
| 212 |
+
void bug_1014() {
|
| 213 |
+
Matrix3d m;
|
| 214 |
+
m << 0.11111111111111114658, 0, 0, 0, 0.11111111111111109107, 0, 0, 0, 0.11111111111111107719;
|
| 215 |
+
selfadjointeigensolver_essential_check(m);
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
template <int>
|
| 219 |
+
void bug_1225() {
|
| 220 |
+
Matrix3d m1, m2;
|
| 221 |
+
m1.setRandom();
|
| 222 |
+
m1 = m1 * m1.transpose();
|
| 223 |
+
m2 = m1.triangularView<Upper>();
|
| 224 |
+
SelfAdjointEigenSolver<Matrix3d> eig1(m1);
|
| 225 |
+
SelfAdjointEigenSolver<Matrix3d> eig2(m2.selfadjointView<Upper>());
|
| 226 |
+
VERIFY_IS_APPROX(eig1.eigenvalues(), eig2.eigenvalues());
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
+
template <int>
|
| 230 |
+
void bug_1204() {
|
| 231 |
+
SparseMatrix<double> A(2, 2);
|
| 232 |
+
A.setIdentity();
|
| 233 |
+
SelfAdjointEigenSolver<Eigen::SparseMatrix<double> > eig(A);
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
EIGEN_DECLARE_TEST(eigensolver_selfadjoint) {
|
| 237 |
+
int s = 0;
|
| 238 |
+
for (int i = 0; i < g_repeat; i++) {
|
| 239 |
+
// trivial test for 1x1 matrices:
|
| 240 |
+
CALL_SUBTEST_1(selfadjointeigensolver(Matrix<float, 1, 1>()));
|
| 241 |
+
CALL_SUBTEST_1(selfadjointeigensolver(Matrix<double, 1, 1>()));
|
| 242 |
+
CALL_SUBTEST_1(selfadjointeigensolver(Matrix<std::complex<double>, 1, 1>()));
|
| 243 |
+
|
| 244 |
+
// very important to test 3x3 and 2x2 matrices since we provide special paths for them
|
| 245 |
+
CALL_SUBTEST_12(selfadjointeigensolver(Matrix2f()));
|
| 246 |
+
CALL_SUBTEST_12(selfadjointeigensolver(Matrix2d()));
|
| 247 |
+
CALL_SUBTEST_12(selfadjointeigensolver(Matrix2cd()));
|
| 248 |
+
CALL_SUBTEST_13(selfadjointeigensolver(Matrix3f()));
|
| 249 |
+
CALL_SUBTEST_13(selfadjointeigensolver(Matrix3d()));
|
| 250 |
+
CALL_SUBTEST_13(selfadjointeigensolver(Matrix3cd()));
|
| 251 |
+
CALL_SUBTEST_2(selfadjointeigensolver(Matrix4d()));
|
| 252 |
+
CALL_SUBTEST_2(selfadjointeigensolver(Matrix4cd()));
|
| 253 |
+
|
| 254 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 255 |
+
CALL_SUBTEST_3(selfadjointeigensolver(MatrixXf(s, s)));
|
| 256 |
+
CALL_SUBTEST_4(selfadjointeigensolver(MatrixXd(s, s)));
|
| 257 |
+
CALL_SUBTEST_5(selfadjointeigensolver(MatrixXcd(s, s)));
|
| 258 |
+
CALL_SUBTEST_9(selfadjointeigensolver(Matrix<std::complex<double>, Dynamic, Dynamic, RowMajor>(s, s)));
|
| 259 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 260 |
+
|
| 261 |
+
// some trivial but implementation-wise tricky cases
|
| 262 |
+
CALL_SUBTEST_4(selfadjointeigensolver(MatrixXd(1, 1)));
|
| 263 |
+
CALL_SUBTEST_4(selfadjointeigensolver(MatrixXd(2, 2)));
|
| 264 |
+
CALL_SUBTEST_5(selfadjointeigensolver(MatrixXcd(1, 1)));
|
| 265 |
+
CALL_SUBTEST_5(selfadjointeigensolver(MatrixXcd(2, 2)));
|
| 266 |
+
CALL_SUBTEST_6(selfadjointeigensolver(Matrix<double, 1, 1>()));
|
| 267 |
+
CALL_SUBTEST_7(selfadjointeigensolver(Matrix<double, 2, 2>()));
|
| 268 |
+
}
|
| 269 |
+
|
| 270 |
+
CALL_SUBTEST_13(bug_854<0>());
|
| 271 |
+
CALL_SUBTEST_13(bug_1014<0>());
|
| 272 |
+
CALL_SUBTEST_13(bug_1204<0>());
|
| 273 |
+
CALL_SUBTEST_13(bug_1225<0>());
|
| 274 |
+
|
| 275 |
+
// Test problem size constructors
|
| 276 |
+
s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE / 4);
|
| 277 |
+
CALL_SUBTEST_8(SelfAdjointEigenSolver<MatrixXf> tmp1(s));
|
| 278 |
+
CALL_SUBTEST_8(Tridiagonalization<MatrixXf> tmp2(s));
|
| 279 |
+
|
| 280 |
+
TEST_SET_BUT_UNUSED_VARIABLE(s)
|
| 281 |
+
}
|
wheels/TRELLIS.2/o-voxels/third_party/eigen/test/evaluator_common.h
ADDED
|
File without changes
|