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

#include "main.h"
#include <contrib/Eigen/NumericalDiff>
#include <contrib/Eigen/LevenbergMarquardt>

template <typename Scalar_, int Inputs = Dynamic, int Values = Dynamic, int Options = ColMajor>
struct RiddersFunctor {
  using Scalar = Scalar_;
  using InputType = Matrix<Scalar, Inputs, 1>;
  using ValueType = Matrix<Scalar, Values, 1>;
  using JacobianType = Matrix<Scalar, Values, Inputs, Options>;

  static constexpr int InputsAtCompileTime = Inputs;
  static constexpr int ValuesAtCompileTime = Values;

  mutable int evaluations = 0;

  int values() const { return 4; }

  int operator()(const InputType& x, ValueType& y) const {
    ++evaluations;
    y[0] = numext::exp(x[0]);
    y[1] = numext::sin(Scalar(50) * x[0]);
    y[2] = x[0] * x[1];
    y[3] = numext::exp(x[1]);
    return 0;
  }
};

template <typename Scalar, int Inputs, int Values, int Options>
void test_ridders_jacobian() {
  using F = RiddersFunctor<Scalar, Inputs, Values, Options>;

  Ridders<F> diff;
  typename F::InputType x(2), error(2);
  typename F::JacobianType jac(4, 2), expected(4, 2), withoutError(4, 2);

  x << Scalar(1), Scalar(-2);
  const typename F::InputType original = x;

  expected.row(0) << Scalar(std::exp(1.0L)), Scalar(0);
  expected.row(1) << Scalar(50 * std::cos(50.0L)), Scalar(0);
  expected.row(2) << x[1], x[0];
  expected.row(3) << Scalar(0), Scalar(std::exp(-2.0L));

  const int count = diff.df(x, jac, error);
  VERIFY_IS_EQUAL(count, diff.functor().evaluations);
  VERIFY(count >= 8 && count <= 40 && count % 2 == 0);

  VERIFY(jac.allFinite());
  VERIFY(error.allFinite());
  VERIFY((error.array() >= Scalar(0)).all());

  // The initial stencil spans half a radian in the oscillatory component; extrapolation
  // must remove its truncation error to reach a roundoff-scale bound.
  VERIFY((jac - expected).template lpNorm<Infinity>() <=
         Scalar(256) * NumTraits<Scalar>::epsilon() * expected.template lpNorm<Infinity>());

  VERIFY_IS_EQUAL(x, original);
  VERIFY_IS_EQUAL(diff.df(x, withoutError), count);
  VERIFY_IS_EQUAL(jac, withoutError);
}

struct RiddersScalarFunctor {
  using Scalar = double;
  using InputType = Matrix<double, 1, 1>;
  using ValueType = InputType;
  using JacobianType = InputType;

  static constexpr int InputsAtCompileTime = 1;
  static constexpr int ValuesAtCompileTime = 1;

  enum Function { Cubic, LargeCubic, Quintic, SquareRoot, NoisyExp, Identity, Invalid, InvalidRefinement };
  Function function = Cubic;
  mutable int evaluations = 0;

  int values() const { return 1; }

  int operator()(const InputType& x, ValueType& y) const {
    ++evaluations;
    switch (function) {
      case Cubic:
        y[0] = x[0] * x[0] * x[0];
        break;

      case LargeCubic:
        y[0] = 2e307 * x[0] * x[0] * x[0];
        break;

      case Quintic:
        y[0] = x[0] * x[0] * x[0] * x[0] * x[0];
        break;

      case SquareRoot:
        y[0] = std::sqrt(x[0]);
        break;

      case NoisyExp:
        y[0] = double(float(std::exp(x[0])));
        break;

      case Identity:
        y[0] = x[0];
        break;

      case Invalid:
        y[0] = NumTraits<double>::quiet_NaN();
        break;

      case InvalidRefinement:
        y[0] = evaluations <= 2 ? x[0] : NumTraits<double>::quiet_NaN();
        break;
    }
    return 0;
  }
};

