// 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 <contrib/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>());
  }
}
