// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

#define EIGEN_RUNTIME_NO_MALLOC
#include "main.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include "fp_control.h"
#define EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW
#include "AnnoyingScalar.h"
#include "CustomComplex.h"

template <typename Scalar, int Options>
void approx_comparisons_floating() {
  using Real = typename NumTraits<Scalar>::Real;
  using MatrixType = Matrix<Scalar, Dynamic, Dynamic, Options>;
  const Real precision = Real(0.125);
  MatrixType x(3, 5), y(3, 5);
  for (const Real scale :
       {Real(1), NumTraits<Real>::highest() / Real(32), (numext::numeric_limits<Real>::min)() * Real(32)}) {
    x.setConstant(Scalar(scale));
    y = x * Real(2);
    internal::set_is_malloc_allowed(false);
    VERIFY(x.isApprox(x, precision));
    VERIFY(!x.isApprox(y, precision));
    VERIFY(!y.isApprox(x, precision));
    VERIFY(!x.array().isApprox(y.array(), precision));
    VERIFY(!x.transpose().isApprox(y.transpose(), precision));
    VERIFY(!x.isMuchSmallerThan(y, precision));
    VERIFY(x.isMuchSmallerThan(y, Real(0.5)));
    VERIFY(!x.isMuchSmallerThan(scale, precision));
    VERIFY(x.isMuchSmallerThan(Real(4) * scale, Real(1)));
    VERIFY(x.isApprox(y, Real(1)));
    VERIFY(x.isApprox(y, Real(-1)));
    VERIFY(x.isApprox(x, Real(0)));
    VERIFY(!x.isApprox(y, Real(0)));
    y = x * (Real(1) + precision / Real(2));
    VERIFY(x.isApprox(y, precision));
    VERIFY(x.array().isApprox(y.array(), precision));
    VERIFY((x.template block<2, 3>(0, 1).isApprox(y.template block<2, 3>(0, 1), precision)));
    internal::set_is_malloc_allowed(true);
    // The scaled path evaluates a lazy operand, which allocates for dynamic sizes.
    VERIFY(!x.isApprox(MatrixType::Zero(3, 5), precision));
    Matrix<Scalar, Dynamic, Dynamic, Options == ColMajor ? RowMajor : ColMajor> other = y;
    VERIFY(x.isApprox(other, precision));
  }

  // Norms and differences can exceed the scalar range even though every coefficient is finite.
  x.setConstant(Scalar(NumTraits<Real>::highest()));
  y = -x;
  VERIFY(x.isApprox(x, Real(0)));
  VERIFY(!x.isApprox(y, Real(1)));
  VERIFY(x.isApprox(y, Real(2)));
  VERIFY(!x.isMuchSmallerThan(x, precision));
  // The squared difference, but not the bound, can overflow the accumulator here.
  const Real root = numext::ldexp(Real(1), (NumTraits<Real>::max_exponent() - 1) / 2);
  x.setZero();
  x(0, 0) = Scalar(root);
  y = -x;
  VERIFY(!x.isApprox(y, Real(1.9)));
  VERIFY(x.isApprox(y, Real(2)));

  // Squaring either the difference or the tolerance would underflow.
  const Real tiny = (numext::numeric_limits<Real>::min)() * Real(16);
  x.setZero();
  y.setZero();
  x(0, 0) = y(0, 0) = Scalar(1);
  x(2, 4) = Scalar(tiny);
  VERIFY(!x.isApprox(y, Real(0)));
  VERIFY(!x.isApprox(y, tiny / Real(2)));
  VERIFY(x.isApprox(y, tiny * Real(2)));
  VERIFY(x.isApprox(y, NumTraits<Real>::highest()));
  x.setZero();
  VERIFY(x.isMuchSmallerThan(y, Real(0)));
  VERIFY(x.isMuchSmallerThan(Real(1), Real(0)));

  for (Index rows : {Index(0), Index(3)}) {
    x.resize(rows, 0);
    y.resize(rows, 0);
    VERIFY(x.isApprox(y));
    VERIFY(x.isMuchSmallerThan(y));
    VERIFY(x.isMuchSmallerThan(Real(0)));
  }
}

