// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 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/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_APPROX_COMPARISONS_H
#define EIGEN_APPROX_COMPARISONS_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {

// Keep custom scalars on the algebraic path: exponent scaling requires binary floating-point arithmetic.
template <typename Scalar>
struct use_scaled_comparison
    : bool_constant<(std::is_floating_point<Scalar>::value && std::numeric_limits<Scalar>::radix == 2) ||
                    std::is_same<Scalar, half>::value || std::is_same<Scalar, bfloat16>::value> {};

template <typename RealScalar>
struct use_scaled_comparison<std::complex<RealScalar>> : use_scaled_comparison<RealScalar> {};

// A nonnegative magnitude fraction * 2^exponent, including norms larger than the scalar range. Positive finite
// magnitudes order lexicographically by (exponent, fraction), the member order.
template <typename RealScalar>
struct comparison_magnitude {
  int exponent = 0;
  RealScalar fraction;

  EIGEN_DEVICE_FUNC explicit comparison_magnitude(const RealScalar& value) : fraction(value) {
    if (value > RealScalar(0) && value <= NumTraits<RealScalar>::highest()) {
      EIGEN_USING_STD(frexp);
      fraction = frexp(value, &exponent);
    }
  }

  template <typename OtherRealScalar>
  EIGEN_DEVICE_FUNC explicit comparison_magnitude(const comparison_magnitude<OtherRealScalar>& value)
      : exponent(value.exponent), fraction(RealScalar(value.fraction)) {}

  EIGEN_DEVICE_FUNC void multiply(const RealScalar& value) { multiply(comparison_magnitude(value)); }

  EIGEN_DEVICE_FUNC void multiply(const comparison_magnitude& factor) {
    const comparison_magnitude product(fraction * factor.fraction);
    fraction = product.fraction;
    exponent += factor.exponent + product.exponent;
  }

  EIGEN_DEVICE_FUNC bool isFinite() const { return fraction <= RealScalar(1); }
};

template <typename RealScalar>
EIGEN_DEVICE_FUNC bool operator<=(const comparison_magnitude<RealScalar>& x,
                                  const comparison_magnitude<RealScalar>& y) {
  if (!x.isFinite()) return false;
  // Zero and non-finite magnitudes carry no exponent.
  if (!y.isFinite() || x.fraction == RealScalar(0) || y.fraction == RealScalar(0)) return x.fraction <= y.fraction;
  return x.exponent < y.exponent || (x.exponent == y.exponent && x.fraction <= y.fraction);
}

template <typename RealScalar, typename OtherRealScalar>
EIGEN_DEVICE_FUNC bool operator<=(const comparison_magnitude<RealScalar>& x,
                                  const comparison_magnitude<OtherRealScalar>& y) {
  using Common = std::common_type_t<RealScalar, OtherRealScalar>;
  return comparison_magnitude<Common>(x) <= comparison_magnitude<Common>(y);
}

// Types whose data(), rowStride() and colStride() address every coefficient. DirectAccessBit alone does not promise
// this: a single-row IndexedView of a column-major matrix and the RealView of a strided complex block report strides
// that do not.
template <typename X>
struct scaled_comparison_viewable : std::false_type {};

template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
struct scaled_comparison_viewable<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> : std::true_type {};

template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
struct scaled_comparison_viewable<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> : std::true_type {};

template <typename PlainObjectType, int Options, typename StrideType>
struct scaled_comparison_viewable<Map<PlainObjectType, Options, StrideType>> : std::true_type {};

template <typename PlainObjectType, int Options, typename StrideType>
struct scaled_comparison_viewable<Ref<PlainObjectType, Options, StrideType>> : std::true_type {};

template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
struct scaled_comparison_viewable<Block<XprType, BlockRows, BlockCols, InnerPanel>>
    : scaled_comparison_viewable<std::remove_const_t<XprType>> {};

template <typename XprType>
struct scaled_comparison_viewable<Transpose<XprType>> : scaled_comparison_viewable<std::remove_const_t<XprType>> {};

