// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <vector>
#include "main.h"

template <typename Scalar, std::enable_if_t<NumTraits<Scalar>::IsInteger,int> = 0>
std::vector<Scalar> special_values() {
  const Scalar zero = Scalar(0);
  const Scalar one = Scalar(1);
  const Scalar two = Scalar(2);
  const Scalar three = Scalar(3);
  const Scalar min = (std::numeric_limits<Scalar>::min)();
  const Scalar max = (std::numeric_limits<Scalar>::max)();
  return { zero, min, one, two, three, max };
}

template <typename Scalar, std::enable_if_t<!NumTraits<Scalar>::IsInteger, int> = 0>
std::vector<Scalar> special_values() {
  const Scalar zero = Scalar(0);
  const Scalar eps = Eigen::NumTraits<Scalar>::epsilon();
  const Scalar one = Scalar(1);
  const Scalar two = Scalar(2);
  const Scalar three = Scalar(3);
  const Scalar sqrt_half = Scalar(std::sqrt(0.5));
  const Scalar sqrt2 = Scalar(std::sqrt(2));    
  const Scalar inf = Eigen::NumTraits<Scalar>::infinity();
  const Scalar nan = Eigen::NumTraits<Scalar>::quiet_NaN();
  const Scalar denorm_min = std::numeric_limits<Scalar>::denorm_min();
  const Scalar min = (std::numeric_limits<Scalar>::min)();
  const Scalar max = (std::numeric_limits<Scalar>::max)();
  const Scalar max_exp = (static_cast<Scalar>(int(Eigen::NumTraits<Scalar>::max_exponent())) * Scalar(EIGEN_LN2)) / eps;
  return { zero, denorm_min, min, eps, sqrt_half, one, sqrt2, two, three, max_exp, max, inf, nan };
}

template<typename Scalar>
void special_value_pairs(Array<Scalar, Dynamic, Dynamic>& x,
                         Array<Scalar, Dynamic, Dynamic>& y) {
  std::vector<Scalar> abs_vals = special_values<Scalar>();
  const Index abs_cases = (Index)abs_vals.size();
  const Index num_cases = 2*abs_cases * 2*abs_cases;
  // ensure both vectorized and non-vectorized paths taken
  const Index num_repeats = 2 * (Index)internal::packet_traits<Scalar>::size + 1;
  x.resize(num_repeats, num_cases);
  y.resize(num_repeats, num_cases);
  int count = 0;
  for (Index i = 0; i < abs_cases; ++i) {
    const Scalar abs_x = abs_vals[i];
    for (Index sign_x = 0; sign_x < 2; ++sign_x) {
      Scalar x_case = sign_x == 0 ? -abs_x : abs_x;
      for (Index j = 0; j < abs_cases; ++j) {
        const Scalar abs_y = abs_vals[j];
        for (Index sign_y = 0; sign_y < 2; ++sign_y) {
          Scalar y_case = sign_y == 0 ? -abs_y : abs_y;
          for (Index repeat = 0; repeat < num_repeats; ++repeat) {
            x(repeat, count) = x_case;
            y(repeat, count) = y_case;
          }
          ++count;
        }
      }
    }
  }
}

template <typename Scalar, typename Fn, typename RefFn>
void binary_op_test(std::string name, Fn fun, RefFn ref) {
  const Scalar tol = test_precision<Scalar>();
  Array<Scalar, Dynamic, Dynamic> x;
  Array<Scalar, Dynamic, Dynamic> y;
  special_value_pairs(x, y);

  Array<Scalar, Dynamic, Dynamic> actual = fun(x, y);
  bool all_pass = true;
  for (Index i = 0; i < x.rows(); ++i) {
    for (Index j = 0; j < x.cols(); ++j) {
      Scalar e = static_cast<Scalar>(ref(x(i,j), y(i,j)));
      Scalar a = actual(i, j);
      bool success = (a==e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) || ((numext::isnan)(a) && (numext::isnan)(e));
      if ((a == a) && (e == e)) success &= (bool)numext::signbit(e) == (bool)numext::signbit(a);
      all_pass &= success;
      if (!success) {
        std::cout << name << "(" << x(i,j) << "," << y(i,j) << ") = " << a << " !=  " << e << std::endl;
      }
    }
  }
  VERIFY(all_pass);
}

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


template <typename Scalar>
void binary_ops_test() {
  binary_op_test<Scalar>(BINARY_FUNCTOR_TEST_ARGS(pow));
#ifndef EIGEN_COMP_MSVC
  binary_op_test<Scalar>(BINARY_FUNCTOR_TEST_ARGS(atan2));
#else
  binary_op_test<Scalar>(
      "atan2", [](const auto& x, const auto& y) { return Eigen::atan2(x, y); },
      [](Scalar x, Scalar y) {
        auto t = Scalar(std::atan2(x, y));
        // Work around MSVC return value on underflow.
        // |atan(y/x)| is bounded above by |y/x|, so on underflow return y/x according to POSIX spec.
        // MSVC otherwise returns denorm_min.
        if (EIGEN_PREDICT_FALSE(std::abs(t) == std::numeric_limits<decltype(t)>::denorm_min())) {
          return x / y;
        }
        return t;
      });
#endif
}


template <typename Scalar, typename Fn, typename RefFn>
void unary_op_test(std::string name, Fn fun, RefFn ref) {
  const Scalar tol = test_precision<Scalar>();
  auto values = special_values<Scalar>();
  Map<Array<Scalar, Dynamic, 1>> x(values.data(), values.size());

  Array<Scalar, Dynamic, Dynamic> actual = fun(x);
  bool all_pass = true;
  for (Index i = 0; i < x.size(); ++i) {
    Scalar e = static_cast<Scalar>(ref(x(i)));
    Scalar a = actual(i);
    bool success = (a == e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) ||
                   ((numext::isnan)(a) && (numext::isnan)(e));
    if ((a == a) && (e == e)) success &= (bool)numext::signbit(e) == (bool)numext::signbit(a);
    all_pass &= success;
    if (!success) {
      std::cout << name << "(" << x(i) << ") = " << a << " !=  " << e << std::endl;
    }
  }
  VERIFY(all_pass);
}

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

template <typename Scalar>
void unary_ops_test() {
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sqrt));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(exp));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(log));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sin));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(cos));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(tan));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(asin));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(acos));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(atan));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sinh));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(cosh));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(tanh));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(asinh));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(acosh));
  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(atanh));
  /* FIXME: Enable when the behavior of rsqrt on denormals for half and double is fixed. 
  unary_op_test<Scalar>("rsqrt",
                        [](const auto& x) { return Eigen::rsqrt(x); }, 
                        [](Scalar x) {
                          if (x >= 0 && x < (std::numeric_limits<Scalar>::min)()) {
                            // rsqrt return +inf for positive subnormals.
                            return NumTraits<Scalar>::infinity();
                          } else {
                            return  Scalar(std::sqrt(Scalar(1)/x));
                          }
                        });
  */
}


