1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_AUTODIFF_JACOBIAN_H
11#define EIGEN_AUTODIFF_JACOBIAN_H
12
13namespace Eigen
14{
15
16template<typename Functor> class AutoDiffJacobian : public Functor
17{
18public:
19  AutoDiffJacobian() : Functor() {}
20  AutoDiffJacobian(const Functor& f) : Functor(f) {}
21
22  // forward constructors
23  template<typename T0>
24  AutoDiffJacobian(const T0& a0) : Functor(a0) {}
25  template<typename T0, typename T1>
26  AutoDiffJacobian(const T0& a0, const T1& a1) : Functor(a0, a1) {}
27  template<typename T0, typename T1, typename T2>
28  AutoDiffJacobian(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2) {}
29
30  enum {
31    InputsAtCompileTime = Functor::InputsAtCompileTime,
32    ValuesAtCompileTime = Functor::ValuesAtCompileTime
33  };
34
35  typedef typename Functor::InputType InputType;
36  typedef typename Functor::ValueType ValueType;
37  typedef typename Functor::JacobianType JacobianType;
38  typedef typename JacobianType::Scalar Scalar;
39  typedef typename JacobianType::Index Index;
40
41  typedef Matrix<Scalar,InputsAtCompileTime,1> DerivativeType;
42  typedef AutoDiffScalar<DerivativeType> ActiveScalar;
43
44
45  typedef Matrix<ActiveScalar, InputsAtCompileTime, 1> ActiveInput;
46  typedef Matrix<ActiveScalar, ValuesAtCompileTime, 1> ActiveValue;
47
48  void operator() (const InputType& x, ValueType* v, JacobianType* _jac=0) const
49  {
50    eigen_assert(v!=0);
51    if (!_jac)
52    {
53      Functor::operator()(x, v);
54      return;
55    }
56
57    JacobianType& jac = *_jac;
58
59    ActiveInput ax = x.template cast<ActiveScalar>();
60    ActiveValue av(jac.rows());
61
62    if(InputsAtCompileTime==Dynamic)
63      for (Index j=0; j<jac.rows(); j++)
64        av[j].derivatives().resize(this->inputs());
65
66    for (Index i=0; i<jac.cols(); i++)
67      ax[i].derivatives() = DerivativeType::Unit(this->inputs(),i);
68
69    Functor::operator()(ax, &av);
70
71    for (Index i=0; i<jac.rows(); i++)
72    {
73      (*v)[i] = av[i].value();
74      jac.row(i) = av[i].derivatives();
75    }
76  }
77protected:
78
79};
80
81}
82
83#endif // EIGEN_AUTODIFF_JACOBIAN_H
84