// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Christoph Hertzberg <chtz@informatik.uni-bremen.de>
//
// 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"
#include <unsupported/Eigen/AutoDiff>

/*
 * In this file scalar derivations are tested for correctness.
 * TODO add more tests!
 */

template <typename Scalar>
void check_atan2() {
  typedef Matrix<Scalar, 1, 1> Deriv1;
  typedef AutoDiffScalar<Deriv1> AD;

  AD x(internal::random<Scalar>(-3.0, 3.0), Deriv1::UnitX());

  using std::exp;
  Scalar r = exp(internal::random<Scalar>(-10, 10));

  AD s = sin(x), c = cos(x);
  AD res = atan2(r * s, r * c);

  VERIFY_IS_APPROX(res.value(), x.value());
  VERIFY_IS_APPROX(res.derivatives(), x.derivatives());

  res = atan2(r * s + 0, r * c + 0);
  VERIFY_IS_APPROX(res.value(), x.value());
  VERIFY_IS_APPROX(res.derivatives(), x.derivatives());
}

template <typename Scalar>
void check_hyperbolic_functions() {
  using std::cosh;
  using std::sinh;
  using std::tanh;
  typedef Matrix<Scalar, 1, 1> Deriv1;
  typedef AutoDiffScalar<Deriv1> AD;
  Deriv1 p = Deriv1::Random();
  AD val(p.x(), Deriv1::UnitX());

  Scalar cosh_px = std::cosh(p.x());
  AD res1 = tanh(val);
  VERIFY_IS_APPROX(res1.value(), std::tanh(p.x()));
  VERIFY_IS_APPROX(res1.derivatives().x(), Scalar(1.0) / (cosh_px * cosh_px));

  AD res2 = sinh(val);
  VERIFY_IS_APPROX(res2.value(), std::sinh(p.x()));
  VERIFY_IS_APPROX(res2.derivatives().x(), cosh_px);

  AD res3 = cosh(val);
  VERIFY_IS_APPROX(res3.value(), cosh_px);
  VERIFY_IS_APPROX(res3.derivatives().x(), std::sinh(p.x()));

  // Check constant values.
  const Scalar sample_point = Scalar(1) / Scalar(3);
  val = AD(sample_point, Deriv1::UnitX());
  res1 = tanh(val);
  VERIFY_IS_APPROX(res1.derivatives().x(), Scalar(0.896629559604914));

  res2 = sinh(val);
  VERIFY_IS_APPROX(res2.derivatives().x(), Scalar(1.056071867829939));

  res3 = cosh(val);
  VERIFY_IS_APPROX(res3.derivatives().x(), Scalar(0.339540557256150));
}

template <typename Scalar>
void check_limits_specialization() {
  typedef Eigen::Matrix<Scalar, 1, 1> Deriv;
  typedef Eigen::AutoDiffScalar<Deriv> AD;

  typedef std::numeric_limits<AD> A;
  typedef std::numeric_limits<Scalar> B;

  // workaround "unused typedef" warning:
  VERIFY(!bool(std::is_same<B, A>::value));

  VERIFY(bool(std::is_base_of<B, A>::value));
}

// Regression for issue #1870: min(ADS, ADS) and max(ADS, ADS) must agree on
// which argument wins on a tie.  Previously min returned the second argument
// while max returned the first, so the two could yield different derivatives
// for inputs with equal values but different derivative vectors.
template <typename Scalar>
void check_min_max_equal_values() {
  typedef Eigen::Matrix<Scalar, 2, 1> Deriv2;
  typedef Eigen::AutoDiffScalar<Deriv2> AD;

  AD a(Scalar(1), Deriv2(Scalar(1), Scalar(0)));
  AD b(Scalar(1), Deriv2(Scalar(0), Scalar(1)));

  // Parenthesized form avoids the min/max macros installed by test/main.h
  // and lets ADL pick up the AutoDiffScalar overloads.
  VERIFY_IS_EQUAL((min)(a, b).derivatives(), a.derivatives());
  VERIFY_IS_EQUAL((max)(a, b).derivatives(), a.derivatives());
  VERIFY_IS_EQUAL((min)(b, a).derivatives(), b.derivatives());
  VERIFY_IS_EQUAL((max)(b, a).derivatives(), b.derivatives());
}

EIGEN_DECLARE_TEST(autodiff_scalar) {
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(check_atan2<float>());
    CALL_SUBTEST_2(check_atan2<double>());
    CALL_SUBTEST_3(check_hyperbolic_functions<float>());
    CALL_SUBTEST_4(check_hyperbolic_functions<double>());
    CALL_SUBTEST_5(check_limits_specialization<double>());
    CALL_SUBTEST_6(check_min_max_equal_values<float>());
    CALL_SUBTEST_7(check_min_max_equal_values<double>());
  }
}