template <typename Scalar>
void pow_scalar_exponent_test() {
  using Int_t = typename internal::make_integer<Scalar>::type;
  const Scalar tol = test_precision<Scalar>();

  std::vector<Scalar> abs_vals = special_values<Scalar>();
  const Index num_vals = (Index)abs_vals.size();
  Map<Array<Scalar, Dynamic, 1>> bases(abs_vals.data(), num_vals);

  bool all_pass = true;
  for (Scalar abs_exponent : abs_vals) {
    for (Scalar exponent : {-abs_exponent, abs_exponent}) {
      // test integer exponent code path
      bool exponent_is_integer = (numext::isfinite)(exponent) && (numext::round(exponent) == exponent) &&
                                 (numext::abs(exponent) < static_cast<Scalar>(NumTraits<Int_t>::highest()));
      if (exponent_is_integer) {
        Int_t exponent_as_int = static_cast<Int_t>(exponent);
        Array<Scalar, Dynamic, 1> eigenPow = bases.pow(exponent_as_int);
        for (Index j = 0; j < num_vals; j++) {
          Scalar e = static_cast<Scalar>(std::pow(bases(j), exponent));
          Scalar a = eigenPow(j);
          bool success = (a == e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) ||
                         ((numext::isnan)(a) && (numext::isnan)(e));
          if ((a == a) && (e == e)) success &= (bool)numext::signbit(e) == (bool)numext::signbit(a);
          all_pass &= success;
          if (!success) {
            std::cout << "pow(" << bases(j) << "," << exponent << ") = " << a << " !=  " << e << std::endl;
          }
        }
      } else {
        // test floating point exponent code path
        Array<Scalar, Dynamic, 1> eigenPow = bases.pow(exponent);
        for (Index j = 0; j < num_vals; j++) {
          Scalar e = static_cast<Scalar>(std::pow(bases(j), exponent));
          Scalar a = eigenPow(j);
          bool success = (a == e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) ||
                         ((numext::isnan)(a) && (numext::isnan)(e));
          if ((a == a) && (e == e)) success &= (bool)numext::signbit(e) == (bool)numext::signbit(a);
          all_pass &= success;
          if (!success) {
            std::cout << "pow(" << bases(j) << "," << exponent << ")   =   " << a << " !=  " << e << std::endl;
          }
        }
      }
    }
  }
  VERIFY(all_pass);
}

template <typename Scalar, typename ScalarExponent>
Scalar calc_overflow_threshold(const ScalarExponent exponent) {
    EIGEN_USING_STD(exp2);
    EIGEN_USING_STD(log2);
    EIGEN_STATIC_ASSERT((NumTraits<Scalar>::digits() < 2 * NumTraits<double>::digits()), BASE_TYPE_IS_TOO_BIG);

    if (exponent < 2)
        return NumTraits<Scalar>::highest();
    else {
        // base^e <= highest ==> base <= 2^(log2(highest)/e)
        // For floating-point types, consider the bound for integer values that can be reproduced exactly = 2 ^ digits
        double highest_bits = numext::mini(static_cast<double>(NumTraits<Scalar>::digits()),
                                           static_cast<double>(log2(NumTraits<Scalar>::highest())));
        return static_cast<Scalar>(
          numext::floor(exp2(highest_bits / static_cast<double>(exponent))));
    }
}

template <typename Base, typename Exponent, bool ExpIsInteger = NumTraits<Exponent>::IsInteger>
struct ref_pow {
  static Base run(Base base, Exponent exponent) {
    EIGEN_USING_STD(pow);
    return pow(base, static_cast<Base>(exponent));
  }
};

template <typename Base, typename Exponent>
struct ref_pow<Base, Exponent, true> {
  static Base run(Base base, Exponent exponent) {
    EIGEN_USING_STD(pow);
    return pow(base, exponent);
  }
};

template <typename Base, typename Exponent>
void test_exponent(Exponent exponent) {
  const Base max_abs_bases = static_cast<Base>(10000);
  // avoid integer overflow in Base type
  Base threshold = calc_overflow_threshold<Base, Exponent>(numext::abs(exponent));
  // avoid numbers that can't be verified with std::pow
  double double_threshold = calc_overflow_threshold<double, Exponent>(numext::abs(exponent));
  // use the lesser of these two thresholds
  Base testing_threshold =
      static_cast<double>(threshold) < double_threshold ? threshold : static_cast<Base>(double_threshold);
  // test both vectorized and non-vectorized code paths
  const Index array_size = 2 * internal::packet_traits<Base>::size + 1;

  Base max_base = numext::mini(testing_threshold, max_abs_bases);
  Base min_base = NumTraits<Base>::IsSigned ? -max_base : Base(0);

  ArrayX<Base> x(array_size), y(array_size);
  bool all_pass = true;
  for (Base base = min_base; base <= max_base; base++) {
    if (exponent < 0 && base == 0) continue;
    x.setConstant(base);
    y = x.pow(exponent);
    for (Base a : y) {
      Base e = ref_pow<Base, Exponent>::run(base, exponent);
      bool pass = (a == e);
      if (!NumTraits<Base>::IsInteger) {
        pass = pass || (((numext::isfinite)(e) && internal::isApprox(a, e)) ||
                        ((numext::isnan)(a) && (numext::isnan)(e)));
      }
      all_pass &= pass;
      if (!pass) {
        std::cout << "pow(" << base << "," << exponent << ")   =   " << a << " !=  " << e << std::endl;
      }
    }
  }
  VERIFY(all_pass);
}

template <typename Base, typename Exponent>
void unary_pow_test() {
  Exponent max_exponent = static_cast<Exponent>(NumTraits<Base>::digits());
  Exponent min_exponent = static_cast<Exponent>(NumTraits<Exponent>::IsSigned ? -max_exponent : 0);

  for (Exponent exponent = min_exponent; exponent < max_exponent; ++exponent) {
    test_exponent<Base, Exponent>(exponent);
  }
}

void mixed_pow_test() {
  // The following cases will test promoting a smaller exponent type
  // to a wider base type.
  unary_pow_test<double, int>();
  unary_pow_test<double, float>();
  unary_pow_test<float, half>();
  unary_pow_test<double, half>();
  unary_pow_test<float, bfloat16>();
  unary_pow_test<double, bfloat16>();

  // Although in the following cases the exponent cannot be represented exactly
  // in the base type, we do not perform a conversion, but implement
  // the operation using repeated squaring.
  unary_pow_test<float, int>();
  unary_pow_test<double, long long>();

  // The following cases will test promoting a wider exponent type
  // to a narrower base type. This should compile but would generate a
  // deprecation warning:
  // unary_pow_test<float, double>();
}