template <typename XprType>
struct scaled_comparison_viewable<ArrayWrapper<XprType>> : scaled_comparison_viewable<std::remove_const_t<XprType>> {};

template <typename XprType>
struct scaled_comparison_viewable<MatrixWrapper<XprType>> : scaled_comparison_viewable<std::remove_const_t<XprType>> {};

// The scaled path reduces each operand several times, so it runs on at most three view types per scalar type rather
// than being instantiated for every operand expression. A viewable operand with direct access is viewed in place,
// keeping packet access when its inner stride is one; any other operand, including a lazy expression or a shape that
// hides operator*(Scalar) as Homogeneous does, is evaluated first, which allocates only for dynamic sizes and for
// fixed sizes above EIGEN_STACK_ALLOCATION_LIMIT.
template <typename X, bool DirectAccess = has_direct_access<X>::value && scaled_comparison_viewable<X>::value,
          bool UnitInnerStride = inner_stride_at_compile_time<X>::value == 1>
struct scaled_comparison_operand {
  using View =
      Map<const Matrix<typename X::Scalar, Dynamic, Dynamic, X::IsRowMajor ? RowMajor : ColMajor>, 0, OuterStride<>>;
  EIGEN_DEVICE_FUNC explicit scaled_comparison_operand(const X& x)
      : view(x.data(), x.rows(), x.cols(), OuterStride<>(x.outerStride())) {}
  View view;
};

template <typename X>
struct scaled_comparison_operand<X, true, false> {
  using View = Map<const Matrix<typename X::Scalar, Dynamic, Dynamic>, 0, Stride<Dynamic, Dynamic>>;
  EIGEN_DEVICE_FUNC explicit scaled_comparison_operand(const X& x)
      : view(x.data(), x.rows(), x.cols(), Stride<Dynamic, Dynamic>(x.colStride(), x.rowStride())) {}
  View view;
};

template <typename X, bool UnitInnerStride>
struct scaled_comparison_operand<X, false, UnitInnerStride> {
  // A fixed capacity the stack limit would reject makes the comparison fail to compile for an operand the caller
  // never stores, so the temporary takes it only where DenseStorage accepts it.
  static constexpr bool FixedCapacity =
      EIGEN_STACK_ALLOCATION_LIMIT == 0 ||
      (X::MaxSizeAtCompileTime != Dynamic &&
       std::ptrdiff_t(X::MaxSizeAtCompileTime) * std::ptrdiff_t(sizeof(typename X::Scalar)) <=
           std::ptrdiff_t(EIGEN_STACK_ALLOCATION_LIMIT));
  // Column-major unless it holds at most one row, where Matrix requires row-major storage.
  using Plain =
      Matrix<typename X::Scalar, Dynamic, Dynamic,
             X::MaxRowsAtCompileTime == 1 && X::MaxColsAtCompileTime != 1 ? RowMajor : ColMajor,
             FixedCapacity ? X::MaxRowsAtCompileTime : Dynamic, FixedCapacity ? X::MaxColsAtCompileTime : Dynamic>;
  using View = typename scaled_comparison_operand<Plain>::View;
  EIGEN_DEVICE_FUNC explicit scaled_comparison_operand(const X& x)
      : value(x.matrix()), view(scaled_comparison_operand<Plain>(value).view) {}
  Plain value;
  View view;
};

template <typename Components>
EIGEN_DEVICE_FUNC typename Components::Scalar scaled_comparison_max_coeff(const Components& components) {
  using RealScalar = typename Components::Scalar;
  if (components.size() == 0) return RealScalar(0);
  return safe_scaling<RealScalar>::recover_flushed_max_coeff(components,
                                                             components.cwiseAbs().template maxCoeff<PropagateNaN>());
}