void test_ridders_parameters() {
  using DiffType = Ridders<RiddersScalarFunctor>;

  DiffType diff;
  DiffType::Parameters parameters;
  parameters.initialStep = 0.25;
  parameters.stepReduction = 4;
  parameters.maxSteps = 2;
  diff.setParameters(parameters);

  RiddersScalarFunctor::InputType x, error;
  RiddersScalarFunctor::JacobianType jac;
  x[0] = 2;
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 4);
  VERIFY_IS_EQUAL(jac[0], 12.0);

  // The cubic's central differences are 12 + h^2, with h = 1/2 and 1/8.
  VERIFY_IS_EQUAL(error[0], 0.25);

  parameters.maxSteps = 10;
  diff.setParameters(parameters);
  VERIFY(diff.df(x, jac, error) < 20);
  VERIFY_IS_EQUAL(jac[0], 12.0);
  VERIFY_IS_EQUAL(error[0], 0.0);

  parameters.initialStep = 0;
  VERIFY_RAISES_ASSERT(diff.setParameters(parameters));

  parameters.initialStep = 0.01;
  parameters.stepReduction = 1;
  VERIFY_RAISES_ASSERT(diff.setParameters(parameters));

  parameters.stepReduction = 2;
  parameters.maxSteps = 1;
  VERIFY_RAISES_ASSERT(diff.setParameters(parameters));

  parameters.maxSteps = 10;
  parameters.initialStep = NumTraits<double>::infinity();
  VERIFY_RAISES_ASSERT(diff.setParameters(parameters));

  parameters.initialStep = 0.01;
  parameters.stepReduction = NumTraits<double>::infinity();
  VERIFY_RAISES_ASSERT(diff.setParameters(parameters));

  parameters = DiffType::Parameters();
  if (NumTraits<Index>::highest() / 2 < NumTraits<int>::highest()) {
    parameters.maxSteps = static_cast<int>(NumTraits<Index>::highest() / 2) + 1;
    VERIFY_RAISES_ASSERT(diff.setParameters(parameters));
    --parameters.maxSteps;
  } else {
    parameters.maxSteps = NumTraits<int>::highest();
  }
  diff.setParameters(parameters);
}

void test_ridders_repeated_stencil() {
  using DiffType = Ridders<RiddersScalarFunctor>;

  for (int multiplier : {1, 16}) {
    DiffType diff;
    DiffType::Parameters parameters;
    parameters.stepReduction = 1 + multiplier * NumTraits<double>::epsilon();
    diff.setParameters(parameters);

    RiddersScalarFunctor::InputType x, error;
    RiddersScalarFunctor::JacobianType jac;
    x[0] = 1;
    VERIFY_IS_EQUAL(diff.df(x, jac, error), 2);
    VERIFY_IS_EQUAL(diff.functor().evaluations, 2);
    VERIFY((numext::isfinite)(jac[0]));
    VERIFY(std::abs(jac[0] - 3.0001) <= 32 * NumTraits<double>::epsilon());
    VERIFY((numext::isinf)(error[0]) && error[0] > 0);
  }
}

void test_ridders_dimensions() {
  Ridders<RiddersFunctor<double>> diff;
  VectorXd x = VectorXd::Ones(2), error;
  MatrixXd jac(3, 2);
  VERIFY_RAISES_ASSERT(diff.df(x, jac));

  jac.resize(4, 1);
  VERIFY_RAISES_ASSERT(diff.df(x, jac, error));

  jac.resize(4, 0);
  VERIFY_RAISES_ASSERT(diff.df(x, jac));
  VERIFY_IS_EQUAL(diff.functor().evaluations, 0);
}

template <typename Scalar_>
struct RiddersAffineFunctor {
  using Scalar = Scalar_;
  using InputType = Matrix<Scalar, 1, 1>;
  using ValueType = Matrix<Scalar, Dynamic, 1>;
  using JacobianType = Matrix<Scalar, Dynamic, 1>;

  static constexpr int InputsAtCompileTime = 1;
  static constexpr int ValuesAtCompileTime = Dynamic;

  ValueType slopes, offsets;
  Scalar center = Scalar(100);
  Scalar inputScale = Scalar(1);
  mutable int evaluations = 0;
  int finiteEvaluations = 20;

  Index values() const { return slopes.size(); }

  int operator()(const InputType& x, ValueType& y) const {
    ++evaluations;
    y = slopes * ((x[0] - center) * inputScale) + offsets;
    if (evaluations > finiteEvaluations) y.setConstant(NumTraits<Scalar>::quiet_NaN());
    return 0;
  }
};