void int_pow_test() {
  unary_pow_test<int, int>();
  unary_pow_test<unsigned int, unsigned int>();
  unary_pow_test<long long, long long>();
  unary_pow_test<unsigned long long, unsigned long long>();

  // Although in the following cases the exponent cannot be represented exactly
  // in the base type, we do not perform a conversion, but implement the
  // operation using repeated squaring.
  unary_pow_test<long long, int>();
  unary_pow_test<int, unsigned int>();
  unary_pow_test<unsigned int, int>();
  unary_pow_test<long long, unsigned long long>();
  unary_pow_test<unsigned long long, long long>();
  unary_pow_test<long long, int>();
}

namespace Eigen {
namespace internal {
template <typename Scalar>
struct test_signbit_op {
  Scalar constexpr operator()(const Scalar& a) const { return numext::signbit(a); }
  template <typename Packet>
  inline Packet packetOp(const Packet& a) const {
    return psignbit(a);
  }
};
template <typename Scalar>
struct functor_traits<test_signbit_op<Scalar>> {
  enum { Cost = 1, PacketAccess = true }; //todo: define HasSignbit flag
};
}  // namespace internal
}  // namespace Eigen


template <typename Scalar>
void signbit_test() {
  const size_t size = 100 * internal::packet_traits<Scalar>::size;
  ArrayX<Scalar> x(size), y(size);
  x.setRandom();
  std::vector<Scalar> special_vals = special_values<Scalar>();
  for (size_t i = 0; i < special_vals.size(); i++) {
    x(2 * i + 0) = special_vals[i];
    x(2 * i + 1) = -special_vals[i];
  }
  y = x.unaryExpr(internal::test_signbit_op<Scalar>());

  bool all_pass = true;
  for (size_t i = 0; i < size; i++) {
    const Scalar ref_val = numext::signbit(x(i));
    bool not_same = internal::predux_any(internal::bitwise_helper<Scalar>::bitwise_xor(ref_val, y(i)));
    if (not_same) std::cout << "signbit(" << x(i) << ") != " << y(i) << "\n";
    all_pass = all_pass && !not_same;
  }

  VERIFY(all_pass);
}
void signbit_tests() {
  signbit_test<float>();
  signbit_test<double>();
  signbit_test<Eigen::half>();
  signbit_test<Eigen::bfloat16>();

  signbit_test<uint8_t>();
  signbit_test<uint16_t>();
  signbit_test<uint32_t>();
  signbit_test<uint64_t>();

  signbit_test<int8_t>();
  signbit_test<int16_t>();
  signbit_test<int32_t>();
  signbit_test<int64_t>();
}

