// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2014 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

#include "main.h"

template <typename T>
EIGEN_DONT_INLINE T copy(const T& x) {
  return x;
}

template <typename MatrixType>
void stable_norm(const MatrixType& m) {
  /* this test covers the following files:
     StableNorm.h
  */
  using std::abs;
  using std::sqrt;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

  bool complex_real_product_ok = true;

  // Check the basic machine-dependent constants.
  {
    int ibeta, it, iemin, iemax;

    ibeta = std::numeric_limits<RealScalar>::radix;         // base for floating-point numbers
    it = std::numeric_limits<RealScalar>::digits;           // number of base-beta digits in mantissa
    iemin = std::numeric_limits<RealScalar>::min_exponent;  // minimum exponent
    iemax = std::numeric_limits<RealScalar>::max_exponent;  // maximum exponent

    VERIFY((!(iemin > 1 - 2 * it || 1 + it > iemax || (it == 2 && ibeta < 5) || (it <= 4 && ibeta <= 3) || it < 2)) &&
           "the stable norm algorithm cannot be guaranteed on this computer");

    Scalar inf = std::numeric_limits<RealScalar>::infinity();
    if (NumTraits<Scalar>::IsComplex && (numext::isnan)(inf * RealScalar(1))) {
      complex_real_product_ok = false;
      static bool first = true;
      if (first)
        std::cerr << "WARNING: compiler mess up complex*real product, " << inf << " * " << 1.0 << " = "
                  << inf * RealScalar(1) << std::endl;
      first = false;
    }
  }

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

  // Get a random factor bounded away from zero: |factor| >= 0.1.
  Scalar factor = internal::random<Scalar>(Scalar(RealScalar(0.1)), Scalar(RealScalar(1)));
  Scalar big = factor * ((std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4));

  factor = internal::random<Scalar>(Scalar(RealScalar(0.1)), Scalar(RealScalar(1)));
  Scalar small = factor * ((std::numeric_limits<RealScalar>::min)() * RealScalar(1e4));

  Scalar one(1);

  MatrixType vzero = MatrixType::Zero(rows, cols), vrand = MatrixType::Random(rows, cols), vbig(rows, cols),
             vsmall(rows, cols);

  vbig.fill(big);
  vsmall.fill(small);

  VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1));
  VERIFY_IS_APPROX(vrand.stableNorm(), vrand.norm());
  VERIFY_IS_APPROX(vrand.blueNorm(), vrand.norm());
  VERIFY_IS_APPROX(vrand.hypotNorm(), vrand.norm());

  // test with expressions as input
  VERIFY_IS_APPROX((one * vrand).stableNorm(), vrand.norm());
  VERIFY_IS_APPROX((one * vrand).blueNorm(), vrand.norm());
  VERIFY_IS_APPROX((one * vrand).hypotNorm(), vrand.norm());
  VERIFY_IS_APPROX((one * vrand + one * vrand - one * vrand).stableNorm(), vrand.norm());
  VERIFY_IS_APPROX((one * vrand + one * vrand - one * vrand).blueNorm(), vrand.norm());
  VERIFY_IS_APPROX((one * vrand + one * vrand - one * vrand).hypotNorm(), vrand.norm());

  RealScalar size = static_cast<RealScalar>(m.size());

  // test numext::isfinite
  VERIFY(!(numext::isfinite)(std::numeric_limits<RealScalar>::infinity()));
  VERIFY(!(numext::isfinite)(sqrt(-abs(big))));

  // test overflow
  VERIFY((numext::isfinite)(sqrt(size) * abs(big)));
  VERIFY_IS_NOT_APPROX(sqrt(copy(vbig.squaredNorm())), abs(sqrt(size) * big));  // here the default norm must fail
  VERIFY_IS_APPROX(vbig.stableNorm(), sqrt(size) * abs(big));
  VERIFY_IS_APPROX(vbig.blueNorm(), sqrt(size) * abs(big));
  VERIFY_IS_APPROX(vbig.hypotNorm(), sqrt(size) * abs(big));

  // test underflow
  VERIFY((numext::isfinite)(sqrt(size) * abs(small)));
  VERIFY_IS_NOT_APPROX(sqrt(copy(vsmall.squaredNorm())), abs(sqrt(size) * small));  // here the default norm must fail
  VERIFY_IS_APPROX(vsmall.stableNorm(), sqrt(size) * abs(small));
  VERIFY_IS_APPROX(vsmall.blueNorm(), sqrt(size) * abs(small));
  VERIFY_IS_APPROX(vsmall.hypotNorm(), sqrt(size) * abs(small));

  // Test compilation of cwise() version
  VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm());
  VERIFY_IS_APPROX(vrand.colwise().blueNorm(), vrand.colwise().norm());
  VERIFY_IS_APPROX(vrand.colwise().hypotNorm(), vrand.colwise().norm());
  VERIFY_IS_APPROX(vrand.rowwise().stableNorm(), vrand.rowwise().norm());
  VERIFY_IS_APPROX(vrand.rowwise().blueNorm(), vrand.rowwise().norm());
  VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(), vrand.rowwise().norm());

  // test NaN, +inf, -inf
  MatrixType v;
  Index i = internal::random<Index>(0, rows - 1);
  Index j = internal::random<Index>(0, cols - 1);

  // NaN
  {
    v = vrand;
    v(i, j) = std::numeric_limits<RealScalar>::quiet_NaN();
    VERIFY(!(numext::isfinite)(v.squaredNorm()));
    VERIFY((numext::isnan)(v.squaredNorm()));
    VERIFY(!(numext::isfinite)(v.norm()));
    VERIFY((numext::isnan)(v.norm()));
    VERIFY(!(numext::isfinite)(v.stableNorm()));
    VERIFY((numext::isnan)(v.stableNorm()));
    VERIFY(!(numext::isfinite)(v.blueNorm()));
    VERIFY((numext::isnan)(v.blueNorm()));
    VERIFY(!(numext::isfinite)(v.hypotNorm()));
    VERIFY((numext::isnan)(v.hypotNorm()));
  }

  // +inf
  {
    v = vrand;
    v(i, j) = std::numeric_limits<RealScalar>::infinity();
    VERIFY(!(numext::isfinite)(v.squaredNorm()));
    VERIFY(isPlusInf(v.squaredNorm()));
    VERIFY(!(numext::isfinite)(v.norm()));
    VERIFY(isPlusInf(v.norm()));
    VERIFY(!(numext::isfinite)(v.stableNorm()));
    if (complex_real_product_ok) {
      VERIFY(isPlusInf(v.stableNorm()));
    }
    VERIFY(!(numext::isfinite)(v.blueNorm()));
    VERIFY(isPlusInf(v.blueNorm()));
    VERIFY(!(numext::isfinite)(v.hypotNorm()));
    VERIFY(isPlusInf(v.hypotNorm()));
  }

  // -inf
  {
    v = vrand;
    v(i, j) = -std::numeric_limits<RealScalar>::infinity();
    VERIFY(!(numext::isfinite)(v.squaredNorm()));
    VERIFY(isPlusInf(v.squaredNorm()));
    VERIFY(!(numext::isfinite)(v.norm()));
    VERIFY(isPlusInf(v.norm()));
    VERIFY(!(numext::isfinite)(v.stableNorm()));
    if (complex_real_product_ok) {
      VERIFY(isPlusInf(v.stableNorm()));
    }
    VERIFY(!(numext::isfinite)(v.blueNorm()));
    VERIFY(isPlusInf(v.blueNorm()));
    VERIFY(!(numext::isfinite)(v.hypotNorm()));
    VERIFY(isPlusInf(v.hypotNorm()));
  }

  // mix
  {
    Index i2 = internal::random<Index>(0, rows - 1);
    Index j2 = internal::random<Index>(0, cols - 1);
    v = vrand;
    v(i, j) = -std::numeric_limits<RealScalar>::infinity();
    v(i2, j2) = std::numeric_limits<RealScalar>::quiet_NaN();
    VERIFY(!(numext::isfinite)(v.squaredNorm()));
    VERIFY((numext::isnan)(v.squaredNorm()));
    VERIFY(!(numext::isfinite)(v.norm()));
    VERIFY((numext::isnan)(v.norm()));
    VERIFY(!(numext::isfinite)(v.stableNorm()));
    VERIFY((numext::isnan)(v.stableNorm()));
    VERIFY(!(numext::isfinite)(v.blueNorm()));
    VERIFY((numext::isnan)(v.blueNorm()));
    if (i2 != i || j2 != j) {
      // hypot propagates inf over NaN.
      VERIFY(!(numext::isfinite)(v.hypotNorm()));
      VERIFY((numext::isinf)(v.hypotNorm()));
    } else {
      // inf is overwritten by NaN, expect norm to be NaN.
      VERIFY(!(numext::isfinite)(v.hypotNorm()));
      VERIFY((numext::isnan)(v.hypotNorm()));
    }
  }

  // stableNormalize[d]
  {
    VERIFY_IS_APPROX(vrand.stableNormalized(), vrand.normalized());
    MatrixType vcopy(vrand);
    vcopy.stableNormalize();
    VERIFY_IS_APPROX(vcopy, vrand.normalized());
    VERIFY_IS_APPROX((vrand.stableNormalized()).norm(), RealScalar(1));
    VERIFY_IS_APPROX(vcopy.norm(), RealScalar(1));
    VERIFY_IS_APPROX((vbig.stableNormalized()).norm(), RealScalar(1));
    VERIFY_IS_APPROX((vsmall.stableNormalized()).norm(), RealScalar(1));
    RealScalar big_scaling = ((std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4));
    VERIFY_IS_APPROX(vbig / big_scaling, (vbig.stableNorm() * vbig.stableNormalized()).eval() / big_scaling);
    VERIFY_IS_APPROX(vsmall, vsmall.stableNorm() * vsmall.stableNormalized());
  }
}