template <typename Derived>
EIGEN_DEVICE_FUNC comparison_magnitude<typename stable_norm_accumulator<typename Derived::RealScalar>::type>
scaled_comparison_norm_impl(const MatrixBase<Derived>& matrix) {
  using RealScalar = typename stable_norm_accumulator<typename Derived::RealScalar>::type;
  const auto& realComponents = matrix.realView();
  const auto& components = realComponents.template cast<RealScalar>();
  const RealScalar scale = scaled_comparison_max_coeff(components);
  // Classify first so NaNs do not reach the ordered comparison.
  if (!(numext::isfinite)(scale) || !(scale > RealScalar(0))) return comparison_magnitude<RealScalar>(scale);
  RealScalar squaredNorm = RealScalar(0);
  const auto factors = safe_scaling<RealScalar>::with_scaled(
      components, scale, [&](const auto& scaled) { squaredNorm = scaled.squaredNorm(); });
  comparison_magnitude<RealScalar> result(numext::sqrt(squaredNorm));
  result.multiply(factors.scale);
  return result;
}

template <typename X, typename Y>
EIGEN_DEVICE_FUNC comparison_magnitude<typename stable_norm_accumulator<typename X::RealScalar>::type>
scaled_comparison_distance_impl(const MatrixBase<X>& matrixX, const MatrixBase<Y>& matrixY) {
  using Accumulator = typename stable_norm_accumulator<typename X::RealScalar>::type;
  using WideScalar =
      std::conditional_t<NumTraits<typename X::Scalar>::IsComplex || NumTraits<typename Y::Scalar>::IsComplex,
                         std::complex<Accumulator>, Accumulator>;
  const auto& wideX = matrixX.template cast<WideScalar>();
  const auto& wideY = matrixY.template cast<WideScalar>();
  // FTZ flushes a subnormal difference of normal operands. Scaling a maximum M < 1 up by a power of two first loses
  // only differences below M * min; scaling larger operands down could underflow their small components.
  const Accumulator maxCoeff = numext::mini(
      Accumulator(1),
      numext::maxi(scaled_comparison_max_coeff(wideX.realView()), scaled_comparison_max_coeff(wideY.realView())));
  const safe_scaling_factors<Accumulator> factors = supports_power_of_two_scaling<Accumulator>::value
                                                        ? safe_scaling<Accumulator>::compute_floor_factors(maxCoeff)
                                                        : safe_scaling_factors<Accumulator>();
  // Both calls share one expression type, so scaled_comparison_norm_impl is instantiated once.
  auto difference = scaled_comparison_norm_impl(wideX * factors.invScale - wideY * factors.invScale);
  if (!difference.isFinite()) {
    // Finite operands can overflow on subtraction; halving first keeps every component representable.
    const Accumulator halfInvScale = factors.invScale * Accumulator(0.5);
    difference = scaled_comparison_norm_impl(wideX * halfInvScale - wideY * halfInvScale);
    difference.multiply(Accumulator(2));
  }
  difference.multiply(factors.scale);
  return difference;
}

template <typename Derived>
EIGEN_DEVICE_FUNC comparison_magnitude<typename stable_norm_accumulator<typename Derived::RealScalar>::type>
scaled_comparison_norm(const Derived& x) {
  return scaled_comparison_norm_impl(scaled_comparison_operand<Derived>(x).view);
}

template <typename X, typename Y>
EIGEN_DEVICE_FUNC comparison_magnitude<typename stable_norm_accumulator<typename X::RealScalar>::type>
scaled_comparison_distance(const X& x, const Y& y) {
  return scaled_comparison_distance_impl(scaled_comparison_operand<X>(x).view, scaled_comparison_operand<Y>(y).view);
}

// Coefficients widened to the stable-norm accumulator, in which ordinary comparisons square and sum. The cast is the
// identity for float and double; half and bfloat16 widen exactly to float, where no half square underflows.
template <typename X>
using approx_comparison_wide_t =
    std::conditional_t<NumTraits<typename X::Scalar>::IsComplex,
                       std::complex<typename stable_norm_accumulator<typename X::RealScalar>::type>,
                       typename stable_norm_accumulator<typename X::RealScalar>::type>;

