// Benchmarks for Eigen AutoDiff module.
// Compares AutoDiff Jacobian computation against NumericalDiff and hand-coded Jacobians.
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

#include <benchmark/benchmark.h>
#include <Eigen/Core>
#include <contrib/Eigen/AutoDiff>
#include <contrib/Eigen/NumericalDiff>

using namespace Eigen;

// --- Small functor: Rosenbrock-like (2 inputs -> 2 outputs) ---
struct SmallFunctor {
  typedef Matrix<double, 2, 1> InputType;
  typedef Matrix<double, 2, 1> ValueType;
  typedef Matrix<double, 2, 2> JacobianType;

  enum { InputsAtCompileTime = 2, ValuesAtCompileTime = 2 };

  template <typename T>
  void operator()(const Matrix<T, 2, 1>& x, Matrix<T, 2, 1>* v) const {
    (*v)(0) = T(1) - x(0);
    (*v)(1) = T(10) * (x(1) - x(0) * x(0));
  }
};

// --- Medium functor: chain of operations (6 inputs -> 6 outputs) ---
struct MediumFunctor {
  typedef Matrix<double, 6, 1> InputType;
  typedef Matrix<double, 6, 1> ValueType;
  typedef Matrix<double, 6, 6> JacobianType;

  enum { InputsAtCompileTime = 6, ValuesAtCompileTime = 6 };

  template <typename T>
  void operator()(const Matrix<T, 6, 1>& x, Matrix<T, 6, 1>* v) const {
    (*v)(0) = sin(x(0)) * cos(x(1)) + x(2) * x(2);
    (*v)(1) = exp(x(1) * T(0.1)) + x(3);
    (*v)(2) = x(0) * x(2) - x(4) * x(5);
    (*v)(3) = sqrt(x(3) * x(3) + T(1)) + x(0);
    (*v)(4) = x(4) * x(4) + x(5) * x(5) + x(0) * x(1);
    (*v)(5) = log(x(2) * x(2) + T(1)) + x(3) * x(4);
  }
};

// --- Dynamic-size functor (N inputs -> N outputs) ---
struct DynamicFunctor {
  typedef Matrix<double, Dynamic, 1> InputType;
  typedef Matrix<double, Dynamic, 1> ValueType;
  typedef Matrix<double, Dynamic, Dynamic> JacobianType;

  const int n_;
  DynamicFunctor(int n) : n_(n) {}

  enum { InputsAtCompileTime = Dynamic, ValuesAtCompileTime = Dynamic };

  int inputs() const { return n_; }
  int values() const { return n_; }

  template <typename T>
  void operator()(const Matrix<T, Dynamic, 1>& x, Matrix<T, Dynamic, 1>* v) const {
    v->resize(n_);
    (*v)(0) = T(1) - x(0);
    for (int i = 1; i < n_; ++i) {
      (*v)(i) = T(10) * (x(i) - x(i - 1) * x(i - 1));
    }
  }
};

// Wrapper for NumericalDiff compatibility.
struct SmallFunctorND : SmallFunctor {
  typedef double Scalar;
  int inputs() const { return 2; }
  int values() const { return 2; }
  int operator()(const InputType& x, ValueType& v) const {
    SmallFunctor::operator()(x, &v);
    return 0;
  }
};

struct MediumFunctorND : MediumFunctor {
  typedef double Scalar;
  int inputs() const { return 6; }
  int values() const { return 6; }
  int operator()(const InputType& x, ValueType& v) const {
    MediumFunctor::operator()(x, &v);
    return 0;
  }
};

// --- AutoDiff Jacobian benchmarks ---
template <typename Functor>
static void BM_AutoDiffJacobian(benchmark::State& state, Functor func) {
  AutoDiffJacobian<Functor> adf(func);
  typename Functor::InputType x = Functor::InputType::Random();
  typename Functor::ValueType v;
  typename Functor::JacobianType jac;

  for (auto _ : state) {
    adf(x, &v, &jac);
    benchmark::DoNotOptimize(jac.data());
    benchmark::ClobberMemory();
  }
}

// --- Dynamic AutoDiff Jacobian ---
static void BM_AutoDiffJacobian_Dynamic(benchmark::State& state) {
  int n = state.range(0);
  DynamicFunctor func(n);
  AutoDiffJacobian<DynamicFunctor> adf(func);

  VectorXd x = VectorXd::Random(n);
  VectorXd v(n);
  MatrixXd jac(n, n);

  for (auto _ : state) {
    adf(x, &v, &jac);
    benchmark::DoNotOptimize(jac.data());
    benchmark::ClobberMemory();
  }
}

// --- NumericalDiff benchmarks ---
template <typename Functor>
static void BM_NumericalDiffJacobian(benchmark::State& state, Functor func) {
  NumericalDiff<Functor> ndf(func);
  typename Functor::InputType x = Functor::InputType::Random();
  typename Functor::JacobianType jac;

  for (auto _ : state) {
    ndf.df(x, jac);
    benchmark::DoNotOptimize(jac.data());
    benchmark::ClobberMemory();
  }
}

// --- Hand-coded Jacobian (Rosenbrock) for comparison ---
static void BM_HandCoded_Small(benchmark::State& state) {
  Vector2d x = Vector2d::Random();
  Matrix2d jac;

  for (auto _ : state) {
    jac(0, 0) = -1;
    jac(0, 1) = 0;
    jac(1, 0) = -20 * x(0);
    jac(1, 1) = 10;
    benchmark::DoNotOptimize(jac.data());
    benchmark::ClobberMemory();
  }
}

// --- Scalar AutoDiff evaluation (no Jacobian, just forward pass) ---
static void BM_AutoDiffScalar_Eval(benchmark::State& state) {
  int n = state.range(0);
  using ADScalar = AutoDiffScalar<VectorXd>;
  VectorXd x = VectorXd::Random(n);

  for (auto _ : state) {
    ADScalar sum(0.0, VectorXd::Zero(n));
    for (int i = 0; i < n; ++i) {
      ADScalar xi(x(i), n, i);
      sum += xi * xi + sin(xi);
    }
    benchmark::DoNotOptimize(sum.value());
    benchmark::DoNotOptimize(sum.derivatives().data());
    benchmark::ClobberMemory();
  }
}

BENCHMARK_CAPTURE(BM_AutoDiffJacobian, Small, SmallFunctor());
BENCHMARK_CAPTURE(BM_AutoDiffJacobian, Medium, MediumFunctor());
BENCHMARK(BM_AutoDiffJacobian_Dynamic)->Arg(2)->Arg(6)->Arg(20)->Arg(50)->Arg(100);

BENCHMARK_CAPTURE(BM_NumericalDiffJacobian, Small, SmallFunctorND());
BENCHMARK_CAPTURE(BM_NumericalDiffJacobian, Medium, MediumFunctorND());

BENCHMARK(BM_HandCoded_Small);
BENCHMARK(BM_AutoDiffScalar_Eval)->Arg(2)->Arg(6)->Arg(20)->Arg(50)->Arg(100);