template <typename Scalar>
void test_ridders_central_overflow() {
  using Functor = RiddersAffineFunctor<Scalar>;
  using DiffType = Ridders<Functor>;

  const Scalar large = NumTraits<Scalar>::highest() * Scalar(0.75);
  // 32-bit ARM NEON flushes subnormal lanes; there, keep tiny and small * h for the steps h = 1, 1/2 normal.
  constexpr bool kPacketsFlush = EIGEN_ARCH_ARM && internal::packet_traits<Scalar>::Vectorizable;
  const Scalar small = Scalar(kPacketsFlush ? 2 : 1) * (std::numeric_limits<Scalar>::min)();
  const Scalar tiny = kPacketsFlush ? small : (std::numeric_limits<Scalar>::denorm_min)();

  for (Index count : {1, 7, 17}) {
    Functor functor;
    functor.slopes.resize(count);
    functor.offsets.setZero(count);

    for (Index i = 0; i < count; ++i) {
      functor.slopes[i] = i % 3 == 0 ? large : (i % 3 == 1 ? Scalar(-8) : small);
      if (i % 6 == 3) functor.slopes[i] = -large;
    }

    DiffType diff(functor);
    typename Functor::InputType x, error;
    typename Functor::JacobianType jac(count, 1);
    x[0] = functor.center;
    VERIFY_IS_EQUAL(diff.df(x, jac, error), 4);
    VERIFY(jac.allFinite());
    for (Index i = 0; i < count; ++i) VERIFY_IS_EQUAL(jac[i], functor.slopes[i]);
    VERIFY_IS_EQUAL(error[0], Scalar(0));

    // A failed refinement must retain finite entries, including subnormals unless packets flush them, from the
    // initial stencil.
    diff.functor().evaluations = 0;
    diff.functor().finiteEvaluations = 2;
    for (Index i = 2; i < count; i += 3) diff.functor().slopes[i] = tiny;
    VERIFY_IS_EQUAL(diff.df(x, jac, error), 4);
    VERIFY_IS_EQUAL(jac, diff.functor().slopes);
    VERIFY((numext::isinf)(error[0]) && error[0] > Scalar(0));
  }

  Functor functor;
  functor.slopes.setZero(1);
  functor.offsets.setConstant(1, large);

  DiffType diff(functor);
  typename Functor::InputType x, error;
  typename Functor::JacobianType jac(1, 1);
  x[0] = Scalar(100);
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 4);
  VERIFY_IS_EQUAL(jac[0], Scalar(0));

  x[0] = Scalar(0);
  diff.functor().center = Scalar(0);

  typename DiffType::Parameters parameters = diff.parameters();
  parameters.initialStep = (std::numeric_limits<Scalar>::min)();
  diff.setParameters(parameters);
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 4);
  VERIFY_IS_EQUAL(jac[0], Scalar(0));

  // Division first cannot repair a genuinely overflowing derivative or nonfinite samples.
  diff.functor().slopes[0] = NumTraits<Scalar>::highest();
  diff.functor().offsets[0] = Scalar(0);
  diff.functor().inputScale = Scalar(4);
  parameters.initialStep = Scalar(0.25);
  diff.setParameters(parameters);
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 2);
  VERIFY((numext::isnan)(jac[0]));
  VERIFY((numext::isinf)(error[0]) && error[0] > Scalar(0));

  diff.functor().slopes[0] = NumTraits<Scalar>::infinity();
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 2);
  VERIFY((numext::isnan)(jac[0]));
  VERIFY((numext::isinf)(error[0]) && error[0] > Scalar(0));

  parameters.initialStep = Scalar(2);
  diff.setParameters(parameters);
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 2);
  VERIFY((numext::isnan)(jac[0]));
}

void test_ridders_domain_and_noise() {
  using DiffType = Ridders<RiddersScalarFunctor>;

  DiffType diff;
  RiddersScalarFunctor::InputType x, error;
  RiddersScalarFunctor::JacobianType jac;

  diff.functor().function = RiddersScalarFunctor::SquareRoot;
  x[0] = 0.005;

  DiffType::Parameters parameters;
  parameters.initialStep = 0.01 * x[0];
  diff.setParameters(parameters);
  VERIFY(diff.df(x, jac, error) <= 20);

  const double expected = double(0.5L / std::sqrt(static_cast<long double>(x[0])));
  VERIFY(std::abs(jac[0] - expected) <= 256 * NumTraits<double>::epsilon() * expected);
  VERIFY((numext::isfinite)(error[0]));

  diff.functor().function = RiddersScalarFunctor::NoisyExp;
  x[0] = 1;
  parameters.initialStep = 0.01;
  diff.setParameters(parameters);
  VERIFY(diff.df(x, jac, error) < 20);
  VERIFY(std::abs(jac[0] - std::exp(1.0)) <= 256 * double(NumTraits<float>::epsilon()) * std::exp(1.0));
  VERIFY((numext::isfinite)(error[0]));
}