template<typename ArrayType> void array(const ArrayType& m)
{
  typedef typename ArrayType::Scalar Scalar;
  typedef typename ArrayType::RealScalar RealScalar;
  typedef Array<Scalar, ArrayType::RowsAtCompileTime, 1> ColVectorType;
  typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType;

  Index rows = m.rows();
  Index cols = m.cols();

  ArrayType m1 = ArrayType::Random(rows, cols);
  if (NumTraits<RealScalar>::IsInteger && NumTraits<RealScalar>::IsSigned
      && !NumTraits<Scalar>::IsComplex) {
    // Here we cap the size of the values in m1 such that pow(3)/cube()
    // doesn't overflow and result in undefined behavior. Notice that because
    // pow(int, int) promotes its inputs and output to double (according to
    // the C++ standard), we have to make sure that the result fits in 53 bits
    // for int64,
    RealScalar max_val =
        numext::mini(RealScalar(std::cbrt(NumTraits<RealScalar>::highest())),
                     RealScalar(std::cbrt(1LL << 53)))/2;
    m1.array() = (m1.abs().array() <= max_val).select(m1, Scalar(max_val));
  }
  ArrayType  m2 = ArrayType::Random(rows, cols),
             m3(rows, cols);
  ArrayType m4 = m1; // copy constructor
  VERIFY_IS_APPROX(m1, m4);

  ColVectorType cv1 = ColVectorType::Random(rows);
  RowVectorType rv1 = RowVectorType::Random(cols);

  Scalar  s1 = internal::random<Scalar>(),
          s2 = internal::random<Scalar>();

  // scalar addition
  VERIFY_IS_APPROX(m1 + s1, s1 + m1);
  VERIFY_IS_APPROX(m1 + s1, ArrayType::Constant(rows,cols,s1) + m1);
  VERIFY_IS_APPROX(s1 - m1, (-m1)+s1 );
  VERIFY_IS_APPROX(m1 - s1, m1 - ArrayType::Constant(rows,cols,s1));
  VERIFY_IS_APPROX(s1 - m1, ArrayType::Constant(rows,cols,s1) - m1);
  VERIFY_IS_APPROX((m1*Scalar(2)) - s2, (m1+m1) - ArrayType::Constant(rows,cols,s2) );
  m3 = m1;
  m3 += s2;
  VERIFY_IS_APPROX(m3, m1 + s2);
  m3 = m1;
  m3 -= s1;
  VERIFY_IS_APPROX(m3, m1 - s1);

  // scalar operators via Maps
  m3 = m1;  m4 = m1;
  ArrayType::Map(m4.data(), m4.rows(), m4.cols()) -= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
  VERIFY_IS_APPROX(m4, m3 - m2);

  m3 = m1;  m4 = m1;
  ArrayType::Map(m4.data(), m4.rows(), m4.cols()) += ArrayType::Map(m2.data(), m2.rows(), m2.cols());
  VERIFY_IS_APPROX(m4, m3 + m2);

  m3 = m1; m4 = m1;
  ArrayType::Map(m4.data(), m4.rows(), m4.cols()) *= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
  VERIFY_IS_APPROX(m4, m3 * m2);

  m3 = m1; m4 = m1;
  m2 = ArrayType::Random(rows,cols);
  m2 = (m2==0).select(1,m2);
  ArrayType::Map(m4.data(), m4.rows(), m4.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
  VERIFY_IS_APPROX(m4, m3 / m2);

  // reductions
  VERIFY_IS_APPROX(m1.abs().colwise().sum().sum(), m1.abs().sum());
  VERIFY_IS_APPROX(m1.abs().rowwise().sum().sum(), m1.abs().sum());
  using std::abs;
  VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.colwise().sum().sum() - m1.sum()), m1.abs().sum());
  VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.rowwise().sum().sum() - m1.sum()), m1.abs().sum());
  if (!internal::isMuchSmallerThan(abs(m1.sum() - (m1+m2).sum()), m1.abs().sum(), test_precision<Scalar>()))
      VERIFY_IS_NOT_APPROX(((m1+m2).rowwise().sum()).sum(), m1.sum());
  VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar,Scalar>()));

  // vector-wise ops
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);

  // Conversion from scalar
  VERIFY_IS_APPROX((m3 = s1), ArrayType::Constant(rows,cols,s1));
  VERIFY_IS_APPROX((m3 = 1),  ArrayType::Constant(rows,cols,1));
  VERIFY_IS_APPROX((m3.topLeftCorner(rows,cols) = 1),  ArrayType::Constant(rows,cols,1));
  typedef Array<Scalar,
                ArrayType::RowsAtCompileTime==Dynamic?2:ArrayType::RowsAtCompileTime,
                ArrayType::ColsAtCompileTime==Dynamic?2:ArrayType::ColsAtCompileTime,
                ArrayType::Options> FixedArrayType;
  {
    FixedArrayType f1(s1);
    VERIFY_IS_APPROX(f1, FixedArrayType::Constant(s1));
    FixedArrayType f2(numext::real(s1));
    VERIFY_IS_APPROX(f2, FixedArrayType::Constant(numext::real(s1)));
    FixedArrayType f3((int)100*numext::real(s1));
    VERIFY_IS_APPROX(f3, FixedArrayType::Constant((int)100*numext::real(s1)));
    f1.setRandom();
    FixedArrayType f4(f1.data());
    VERIFY_IS_APPROX(f4, f1);
  }
  {
    FixedArrayType f1{s1};
    VERIFY_IS_APPROX(f1, FixedArrayType::Constant(s1));
    FixedArrayType f2{numext::real(s1)};
    VERIFY_IS_APPROX(f2, FixedArrayType::Constant(numext::real(s1)));
    FixedArrayType f3{(int)100*numext::real(s1)};
    VERIFY_IS_APPROX(f3, FixedArrayType::Constant((int)100*numext::real(s1)));
    f1.setRandom();
    FixedArrayType f4{f1.data()};
    VERIFY_IS_APPROX(f4, f1);
  }

  // pow
  VERIFY_IS_APPROX(m1.pow(2), m1.square());
  VERIFY_IS_APPROX(pow(m1,2), m1.square());
  VERIFY_IS_APPROX(m1.pow(3), m1.cube());
  VERIFY_IS_APPROX(pow(m1,3), m1.cube());
  VERIFY_IS_APPROX((-m1).pow(3), -m1.cube());
  VERIFY_IS_APPROX(pow(2*m1,3), 8*m1.cube());
  ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2));
  VERIFY_IS_APPROX(Eigen::pow(m1,exponents), m1.square());
  VERIFY_IS_APPROX(m1.pow(exponents), m1.square());
  VERIFY_IS_APPROX(Eigen::pow(2*m1,exponents), 4*m1.square());
  VERIFY_IS_APPROX((2*m1).pow(exponents), 4*m1.square());
  VERIFY_IS_APPROX(Eigen::pow(m1,2*exponents), m1.square().square());
  VERIFY_IS_APPROX(m1.pow(2*exponents), m1.square().square());
  VERIFY_IS_APPROX(Eigen::pow(m1(0,0), exponents), ArrayType::Constant(rows,cols,m1(0,0)*m1(0,0)));

  // Check possible conflicts with 1D ctor
  typedef Array<Scalar, Dynamic, 1> OneDArrayType;
  {
    OneDArrayType o1(rows);
    VERIFY(o1.size()==rows);
    OneDArrayType o2(static_cast<int>(rows));
    VERIFY(o2.size()==rows);
  }
  {
    OneDArrayType o1{rows};
    VERIFY(o1.size()==rows);
    OneDArrayType o4{int(rows)};
    VERIFY(o4.size()==rows);
  }
  // Check possible conflicts with 2D ctor
  typedef Array<Scalar, Dynamic, Dynamic> TwoDArrayType;
  typedef Array<Scalar, 2, 1> ArrayType2;
  {
    TwoDArrayType o1(rows,cols);
    VERIFY(o1.rows()==rows);
    VERIFY(o1.cols()==cols);
    TwoDArrayType o2(static_cast<int>(rows),static_cast<int>(cols));
    VERIFY(o2.rows()==rows);
    VERIFY(o2.cols()==cols);

    ArrayType2 o3(rows,cols);
    VERIFY(o3(0)==Scalar(rows) && o3(1)==Scalar(cols));
    ArrayType2 o4(static_cast<int>(rows),static_cast<int>(cols));
    VERIFY(o4(0)==Scalar(rows) && o4(1)==Scalar(cols));
  }
  {
    TwoDArrayType o1{rows,cols};
    VERIFY(o1.rows()==rows);
    VERIFY(o1.cols()==cols);
    TwoDArrayType o2{int(rows),int(cols)};
    VERIFY(o2.rows()==rows);
    VERIFY(o2.cols()==cols);

    ArrayType2 o3{rows,cols};
    VERIFY(o3(0)==Scalar(rows) && o3(1)==Scalar(cols));
    ArrayType2 o4{int(rows),int(cols)};
    VERIFY(o4(0)==Scalar(rows) && o4(1)==Scalar(cols));
  }
}

template<typename ArrayType> void comparisons(const ArrayType& m)
{
  using std::abs;
  typedef typename ArrayType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  Index rows = m.rows();
  Index cols = m.cols();

  Index r = internal::random<Index>(0, rows-1),
        c = internal::random<Index>(0, cols-1);

  ArrayType m1 = ArrayType::Random(rows, cols),
            m2 = ArrayType::Random(rows, cols),
            m3(rows, cols),
            m4 = m1;

  m4 = (m4.abs()==Scalar(0)).select(1,m4);

  VERIFY(((m1 + Scalar(1)) > m1).all());
  VERIFY(((m1 - Scalar(1)) < m1).all());
  if (rows*cols>1)
  {
    m3 = m1;
    m3(r,c) += 1;
    VERIFY(! (m1 < m3).all() );
    VERIFY(! (m1 > m3).all() );
  }
  VERIFY(!(m1 > m2 && m1 < m2).any());
  VERIFY((m1 <= m2 || m1 >= m2).all());

  // comparisons array to scalar
  VERIFY( (m1 != (m1(r,c)+1) ).any() );
  VERIFY( (m1 >  (m1(r,c)-1) ).any() );
  VERIFY( (m1 <  (m1(r,c)+1) ).any() );
  VERIFY( (m1 ==  m1(r,c)    ).any() );

  // comparisons scalar to array
  VERIFY( ( (m1(r,c)+1) != m1).any() );
  VERIFY( ( (m1(r,c)-1) <  m1).any() );
  VERIFY( ( (m1(r,c)+1) >  m1).any() );
  VERIFY( (  m1(r,c)    == m1).any() );

  // test Select
  VERIFY_IS_APPROX( (m1<m2).select(m1,m2), m1.cwiseMin(m2) );
  VERIFY_IS_APPROX( (m1>m2).select(m1,m2), m1.cwiseMax(m2) );
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
  for (int j=0; j<cols; ++j)
  for (int i=0; i<rows; ++i)
    m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
                        .select(ArrayType::Zero(rows,cols),m1), m3);
  // shorter versions:
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
                        .select(0,m1), m3);
  VERIFY_IS_APPROX( (m1.abs()>=ArrayType::Constant(rows,cols,mid))
                        .select(m1,0), m3);
  // even shorter version:
  VERIFY_IS_APPROX( (m1.abs()<mid).select(0,m1), m3);

  // count
  VERIFY(((m1.abs()+1)>RealScalar(0.1)).count() == rows*cols);

  // and/or
  VERIFY( (m1<RealScalar(0) && m1>RealScalar(0)).count() == 0);
  VERIFY( (m1<RealScalar(0) || m1>=RealScalar(0)).count() == rows*cols);
  RealScalar a = m1.abs().mean();
  VERIFY( (m1<-a || m1>a).count() == (m1.abs()>a).count());

  typedef Array<Index, Dynamic, 1> ArrayOfIndices;

  // TODO allows colwise/rowwise for array
  VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).colwise().count(), ArrayOfIndices::Constant(cols,rows).transpose());
  VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).rowwise().count(), ArrayOfIndices::Constant(rows, cols));
}