template <typename Scalar, bool = use_scaled_comparison<Scalar>::value>
struct approx_comparison_impl {
  using RealScalar = typename NumTraits<Scalar>::Real;

  template <typename X, typename Y>
  EIGEN_DEVICE_FUNC static bool isApprox(const X& x, const Y& y, const RealScalar& prec) {
    return (x.matrix() - y.matrix()).cwiseAbs2().sum() <=
           prec * prec * numext::mini(x.cwiseAbs2().sum(), y.cwiseAbs2().sum());
  }

  template <typename X, typename Y>
  EIGEN_DEVICE_FUNC static bool isMuchSmallerThan(const X& x, const Y& y, const RealScalar& prec) {
    return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum();
  }

  template <typename X>
  EIGEN_DEVICE_FUNC static bool isMuchSmallerThan(const X& x, const RealScalar& y, const RealScalar& prec) {
    return x.cwiseAbs2().sum() <= numext::abs2(prec * y);
  }
};

template <typename Scalar>
struct approx_comparison_impl<Scalar, true> {
  using RealScalar = typename NumTraits<Scalar>::Real;
  using Accumulator = typename stable_norm_accumulator<RealScalar>::type;
  template <typename Y>
  using CommonAccumulator =
      std::common_type_t<Accumulator, typename stable_norm_accumulator<typename Y::RealScalar>::type>;

  template <typename ValueScalar>
  EIGEN_DEVICE_FUNC static typename stable_norm_accumulator<ValueScalar>::type squared_norm_lower_bound(Index size) {
    using ValueAccumulator = typename stable_norm_accumulator<ValueScalar>::type;
    // Squares accumulate in ValueAccumulator; below n * min / epsilon, flushed squares can affect the comparison.
    return stable_normalization_normal_min<ValueAccumulator, ValueAccumulator>::run() /
           NumTraits<ValueAccumulator>::epsilon() * ValueAccumulator(size);
  }

  template <typename BoundScalar>
  EIGEN_DEVICE_FUNC static bool safe_squared_norm(const BoundScalar& value, Index size) {
    using Common = std::common_type_t<Accumulator, BoundScalar>;
    return Common(value) >= Common(squared_norm_lower_bound<RealScalar>(size)) &&
           Common(value) <= Common(NumTraits<Accumulator>::highest());
  }

  template <typename X, typename Y>
  EIGEN_DEVICE_FUNC static bool isApprox(const X& x, const Y& y, const RealScalar& prec) {
    // Widening must not admit operands that cannot be subtracted, such as half and float.
    EIGEN_CHECK_BINARY_COMPATIBILITY(scalar_difference_op<typename X::Scalar EIGEN_COMMA typename Y::Scalar>,
                                     typename X::Scalar, typename Y::Scalar)
    const auto& wideX = x.template cast<approx_comparison_wide_t<X>>();
    const auto& wideY = y.template cast<approx_comparison_wide_t<Y>>();
    const Accumulator x2 = wideX.cwiseAbs2().sum();
    const Accumulator y2 = wideY.cwiseAbs2().sum();
    const Accumulator minimum = numext::mini(x2, y2);
    const Accumulator precision2 = Accumulator(prec) * Accumulator(prec);
    const Accumulator bound = precision2 * minimum;
    // Only the smaller norm enters the bound; overflow of the larger norm is harmless.
    if (safe_squared_norm(bound, x.size()) && minimum >= squared_norm_lower_bound<RealScalar>(x.size()) &&
        precision2 >= squared_norm_lower_bound<RealScalar>(1))
      return (wideX.matrix() - wideY.matrix()).cwiseAbs2().sum() <= bound;

    return isApprox_scaled(x, y, prec);
  }