void test_ridders_richardson_overflow() {
  Ridders<RiddersScalarFunctor> diff;
  diff.functor().function = RiddersScalarFunctor::LargeCubic;
  RiddersScalarFunctor::InputType x, error;
  RiddersScalarFunctor::JacobianType jac;
  x[0] = 1;

  const int evaluations = diff.df(x, jac, error);
  VERIFY_IS_EQUAL(evaluations, diff.functor().evaluations);
  VERIFY(evaluations > 4 && evaluations <= 20);

  VERIFY((numext::isfinite)(jac[0]));
  VERIFY((numext::isfinite)(error[0]));
  VERIFY(error[0] >= 0);

  // The cubic's truncation error cancels on extrapolation; divide before comparing near the range limit.
  VERIFY(std::abs(jac[0] / 6e307 - 1) <= 256 * NumTraits<double>::epsilon());
}

void test_ridders_stencil() {
  using DiffType = Ridders<RiddersScalarFunctor>;

  DiffType diff;
  diff.functor().function = RiddersScalarFunctor::Quintic;

  DiffType::Parameters parameters;
  parameters.initialStep = 0.25;
  parameters.maxSteps = 3;
  diff.setParameters(parameters);

  RiddersScalarFunctor::InputType x, error, value;
  RiddersScalarFunctor::JacobianType jac;
  x[0] = 1;
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 6);
  VERIFY_IS_EQUAL(jac[0], 5.0);

  // At depth three the extrapolation is the degree-five-exact stencil on these six nodes.
  const Stencil<1, double, 6> stencil({-0.25, 0.25, -0.125, 0.125, -0.0625, 0.0625});
  double expected = 0;
  for (Index i = 0; i < 6; ++i) {
    RiddersScalarFunctor::InputType point;
    point[0] = x[0] + stencil.point(i);
    diff(point, value);
    expected += stencil.weight(i) * value[0];
  }

  VERIFY(std::abs(jac[0] - expected) <= 32 * NumTraits<double>::epsilon() * std::abs(jac[0]));
}

// Tests construction from a functor without a default constructor and optional inputs() forwarding.
struct OwnedRiddersFunctor : RiddersScalarFunctor {
  explicit OwnedRiddersFunctor(Function selected) { function = selected; }

  int inputs() const { return 1; }
};

void test_ridders_composition() {
  using Derivative = Ridders<OwnedRiddersFunctor>;

  static_assert(!std::is_base_of<OwnedRiddersFunctor, Derivative>::value, "Ridders owns its functor by composition");

  OwnedRiddersFunctor functor(RiddersScalarFunctor::Cubic);
  Derivative::Parameters parameters;
  parameters.initialStep = 0.25;
  parameters.maxSteps = 2;
  Derivative derivative(functor, parameters);
  VERIFY_IS_EQUAL(derivative.inputs(), 1);
  VERIFY_IS_EQUAL(derivative.values(), 1);
  VERIFY_IS_EQUAL(derivative.parameters().maxSteps, 2);

  const int* inputs = &Derivative::InputsAtCompileTime;
  const int* values = &Derivative::ValuesAtCompileTime;
  VERIFY_IS_EQUAL(*inputs, 1);
  VERIFY_IS_EQUAL(*values, 1);

  OwnedRiddersFunctor::InputType x, y, error;
  OwnedRiddersFunctor::JacobianType jac;
  x[0] = 2;
  VERIFY_IS_EQUAL(derivative(x, y), 0);
  VERIFY_IS_EQUAL(y[0], 8.0);

  VERIFY_IS_EQUAL(derivative.df(x, jac, error), 4);
  VERIFY_IS_EQUAL(jac[0], 12.0);
  VERIFY_IS_EQUAL(functor.evaluations, 0);

  const Derivative& constDerivative = derivative;
  VERIFY_IS_EQUAL(constDerivative.functor().evaluations, 5);
}

struct LinearRiddersFunctor : RiddersFunctor<double, 7, 7> {
  int values() const { return 7; }

  int operator()(const InputType& x, ValueType& y) const {
    y = x * 8;
    return 0;
  }
};

void test_ridders_step_alignment() {
  Ridders<LinearRiddersFunctor> derivative;
  LinearRiddersFunctor::InputType x;
  x << 0.0, 0.082, 1.13, -2350.7, 7.7e8 + 0.3, -1.0 - std::ldexp(1.0, -27), -1.0;
  LinearRiddersFunctor::JacobianType jac;

  derivative.df(x, jac);
  VERIFY_IS_EQUAL(jac, LinearRiddersFunctor::JacobianType::Identity() * 8);
}

