array_cwise.cpp File Reference
#include <vector>
#include "main.h"
#include "random_without_cast_overflow.h"

Classes

struct  negative_or_zero_impl< Scalar, IsSigned >
 
struct  negative_or_zero_impl< Scalar, false >
 
struct  ref_pow< Base, Exponent, ExpIsInteger >
 
struct  ref_pow< Base, Exponent, true >
 
struct  pow_helper< Exponent, ExpIsInteger >
 
struct  pow_helper< Exponent, true >
 
struct  Eigen::internal::test_signbit_op< Scalar >
 
struct  Eigen::internal::functor_traits< test_signbit_op< Scalar > >
 
struct  shift_imm_traits< Scalar >
 
struct  logical_left_shift_op< N, Scalar >
 
struct  logical_right_shift_op< N, Scalar >
 
struct  arithmetic_right_shift_op< N, Scalar >
 
struct  Eigen::internal::functor_traits< logical_left_shift_op< N, Scalar > >
 
struct  Eigen::internal::functor_traits< logical_right_shift_op< N, Scalar > >
 
struct  Eigen::internal::functor_traits< arithmetic_right_shift_op< N, Scalar > >
 
struct  shift_test_impl< ArrayType >
 
struct  typed_logicals_test_impl< ArrayType >
 
struct  cast_test_impl< SrcType, DstType, RowsAtCompileTime, ColsAtCompileTime >
 
struct  cast_test_impl< SrcType, DstType, RowsAtCompileTime, ColsAtCompileTime >::RandomOp
 
struct  cast_tests_impl< RowsAtCompileTime, ColsAtCompileTime, ScalarTypes >
 

Namespaces

 Eigen
 Namespace containing all symbols from the Eigen library.
 
 Eigen::internal
 Namespace containing low-level routines from the Eigen library.
 

Macros

#define BINARY_FUNCTOR_TEST_ARGS(fun)
 
#define UNARY_FUNCTOR_TEST_ARGS(fun)    #fun, [](const auto& x_) { return (Eigen::fun)(x_); }, [](const auto& y_) { return (std::fun)(y_); }
 

Functions

template<typename Scalar >
Scalar negative_or_zero (const Scalar &a)
 
template<typename Scalar , std::enable_if_t< NumTraits< Scalar >::IsInteger, int > = 0>
std::vector< Scalarspecial_values ()
 
template<typename Scalar >
void special_value_pairs (Array< Scalar, Dynamic, Dynamic > &x, Array< Scalar, Dynamic, Dynamic > &y)
 
template<typename Scalar , typename Fn , typename RefFn >
void binary_op_test (std::string name, Fn fun, RefFn ref)
 
template<typename Scalar >
void binary_ops_test ()
 
template<typename Scalar , typename Fn , typename RefFn >
void unary_op_test (std::string name, Fn fun, RefFn ref)
 
template<typename Scalar >
void unary_ops_test ()
 
template<typename Exponent >
bool is_integer (const Exponent &exp)
 
template<typename Exponent >
bool is_odd (const Exponent &exp)
 
template<typename Base , typename Exponent >
void float_pow_test_impl ()
 
template<typename Scalar , typename ScalarExponent >
Scalar calc_overflow_threshold (const ScalarExponent exponent)
 
template<typename Base , typename Exponent >
void test_exponent (Exponent exponent)
 
template<typename Base , typename Exponent >
void int_pow_test_impl ()
 
void float_pow_test ()
 
void mixed_pow_test ()
 
void int_pow_test ()
 
template<typename Scalar >
void signbit_test ()
 
void signbit_tests ()
 
template<typename ArrayType >
void array_generic (const ArrayType &m)
 
template<typename ArrayType >
void comparisons (const ArrayType &m)
 
template<typename ArrayType >
void array_real (const ArrayType &m)
 
template<typename ArrayType >
void array_complex (const ArrayType &m)
 
template<typename ArrayType >
void min_max (const ArrayType &m)
 
template<typename ArrayType >
void shift_test (const ArrayType &m)
 
template<typename ArrayType >
void typed_logicals_test (const ArrayType &m)
 
template<int RowsAtCompileTime, int ColsAtCompileTime>
void cast_test ()
 
 EIGEN_DECLARE_TEST (array_cwise)
 

Macro Definition Documentation

◆ BINARY_FUNCTOR_TEST_ARGS

#define BINARY_FUNCTOR_TEST_ARGS (   fun)
Value:
#fun, [](const auto& x_, const auto& y_) { return (Eigen::fun)(x_, y_); }, \
[](const auto& x_, const auto& y_) { return (std::fun)(x_, y_); }

◆ UNARY_FUNCTOR_TEST_ARGS

#define UNARY_FUNCTOR_TEST_ARGS (   fun)     #fun, [](const auto& x_) { return (Eigen::fun)(x_); }, [](const auto& y_) { return (std::fun)(y_); }

Function Documentation

◆ array_complex()