template<typename ArrayType> void array_real(const ArrayType& m)
{
  using std::abs;
  using std::sqrt;
  typedef typename ArrayType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  Index rows = m.rows();
  Index cols = m.cols();

  ArrayType m1 = ArrayType::Random(rows, cols),
            m2 = ArrayType::Random(rows, cols),
            m3(rows, cols),
            m4 = m1;

  m4 = (m4.abs()==Scalar(0)).select(Scalar(1),m4);

  Scalar  s1 = internal::random<Scalar>();

  // these tests are mostly to check possible compilation issues with free-functions.
  VERIFY_IS_APPROX(m1.sin(), sin(m1));
  VERIFY_IS_APPROX(m1.cos(), cos(m1));
  VERIFY_IS_APPROX(m1.tan(), tan(m1));
  VERIFY_IS_APPROX(m1.asin(), asin(m1));
  VERIFY_IS_APPROX(m1.acos(), acos(m1));
  VERIFY_IS_APPROX(m1.atan(), atan(m1));
  VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
  VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
  VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
  VERIFY_IS_APPROX(m1.atan2(m2), atan2(m1,m2));

  VERIFY_IS_APPROX(m1.tanh().atanh(), atanh(tanh(m1)));
  VERIFY_IS_APPROX(m1.sinh().asinh(), asinh(sinh(m1)));
  VERIFY_IS_APPROX(m1.cosh().acosh(), acosh(cosh(m1)));
  VERIFY_IS_APPROX(m1.tanh().atanh(), atanh(tanh(m1)));
  VERIFY_IS_APPROX(m1.logistic(), logistic(m1));

  VERIFY_IS_APPROX(m1.arg(), arg(m1));
  VERIFY_IS_APPROX(m1.round(), round(m1));
  VERIFY_IS_APPROX(m1.rint(), rint(m1));
  VERIFY_IS_APPROX(m1.floor(), floor(m1));
  VERIFY_IS_APPROX(m1.ceil(), ceil(m1));
  VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
  VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
  VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
  VERIFY_IS_APPROX(m4.inverse(), inverse(m4));
  VERIFY_IS_APPROX(m1.abs(), abs(m1));
  VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
  VERIFY_IS_APPROX(m1.square(), square(m1));
  VERIFY_IS_APPROX(m1.cube(), cube(m1));
  VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval()));
  VERIFY_IS_APPROX(m1.sign(), sign(m1));
  VERIFY((m1.sqrt().sign().isNaN() == (Eigen::isnan)(sign(sqrt(m1)))).all());

  // avoid inf and NaNs so verification doesn't fail
  m3 = m4.abs();
  VERIFY_IS_APPROX(m3.sqrt(), sqrt(abs(m3)));
  VERIFY_IS_APPROX(m3.rsqrt(), Scalar(1)/sqrt(abs(m3)));
  VERIFY_IS_APPROX(rsqrt(m3), Scalar(1)/sqrt(abs(m3)));
  VERIFY_IS_APPROX(m3.log(), log(m3));
  VERIFY_IS_APPROX(m3.log1p(), log1p(m3));
  VERIFY_IS_APPROX(m3.log10(), log10(m3));
  VERIFY_IS_APPROX(m3.log2(), log2(m3));


  VERIFY((!(m1>m2) == (m1<=m2)).all());

  VERIFY_IS_APPROX(sin(m1.asin()), m1);
  VERIFY_IS_APPROX(cos(m1.acos()), m1);
  VERIFY_IS_APPROX(tan(m1.atan()), m1);
  VERIFY_IS_APPROX(sinh(m1), Scalar(0.5)*(exp(m1)-exp(-m1)));
  VERIFY_IS_APPROX(cosh(m1), Scalar(0.5)*(exp(m1)+exp(-m1)));
  VERIFY_IS_APPROX(tanh(m1), (Scalar(0.5)*(exp(m1)-exp(-m1)))/(Scalar(0.5)*(exp(m1)+exp(-m1))));
  VERIFY_IS_APPROX(logistic(m1), (Scalar(1)/(Scalar(1)+exp(-m1))));
  VERIFY_IS_APPROX(arg(m1), ((m1<Scalar(0)).template cast<Scalar>())*Scalar(std::acos(Scalar(-1))));
  VERIFY((round(m1) <= ceil(m1) && round(m1) >= floor(m1)).all());
  VERIFY((rint(m1) <= ceil(m1) && rint(m1) >= floor(m1)).all());
  VERIFY(((ceil(m1) - round(m1)) <= Scalar(0.5) || (round(m1) - floor(m1)) <= Scalar(0.5)).all());
  VERIFY(((ceil(m1) - round(m1)) <= Scalar(1.0) && (round(m1) - floor(m1)) <= Scalar(1.0)).all());
  VERIFY(((ceil(m1) - rint(m1)) <= Scalar(0.5) || (rint(m1) - floor(m1)) <= Scalar(0.5)).all());
  VERIFY(((ceil(m1) - rint(m1)) <= Scalar(1.0) && (rint(m1) - floor(m1)) <= Scalar(1.0)).all());
  VERIFY((Eigen::isnan)((m1*Scalar(0))/Scalar(0)).all());
  VERIFY((Eigen::isinf)(m4/Scalar(0)).all());
  VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1*Scalar(0)/Scalar(0))) && (!(Eigen::isfinite)(m4/Scalar(0)))).all());
  VERIFY_IS_APPROX(inverse(inverse(m4)),m4);
  VERIFY((abs(m1) == m1 || abs(m1) == -m1).all());
  VERIFY_IS_APPROX(m3, sqrt(abs2(m3)));
  VERIFY_IS_APPROX(m1.absolute_difference(m2), (m1 > m2).select(m1 - m2, m2 - m1));
  VERIFY_IS_APPROX( m1.sign(), -(-m1).sign() );
  VERIFY_IS_APPROX( m1*m1.sign(),m1.abs());
  VERIFY_IS_APPROX(m1.sign() * m1.abs(), m1);
  
  ArrayType tmp = m1.atan2(m2);
  for (Index i = 0; i < tmp.size(); ++i) {
    Scalar actual = tmp.array()(i);
    Scalar expected = atan2(m1.array()(i), m2.array()(i));
    VERIFY_IS_APPROX(actual, expected);
  }

  VERIFY_IS_APPROX(numext::abs2(numext::real(m1)) + numext::abs2(numext::imag(m1)), numext::abs2(m1));
  VERIFY_IS_APPROX(numext::abs2(Eigen::real(m1)) + numext::abs2(Eigen::imag(m1)), numext::abs2(m1));
  if(!NumTraits<Scalar>::IsComplex)
    VERIFY_IS_APPROX(numext::real(m1), m1);

  // shift argument of logarithm so that it is not zero
  Scalar smallNumber = NumTraits<Scalar>::dummy_precision();
  VERIFY_IS_APPROX((m3 + smallNumber).log() , log(abs(m3) + smallNumber));
  VERIFY_IS_APPROX((m3 + smallNumber + Scalar(1)).log() , log1p(abs(m3) + smallNumber));

  VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2));
  VERIFY_IS_APPROX(m1.exp(), exp(m1));
  VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp());

  VERIFY_IS_APPROX(m1.expm1(), expm1(m1));
  VERIFY_IS_APPROX((m3 + smallNumber).exp() - Scalar(1), expm1(abs(m3) + smallNumber));

  VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());
  VERIFY_IS_APPROX(pow(m3,RealScalar(0.5)), m3.sqrt());

  VERIFY_IS_APPROX(m3.pow(RealScalar(-0.5)), m3.rsqrt());
  VERIFY_IS_APPROX(pow(m3,RealScalar(-0.5)), m3.rsqrt());

  // Avoid inf and NaN.
  m3 = (m1.square()<NumTraits<Scalar>::epsilon()).select(Scalar(1),m3);
  VERIFY_IS_APPROX(m3.pow(RealScalar(-2)), m3.square().inverse());

  // Test pow and atan2 on special IEEE values.
  unary_ops_test<Scalar>();
  binary_ops_test<Scalar>();
  pow_scalar_exponent_test<Scalar>();

  VERIFY_IS_APPROX(log10(m3), log(m3)/numext::log(Scalar(10)));
  VERIFY_IS_APPROX(log2(m3), log(m3)/numext::log(Scalar(2)));

  // scalar by array division
  const RealScalar tiny = sqrt(std::numeric_limits<RealScalar>::epsilon());
  s1 += Scalar(tiny);
  m1 += ArrayType::Constant(rows,cols,Scalar(tiny));
  VERIFY_IS_CWISE_APPROX(s1/m1, s1 * m1.inverse());

  // check inplace transpose
  m3 = m1;
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3, m1.transpose());
  m3.transposeInPlace();
  VERIFY_IS_APPROX(m3, m1);
}