// The scaled path views plain objects, maps and their blocks in place, whatever their strides, and evaluates other
// operands, on the stack when their size is bounded.
template <typename Scalar>
void approx_comparisons_strided_operands() {
  using Real = typename NumTraits<Scalar>::Real;
  using ColMatrix = Matrix<Scalar, Dynamic, Dynamic, ColMajor>;
  using RowMatrix = Matrix<Scalar, Dynamic, Dynamic, RowMajor>;
  using StridedMap = Map<const ColMatrix, 0, Stride<Dynamic, Dynamic>>;
  const Real precision = Real(0.125);
  // Squares of these coefficients underflow, which selects the scaled path.
  const Real scale = (numext::numeric_limits<Real>::min)() * Real(32);
  const ColMatrix x = ColMatrix::Random(6, 8) * scale;
  const ColMatrix y = x * (Real(1) + precision / Real(2));
  const ColMatrix z = x * Real(2);
  const RowMatrix xr = x, yr = y, zr = z;
  const Stride<Dynamic, Dynamic> stride(12, 2);
  const ColMatrix ys = StridedMap(y.data(), 3, 4, stride);
  internal::set_is_malloc_allowed(false);
  VERIFY(xr.isApprox(y, precision));
  VERIFY(!xr.isApprox(z, precision));
  VERIFY(x.row(2).isApprox(yr.row(2), precision));
  VERIFY(!x.row(2).isApprox(zr.row(2), precision));
  VERIFY(xr.col(3).isApprox(y.col(3), precision));
  VERIFY(!xr.col(3).isApprox(z.col(3), precision));
  VERIFY(StridedMap(x.data(), 3, 4, stride).isApprox(ys, precision));
  VERIFY(!StridedMap(x.data(), 3, 4, stride).isApprox(StridedMap(z.data(), 3, 4, stride), precision));
  VERIFY((Real(2) * x.template topLeftCorner<3, 3>()).isApprox(Real(2) * y.template topLeftCorner<3, 3>(), precision));
  VERIFY(!(Real(2) * x.template topLeftCorner<3, 3>()).isApprox(x.template topLeftCorner<3, 3>(), precision));
  internal::set_is_malloc_allowed(true);
  // These have direct access, but their strides do not address every coefficient.
  VERIFY(x(2, seq(0, 7, 2)).isApprox(yr(2, seq(0, 7, 2)), precision));
  VERIFY(xr(seq(0, 5, 2), 3).isApprox(y(seq(0, 5, 2), 3), precision));
  VERIFY(x.row(2).realView().isApprox(yr.row(2).realView(), precision));
}

template <typename Real>
void approx_comparisons_rounding_boundary() {
  using Vector = Matrix<Real, 1, 1>;
  const Real eps = NumTraits<Real>::epsilon();
  // One nonzero component and power-of-two scales make the relative difference exactly 8*eps.
  for (int exponent : {0, NumTraits<Real>::min_exponent() + 4, NumTraits<Real>::max_exponent() - 8}) {
    const Real scale = numext::ldexp(Real(1), exponent);
    const Vector x = Vector::Constant(scale);
    const Vector y = Vector::Constant(scale * (Real(1) + Real(8) * eps));
    VERIFY(!x.isApprox(y, Real(7) * eps));
    VERIFY(x.isApprox(y, Real(8) * eps));
    VERIFY(x.isApprox(y, Real(9) * eps));
  }
}

template <typename Real>
void approx_comparisons_flush_to_zero() {
  ScopedFlushToZero flushToZero;
  using Vector = Matrix<Real, 2, 1>;
  // The difference of these normal operands is subnormal.
  const Real normalMin = (numext::numeric_limits<Real>::min)();
  const Vector x(Real(1.5) * normalMin, Real(0)), y(normalMin, Real(0));
  VERIFY(!x.isApprox(y, Real(0.25)));
  VERIFY(!x.isApprox(y, Real(0)));
  VERIFY(x.isApprox(y, Real(0.5)));
  VERIFY_IS_EQUAL(test_relative_error(x, y), Real(0.5));
  approx_comparisons_rounding_boundary<Real>();
}