template<typename ArrayType >
void array_complex ( const ArrayType &  m)
922  {
923  typedef typename ArrayType::Scalar Scalar;
924  typedef typename NumTraits<Scalar>::Real RealScalar;
925 
926  Index rows = m.rows();
927  Index cols = m.cols();
928 
929  ArrayType m1 = ArrayType::Random(rows, cols), m2(rows, cols), m4 = m1;
930 
931  m4.real() = (m4.real().abs() == RealScalar(0)).select(RealScalar(1), m4.real());
932  m4.imag() = (m4.imag().abs() == RealScalar(0)).select(RealScalar(1), m4.imag());
933 
934  Array<RealScalar, -1, -1> m3(rows, cols);
935 
936  for (Index i = 0; i < m.rows(); ++i)
937  for (Index j = 0; j < m.cols(); ++j) m2(i, j) = sqrt(m1(i, j));
938 
939  // these tests are mostly to check possible compilation issues with free-functions.
940  VERIFY_IS_APPROX(m1.sin(), sin(m1));
941  VERIFY_IS_APPROX(m1.cos(), cos(m1));
942  VERIFY_IS_APPROX(m1.tan(), tan(m1));
943  VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
944  VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
945  VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
946  VERIFY_IS_APPROX(m1.logistic(), logistic(m1));
947  VERIFY_IS_APPROX(m1.arg(), arg(m1));
948  VERIFY_IS_APPROX(m1.carg(), carg(m1));
949  VERIFY_IS_APPROX(arg(m1), carg(m1));
950  VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
951  VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
952  VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
953  VERIFY_IS_APPROX(m4.inverse(), inverse(m4));
954  VERIFY_IS_APPROX(m1.log(), log(m1));
955  VERIFY_IS_APPROX(m1.log10(), log10(m1));
956  VERIFY_IS_APPROX(m1.log2(), log2(m1));
957  VERIFY_IS_APPROX(m1.abs(), abs(m1));
958  VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
959  VERIFY_IS_APPROX(m1.sqrt(), sqrt(m1));
960  VERIFY_IS_APPROX(m1.square(), square(m1));
961  VERIFY_IS_APPROX(m1.cube(), cube(m1));
962  VERIFY_IS_APPROX(cos(m1 + RealScalar(3) * m2), cos((m1 + RealScalar(3) * m2).eval()));
963  VERIFY_IS_APPROX(m1.sign(), sign(m1));
964 
965  VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1 + m2));
966  VERIFY_IS_APPROX(m1.exp(), exp(m1));
967  VERIFY_IS_APPROX(m1.exp() / m2.exp(), (m1 - m2).exp());
968 
969  VERIFY_IS_APPROX(m1.expm1(), expm1(m1));
970  VERIFY_IS_APPROX(expm1(m1), exp(m1) - 1.);
971  // Check for larger magnitude complex numbers that expm1 matches exp - 1.
972  VERIFY_IS_APPROX(expm1(10. * m1), exp(10. * m1) - 1.);
973 
974  VERIFY_IS_APPROX(sinh(m1), 0.5 * (exp(m1) - exp(-m1)));
975  VERIFY_IS_APPROX(cosh(m1), 0.5 * (exp(m1) + exp(-m1)));
976  VERIFY_IS_APPROX(tanh(m1), (0.5 * (exp(m1) - exp(-m1))) / (0.5 * (exp(m1) + exp(-m1))));
977  VERIFY_IS_APPROX(logistic(m1), (1.0 / (1.0 + exp(-m1))));
978  if (m1.size() > 0) {
979  // Complex exponential overflow edge-case.
980  Scalar old_m1_val = m1(0, 0);
981  m1(0, 0) = std::complex<RealScalar>(1000.0, 1000.0);
982  VERIFY_IS_APPROX(logistic(m1), (1.0 / (1.0 + exp(-m1))));
983  m1(0, 0) = old_m1_val; // Restore value for future tests.
984  }
985 
986  for (Index i = 0; i < m.rows(); ++i)
987  for (Index j = 0; j < m.cols(); ++j) m3(i, j) = std::atan2(m1(i, j).imag(), m1(i, j).real());
988  VERIFY_IS_APPROX(arg(m1), m3);
989  VERIFY_IS_APPROX(carg(m1), m3);
990 
991  std::complex<RealScalar> zero(0.0, 0.0);
992  VERIFY((Eigen::isnan)(m1 * zero / zero).all());
993 #if EIGEN_COMP_MSVC
994  // msvc complex division is not robust
995  VERIFY((Eigen::isinf)(m4 / RealScalar(0)).all());
996 #else
997 #if EIGEN_COMP_CLANG
998  // clang's complex division is notoriously broken too
999  if ((numext::isinf)(m4(0, 0) / RealScalar(0))) {
1000 #endif
1001  VERIFY((Eigen::isinf)(m4 / zero).all());
1002 #if EIGEN_COMP_CLANG
1003  } else {
1004  VERIFY((Eigen::isinf)(m4.real() / zero.real()).all());
1005  }
1006 #endif
1007 #endif // MSVC
1008 
1009  VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1 * zero / zero)) && (!(Eigen::isfinite)(m1 / zero))).all());
1010 
1011  VERIFY_IS_APPROX(inverse(inverse(m4)), m4);
1012  VERIFY_IS_APPROX(conj(m1.conjugate()), m1);
1013  VERIFY_IS_APPROX(abs(m1), sqrt(square(m1.real()) + square(m1.imag())));
1015  VERIFY_IS_APPROX(log10(m1), log(m1) / log(10));
1016  VERIFY_IS_APPROX(log2(m1), log(m1) / log(2));
1017 
1018  VERIFY_IS_APPROX(m1.sign(), -(-m1).sign());
1019  VERIFY_IS_APPROX(m1.sign() * m1.abs(), m1);
1020 
1021  // scalar by array division
1022  Scalar s1 = internal::random<Scalar>();
1024  s1 += Scalar(tiny);
1025  m1 += ArrayType::Constant(rows, cols, Scalar(tiny));
1026  VERIFY_IS_APPROX(s1 / m1, s1 * m1.inverse());
1027 
1028  // check inplace transpose
1029  m2 = m1;
1030  m2.transposeInPlace();
1031  VERIFY_IS_APPROX(m2, m1.transpose());
1032  m2.transposeInPlace();
1034  // Check vectorized inplace transpose.
1035  ArrayType m5 = ArrayType::Random(131, 131);
1036  ArrayType m6 = m5;
1037  m6.transposeInPlace();
1038  VERIFY_IS_APPROX(m6, m5.transpose());
1039 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
AnnoyingScalar atan2(const AnnoyingScalar &y, const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:139
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
AnnoyingScalar conj(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:133
AnnoyingScalar imag(const AnnoyingScalar &)
Definition: AnnoyingScalar.h:132
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Matrix3d m1
Definition: IOFormat.cpp:2
MatrixType m2(n_dims)
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
General-purpose arrays with easy API for coefficient-wise operations.
Definition: Array.h:48
float real
Definition: datatypes.h:10
static constexpr Eigen::internal::all_t all
Definition: IndexedViewHelper.h:86
#define VERIFY_IS_APPROX(a, b)
Definition: integer_types.cpp:13
void inverse(const MatrixType &m)
Definition: inverse.cpp:64
int * m
Definition: level2_cplx_impl.h:294
#define isfinite(X)
Definition: main.h:111
#define VERIFY(a)
Definition: main.h:362
#define isnan(X)
Definition: main.h:109
#define isinf(X)
Definition: main.h:110
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 tanh(const bfloat16 &a)
Definition: BFloat16.h:639
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 cosh(const bfloat16 &a)
Definition: BFloat16.h:638
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 log10(const bfloat16 &a)
Definition: BFloat16.h:620
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp(const bfloat16 &a)
Definition: BFloat16.h:615
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 expm1(const bfloat16 &a)
Definition: BFloat16.h:617
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 log(const bfloat16 &a)
Definition: BFloat16.h:618
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 sinh(const bfloat16 &a)
Definition: BFloat16.h:637
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 tan(const bfloat16 &a)
Definition: BFloat16.h:633
EIGEN_DEVICE_FUNC bool abs2(bool x)
Definition: MathFunctions.h:1102
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
squared absolute sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2 square(power 2)
T cube(T x)
Definition: cxx11_tensor_builtins_sycl.cpp:56
T sign(T x)
Definition: cxx11_tensor_builtins_sycl.cpp:172
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
Scalar log2(Scalar x)
Definition: packetmath.cpp:754
internal::nested_eval< T, 1 >::type eval(const T &xpr)
Definition: sparse_permutations.cpp:47
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
EIGEN_DONT_INLINE Scalar zero()
Definition: svd_common.h:232
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References abs(), Eigen::numext::abs2(), Eigen::placeholders::all, atan2(), cols, conj(), cos(), Eigen::bfloat16_impl::cosh(), SYCL::cube(), oomph::SarahBL::epsilon, eval(), Eigen::bfloat16_impl::exp(), Eigen::bfloat16_impl::expm1(), i, imag(), inverse(), isfinite, isinf, isnan, j, Eigen::bfloat16_impl::log(), Eigen::bfloat16_impl::log10(), log2(), m, m1, m2(), rows, SYCL::sign(), sin(), Eigen::bfloat16_impl::sinh(), sqrt(), Eigen::square(), Eigen::bfloat16_impl::tan(), Eigen::bfloat16_impl::tanh(), VERIFY, VERIFY_IS_APPROX, and zero().

Referenced by EIGEN_DECLARE_TEST().

◆ array_generic()

template<typename ArrayType >
void array_generic ( const ArrayType &  m)
476  {
477  typedef typename ArrayType::Scalar Scalar;
478  typedef typename ArrayType::RealScalar RealScalar;
481 
482  Index rows = m.rows();
483  Index cols = m.cols();
484 
485  ArrayType m1 = ArrayType::Random(rows, cols);
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 =
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));
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 }
EIGEN_DEVICE_FUNC const GlobalUnaryPowReturnType< Derived, ScalarExponent > pow(const Eigen::ArrayBase< Derived > &x, const ScalarExponent &exponent)
Definition: GlobalFunctions.h:137
#define VERIFY_IS_NOT_APPROX(a, b)
Definition: integer_types.cpp:15
return int(ret)+1
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b)
Definition: main.h:371
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
EIGEN_DEVICE_FUNC bool isMuchSmallerThan(const Scalar &x, const OtherScalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Definition: MathFunctions.h:1916
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T cbrt(const T &x)
Definition: MathFunctions.h:1320
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T mini(const T &x, const T &y)
Definition: MathFunctions.h:920
EIGEN_DEVICE_FUNC const const Eigen::ArrayBase< Derived > & exponents
Definition: GlobalFunctions.h:189
const int Dynamic
Definition: Constants.h:25
double f2(const Vector< double > &coord)
f2 function, in front of the C2 unknown
Definition: poisson/poisson_with_singularity/two_d_poisson.cc:233
double f1(const Vector< double > &coord)
f1 function, in front of the C1 unknown
Definition: poisson/poisson_with_singularity/two_d_poisson.cc:147

References abs(), Eigen::numext::cbrt(), cols, Eigen::Dynamic, Eigen::exponents, Global_parameters::f1(), Global_parameters::f2(), int(), Eigen::internal::isMuchSmallerThan(), m, m1, m2(), Eigen::numext::mini(), Eigen::bfloat16_impl::pow(), Eigen::ArrayBase< Derived >::pow(), rows, VERIFY, VERIFY_IS_APPROX, VERIFY_IS_MUCH_SMALLER_THAN, and VERIFY_IS_NOT_APPROX.

Referenced by EIGEN_DECLARE_TEST().

◆ array_real()

template<typename ArrayType >
void array_real ( const ArrayType &  m)
768  {
769  using numext::abs;
770  using std::sqrt;
771  typedef typename ArrayType::Scalar Scalar;
772  typedef typename NumTraits<Scalar>::Real RealScalar;
773 
774  Index rows = m.rows();
775  Index cols = m.cols();
776 
777  ArrayType m1 = ArrayType::Random(rows, cols), m2 = ArrayType::Random(rows, cols), m3(rows, cols), m4 = m1;
778 
779  // avoid denormalized values so verification doesn't fail on platforms that don't support them
780  // denormalized behavior is tested elsewhere (unary_op_test, binary_ops_test)
782  m1 = (m1.abs() < min).select(Scalar(0), m1);
783  m2 = (m2.abs() < min).select(Scalar(0), m2);
784  m4 = (m4.abs() < min).select(Scalar(1), m4);
785 
786  Scalar s1 = internal::random<Scalar>();
787 
788  // these tests are mostly to check possible compilation issues with free-functions.
789  VERIFY_IS_APPROX(m1.sin(), sin(m1));
790  VERIFY_IS_APPROX(m1.cos(), cos(m1));
791  VERIFY_IS_APPROX(m1.tan(), tan(m1));
792  VERIFY_IS_APPROX(m1.asin(), asin(m1));
793  VERIFY_IS_APPROX(m1.acos(), acos(m1));
794  VERIFY_IS_APPROX(m1.atan(), atan(m1));
795  VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
796  VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
797  VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
798  VERIFY_IS_APPROX(m1.atan2(m2), atan2(m1, m2));
799 
800  VERIFY_IS_APPROX(m1.tanh().atanh(), atanh(tanh(m1)));
801  VERIFY_IS_APPROX(m1.sinh().asinh(), asinh(sinh(m1)));
802  VERIFY_IS_APPROX(m1.cosh().acosh(), acosh(cosh(m1)));
803  VERIFY_IS_APPROX(m1.tanh().atanh(), atanh(tanh(m1)));
804  VERIFY_IS_APPROX(m1.logistic(), logistic(m1));
805 
806  VERIFY_IS_APPROX(m1.arg(), arg(m1));
807  VERIFY_IS_APPROX(m1.round(), round(m1));
808  VERIFY_IS_APPROX(m1.rint(), rint(m1));
809  VERIFY_IS_APPROX(m1.floor(), floor(m1));
810  VERIFY_IS_APPROX(m1.ceil(), ceil(m1));
811  VERIFY_IS_APPROX(m1.trunc(), trunc(m1));
812  VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
813  VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
814  VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
815  VERIFY_IS_APPROX(m4.inverse(), inverse(m4));
816  VERIFY_IS_APPROX(m1.abs(), abs(m1));
817  VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
818  VERIFY_IS_APPROX(m1.square(), square(m1));
819  VERIFY_IS_APPROX(m1.cube(), cube(m1));
820  VERIFY_IS_APPROX(cos(m1 + RealScalar(3) * m2), cos((m1 + RealScalar(3) * m2).eval()));
821  VERIFY_IS_APPROX(m1.sign(), sign(m1));
822  VERIFY((m1.sqrt().sign().isNaN() == (Eigen::isnan)(sign(sqrt(m1)))).all());
823 
824  // avoid inf and NaNs so verification doesn't fail
825  m3 = m4.abs();
826 
827  VERIFY_IS_APPROX(m3.sqrt(), sqrt(abs(m3)));
828  VERIFY_IS_APPROX(m3.cbrt(), cbrt(m3));
829  VERIFY_IS_APPROX(m3.rsqrt(), Scalar(1) / sqrt(abs(m3)));
830  VERIFY_IS_APPROX(rsqrt(m3), Scalar(1) / sqrt(abs(m3)));
831  VERIFY_IS_APPROX(m3.log(), log(m3));
832  VERIFY_IS_APPROX(m3.log1p(), log1p(m3));
833  VERIFY_IS_APPROX(m3.log10(), log10(m3));
834  VERIFY_IS_APPROX(m3.log2(), log2(m3));
835 
836  VERIFY((!(m1 > m2) == (m1 <= m2)).all());
837 
838  VERIFY_IS_APPROX(sin(m1.asin()), m1);
839  VERIFY_IS_APPROX(cos(m1.acos()), m1);
840  VERIFY_IS_APPROX(tan(m1.atan()), m1);
841  VERIFY_IS_APPROX(sinh(m1), Scalar(0.5) * (exp(m1) - exp(-m1)));
842  VERIFY_IS_APPROX(cosh(m1), Scalar(0.5) * (exp(m1) + exp(-m1)));
843  VERIFY_IS_APPROX(tanh(m1), (Scalar(0.5) * (exp(m1) - exp(-m1))) / (Scalar(0.5) * (exp(m1) + exp(-m1))));
844  VERIFY_IS_APPROX(logistic(m1), (Scalar(1) / (Scalar(1) + exp(-m1))));
845  VERIFY_IS_APPROX(arg(m1), ((m1 < Scalar(0)).template cast<Scalar>()) * Scalar(std::acos(Scalar(-1))));
846  VERIFY((round(m1) <= ceil(m1) && round(m1) >= floor(m1)).all());
847  VERIFY((rint(m1) <= ceil(m1) && rint(m1) >= floor(m1)).all());
848  VERIFY(((ceil(m1) - round(m1)) <= Scalar(0.5) || (round(m1) - floor(m1)) <= Scalar(0.5)).all());
849  VERIFY(((ceil(m1) - round(m1)) <= Scalar(1.0) && (round(m1) - floor(m1)) <= Scalar(1.0)).all());
850  VERIFY(((ceil(m1) - rint(m1)) <= Scalar(0.5) || (rint(m1) - floor(m1)) <= Scalar(0.5)).all());
851  VERIFY(((ceil(m1) - rint(m1)) <= Scalar(1.0) && (rint(m1) - floor(m1)) <= Scalar(1.0)).all());
852  VERIFY((Eigen::isnan)((m1 * Scalar(0)) / Scalar(0)).all());
853  VERIFY((Eigen::isinf)(m4 / Scalar(0)).all());
854  VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1 * Scalar(0) / Scalar(0))) &&
855  (!(Eigen::isfinite)(m4 / Scalar(0))))
856  .all());
857  VERIFY_IS_APPROX(inverse(inverse(m4)), m4);
858  VERIFY((abs(m1) == m1 || abs(m1) == -m1).all());
859  VERIFY_IS_APPROX(m3, sqrt(abs2(m3)));
860  VERIFY_IS_APPROX(m1.absolute_difference(m2), (m1 > m2).select(m1 - m2, m2 - m1));
861  VERIFY_IS_APPROX(m1.sign(), -(-m1).sign());
862  VERIFY_IS_APPROX(m1 * m1.sign(), m1.abs());
863  VERIFY_IS_APPROX(m1.sign() * m1.abs(), m1);
864 
865  ArrayType tmp = m1.atan2(m2);
866  for (Index i = 0; i < tmp.size(); ++i) {
867  Scalar actual = tmp.array()(i);
868  Scalar expected = Scalar(std::atan2(m1.array()(i), m2.array()(i)));
869  VERIFY_IS_APPROX(actual, expected);
870  }
871 
875 
876  // shift argument of logarithm so that it is not zero
878  VERIFY_IS_APPROX((m3 + smallNumber).log(), log(abs(m3) + smallNumber));
879  VERIFY_IS_APPROX((m3 + smallNumber + Scalar(1)).log(), log1p(abs(m3) + smallNumber));
880 
881  VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1 + m2));
882  VERIFY_IS_APPROX(m1.exp(), exp(m1));
883  VERIFY_IS_APPROX(m1.exp() / m2.exp(), (m1 - m2).exp());
884 
885  VERIFY_IS_APPROX(m1.expm1(), expm1(m1));
886  VERIFY_IS_APPROX((m3 + smallNumber).exp() - Scalar(1), expm1(abs(m3) + smallNumber));
887 
888  VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());
889  VERIFY_IS_APPROX(pow(m3, RealScalar(0.5)), m3.sqrt());
890  VERIFY_IS_APPROX(m3.pow(RealScalar(1.0 / 3.0)), m3.cbrt());
891  VERIFY_IS_APPROX(pow(m3, RealScalar(1.0 / 3.0)), m3.cbrt());
892 
893  VERIFY_IS_APPROX(m3.pow(RealScalar(-0.5)), m3.rsqrt());
894  VERIFY_IS_APPROX(pow(m3, RealScalar(-0.5)), m3.rsqrt());
895 
896  // Avoid inf and NaN.
897  m3 = (m1.square() < NumTraits<Scalar>::epsilon()).select(Scalar(1), m3);
898  VERIFY_IS_APPROX(m3.pow(RealScalar(-2)), m3.square().inverse());
899 
900  // Test pow and atan2 on special IEEE values.
901  unary_ops_test<Scalar>();
902  binary_ops_test<Scalar>();
903 
904  VERIFY_IS_APPROX(log10(m3), log(m3) / numext::log(Scalar(10)));
905  VERIFY_IS_APPROX(log2(m3), log(m3) / numext::log(Scalar(2)));
906 
907  // scalar by array division
909  s1 += Scalar(tiny);
910  m1 += ArrayType::Constant(rows, cols, Scalar(tiny));
911  VERIFY_IS_CWISE_APPROX(s1 / m1, s1 * m1.inverse());
912 
913  // check inplace transpose
914  m3 = m1;
915  m3.transposeInPlace();
916  VERIFY_IS_APPROX(m3, m1.transpose());
917  m3.transposeInPlace();
918  VERIFY_IS_APPROX(m3, m1);
919 }
AnnoyingScalar acos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:138
#define min(a, b)
Definition: datatypes.h:22
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
#define VERIFY_IS_CWISE_APPROX(a, b)
Definition: main.h:376
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 floor(const bfloat16 &a)
Definition: BFloat16.h:643
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 atanh(const bfloat16 &a)
Definition: BFloat16.h:642
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 ceil(const bfloat16 &a)
Definition: BFloat16.h:644
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 trunc(const bfloat16 &a)
Definition: BFloat16.h:647
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 rint(const bfloat16 &a)
Definition: BFloat16.h:645
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 asin(const bfloat16 &a)
Definition: BFloat16.h:634
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 atan(const bfloat16 &a)
Definition: BFloat16.h:636
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 round(const bfloat16 &a)
Definition: BFloat16.h:646
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 acosh(const bfloat16 &a)
Definition: BFloat16.h:641
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 log1p(const bfloat16 &a)
Definition: BFloat16.h:619
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 asinh(const bfloat16 &a)
Definition: BFloat16.h:640
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T rsqrt(const T &x)
Definition: MathFunctions.h:1327
const AutoDiffScalar< DerType > & real(const AutoDiffScalar< DerType > &x)
Definition: AutoDiffScalar.h:486
DerType::Scalar imag(const AutoDiffScalar< DerType > &)
Definition: AutoDiffScalar.h:490