template<typename ArrayType> void array_complex(const ArrayType& m)
{
  typedef typename ArrayType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  Index rows = m.rows();
  Index cols = m.cols();

  ArrayType m1 = ArrayType::Random(rows, cols),
            m2(rows, cols),
            m4 = m1;

  m4.real() = (m4.real().abs()==RealScalar(0)).select(RealScalar(1),m4.real());
  m4.imag() = (m4.imag().abs()==RealScalar(0)).select(RealScalar(1),m4.imag());

  Array<RealScalar, -1, -1> m3(rows, cols);

  for (Index i = 0; i < m.rows(); ++i)
    for (Index j = 0; j < m.cols(); ++j)
      m2(i,j) = sqrt(m1(i,j));

  // these tests are mostly to check possible compilation issues with free-functions.
  VERIFY_IS_APPROX(m1.sin(), sin(m1));
  VERIFY_IS_APPROX(m1.cos(), cos(m1));
  VERIFY_IS_APPROX(m1.tan(), tan(m1));
  VERIFY_IS_APPROX(m1.sinh(), sinh(m1));
  VERIFY_IS_APPROX(m1.cosh(), cosh(m1));
  VERIFY_IS_APPROX(m1.tanh(), tanh(m1));
  VERIFY_IS_APPROX(m1.logistic(), logistic(m1));
  VERIFY_IS_APPROX(m1.arg(), arg(m1));
  VERIFY_IS_APPROX(m1.carg(), carg(m1));
  VERIFY_IS_APPROX(arg(m1), carg(m1));
  VERIFY((m1.isNaN() == (Eigen::isnan)(m1)).all());
  VERIFY((m1.isInf() == (Eigen::isinf)(m1)).all());
  VERIFY((m1.isFinite() == (Eigen::isfinite)(m1)).all());
  VERIFY_IS_APPROX(m4.inverse(), inverse(m4));
  VERIFY_IS_APPROX(m1.log(), log(m1));
  VERIFY_IS_APPROX(m1.log10(), log10(m1));
  VERIFY_IS_APPROX(m1.log2(), log2(m1));
  VERIFY_IS_APPROX(m1.abs(), abs(m1));
  VERIFY_IS_APPROX(m1.abs2(), abs2(m1));
  VERIFY_IS_APPROX(m1.sqrt(), sqrt(m1));
  VERIFY_IS_APPROX(m1.square(), square(m1));
  VERIFY_IS_APPROX(m1.cube(), cube(m1));
  VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval()));
  VERIFY_IS_APPROX(m1.sign(), sign(m1));

  VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2));
  VERIFY_IS_APPROX(m1.exp(), exp(m1));
  VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp());

  VERIFY_IS_APPROX(m1.expm1(), expm1(m1));
  VERIFY_IS_APPROX(expm1(m1), exp(m1) - 1.);
  // Check for larger magnitude complex numbers that expm1 matches exp - 1.
  VERIFY_IS_APPROX(expm1(10. * m1), exp(10. * m1) - 1.);

  VERIFY_IS_APPROX(sinh(m1), 0.5*(exp(m1)-exp(-m1)));
  VERIFY_IS_APPROX(cosh(m1), 0.5*(exp(m1)+exp(-m1)));
  VERIFY_IS_APPROX(tanh(m1), (0.5*(exp(m1)-exp(-m1)))/(0.5*(exp(m1)+exp(-m1))));
  VERIFY_IS_APPROX(logistic(m1), (1.0/(1.0 + exp(-m1))));

  for (Index i = 0; i < m.rows(); ++i)
    for (Index j = 0; j < m.cols(); ++j)
      m3(i,j) = std::atan2(m1(i,j).imag(), m1(i,j).real());
  VERIFY_IS_APPROX(arg(m1), m3);
  VERIFY_IS_APPROX(carg(m1), m3);

  std::complex<RealScalar> zero(0.0,0.0);
  VERIFY((Eigen::isnan)(m1*zero/zero).all());