void test_empty() {
  Eigen::VectorXf empty(0);
  VERIFY_IS_EQUAL(empty.stableNorm(), 0.0f);
}

template <typename Scalar>
void test_hypot() {
  typedef typename NumTraits<Scalar>::Real RealScalar;
  // Get a random factor bounded away from zero: |factor| >= 0.1.
  Scalar factor = internal::random<Scalar>(Scalar(RealScalar(0.1)), Scalar(RealScalar(1)));
  Scalar big = factor * ((std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4));

  factor = internal::random<Scalar>(Scalar(RealScalar(0.1)), Scalar(RealScalar(1)));
  Scalar small = factor * ((std::numeric_limits<RealScalar>::min)() * RealScalar(1e4));

  Scalar one(1), zero(0), sqrt2(std::sqrt(2)), nan(std::numeric_limits<RealScalar>::quiet_NaN());

  Scalar a = internal::random<Scalar>(-1, 1);
  Scalar b = internal::random<Scalar>(-1, 1);
  VERIFY_IS_APPROX(numext::hypot(a, b), std::sqrt(numext::abs2(a) + numext::abs2(b)));
  VERIFY_IS_EQUAL(numext::hypot(zero, zero), zero);
  VERIFY_IS_APPROX(numext::hypot(one, one), sqrt2);
  VERIFY_IS_APPROX(numext::hypot(big, big), sqrt2 * numext::abs(big));
  VERIFY_IS_APPROX(numext::hypot(small, small), sqrt2 * numext::abs(small));
  VERIFY_IS_APPROX(numext::hypot(small, big), numext::abs(big));
  VERIFY((numext::isnan)(numext::hypot(nan, a)));
  VERIFY((numext::isnan)(numext::hypot(a, nan)));
}

