// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#ifndef EIGEN_ADLOC_FORWARD
#define EIGEN_ADLOC_FORWARD

//--------------------------------------------------------------------------------
//
// This file provides support for adolc's adouble type in forward mode.
// ADOL-C is a C++ automatic differentiation library,
// see https://projects.coin-or.org/ADOL-C for more information.
//
// Note that the maximal number of directions is controlled by
// the preprocessor token NUMBER_DIRECTIONS. The default is 2.
//
//--------------------------------------------------------------------------------

#define ADOLC_TAPELESS
#ifndef NUMBER_DIRECTIONS
# define NUMBER_DIRECTIONS 2
#endif
#include <adolc/adouble.h>

// adolc defines some very stupid macros:
#if defined(malloc)
# undef malloc
#endif

#if defined(calloc)
# undef calloc
#endif

#if defined(realloc)
# undef realloc
#endif

#include <Eigen/Core>

namespace Eigen {

/** \ingroup Unsupported_modules
  * \defgroup AdolcForward_Module Adolc forward module
  * This module provides support for adolc's adouble type in forward mode.
  * ADOL-C is a C++ automatic differentiation library,
  * see https://projects.coin-or.org/ADOL-C for more information.
  * It mainly consists in:
  *  - a struct Eigen::NumTraits<adtl::adouble> specialization
  *  - overloads of ei_* math function for adtl::adouble type.
  *
  * Note that the maximal number of directions is controlled by
  * the preprocessor token NUMBER_DIRECTIONS. The default is 2.
  *
  * \code
  * #include <unsupported/Eigen/AdolcSupport>
  * \endcode
  */
  //@{

} // namespace Eigen

// the Adolc's type adouble is defined in the adtl namespace
// therefore, the following ei_* functions *must* be defined
// in the same namespace
namespace adtl {

  inline const adouble& ei_conj(const adouble& x)  { return x; }
  inline const adouble& ei_real(const adouble& x)  { return x; }
  inline adouble ei_imag(const adouble&)    { return 0.; }
  inline adouble ei_abs(const adouble&  x)  { return fabs(x); }
  inline adouble ei_abs2(const adouble& x)  { return x*x; }
  inline adouble ei_sqrt(const adouble& x)  { return sqrt(x); }
  inline adouble ei_exp(const adouble&  x)  { return exp(x); }
  inline adouble ei_log(const adouble&  x)  { return log(x); }
  inline adouble ei_sin(const adouble&  x)  { return sin(x); }
  inline adouble ei_cos(const adouble&  x)  { return cos(x); }
  inline adouble ei_pow(const adouble& x, adouble y)  { return pow(x, y); }

}

namespace Eigen {

template<> struct NumTraits<adtl::adouble>
{
  typedef adtl::adouble Real;
  typedef adtl::adouble NonInteger;
  typedef adtl::adouble Nested;
  enum {
    IsComplex = 0,
    IsInteger = 0,
    IsSigned = 1,
    ReadCost = 1,
    AddCost = 1,
    MulCost = 1
  };
};

template<typename Functor> class AdolcForwardJacobian : public Functor
{
  typedef adtl::adouble ActiveScalar;
public:

  AdolcForwardJacobian() : Functor() {}
  AdolcForwardJacobian(const Functor& f) : Functor(f) {}

  // forward constructors
  template<typename T0>
  AdolcForwardJacobian(const T0& a0) : Functor(a0) {}
  template<typename T0, typename T1>
  AdolcForwardJacobian(const T0& a0, const T1& a1) : Functor(a0, a1) {}
  template<typename T0, typename T1, typename T2>
  AdolcForwardJacobian(const T0& a0, const T1& a1, const T1& a2) : Functor(a0, a1, a2) {}

  typedef typename Functor::InputType InputType;
  typedef typename Functor::ValueType ValueType;
  typedef typename Functor::JacobianType JacobianType;

  typedef Matrix<ActiveScalar, InputType::SizeAtCompileTime, 1> ActiveInput;
  typedef Matrix<ActiveScalar, ValueType::SizeAtCompileTime, 1> ActiveValue;

  void operator() (const InputType& x, ValueType* v, JacobianType* _jac) const
  {
    ei_assert(v!=0);
    if (!_jac)
    {
      Functor::operator()(x, v);
      return;
    }

    JacobianType& jac = *_jac;

    ActiveInput ax = x.template cast<ActiveScalar>();
    ActiveValue av(jac.rows());

    for (int j=0; j<jac.cols(); j++)
      for (int i=0; i<jac.cols(); i++)
        ax[i].setADValue(j, i==j ? 1 : 0);

    Functor::operator()(ax, &av);

    for (int i=0; i<jac.rows(); i++)
    {
      (*v)[i] = av[i].getValue();
      for (int j=0; j<jac.cols(); j++)
        jac.coeffRef(i,j) = av[i].getADValue(j);
    }
  }
protected:

};

//@}

}

#endif // EIGEN_ADLOC_FORWARD