void test_ridders_fallback() {
  using DiffType = Ridders<RiddersScalarFunctor>;

  DiffType diff;
  RiddersScalarFunctor::InputType x, error;
  RiddersScalarFunctor::JacobianType jac;
  x[0] = 1;

  diff.functor().function = RiddersScalarFunctor::Invalid;
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 2);
  VERIFY((numext::isnan)(jac[0]));
  VERIFY((numext::isinf)(error[0]) && error[0] > 0);

  diff.functor().function = RiddersScalarFunctor::InvalidRefinement;
  diff.functor().evaluations = 0;
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 4);
  VERIFY_IS_EQUAL(jac[0], 1.0);
  VERIFY((numext::isinf)(error[0]));

  diff.functor().function = RiddersScalarFunctor::Identity;

  DiffType::Parameters parameters;
  parameters.initialStep = NumTraits<double>::epsilon() / 16;
  diff.setParameters(parameters);
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 0);
  VERIFY((numext::isnan)(jac[0]));
  VERIFY((numext::isinf)(error[0]));

  parameters.initialStep = NumTraits<double>::epsilon();
  diff.setParameters(parameters);
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 4);
  VERIFY_IS_EQUAL(jac[0], 1.0);
  VERIFY_IS_EQUAL(error[0], 0.0);
}

struct RiddersLevenbergMarquardtFunctor : DenseFunctor<double> {
  RiddersLevenbergMarquardtFunctor() : DenseFunctor<double>(1, 1) {}

  int operator()(const InputType& x, ValueType& y) const {
    y[0] = x[0] * x[0] - 2;
    return 0;
  }
};

void test_ridders_levenberg_marquardt() {
  using Functor = RiddersLevenbergMarquardtFunctor;
  using Derivative = Ridders<Functor>;

  static_assert(std::is_same<typename Derivative::QRSolver, typename Functor::QRSolver>::value,
                "Ridders must preserve the functor's QRSolver type");

  Derivative derivative;
  LevenbergMarquardt<Derivative> solver(derivative);
  VectorXd x = VectorXd::Ones(1);

  const LevenbergMarquardtSpace::Status status = solver.minimize(x);
  VERIFY(status >= LevenbergMarquardtSpace::RelativeReductionTooSmall &&
         status <= LevenbergMarquardtSpace::CosinusTooSmall);
  VERIFY(std::abs(x[0] - std::sqrt(2.0)) <= 256 * NumTraits<double>::epsilon());
}

struct EmptyRiddersFunctor : RiddersFunctor<double> {
  int values() const { return 0; }
};

void test_ridders_empty() {
  Ridders<EmptyRiddersFunctor> diff;
  VectorXd x = VectorXd::Ones(2), error;
  MatrixXd jac(0, 2);
  VERIFY_IS_EQUAL(diff.df(x, jac, error), 0);
  VERIFY_IS_EQUAL(error, VectorXd::Zero(2));
  VERIFY_IS_EQUAL(diff.functor().evaluations, 0);

  Ridders<RiddersFunctor<double>> noInputs;
  x.resize(0);
  jac.resize(4, 0);
  VERIFY_IS_EQUAL(noInputs.df(x, jac, error), 0);
  VERIFY_IS_EQUAL(error.size(), 0);
  VERIFY_IS_EQUAL(noInputs.functor().evaluations, 0);
}

EIGEN_DECLARE_TEST(ridders) {
  CALL_SUBTEST((test_ridders_jacobian<float, 2, 4, ColMajor>()));
  CALL_SUBTEST((test_ridders_jacobian<double, 2, 4, RowMajor>()));
  CALL_SUBTEST((test_ridders_jacobian<double, Dynamic, Dynamic, ColMajor>()));
  CALL_SUBTEST((test_ridders_jacobian<long double, Dynamic, Dynamic, RowMajor>()));

  CALL_SUBTEST(test_ridders_parameters());
  CALL_SUBTEST(test_ridders_repeated_stencil());
  CALL_SUBTEST(test_ridders_dimensions());

  CALL_SUBTEST(test_ridders_central_overflow<float>());
  CALL_SUBTEST(test_ridders_central_overflow<double>());

  CALL_SUBTEST(test_ridders_domain_and_noise());
  CALL_SUBTEST(test_ridders_richardson_overflow());
  CALL_SUBTEST(test_ridders_stencil());

  CALL_SUBTEST(test_ridders_composition());
  CALL_SUBTEST(test_ridders_step_alignment());
  CALL_SUBTEST(test_ridders_fallback());

  CALL_SUBTEST(test_ridders_levenberg_marquardt());
  CALL_SUBTEST(test_ridders_empty());
}