References abs(), Eigen::numext::abs2(), acos(), Eigen::bfloat16_impl::acosh(), Eigen::placeholders::all, Eigen::bfloat16_impl::asin(), Eigen::bfloat16_impl::asinh(), Eigen::bfloat16_impl::atan(), atan2(), Eigen::bfloat16_impl::atanh(), Eigen::numext::cbrt(), Eigen::bfloat16_impl::ceil(), cols, cos(), Eigen::bfloat16_impl::cosh(), SYCL::cube(), oomph::SarahBL::epsilon, eval(), Eigen::bfloat16_impl::exp(), Eigen::bfloat16_impl::expm1(), Eigen::bfloat16_impl::floor(), i, imag(), Eigen::imag(), inverse(), isfinite, isinf, isnan, Eigen::bfloat16_impl::log(), Eigen::bfloat16_impl::log10(), Eigen::bfloat16_impl::log1p(), log2(), m, m1, m2(), min, Eigen::ArrayBase< Derived >::pow(), Eigen::real(), Eigen::bfloat16_impl::rint(), Eigen::bfloat16_impl::round(), rows, Eigen::numext::rsqrt(), SYCL::sign(), sin(), Eigen::bfloat16_impl::sinh(), sqrt(), Eigen::square(), Eigen::bfloat16_impl::tan(), Eigen::bfloat16_impl::tanh(), tmp, Eigen::bfloat16_impl::trunc(), VERIFY, VERIFY_IS_APPROX, and VERIFY_IS_CWISE_APPROX.