#if EIGEN_COMP_MSVC
  // msvc complex division is not robust
  VERIFY((Eigen::isinf)(m4/RealScalar(0)).all());
#else
#if EIGEN_COMP_CLANG
  // clang's complex division is notoriously broken too
  if((numext::isinf)(m4(0,0)/RealScalar(0))) {
#endif
    VERIFY((Eigen::isinf)(m4/zero).all());
#if EIGEN_COMP_CLANG
  }
  else
  {
    VERIFY((Eigen::isinf)(m4.real()/zero.real()).all());
  }
#endif
#endif // MSVC

  VERIFY(((Eigen::isfinite)(m1) && (!(Eigen::isfinite)(m1*zero/zero)) && (!(Eigen::isfinite)(m1/zero))).all());

  VERIFY_IS_APPROX(inverse(inverse(m4)),m4);
  VERIFY_IS_APPROX(conj(m1.conjugate()), m1);
  VERIFY_IS_APPROX(abs(m1), sqrt(square(m1.real())+square(m1.imag())));
  VERIFY_IS_APPROX(abs(m1), sqrt(abs2(m1)));
  VERIFY_IS_APPROX(log10(m1), log(m1)/log(10));
  VERIFY_IS_APPROX(log2(m1), log(m1)/log(2));

  VERIFY_IS_APPROX( m1.sign(), -(-m1).sign() );
  VERIFY_IS_APPROX( m1.sign() * m1.abs(), m1);

  // scalar by array division
  Scalar  s1 = internal::random<Scalar>();
  const RealScalar tiny = std::sqrt(std::numeric_limits<RealScalar>::epsilon());
  s1 += Scalar(tiny);
  m1 += ArrayType::Constant(rows,cols,Scalar(tiny));
  VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse());

  // check inplace transpose
  m2 = m1;
  m2.transposeInPlace();
  VERIFY_IS_APPROX(m2, m1.transpose());
  m2.transposeInPlace();
  VERIFY_IS_APPROX(m2, m1);
  // Check vectorized inplace transpose.
  ArrayType m5 = ArrayType::Random(131, 131);
  ArrayType m6 = m5;
  m6.transposeInPlace();
  VERIFY_IS_APPROX(m6, m5.transpose());
}

template<typename ArrayType> void min_max(const ArrayType& m)
{
  typedef typename ArrayType::Scalar Scalar;

  Index rows = m.rows();
  Index cols = m.cols();

  ArrayType m1 = ArrayType::Random(rows, cols);

  // min/max with array
  Scalar maxM1 = m1.maxCoeff();
  Scalar minM1 = m1.minCoeff();

  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, minM1), (m1.min)(ArrayType::Constant(rows,cols, minM1)));
  VERIFY_IS_APPROX(m1, (m1.min)(ArrayType::Constant(rows,cols, maxM1)));

  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, maxM1), (m1.max)(ArrayType::Constant(rows,cols, maxM1)));
  VERIFY_IS_APPROX(m1, (m1.max)(ArrayType::Constant(rows,cols, minM1)));

  // min/max with scalar input
  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, minM1), (m1.min)( minM1));
  VERIFY_IS_APPROX(m1, (m1.min)( maxM1));

  VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, maxM1), (m1.max)( maxM1));
  VERIFY_IS_APPROX(m1, (m1.max)( minM1));


  // min/max with various NaN propagation options.
  if (m1.size() > 1 && !NumTraits<Scalar>::IsInteger) {
    m1(0,0) = NumTraits<Scalar>::quiet_NaN();
    maxM1 = m1.template maxCoeff<PropagateNaN>();
    minM1 = m1.template minCoeff<PropagateNaN>();
    VERIFY((numext::isnan)(maxM1));
    VERIFY((numext::isnan)(minM1));

    maxM1 = m1.template maxCoeff<PropagateNumbers>();
    minM1 = m1.template minCoeff<PropagateNumbers>();
    VERIFY(!(numext::isnan)(maxM1));
    VERIFY(!(numext::isnan)(minM1));
  }
}

template<int N>
struct shift_left {
  template<typename Scalar>
  Scalar operator()(const Scalar& v) const {
    return v << N;
  }
};

template<int N>
struct arithmetic_shift_right {
  template<typename Scalar>
  Scalar operator()(const Scalar& v) const {
    return v >> N;
  }
};

template<typename ArrayType> void array_integer(const ArrayType& m)
{
  Index rows = m.rows();
  Index cols = m.cols();

  ArrayType m1 = ArrayType::Random(rows, cols),
            m2(rows, cols);

  m2 = m1.template shiftLeft<2>();
  VERIFY( (m2 == m1.unaryExpr(shift_left<2>())).all() );
  m2 = m1.template shiftLeft<9>();
  VERIFY( (m2 == m1.unaryExpr(shift_left<9>())).all() );
  
  m2 = m1.template shiftRight<2>();
  VERIFY( (m2 == m1.unaryExpr(arithmetic_shift_right<2>())).all() );
  m2 = m1.template shiftRight<9>();
  VERIFY( (m2 == m1.unaryExpr(arithmetic_shift_right<9>())).all() );
}

template <typename ArrayType>
struct signed_shift_test_impl {
  typedef typename ArrayType::Scalar Scalar;
  static constexpr size_t Size = sizeof(Scalar);
  static constexpr size_t MaxShift = (CHAR_BIT * Size) - 1;

  template <size_t N = 0>
  static inline std::enable_if_t<(N >  MaxShift), void> run(const ArrayType&  ) {}
  template <size_t N = 0>
  static inline std::enable_if_t<(N <= MaxShift), void> run(const ArrayType& m) {
    const Index rows = m.rows();
    const Index cols = m.cols();

    ArrayType m1 = ArrayType::Random(rows, cols), m2(rows, cols);

    m2 = m1.unaryExpr([](const Scalar& x) { return x >> N; });
    VERIFY((m2 == m1.unaryExpr(internal::scalar_shift_right_op<Scalar, N>())).all());

    m2 = m1.unaryExpr([](const Scalar& x) { return x << N; });
    VERIFY((m2 == m1.unaryExpr( internal::scalar_shift_left_op<Scalar, N>())).all());

    run<N + 1>(m);
  }
};
template <typename ArrayType>
void signed_shift_test(const ArrayType& m) {
    signed_shift_test_impl<ArrayType>::run(m);
}

template <typename ArrayType>
struct typed_logicals_test_impl {
  using Scalar = typename ArrayType::Scalar;

  static bool scalar_to_bool(const Scalar& x) { return x != Scalar(0); }
  static Scalar bool_to_scalar(const bool& x) { return x ? Scalar(1) : Scalar(0); }