template <typename Scalar>
void stable_norm_complex_infinity() {
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, Dynamic, 1> VecType;

  const RealScalar inf = std::numeric_limits<RealScalar>::infinity();
  const Scalar finite(RealScalar(3), RealScalar(-4));
  const Scalar both_inf(inf, inf);
  const Scalar real_inf(inf, RealScalar(1));
  const Scalar imag_inf(RealScalar(1), -inf);

  VERIFY(isPlusInf(numext::abs(both_inf)));
  VERIFY(isPlusInf(numext::abs(real_inf)));
  VERIFY(isPlusInf(numext::abs(imag_inf)));
  VERIFY(isPlusInf(numext::hypot(both_inf, finite)));

  VecType v(4);
  v << both_inf, finite, real_inf, imag_inf;

  VERIFY(isPlusInf(v.cwiseAbs().maxCoeff()));
  VERIFY(isPlusInf(v.stableNorm()));
  VERIFY(isPlusInf(v.blueNorm()));
  VERIFY(isPlusInf(v.hypotNorm()));
}

// Test stableNorm at the 4096-element block boundary.
// stable_norm_impl_inner_step processes vectors in blocks of 4096.
// Sizes near this boundary exercise the transition between full blocks
// and the remainder tail, including scale propagation across blocks.
template <typename Scalar>
void stable_norm_block_boundary() {
  using std::abs;
  using std::sqrt;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Matrix<Scalar, Dynamic, 1> VecType;

  // Test sizes around the 4096 block boundary.
  const Index sizes[] = {4095, 4096, 4097, 8191, 8192, 8193, 12288};
  for (int si = 0; si < 7; ++si) {
    Index n = sizes[si];
    VecType v = VecType::Random(n);
    VERIFY_IS_APPROX(v.stableNorm(), v.norm());
    VERIFY_IS_APPROX(v.blueNorm(), v.norm());
  }

  // Test scale transitions across blocks: first block has tiny values,
  // second block has huge values. This exercises the scale/invScale
  // update logic when maxCoeff > scale in stable_norm_kernel.
  {
    RealScalar tiny = (std::numeric_limits<RealScalar>::min)() * RealScalar(1e4);
    RealScalar huge_val = (std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4);
    Index n = 8192;
    VecType v(n);
    // First 4096 elements: tiny. Second 4096 elements: huge.
    v.head(4096).setConstant(Scalar(tiny));
    v.tail(4096).setConstant(Scalar(huge_val));
    // The huge part dominates, so the expected norm is sqrt(4096)*huge_val.
    RealScalar expected = sqrt(RealScalar(4096)) * abs(huge_val);
    VERIFY_IS_APPROX(v.stableNorm(), expected);
    VERIFY_IS_APPROX(v.blueNorm(), expected);
  }

  // Reverse: first block huge, second block tiny.
  {
    RealScalar tiny = (std::numeric_limits<RealScalar>::min)() * RealScalar(1e4);
    RealScalar huge_val = (std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4);
    Index n = 8192;
    VecType v(n);
    v.head(4096).setConstant(Scalar(huge_val));
    v.tail(4096).setConstant(Scalar(tiny));
    RealScalar expected = sqrt(RealScalar(4096)) * abs(huge_val);
    VERIFY_IS_APPROX(v.stableNorm(), expected);
    VERIFY_IS_APPROX(v.blueNorm(), expected);
  }

  // Matrix version: columns with different magnitudes.
  // Scale must propagate correctly across columns.
  {
    RealScalar tiny = (std::numeric_limits<RealScalar>::min)() * RealScalar(1e4);
    RealScalar huge_val = (std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4);
    typedef Matrix<Scalar, Dynamic, Dynamic> MatType;
    MatType m(100, 2);
    m.col(0).setConstant(Scalar(tiny));
    m.col(1).setConstant(Scalar(huge_val));
    RealScalar expected = sqrt(RealScalar(100)) * abs(huge_val);
    VERIFY_IS_APPROX(m.stableNorm(), expected);
    VERIFY_IS_APPROX(m.blueNorm(), expected);
  }
}