// The squared differences, 2^-118 and just below 2^-126, accumulate in float, where FTZ flushes the second.
template <typename = void>
void approx_comparisons_flush_to_zero_bfloat16() {
  ScopedFlushToZero flushToZero;
  using Vector = Matrix<bfloat16, 2, 1>;
  // Opaque, so the compiler cannot square it with IEEE subnormals at compile time.
  volatile float tail = numext::ldexp(1.9921875f, -64);
  const Vector x(bfloat16(numext::ldexp(1.0f, -52)), bfloat16(0.0f));
  const Vector y(bfloat16(numext::ldexp(1.0f + 1.0f / 128, -52)), bfloat16(float(tail)));
  VERIFY(!x.isApprox(y, bfloat16(1.0f / 128)));
}

template <typename Real>
void approx_comparisons_special_values() {
  using Vector = Matrix<Real, 2, 1>;
  const Real inf = NumTraits<Real>::infinity();
  const Real nan = NumTraits<Real>::quiet_NaN();
  Vector x = Vector::Ones(), y = Vector::Ones();
  for (Index i = 0; i < 2; ++i) {
    y = x;
    y(i) = nan;
    VERIFY(!x.isApprox(y));
    VERIFY(!y.isApprox(x));
    VERIFY(!y.isApprox(y));
    VERIFY(!x.isMuchSmallerThan(y));
    VERIFY(!y.isMuchSmallerThan(x));
    y(i) = inf;
    VERIFY(!x.isApprox(y));
    VERIFY(!y.isApprox(y));
    VERIFY(!y.isMuchSmallerThan(y));
    VERIFY(x.isMuchSmallerThan(y));
  }
  VERIFY(!x.isApprox(x, nan));
  VERIFY(!x.isMuchSmallerThan(x, nan));
  VERIFY(!x.isMuchSmallerThan(nan));
  VERIFY(!x.isMuchSmallerThan(inf, Real(0)));

  if (subnormalDivisionIsExact<Real>()) {
    const Real tiny = (numext::numeric_limits<Real>::denorm_min)();
    x.setConstant(tiny);
    y = Real(2) * x;
    VERIFY(!x.isApprox(y));
    VERIFY(x.isApprox(x, Real(0)));
    VERIFY(!x.isApprox(Vector::Zero()));
    VERIFY(!x.isMuchSmallerThan(y));
    VERIFY(!x.isMuchSmallerThan(tiny));
  }
}

template <typename Scalar>
void approx_comparisons_exact() {
  using MatrixType = Matrix<Scalar, 2, 2>;
  const MatrixType zero = MatrixType::Zero();
  const MatrixType one = MatrixType::Ones();
  VERIFY(zero.isApprox(zero));
  VERIFY(one.isApprox(one));
  VERIFY(!zero.isApprox(one));
  VERIFY(!one.isApprox(zero));
  VERIFY(zero.isMuchSmallerThan(one));
  VERIFY(zero.isMuchSmallerThan(Scalar(0)));
  VERIFY(!one.isMuchSmallerThan(one));
  VERIFY(!one.isMuchSmallerThan(Scalar(1)));
}