  template <typename X, typename Y>
  EIGEN_DEVICE_FUNC static bool isMuchSmallerThan(const X& x, const Y& y, const RealScalar& prec) {
    using Common = CommonAccumulator<Y>;
    typename nested_eval<X, 2>::type nested(x);
    typename nested_eval<Y, 2>::type otherNested(y);
    const Accumulator x2 = nested.template cast<approx_comparison_wide_t<X>>().cwiseAbs2().sum();
    const auto y2 = otherNested.template cast<approx_comparison_wide_t<Y>>().cwiseAbs2().sum();
    const Accumulator precision2 = numext::abs2(Accumulator(prec));
    const Common bound = Common(precision2) * Common(y2);
    // A finite bound above the flushing error makes overflow/underflow of x2 harmless.
    if (safe_squared_norm(bound, x.size()) &&
        Common(y2) >= Common(squared_norm_lower_bound<typename Y::RealScalar>(y.size())) &&
        precision2 >= squared_norm_lower_bound<RealScalar>(1))
      return Common(x2) <= bound;
    return isMuchSmallerThan_scaled(nested, otherNested, prec);
  }

  template <typename X>
  EIGEN_DEVICE_FUNC static bool isMuchSmallerThan(const X& x, const RealScalar& y, const RealScalar& prec) {
    typename nested_eval<X, 2>::type nested(x);
    const Accumulator x2 = nested.template cast<approx_comparison_wide_t<X>>().cwiseAbs2().sum();
    const Accumulator bound = numext::abs2(Accumulator(prec) * Accumulator(y));
    if (safe_squared_norm(bound, x.size())) return x2 <= bound;
    return isMuchSmallerThan_scaled(nested, y, prec);
  }

 private:
  // Keep exponent scaling from inhibiting inlining of ordinary comparisons.
  template <typename X, typename Y>
  EIGEN_DEVICE_FUNC static EIGEN_DONT_INLINE bool isApprox_scaled(const X& xExpr, const Y& yExpr,
                                                                  const RealScalar& prec) {
    const scaled_comparison_operand<X> x(xExpr);
    const scaled_comparison_operand<Y> y(yExpr);
    const auto nx = scaled_comparison_norm_impl(x.view);
    const auto ny = scaled_comparison_norm_impl(y.view);
    if (!nx.isFinite() || !ny.isFinite()) return false;
    auto tolerance = nx <= ny ? nx : ny;
    tolerance.multiply(numext::abs(Accumulator(prec)));
    return scaled_comparison_distance_impl(x.view, y.view) <= tolerance;
  }

  template <typename X, typename Y>
  EIGEN_DEVICE_FUNC static EIGEN_DONT_INLINE bool isMuchSmallerThan_scaled(const X& x, const Y& y,
                                                                           const RealScalar& prec) {
    using Common = CommonAccumulator<Y>;
    comparison_magnitude<Common> tolerance(scaled_comparison_norm(y));
    tolerance.multiply(numext::abs(Common(prec)));
    return scaled_comparison_norm(x) <= tolerance;
  }

  template <typename X>
  EIGEN_DEVICE_FUNC static EIGEN_DONT_INLINE bool isMuchSmallerThan_scaled(const X& x, const RealScalar& y,
                                                                           const RealScalar& prec) {
    comparison_magnitude<Accumulator> tolerance(numext::abs(Accumulator(y)));
    tolerance.multiply(numext::abs(Accumulator(prec)));
    return scaled_comparison_norm(x) <= tolerance;
  }
};

// Exponent scaling needs binary floating-point on both sides.
template <typename Derived, typename OtherDerived>
using approx_comparison_impl_t =
    approx_comparison_impl<typename Derived::Scalar, use_scaled_comparison<typename Derived::Scalar>::value &&
                                                         use_scaled_comparison<typename OtherDerived::Scalar>::value>;

template <typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
struct isApprox_selector {
  EIGEN_DEVICE_FUNC static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) {
    typename internal::nested_eval<Derived, 2>::type nested(x);
    typename internal::nested_eval<OtherDerived, 2>::type otherNested(y);
    return approx_comparison_impl_t<Derived, OtherDerived>::isApprox(nested, otherNested, prec);
  }
};

template <typename Derived, typename OtherDerived>
struct isApprox_selector<Derived, OtherDerived, true> {
  EIGEN_DEVICE_FUNC static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar&) {
    return x.matrix() == y.matrix();
  }
};