EIGEN_DECLARE_TEST(stable_norm) {
  CALL_SUBTEST_1(test_empty());

  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_3(test_hypot<double>());
    CALL_SUBTEST_4(test_hypot<float>());
    CALL_SUBTEST_5(test_hypot<std::complex<double> >());
    CALL_SUBTEST_6(test_hypot<std::complex<float> >());

    CALL_SUBTEST_1(stable_norm(Matrix<float, 1, 1>()));
    CALL_SUBTEST_2(stable_norm(Vector4d()));
    CALL_SUBTEST_3(stable_norm(VectorXd(internal::random<int>(10, 2000))));
    CALL_SUBTEST_3(stable_norm(MatrixXd(internal::random<int>(10, 200), internal::random<int>(10, 200))));
    CALL_SUBTEST_4(stable_norm(VectorXf(internal::random<int>(10, 2000))));
    CALL_SUBTEST_5(stable_norm(VectorXcd(internal::random<int>(10, 2000))));
    CALL_SUBTEST_6(stable_norm(VectorXcf(internal::random<int>(10, 2000))));
  }

  // Block boundary and scale transition tests (deterministic, outside g_repeat).
  CALL_SUBTEST_7(stable_norm_block_boundary<float>());
  CALL_SUBTEST_7(stable_norm_block_boundary<double>());
  CALL_SUBTEST_8(stable_norm_complex_infinity<std::complex<float> >());
  CALL_SUBTEST_8(stable_norm_complex_infinity<std::complex<double> >());
}