template <typename = void>
void approx_comparisons_expressions() {
  Matrix2d x;
  x << 1, 2, 3, 4;
  VERIFY((x * x).isApprox((x * x).eval()));
  VERIFY((x + x).isApprox(2 * x));
  VERIFY((x * x * 0).isMuchSmallerThan(x * x));
  VERIFY((x * x * 0).isMuchSmallerThan(1.0));
  VERIFY(!Matrix2f::Ones().isMuchSmallerThan(Matrix2d::Constant(1e200), 0.0f));
  VERIFY(Matrix2f::Ones().isMuchSmallerThan(Matrix2d::Constant(1e200)));
  VERIFY(!Matrix2d::Ones().isMuchSmallerThan(Matrix2f::Constant(1e-30f)));
  VERIFY(Matrix2d::Constant(1e-300).isMuchSmallerThan(Matrix2f::Constant(1e10f), 1e-300));
  VERIFY(!Matrix2f::Constant(1e-23f).isMuchSmallerThan(Matrix2d::Constant(1e-20), 1e-5f));
  VERIFY(Matrix2f::Constant(1e20f).isMuchSmallerThan(Matrix2d::Constant(1e30), 1e-5f));
  const Matrix2d tiny = Matrix2d::Constant(1e-200);
  const Matrix2cd complexTiny = tiny.cast<std::complex<double>>();
  VERIFY(tiny.isApprox(complexTiny));
  VERIFY(complexTiny.isApprox(tiny));
  STATIC_CHECK(!internal::use_scaled_comparison<AnnoyingScalar>::value);
  approx_comparisons_exact<AnnoyingScalar>();
  const Matrix<AnnoyingScalar, 2, 2> custom = Matrix<AnnoyingScalar, 2, 2>::Ones();
  VERIFY(test_isCwiseApprox(custom, custom, false));
  VERIFY(test_relative_error(custom, custom) == AnnoyingScalar(0));
  // A custom complex scalar over a built-in real has no dedicated coefficient overload.
  using CustomComplexScalar = CustomComplex<double>;
  STATIC_CHECK(!internal::use_scaled_comparison<CustomComplexScalar>::value);
  const Matrix<CustomComplexScalar, 2, 2> customComplex =
      Matrix<CustomComplexScalar, 2, 2>::Constant(CustomComplexScalar(1, 2));
  VERIFY(test_isCwiseApprox(customComplex, customComplex, true));
  VERIFY(test_isCwiseApprox(customComplex, customComplex, false));
  VERIFY(!test_isCwiseApprox(customComplex, (customComplex * CustomComplexScalar(2)).eval(), false));
  VERIFY_IS_EQUAL(test_relative_error(customComplex, customComplex), 0.0);
}

template <typename Real>
void approx_comparisons_complex_components() {
  using Complex = std::complex<Real>;
  using Vector = Matrix<Complex, 2, 1>;
  const Real big = NumTraits<Real>::highest();
  const Vector x = Vector::Constant(Complex(big, big));
  const Vector y = -x;
  VERIFY(x.isApprox(x, Real(0)));
  VERIFY(!x.isApprox(y, Real(1)));
  VERIFY(x.isApprox(y, Real(2)));
  VERIFY(!x.isMuchSmallerThan(y, Real(0.5)));
  VERIFY(!x.isMuchSmallerThan(big, Real(1)));
}

// nested_eval keeps these cheap expressions lazy, so they reach the scaled path without direct access.
template <typename Real>
void approx_comparisons_lazy_operands() {
  using Complex = std::complex<Real>;
  using Vector3 = Matrix<Real, 3, 1>;
  using Vector4 = Matrix<Real, 4, 1>;
  using Array4 = Array<Real, 4, 1>;
  const Real precision = Real(0.125);
  const Array4 base = Array4::LinSpaced(Real(1), Real(2));
  for (int exponent : {0, NumTraits<Real>::min_exponent() + 4, NumTraits<Real>::max_exponent() - 8}) {
    const Real scale = numext::ldexp(Real(1), exponent);
    const Vector3 x = Vector3::Constant(scale);
    Vector4 y;
    y << x, Real(1);
    VERIFY(x.homogeneous().isApprox(y, precision));
    VERIFY(y.isApprox(x.homogeneous(), precision));
    VERIFY_IS_EQUAL(test_relative_error(x.homogeneous(), y), Real(0));
    VERIFY(!x.homogeneous().isMuchSmallerThan(y, precision));
    y *= Real(2);
    VERIFY(!x.homogeneous().isApprox(y, precision));
    VERIFY(!y.isApprox(x.homogeneous(), precision));
    VERIFY(test_relative_error(x.homogeneous(), y) > precision);

    const Array4 a = base * scale;
    VERIFY((a + a).isApprox(a * Real(2), precision));
    VERIFY(!(a + a).isApprox(a, precision));
    VERIFY_IS_EQUAL(test_relative_error(a + a, a * Real(2)), Real(0));
  }
  // A unary functor whose result is complex but whose argument is real.
  const Complex power(Real(2), Real(1));
  VERIFY(base.pow(power).isApprox(base.template cast<Complex>().pow(power), precision));
  VERIFY(test_relative_error(base.pow(power), base.template cast<Complex>().pow(power)) <= precision);
}