Referenced by EIGEN_DECLARE_TEST().

◆ binary_op_test()

template<typename Scalar , typename Fn , typename RefFn >
void binary_op_test ( std::string  name,
Fn  fun,
RefFn  ref 
)
89  {
90  const Scalar tol = test_precision<Scalar>();
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.
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 }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
void special_value_pairs(Array< Scalar, Dynamic, Dynamic > &x, Array< Scalar, Dynamic, Dynamic > &y)
Definition: array_cwise.cpp:69
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:192
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:191
const Scalar * a
Definition: level2_cplx_impl.h:32
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Definition: MathFunctions.h:1923
EIGEN_DEVICE_FUNC static constexpr EIGEN_ALWAYS_INLINE Scalar signbit(const Scalar &x)
Definition: MathFunctions.h:1419
string name
Definition: plotDoE.py:33

References a, Eigen::PlainObjectBase< Derived >::cols(), e(), i, Eigen::internal::isApprox(), isfinite, isnan, j, min, plotDoE::name, Eigen::PlainObjectBase< Derived >::rows(), Eigen::numext::signbit(), special_value_pairs(), and VERIFY.

◆ binary_ops_test()

template<typename Scalar >
void binary_ops_test ( )
126  {
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 }
#define EIGEN_PREDICT_FALSE(x)
Definition: Macros.h:1179
#define BINARY_FUNCTOR_TEST_ARGS(fun)
Definition: array_cwise.cpp:121
Scalar * y
Definition: level1_cplx_impl.h:128
AutoDiffScalar< Matrix< typename internal::traits< internal::remove_all_t< DerTypeA > >::Scalar, Dynamic, 1 > > atan2(const AutoDiffScalar< DerTypeA > &a, const AutoDiffScalar< DerTypeB > &b)
Definition: AutoDiffScalar.h:558
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36