template <typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
struct isMuchSmallerThan_object_selector {
  EIGEN_DEVICE_FUNC static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) {
    return approx_comparison_impl_t<Derived, OtherDerived>::isMuchSmallerThan(x, y, prec);
  }
};

template <typename Derived, typename OtherDerived>
struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true> {
  EIGEN_DEVICE_FUNC static bool run(const Derived& x, const OtherDerived&, const typename Derived::RealScalar&) {
    return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
  }
};

template <typename Derived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
struct isMuchSmallerThan_scalar_selector {
  EIGEN_DEVICE_FUNC static bool run(const Derived& x, const typename Derived::RealScalar& y,
                                    const typename Derived::RealScalar& prec) {
    return approx_comparison_impl<typename Derived::Scalar>::isMuchSmallerThan(x, y, prec);
  }
};

template <typename Derived>
struct isMuchSmallerThan_scalar_selector<Derived, true>
    : isMuchSmallerThan_object_selector<Derived, typename Derived::RealScalar, true> {};

// a b = fraction 2^exponent, with the frexp significands of a and b multiplied in [1/4, 1): a b rounded as if the
// exponent range were unbounded. Zero if a or b is.
template <typename RealScalar>
struct unbounded_product {
  EIGEN_DEVICE_FUNC unbounded_product(const RealScalar& a, const RealScalar& b) {
    int exponentA = 0, exponentB = 0;
    const RealScalar fractionA = frexp_preserving_subnormals(a, exponentA);
    const RealScalar fractionB = frexp_preserving_subnormals(b, exponentB);
    fraction = fractionA * fractionB;
    exponent = exponentA + exponentB;
  }

  // a b 2^-maxExponent, exact unless it falls below the normal range.
  EIGEN_DEVICE_FUNC RealScalar scaled(int maxExponent) const {
    return ldexp_preserving_subnormals(fraction, exponent - maxExponent);
  }

  RealScalar fraction;
  int exponent;
};

// |<v, w>| <= prec |v| |w|. The squared form, |<v, w>|^2 <= prec^2 |v|^2 |w|^2, is homogeneous of degree four, so for
// |v_i| above ~4e9 or below ~1e-11 in float both sides overflow to inf <= inf or underflow to 0 <= 0. Scalars that
// isApprox() does not scale, integers, custom complex and exact custom types included, keep it: it needs no sqrt.
template <typename Derived, typename OtherDerived,
          bool Scaled = use_scaled_comparison<typename Derived::Scalar>::value &&
                        use_scaled_comparison<typename OtherDerived::Scalar>::value>
struct is_orthogonal_impl {
  template <typename RealScalar>
  static bool run(const Derived& v, const OtherDerived& w, const RealScalar& prec) {
    typename nested_eval<Derived, 2>::type nested(v);
    typename nested_eval<OtherDerived, 2>::type otherNested(w);
    return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
  }
};

// Unsquared from the coefficients while |v|^2, |w|^2 and |<v, w>| are in range; otherwise with every product of
// components rounded at its own exponent, so that neither an exact cancellation nor a nonzero product outside the
// exponent range is lost.
template <typename Derived, typename OtherDerived>
struct is_orthogonal_impl<Derived, OtherDerived, true> {
  // half and bfloat16 are compared in float, which holds them exactly.
  using Accumulator = std::common_type_t<
      typename stable_norm_accumulator<typename NumTraits<typename Derived::Scalar>::Real>::type,
      typename stable_norm_accumulator<typename NumTraits<typename OtherDerived::Scalar>::Real>::type>;
  template <typename Xpr>
  using Wide = std::conditional_t<NumTraits<typename Xpr::Scalar>::IsComplex, std::complex<Accumulator>, Accumulator>;

