autodiff_chain_jacobian_sparse.h
Go to the documentation of this file.
1 // Copyright (C) 2018
2 //
3 // This Source Code Form is subject to the terms of the Mozilla
4 // Public License v. 2.0. If a copy of the MPL was not distributed
5 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 //
7 // Modified from unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h
8 
9 #ifndef EIGEN_AUTODIFF_CHAIN_JACOBIAN_SPARSE_H_
10 #define EIGEN_AUTODIFF_CHAIN_JACOBIAN_SPARSE_H_
11 
14 
15 namespace Eigen
16 {
17 template <typename Functor>
19 {
20 public:
23 // forward constructors
24 #if EIGEN_HAS_VARIADIC_TEMPLATES
25  template <typename... T>
26  AutoDiffChainJacobianSparse(const T &... Values) : Functor(Values...)
27  {
28  }
29 #else
30  template <typename T0>
32  {
33  }
34  template <typename T0, typename T1>
35  AutoDiffChainJacobianSparse(const T0 &a0, const T1 &a1) : Functor(a0, a1)
36  {
37  }
38  template <typename T0, typename T1, typename T2>
39  AutoDiffChainJacobianSparse(const T0 &a0, const T1 &a1, const T2 &a2) : Functor(a0, a1, a2)
40  {
41  }
42 #endif
43 
44  typedef typename Functor::InputType InputType;
45  typedef typename Functor::ValueType ValueType;
46  typedef typename ValueType::Scalar Scalar;
47 
48  enum
49  {
50  InputsAtCompileTime = InputType::RowsAtCompileTime,
51  ValuesAtCompileTime = ValueType::RowsAtCompileTime,
52  JacobianInputsAtCompileTime = Functor::JacobianColsAtCompileTime // JacobianInputsAtCompileTime no longer have to match InputsAtCompileTime
53  };
54 
55  typedef SparseMatrix<Scalar> JacobianType;
56 
57  typedef SparseMatrix<Scalar> InputJacobianType; // Jacobian.cols() matches InputJacobian.cols()
58  typedef typename JacobianType::Index Index;
59 
60  typedef SparseVector<Scalar> DerivativeType; // Derivative rows() matches InputJacobian.cols()
62  typedef typename DerivativeType::InnerIterator JacobianInnerIteratorType;
63 
64  typedef Matrix<ActiveScalar, InputsAtCompileTime, 1> ActiveInput;
65  typedef Matrix<ActiveScalar, ValuesAtCompileTime, 1> ActiveValue;
66 
67 #if EIGEN_HAS_VARIADIC_TEMPLATES
68  // Some compilers don't accept variadic parameters after a default parameter,
69  // i.e., we can't just write _jac=0 but we need to overload operator():
70  EIGEN_STRONG_INLINE
71  void operator()(const InputType &x, ValueType &v) const
72  {
73  this->operator()(x, v);
74  }
75 
76  template <typename... ParamsType>
77  void operator()(const InputType &x, ValueType &v, const ParamsType &... Params) const
78  {
79  this->operator()(x, v, Params...);
80  }
81 
82  template <typename... ParamsType>
83  void operator()(const InputType &x, ValueType &v, JacobianType &jac, const ParamsType &... Params) const
84  {
85  this->operator()(x, v, jac, nullptr, Params...);
86  }
87 
88  template <typename... ParamsType>
89  void operator()(const InputType &x, ValueType &v, JacobianType &jac, const InputJacobianType &ijac,
90  const ParamsType &... Params) const
91  {
92  this->operator()(x, v, jac, &ijac, Params...);
93  }
94 
95  // Optional parameter InputJacobian (_ijac)
96  template <typename... ParamsType>
97  void operator()(const InputType &x, ValueType &v, JacobianType &jac, const InputJacobianType *_ijac = 0,
98  const ParamsType &... Params) const
99 #else
100  EIGEN_STRONG_INLINE
101  void operator()(const InputType &x, ValueType &v) const
102  {
103  this->operator()(x, v);
104  }
105 
106  void operator()(const InputType &x, ValueType &v, JacobianType &jac) const
107  {
108  this->operator()(x, v, jac, nullptr);
109  }
110 
111  void operator()(const InputType &x, ValueType &v, JacobianType &jac, const InputJacobianType &ijac) const
112  {
113  this->operator()(x, v, jac, &ijac);
114  }
115 
116  void operator()(const InputType &x, ValueType &v, JacobianType &jac = 0, const InputJacobianType *_ijac = 0) const
117 #endif
118  {
119  ActiveInput ax = x.template cast<ActiveScalar>();
120  ActiveValue av(jac.rows());
121 
122  if (!_ijac)
123  {
124  eigen_assert(x.rows() == jac.cols());
125  for (Index j = 0; j < jac.rows(); ++j)
126  av[j].derivatives().resize(x.rows());
127 
128  for (Index i = 0; i < x.rows(); ++i)
129  {
130  ax[i].derivatives().resize(x.rows());
131  ax[i].derivatives().insert(i) = 1.0;
132  }
133  }
134  else
135  {
136  // If specified, copy derivatives from InputJacobian
137  const InputJacobianType &ijac = *_ijac;
138 
139  for (Index j = 0; j < jac.rows(); ++j)
140  av[j].derivatives().resize(ijac.cols());
141 
142  for (Index i = 0; i < x.rows(); ++i)
143  {
144  ax[i].derivatives().resize(ijac.cols());
145  ax[i].derivatives() = ijac.row(i);
146  }
147  }
148 
149 #if EIGEN_HAS_VARIADIC_TEMPLATES
150  Functor::operator()(ax, av, Params...);
151 #else
152  Functor::operator()(ax, av);
153 #endif
154 
155  for (int i = 0; i < jac.rows(); ++i)
156  {
157  v[i] = av[i].value();
158  for (JacobianInnerIteratorType it(av[i].derivatives(), 0); it; ++it)
159  {
160  jac.insert(i, it.row()) = av[i].derivatives().coeffRef(it.row());
161  }
162  }
163  }
164 };
165 
166 } // namespace Eigen
167 
168 #endif // EIGEN_AUTODIFF_CHAIN_JACOBIAN_SPARSE_H_
EIGEN_STRONG_INLINE void operator()(const InputType &x, ValueType &v) const
void operator()(const InputType &x, ValueType &v, JacobianType &jac, const InputJacobianType &ijac) const
FunctorBase< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic > Functor
Definition: functor.h:49
void operator()(const InputType &x, ValueType &v, JacobianType &jac=0, const InputJacobianType *_ijac=0) const
AutoDiffChainJacobianSparse(const T0 &a0, const T1 &a1, const T2 &a2)
DerivativeType::InnerIterator JacobianInnerIteratorType
AutoDiffScalar< DerivativeType > ActiveScalar
AutoDiffChainJacobianSparse(const T0 &a0, const T1 &a1)
void operator()(const InputType &x, ValueType &v, JacobianType &jac) const
Matrix< ActiveScalar, ValuesAtCompileTime, 1 > ActiveValue
Matrix< ActiveScalar, InputsAtCompileTime, 1 > ActiveInput
double x


exotica_core
Author(s): Yiming Yang, Michael Camilleri
autogenerated on Sat Apr 10 2021 02:34:49