References abs(), atan2(), Eigen::atan2(), BINARY_FUNCTOR_TEST_ARGS, EIGEN_PREDICT_FALSE, Eigen::ArrayBase< Derived >::pow(), plotPSD::t, plotDoE::x, and y.

◆ calc_overflow_threshold()

template<typename Scalar , typename ScalarExponent >
Scalar calc_overflow_threshold ( const ScalarExponent  exponent)
320  {
324 
325  if (exponent < 2)
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 }
#define EIGEN_USING_STD(FUNC)
Definition: Macros.h:1090
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp2(const bfloat16 &a)
Definition: BFloat16.h:616

References EIGEN_STATIC_ASSERT, EIGEN_USING_STD, Eigen::bfloat16_impl::exp2(), Eigen::bfloat16_impl::floor(), log2(), and Eigen::numext::mini().

◆ cast_test()

template<int RowsAtCompileTime, int ColsAtCompileTime>
void cast_test ( )
1331  {
1332  cast_tests_impl<RowsAtCompileTime, ColsAtCompileTime, bool, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t,
1333  uint32_t, uint64_t, float, double, /*long double, */ half, bfloat16>::run();
1334 }
std::int32_t int32_t
Definition: Meta.h:41
std::int8_t int8_t
Definition: Meta.h:37
std::uint8_t uint8_t
Definition: Meta.h:36
std::int16_t int16_t
Definition: Meta.h:39
std::int64_t int64_t
Definition: Meta.h:43
std::uint16_t uint16_t
Definition: Meta.h:38
std::uint32_t uint32_t
Definition: Meta.h:40
std::uint64_t uint64_t
Definition: Meta.h:42
Definition: BFloat16.h:101
Definition: Half.h:139
Definition: array_cwise.cpp:1310
void run(const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
Definition: two_d_poisson_compare_solvers.cc:317

References run().

◆ comparisons()

template<typename ArrayType >
void comparisons ( const ArrayType &  m)
654  {
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 }
#define VERIFY_IS_CWISE_EQUAL(a, b)
Definition: main.h:375
r
Definition: UniformPSDSelfTest.py:20
void transpose()
Definition: skew_symmetric_matrix3.cpp:135
int c
Definition: calibrate.py:100
double Zero
Definition: pseudosolid_node_update_elements.cc:35

References a, abs(), Eigen::placeholders::all, calibrate::c, cols, i, j, m, m1, m2(), UniformPSDSelfTest::r, rows, anonymous_namespace{skew_symmetric_matrix3.cpp}::transpose(), VERIFY, VERIFY_IS_APPROX, VERIFY_IS_CWISE_EQUAL, and oomph::PseudoSolidHelper::Zero.

Referenced by EIGEN_DECLARE_TEST().

◆ EIGEN_DECLARE_TEST()

EIGEN_DECLARE_TEST ( array_cwise  )
1336  {
1337  for (int i = 0; i < g_repeat; i++) {
1339  CALL_SUBTEST_2(array_generic(Array22f()));
1340  CALL_SUBTEST_3(array_generic(Array44d()));
1342  ArrayXXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1344  ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1346  ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1348  internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1350  ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1352  internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1354  internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1356  internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1357  }
1358  for (int i = 0; i < g_repeat; i++) {
1360  CALL_SUBTEST_2(comparisons(Array22f()));
1361  CALL_SUBTEST_3(comparisons(Array44d()));
1363  ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1365  ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1366  }
1367  for (int i = 0; i < g_repeat; i++) {
1369  CALL_SUBTEST_7(min_max(Array22f()));
1370  CALL_SUBTEST_8(min_max(Array44d()));
1372  ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1374  ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1375  }
1376  for (int i = 0; i < g_repeat; i++) {
1378  CALL_SUBTEST_12(array_real(Array22f()));
1379  CALL_SUBTEST_13(array_real(Array44d()));
1381  ArrayXXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1384  }
1385  for (int i = 0; i < g_repeat; i++) {
1387  ArrayXXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1389  ArrayXXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1390  }
1391 
1392  for (int i = 0; i < g_repeat; i++) {
1397  }
1398  for (int i = 0; i < g_repeat; i++) {
1399  CALL_SUBTEST_23(typed_logicals_test(ArrayX<int>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1400  CALL_SUBTEST_24(typed_logicals_test(ArrayX<float>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1401  CALL_SUBTEST_25(typed_logicals_test(ArrayX<double>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1402  CALL_SUBTEST_26(typed_logicals_test(ArrayX<std::complex<float>>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1403  CALL_SUBTEST_27(typed_logicals_test(ArrayX<std::complex<double>>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
1404  }
1405 
1406  for (int i = 0; i < g_repeat; i++) {
1407  CALL_SUBTEST_28((cast_test<1, 1>()));
1408  CALL_SUBTEST_29((cast_test<3, 1>()));
1409  CALL_SUBTEST_30((cast_test<5, 1>()));
1410  CALL_SUBTEST_31((cast_test<9, 1>()));
1411  CALL_SUBTEST_32((cast_test<17, 1>()));
1412  CALL_SUBTEST_33((cast_test<Dynamic, 1>()));
1413  }
1414 
1418  typedef CwiseUnaryOp<internal::scalar_abs_op<double>, ArrayXd> Xpr;
1420 }
void float_pow_test()
Definition: array_cwise.cpp:381
void typed_logicals_test(const ArrayType &m)
Definition: array_cwise.cpp:1262
void array_real(const ArrayType &m)
Definition: array_cwise.cpp:768
void mixed_pow_test()
Definition: array_cwise.cpp:386
void comparisons(const ArrayType &m)
Definition: array_cwise.cpp:654
void shift_test(const ArrayType &m)
Definition: array_cwise.cpp:1154
void signbit_tests()
Definition: array_cwise.cpp:464
void array_complex(const ArrayType &m)
Definition: array_cwise.cpp:922
void min_max(const ArrayType &m)
Definition: array_cwise.cpp:1042
void array_generic(const ArrayType &m)
Definition: array_cwise.cpp:476
void int_pow_test()
Definition: array_cwise.cpp:408
#define EIGEN_TEST_MAX_SIZE
Definition: boostmultiprec.cpp:16
Base class for all 1D and 2D array, and related expressions.
Definition: ArrayBase.h:44
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition: CwiseUnaryOp.h:53
squared absolute value
Definition: GlobalFunctions.h:87
static int g_repeat
Definition: main.h:191
#define CALL_SUBTEST_21(FUNC)
Definition: split_test_helper.h:124
#define CALL_SUBTEST_32(FUNC)
Definition: split_test_helper.h:190
#define CALL_SUBTEST_33(FUNC)
Definition: split_test_helper.h:196
#define CALL_SUBTEST_6(FUNC)
Definition: split_test_helper.h:34
#define CALL_SUBTEST_3(FUNC)
Definition: split_test_helper.h:16
#define CALL_SUBTEST_26(FUNC)
Definition: split_test_helper.h:154
#define CALL_SUBTEST_31(FUNC)
Definition: split_test_helper.h:184
#define CALL_SUBTEST_16(FUNC)
Definition: split_test_helper.h:94
#define CALL_SUBTEST_18(FUNC)
Definition: split_test_helper.h:106
#define CALL_SUBTEST_1(FUNC)
Definition: split_test_helper.h:4
#define CALL_SUBTEST_20(FUNC)
Definition: split_test_helper.h:118
#define CALL_SUBTEST_13(FUNC)
Definition: split_test_helper.h:76
#define CALL_SUBTEST_14(FUNC)
Definition: split_test_helper.h:82
#define CALL_SUBTEST_8(FUNC)
Definition: split_test_helper.h:46
#define CALL_SUBTEST_24(FUNC)
Definition: split_test_helper.h:142
#define CALL_SUBTEST_11(FUNC)
Definition: split_test_helper.h:64
#define CALL_SUBTEST_12(FUNC)
Definition: split_test_helper.h:70
#define CALL_SUBTEST_2(FUNC)
Definition: split_test_helper.h:10
#define CALL_SUBTEST_27(FUNC)
Definition: split_test_helper.h:160
#define CALL_SUBTEST_7(FUNC)
Definition: split_test_helper.h:40
#define CALL_SUBTEST_23(FUNC)
Definition: split_test_helper.h:136
#define CALL_SUBTEST_15(FUNC)
Definition: split_test_helper.h:88
#define CALL_SUBTEST_4(FUNC)
Definition: split_test_helper.h:22
#define CALL_SUBTEST_30(FUNC)
Definition: split_test_helper.h:178
#define CALL_SUBTEST_29(FUNC)
Definition: split_test_helper.h:172
#define CALL_SUBTEST_17(FUNC)
Definition: split_test_helper.h:100
#define CALL_SUBTEST_25(FUNC)
Definition: split_test_helper.h:148
#define CALL_SUBTEST_28(FUNC)
Definition: split_test_helper.h:166
#define CALL_SUBTEST_9(FUNC)
Definition: split_test_helper.h:52
#define CALL_SUBTEST_10(FUNC)
Definition: split_test_helper.h:58
#define CALL_SUBTEST_19(FUNC)
Definition: split_test_helper.h:112
#define CALL_SUBTEST_22(FUNC)
Definition: split_test_helper.h:130

References array_complex(), array_generic(), array_real(), CALL_SUBTEST_1, CALL_SUBTEST_10, CALL_SUBTEST_11, CALL_SUBTEST_12, CALL_SUBTEST_13, CALL_SUBTEST_14, CALL_SUBTEST_15, CALL_SUBTEST_16, CALL_SUBTEST_17, CALL_SUBTEST_18, CALL_SUBTEST_19, CALL_SUBTEST_2, CALL_SUBTEST_20, CALL_SUBTEST_21, CALL_SUBTEST_22, CALL_SUBTEST_23, CALL_SUBTEST_24, CALL_SUBTEST_25, CALL_SUBTEST_26, CALL_SUBTEST_27, CALL_SUBTEST_28, CALL_SUBTEST_29, CALL_SUBTEST_3, CALL_SUBTEST_30, CALL_SUBTEST_31, CALL_SUBTEST_32, CALL_SUBTEST_33, CALL_SUBTEST_4, CALL_SUBTEST_6, CALL_SUBTEST_7, CALL_SUBTEST_8, CALL_SUBTEST_9, comparisons(), EIGEN_TEST_MAX_SIZE, float_pow_test(), Eigen::g_repeat, i, int_pow_test(), min_max(), mixed_pow_test(), shift_test(), signbit_tests(), typed_logicals_test(), Eigen::value, and VERIFY.

◆ float_pow_test()

void float_pow_test ( )
381  {
382  float_pow_test_impl<float, float>();
383  float_pow_test_impl<double, double>();
384 }

Referenced by EIGEN_DECLARE_TEST().

◆ float_pow_test_impl()

template<typename Base , typename Exponent >
void float_pow_test_impl ( )
257  {
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 }
bool is_integer(const Exponent &exp)
Definition: array_cwise.cpp:248
Scalar negative_or_zero(const Scalar &a)
Definition: array_cwise.cpp:24
bool is_odd(const Exponent &exp)
Definition: array_cwise.cpp:252
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
string type_name()
Definition: benchmark-blocking-sizes.cpp:226
static Base run(Base base, Exponent exponent)
Definition: array_cwise.cpp:219

References a, e(), i, is_integer(), is_odd(), Eigen::internal::isApprox(), isnan, j, negative_or_zero(), ref_pow< Base, Exponent, ExpIsInteger >::run(), Eigen::numext::signbit(), size, type_name(), and VERIFY.

◆ int_pow_test()

void int_pow_test ( )
408  {
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 }

Referenced by EIGEN_DECLARE_TEST().

◆ int_pow_test_impl()

template<typename Base , typename Exponent >
void int_pow_test_impl ( )
372  {
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 }

References negative_or_zero().

◆ is_integer()

template<typename Exponent >
bool is_integer ( const Exponent &  exp)
248  {
250 }
static bool is_integer_impl(const Exponent &exp)
Definition: array_cwise.cpp:235

References Eigen::bfloat16_impl::exp(), and pow_helper< Exponent, ExpIsInteger >::is_integer_impl().

Referenced by float_pow_test_impl().

◆ is_odd()

template<typename Exponent >
bool is_odd ( const Exponent &  exp)
252  {
254 }
static bool is_odd_impl(const Exponent &exp)
Definition: array_cwise.cpp:236

References Eigen::bfloat16_impl::exp(), and pow_helper< Exponent, ExpIsInteger >::is_odd_impl().

Referenced by float_pow_test_impl(), and Eigen::internal::unary_pow::int_pow().

◆ min_max()

template<typename ArrayType >
void min_max ( const ArrayType &  m)
1042  {
1043  typedef typename ArrayType::Scalar Scalar;
1044 
1045  Index rows = m.rows();
1046  Index cols = m.cols();
1047 
1048  ArrayType m1 = ArrayType::Random(rows, cols);
1049 
1050  // min/max with array
1051  Scalar maxM1 = m1.maxCoeff();
1052  Scalar minM1 = m1.minCoeff();
1053 
1054  VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, minM1), (m1.min)(ArrayType::Constant(rows, cols, minM1)));
1055  VERIFY_IS_APPROX(m1, (m1.min)(ArrayType::Constant(rows, cols, maxM1)));
1056 
1057  VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, maxM1), (m1.max)(ArrayType::Constant(rows, cols, maxM1)));
1058  VERIFY_IS_APPROX(m1, (m1.max)(ArrayType::Constant(rows, cols, minM1)));
1059 
1060  // min/max with scalar input
1061  VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, minM1), (m1.min)(minM1));
1062  VERIFY_IS_APPROX(m1, (m1.min)(maxM1));
1063 
1064  VERIFY_IS_APPROX(ArrayType::Constant(rows, cols, maxM1), (m1.max)(maxM1));
1065  VERIFY_IS_APPROX(m1, (m1.max)(minM1));
1066 
1067  // min/max with various NaN propagation options.
1068  if (m1.size() > 1 && !NumTraits<Scalar>::IsInteger) {
1069  m1(0, 0) = NumTraits<Scalar>::quiet_NaN();
1070  maxM1 = m1.template maxCoeff<PropagateNaN>();
1071  minM1 = m1.template minCoeff<PropagateNaN>();
1072  VERIFY((numext::isnan)(maxM1));
1073  VERIFY((numext::isnan)(minM1));
1074 
1075  maxM1 = m1.template maxCoeff<PropagateNumbers>();
1076  minM1 = m1.template minCoeff<PropagateNumbers>();
1077  VERIFY(!(numext::isnan)(maxM1));
1078  VERIFY(!(numext::isnan)(minM1));
1079  }
1080 }

References cols, isnan, m, m1, rows, VERIFY, and VERIFY_IS_APPROX.

Referenced by EIGEN_DECLARE_TEST().

◆ mixed_pow_test()

void mixed_pow_test ( )
386  {
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 }

Referenced by EIGEN_DECLARE_TEST().

◆ negative_or_zero()

template<typename Scalar >
Scalar negative_or_zero ( const Scalar a)
24  {
26 }
static Scalar run(const Scalar &a)
Definition: array_cwise.cpp:17

References a, and negative_or_zero_impl< Scalar, IsSigned >::run().

Referenced by float_pow_test_impl(), int_pow_test_impl(), signbit_test(), and test_exponent().

◆ shift_test()

template<typename ArrayType >
void shift_test ( const ArrayType &  m)
1154  {
1156 }
static std::enable_if_t<(N > MaxShift), void > run(const ArrayType &)
Definition: array_cwise.cpp:1130

References m, and shift_test_impl< ArrayType >::run().

Referenced by EIGEN_DECLARE_TEST().

◆ signbit_test()

template<typename Scalar >
void signbit_test ( )
443  {
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 }
EIGEN_STRONG_INLINE bool predux_any(const Packet4f &x)
Definition: AltiVec/PacketMath.h:2751

References i, negative_or_zero(), Eigen::internal::predux_any(), Eigen::numext::signbit(), size, VERIFY, plotDoE::x, and y.

◆ signbit_tests()

void signbit_tests ( )
464  {
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 }

Referenced by EIGEN_DECLARE_TEST().

◆ special_value_pairs()

template<typename Scalar >
void special_value_pairs ( Array< Scalar, Dynamic, Dynamic > &  x,
Array< Scalar, Dynamic, Dynamic > &  y 
)
69  {
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 }
constexpr array< t, n > repeat(t v)
Definition: MoreMeta.h:583

References Eigen::internal::repeat(), size, plotDoE::x, and y.

Referenced by binary_op_test().

◆ special_values()

template<typename Scalar , std::enable_if_t< NumTraits< Scalar >::IsInteger, int > = 0>
std::vector< Scalar > special_values ( )
29  {
30  const Scalar zero = Scalar(0);
31  const Scalar one = Scalar(1);
32  const Scalar two = Scalar(2);
33  const Scalar three = Scalar(3);
36  return {zero, min, one, two, three, max};
37 }
#define max(a, b)
Definition: datatypes.h:23

References max, min, and zero().

◆ test_exponent()

template<typename Base , typename Exponent >
void test_exponent ( Exponent  exponent)
337  {
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 }

References a, abs(), e(), EIGEN_STATIC_ASSERT, Eigen::numext::mini(), negative_or_zero(), ref_pow< Base, Exponent, ExpIsInteger >::run(), size, VERIFY, plotDoE::x, and y.

◆ typed_logicals_test()

template<typename ArrayType >
void typed_logicals_test ( const ArrayType &  m)
1262  {
1264 }
static void run(const ArrayType &m)
Definition: array_cwise.cpp:1176

References m, and typed_logicals_test_impl< ArrayType >::run().

Referenced by EIGEN_DECLARE_TEST().

◆ unary_op_test()

template<typename Scalar , typename Fn , typename RefFn >
void unary_op_test ( std::string  name,
Fn  fun,
RefFn  ref 
)
147  {
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.
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 }
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96

References a, e(), i, Eigen::internal::isApprox(), isfinite, isnan, min, plotDoE::name, Eigen::numext::signbit(), and VERIFY.

◆ unary_ops_test()

template<typename Scalar >
void unary_ops_test ( )
180  {
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 }
#define UNARY_FUNCTOR_TEST_ARGS(fun)
Definition: array_cwise.cpp:176

References acos(), Eigen::bfloat16_impl::acosh(), Eigen::bfloat16_impl::asin(), Eigen::bfloat16_impl::asinh(), Eigen::bfloat16_impl::atan(), Eigen::bfloat16_impl::atanh(), Eigen::numext::cbrt(), Eigen::bfloat16_impl::ceil(), cos(), Eigen::bfloat16_impl::cosh(), Eigen::bfloat16_impl::exp(), Eigen::bfloat16_impl::exp2(), Eigen::bfloat16_impl::floor(), Eigen::bfloat16_impl::log(), Eigen::bfloat16_impl::rint(), Eigen::bfloat16_impl::round(), sin(), Eigen::bfloat16_impl::sinh(), sqrt(), Eigen::bfloat16_impl::tan(), Eigen::bfloat16_impl::tanh(), Eigen::bfloat16_impl::trunc(), and UNARY_FUNCTOR_TEST_ARGS.