  static Scalar eval_bool_and(const Scalar& x, const Scalar& y) { return bool_to_scalar(scalar_to_bool(x) && scalar_to_bool(y)); }
  static Scalar eval_bool_or(const Scalar& x, const Scalar& y) { return bool_to_scalar(scalar_to_bool(x) || scalar_to_bool(y)); }
  static Scalar eval_bool_xor(const Scalar& x, const Scalar& y) { return bool_to_scalar(scalar_to_bool(x) != scalar_to_bool(y)); }
  static Scalar eval_bool_not(const Scalar& x) { return bool_to_scalar(!scalar_to_bool(x)); }

  static void run(const ArrayType& m) {
      
    Index rows = m.rows();
    Index cols = m.cols();

    ArrayType m1(rows, cols), m2(rows, cols), m3(rows, cols), m4(rows, cols);

    m1.setRandom();
    m2.setRandom();
    m1 *= ArrayX<bool>::Random(rows, cols).cast<Scalar>();
    m2 *= ArrayX<bool>::Random(rows, cols).cast<Scalar>();

    // test boolean and
    m3 = m1 && m2;
    m4 = m1.binaryExpr(m2, [](const Scalar& x, const Scalar& y) { return eval_bool_and(x, y); });
    VERIFY_IS_CWISE_EQUAL(m3, m4);
    for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));

    // test boolean or
    m3 = m1 || m2;
    m4 = m1.binaryExpr(m2, [](const Scalar& x, const Scalar& y) { return eval_bool_or(x, y); });
    VERIFY_IS_CWISE_EQUAL(m3, m4);
    for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));

    // test boolean xor
    m3 = m1.binaryExpr(m2, internal::scalar_boolean_xor_op<Scalar>());
    m4 = m1.binaryExpr(m2, [](const Scalar& x, const Scalar& y) { return eval_bool_xor(x, y); });
    VERIFY_IS_CWISE_EQUAL(m3, m4);
    for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));

    // test boolean not
    m3 = !m1;
    m4 = m1.unaryExpr([](const Scalar& x) { return eval_bool_not(x); });
    VERIFY_IS_CWISE_EQUAL(m3, m4);
    for (const Scalar& val : m3) VERIFY(val == Scalar(0) || val == Scalar(1));

    // test something more complicated
    m3 = m1 && m2;
    m4 = !(!m1 || !m2);
    VERIFY_IS_CWISE_EQUAL(m3, m4);

    m3 = m1.binaryExpr(m2, internal::scalar_boolean_xor_op<Scalar>());
    m4 = (!m1).binaryExpr((!m2), internal::scalar_boolean_xor_op<Scalar>());
    VERIFY_IS_CWISE_EQUAL(m3, m4);

    const Index bytes = rows * cols * sizeof(Scalar);
    const uint8_t* m1_data = reinterpret_cast<const uint8_t*>(m1.data());
    const uint8_t* m2_data = reinterpret_cast<const uint8_t*>(m2.data());
    uint8_t* m3_data = reinterpret_cast<uint8_t*>(m3.data());
    uint8_t* m4_data = reinterpret_cast<uint8_t*>(m4.data());

    // test bitwise and
    m3 = m1 & m2;
    for (Index i = 0; i < bytes; i++) m4_data[i] = m1_data[i] & m2_data[i];
    for (Index i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_data[i], m4_data[i]);

    // test bitwise or
    m3 = m1 | m2;
    for (Index i = 0; i < bytes; i++) m4_data[i] = m1_data[i] | m2_data[i];
    for (Index i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_data[i], m4_data[i]);

    // test bitwise xor
    m3 = m1 ^ m2;
    for (Index i = 0; i < bytes; i++) m4_data[i] = m1_data[i] ^ m2_data[i];
    for (Index i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_data[i], m4_data[i]);

    // test bitwise not
    m3 = ~m1;
    for (Index i = 0; i < bytes; i++) m4_data[i] = ~m1_data[i];
    for (Index i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_data[i], m4_data[i]);

    // test something more complicated
    m3 = m1 & m2;
    m4 = ~(~m1 | ~m2);
    for (Index i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_data[i], m4_data[i]);

    m3 = m1 ^ m2;
    m4 = (~m1) ^ (~m2);
    for (Index i = 0; i < bytes; i++) VERIFY_IS_EQUAL(m3_data[i], m4_data[i]);
  }
};
template <typename ArrayType>
void typed_logicals_test(const ArrayType& m) {
    typed_logicals_test_impl<ArrayType>::run(m);
}

EIGEN_DECLARE_TEST(array_cwise)
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( array(Array<float, 1, 1>()) );
    CALL_SUBTEST_2( array(Array22f()) );
    CALL_SUBTEST_3( array(Array44d()) );
    CALL_SUBTEST_4( array(ArrayXXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_5( array(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( array(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( array(Array<Index,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( array_integer(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( array_integer(Array<Index,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_7( signed_shift_test(ArrayXXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_7( signed_shift_test(Array<Index, Dynamic, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));

  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( comparisons(Array<float, 1, 1>()) );
    CALL_SUBTEST_2( comparisons(Array22f()) );
    CALL_SUBTEST_3( comparisons(Array44d()) );
    CALL_SUBTEST_5( comparisons(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( comparisons(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( min_max(Array<float, 1, 1>()) );
    CALL_SUBTEST_2( min_max(Array22f()) );
    CALL_SUBTEST_3( min_max(Array44d()) );
    CALL_SUBTEST_5( min_max(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_6( min_max(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( array_real(Array<float, 1, 1>()) );
    CALL_SUBTEST_2( array_real(Array22f()) );
    CALL_SUBTEST_3( array_real(Array44d()) );
    CALL_SUBTEST_5( array_real(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_7( array_real(Array<Eigen::half, 32, 32>()) );
    CALL_SUBTEST_8( array_real(Array<Eigen::bfloat16, 32, 32>()) );
  }
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_4( array_complex(ArrayXXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_5( array_complex(ArrayXXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
  }

  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_6( int_pow_test() );
    CALL_SUBTEST_7( mixed_pow_test() );
    CALL_SUBTEST_8( signbit_tests() );
  }
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1( typed_logicals_test(ArrayX<bool>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_2( typed_logicals_test(ArrayX<int>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_2( typed_logicals_test(ArrayX<float>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))) );
    CALL_SUBTEST_3( typed_logicals_test(ArrayX<double>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_3( typed_logicals_test(ArrayX<std::complex<float>>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_3( typed_logicals_test(ArrayX<std::complex<double>>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }

  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<int>::type, int >::value));
  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<float>::type, float >::value));
  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<Array2i>::type, ArrayBase<Array2i> >::value));
  typedef CwiseUnaryOp<internal::scalar_abs_op<double>, ArrayXd > Xpr;
  VERIFY((internal::is_same< internal::global_math_functions_filtering_base<Xpr>::type,
                           ArrayBase<Xpr>
                         >::value));
}