  template <typename RealScalar>
  static bool run(const Derived& v, const OtherDerived& w, const RealScalar& prec) {
    // Widening must not admit operands that dot() rejects, such as float and double.
    EIGEN_CHECK_BINARY_COMPATIBILITY(
        scalar_conj_product_op<typename Derived::Scalar EIGEN_COMMA typename OtherDerived::Scalar>,
        typename Derived::Scalar, typename OtherDerived::Scalar)
    typename nested_eval<Derived, 2>::type nested(v);
    typename nested_eval<OtherDerived, 2>::type otherNested(w);
    const auto& wideV = nested.template cast<Wide<Derived>>();
    const auto& wideW = otherNested.template cast<Wide<OtherDerived>>();
    const Accumulator v2 = wideV.squaredNorm();
    const Accumulator w2 = wideW.squaredNorm();
    // Each flushed product, square or partial sum moves |v|^2, |w|^2 or <v, w> by less than min, and a complex
    // coefficient takes up to four per component: less than 8n min in all, at most epsilon x for any x >= lower.
    const Accumulator lower = Accumulator(8) * Accumulator(v.size()) *
                              stable_normalization_normal_min<Accumulator, Accumulator>::run() /
                              NumTraits<Accumulator>::epsilon();
    const Accumulator highest = NumTraits<Accumulator>::highest();
    if (v2 >= lower && v2 <= highest && w2 >= lower && w2 <= highest) {
      const Accumulator absDot = numext::abs(wideV.dot(wideW));
      const Accumulator bound = Accumulator(prec) * (numext::sqrt(v2) * numext::sqrt(w2));
      // |<v, w>| <= |v| |w| <= highest up to rounding. Below lower, underflow may have hidden all of <v, w>, but
      // |<v, w>| < 2 lower.
      if (absDot >= lower && absDot <= highest) return absDot <= bound;
      if (absDot < lower && bound >= Accumulator(2) * lower) return true;
    }
    return run_unbounded(wideV, wideW, Accumulator(prec));
  }

 private:
  using Product = unbounded_product<Accumulator>;

  // func(ac, bd, ad, bc) for each conj(x_k) y_k = (ac + bd) + i (ad - bc), where x_k = a + ib and y_k = c + id.
  template <typename X, typename Y, typename Func>
  static void for_each_product(const X& x, const Y& y, Func func) {
    const evaluator<X> xCoeffs(x);
    const evaluator<Y> yCoeffs(y);
    for (Index k = 0; k < x.size(); ++k) {
      const Accumulator a = numext::real(xCoeffs.coeff(k)), b = numext::imag(xCoeffs.coeff(k));
      const Accumulator c = numext::real(yCoeffs.coeff(k)), d = numext::imag(yCoeffs.coeff(k));
      func(Product(a, c), Product(b, d), Product(a, d), Product(b, c));
    }
  }

  // |<x, y>| from the products scaled by 2^-E, E the largest product exponent: the largest term is at least 1/4, and
  // only a term that falls below the normal range, far under an ulp of it, rounds again.
  template <typename X, typename Y>
  static comparison_magnitude<Accumulator> unbounded_dot_magnitude(const X& x, const Y& y) {
    bool nonzero = false;
    int maxExponent = 0;
    const auto include = [&](const Product& product) {
      if (product.fraction == Accumulator(0)) return;
      maxExponent = nonzero ? numext::maxi(maxExponent, product.exponent) : product.exponent;
      nonzero = true;
    };
    for_each_product(x, y, [&](const Product& ac, const Product& bd, const Product& ad, const Product& bc) {
      include(ac);
      include(bd);
      include(ad);
      include(bc);
    });
    if (!nonzero) return comparison_magnitude<Accumulator>(Accumulator(0));
    Accumulator re(0), im(0);
    for_each_product(x, y, [&](const Product& ac, const Product& bd, const Product& ad, const Product& bc) {
      re += ac.scaled(maxExponent) + bd.scaled(maxExponent);
      im += ad.scaled(maxExponent) - bc.scaled(maxExponent);
    });
    comparison_magnitude<Accumulator> magnitude(numext::hypot(re, im));
    magnitude.exponent += maxExponent;
    return magnitude;
  }