template <typename Real>
void approx_comparisons_scale_invariance() {
  using Vector = Matrix<Real, 17, 1>;
  const Real precision = Real(0.125);
  const long double precision2 = static_cast<long double>(precision) * static_cast<long double>(precision);
  for (int repeat = 0; repeat < g_repeat; ++repeat) {
    const Vector a = Vector::Random();
    for (int close = 0; close < 2; ++close) {
      Vector b = Vector::Random();
      if (close) b = a + precision * Real(0.25) * b;
      long double difference = 0, a2 = 0, b2 = 0;
      for (Index i = 0; i < a.size(); ++i) {
        const long double av = static_cast<long double>(a(i));
        const long double bv = static_cast<long double>(b(i));
        difference += (av - bv) * (av - bv);
        a2 += av * av;
        b2 += bv * bv;
      }
      const bool expected = difference <= precision2 * (std::min)(a2, b2);
      for (int exponent : {0, NumTraits<Real>::min_exponent() + 4, NumTraits<Real>::max_exponent() - 8}) {
        const Real scale = numext::ldexp(Real(1), exponent);
        const Vector x = a * scale, y = b * scale;
        VERIFY_IS_EQUAL(x.isApprox(y, precision), expected);
      }
    }
  }
}

EIGEN_DECLARE_TEST(approx_comparisons) {
  CALL_SUBTEST_1((approx_comparisons_floating<float, ColMajor>()));
  CALL_SUBTEST_1((approx_comparisons_floating<double, RowMajor>()));
  CALL_SUBTEST_1(approx_comparisons_strided_operands<float>());
  CALL_SUBTEST_1(approx_comparisons_strided_operands<double>());
  CALL_SUBTEST_1(approx_comparisons_special_values<float>());
  CALL_SUBTEST_1(approx_comparisons_special_values<double>());
  CALL_SUBTEST_1(approx_comparisons_rounding_boundary<float>());
  CALL_SUBTEST_1(approx_comparisons_rounding_boundary<double>());
  CALL_SUBTEST_1(approx_comparisons_scale_invariance<float>());
  CALL_SUBTEST_1(approx_comparisons_scale_invariance<double>());
  CALL_SUBTEST_1(approx_comparisons_flush_to_zero<float>());
  CALL_SUBTEST_1(approx_comparisons_flush_to_zero<double>());
  CALL_SUBTEST_2((approx_comparisons_floating<std::complex<float>, RowMajor>()));
  CALL_SUBTEST_2((approx_comparisons_floating<std::complex<double>, ColMajor>()));
  CALL_SUBTEST_2(approx_comparisons_strided_operands<std::complex<float>>());
  CALL_SUBTEST_2(approx_comparisons_complex_components<float>());
  CALL_SUBTEST_2(approx_comparisons_complex_components<double>());
  CALL_SUBTEST_2(approx_comparisons_lazy_operands<float>());
  CALL_SUBTEST_2(approx_comparisons_lazy_operands<double>());
  CALL_SUBTEST_3((approx_comparisons_floating<half, ColMajor>()));
  CALL_SUBTEST_3((approx_comparisons_floating<bfloat16, RowMajor>()));
  CALL_SUBTEST_3((approx_comparisons_floating<long double, ColMajor>()));
  CALL_SUBTEST_3(approx_comparisons_rounding_boundary<half>());
  CALL_SUBTEST_3(approx_comparisons_rounding_boundary<bfloat16>());
  CALL_SUBTEST_3(approx_comparisons_flush_to_zero<bfloat16>());
  CALL_SUBTEST_3(approx_comparisons_flush_to_zero_bfloat16<>());
  CALL_SUBTEST_4(approx_comparisons_exact<int>());
  CALL_SUBTEST_4(approx_comparisons_exact<unsigned int>());
  CALL_SUBTEST_4(approx_comparisons_exact<bool>());
  CALL_SUBTEST_4(approx_comparisons_expressions<>());
}