  // Keep the exponent arithmetic from inhibiting inlining of ordinary comparisons.
  template <typename V, typename W>
  static EIGEN_DONT_INLINE bool run_unbounded(const V& v, const W& w, const Accumulator& prec) {
    // A vector with a non-finite coefficient is orthogonal to nothing, a zero vector to everything.
    if (!v.allFinite() || !w.allFinite()) return false;
    // |<v, w>|^2 <= prec^2 |v|^2 |w|^2 between magnitudes that carry their own exponents.
    const comparison_magnitude<Accumulator> absDot = unbounded_dot_magnitude(v, w);
    comparison_magnitude<Accumulator> dot2 = absDot;
    dot2.multiply(absDot);
    comparison_magnitude<Accumulator> bound = unbounded_dot_magnitude(v, v);
    bound.multiply(unbounded_dot_magnitude(w, w));
    bound.multiply(prec);
    bound.multiply(prec);
    return dot2 <= bound;
  }
};

}  // end namespace internal

/** \returns \c true if \c *this is approximately equal to \a other, within the precision
 * determined by \a prec.
 *
 * \note This is a relative norm comparison. Two vectors \f$ v \f$ and \f$ w \f$
 * are considered to be approximately equal within precision \f$ p \f$ if
 * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f]
 * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm
 * L2 norm).
 *
 * \a prec is a relative tolerance chosen by the caller, not a bound on floating-point rounding error.
 * The default, NumTraits<Scalar>::dummy_precision(), does not account for the operation, dimensions,
 * or conditioning of the problem. Choose an explicit tolerance when checking numerical accuracy.
 * A norm comparison also does not bound the relative error of each coefficient.
 *
 * \note Because of the multiplicativeness of this comparison, one can't use this function
 * to check whether \c *this is approximately equal to the zero matrix or vector.
 * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix
 * or vector. If you want to test whether \c *this is small relative to a reference norm,
 * use isMuchSmallerThan() instead.
 *
 * \sa isMuchSmallerThan(), isZero()
 */
template <typename Derived>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr bool DenseBase<Derived>::isApprox(const DenseBase<OtherDerived>& other,
                                                              const RealScalar& prec) const {
  return internal::isApprox_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
}

/** \returns \c true if the norm of \c *this is much smaller than \a other,
 * within the precision determined by \a prec.
 *
 * \note This is a relative norm comparison. A vector \f$ v \f$ is
 * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if
 * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f]
 *
 * For matrices, the comparison is done using the Hilbert-Schmidt norm. For this reason,
 * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm
 * of a reference matrix of same dimensions.
 *
 * \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const
 */
template <typename Derived>
EIGEN_DEVICE_FUNC constexpr bool DenseBase<Derived>::isMuchSmallerThan(const typename NumTraits<Scalar>::Real& other,
                                                                       const RealScalar& prec) const {
  return internal::isMuchSmallerThan_scalar_selector<Derived>::run(derived(), other, prec);
}

/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other,
 * within the precision determined by \a prec.
 *
 * \note This is a relative norm comparison. A vector \f$ v \f$ is
 * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if
 * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f]
 * For matrices, the comparison is done using the Hilbert-Schmidt norm.
 *
 * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const
 */
template <typename Derived>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC constexpr bool DenseBase<Derived>::isMuchSmallerThan(const DenseBase<OtherDerived>& other,
                                                                       const RealScalar& prec) const {
  return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
}

/** \returns true if *this is approximately orthogonal to \a other,
 *          within the precision given by \a prec.
 *
 * Example: \include MatrixBase_isOrthogonal.cpp
 * Output: \verbinclude MatrixBase_isOrthogonal.out
 */
template <typename Derived>
template <typename OtherDerived>
bool MatrixBase<Derived>::isOrthogonal(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const {
  return internal::is_orthogonal_impl<Derived, OtherDerived>::run(derived(), other.derived(), prec);
}

}  // end namespace Eigen

#endif  // EIGEN_APPROX_COMPARISONS_H
