CppADCodeGen  2.3.0
A C++ Algorithmic Differentiation Package with Source Code Generation
generic_model.hpp
1 #ifndef CPPAD_CG_GENERIC_MODEL_INCLUDED
2 #define CPPAD_CG_GENERIC_MODEL_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2012 Ciengis
6  *
7  * CppADCodeGen is distributed under multiple licenses:
8  *
9  * - Eclipse Public License Version 1.0 (EPL1), and
10  * - GNU General Public License Version 3 (GPL3).
11  *
12  * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13  * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14  * ----------------------------------------------------------------------------
15  * Author: Joao Leal
16  */
17 
18 namespace CppAD {
19 namespace cg {
20 
26 template<class Base>
27 class GenericModel {
28 protected:
29  CGAtomicGenericModel<Base>* _atomic;
30  // whether or not to evaluate forward mode of atomics during a reverse sweep
31  bool _evalAtomicForwardOne4CppAD;
32 public:
33 
34  GenericModel() :
35  _atomic(nullptr),
36  _evalAtomicForwardOne4CppAD(true) {
37  }
38 
39  inline virtual ~GenericModel() {
40  delete _atomic;
41  }
42 
48  virtual const std::string& getName() const = 0;
49 
50 
56  virtual bool isJacobianSparsityAvailable() = 0;
57 
58  // Jacobian sparsity
59  virtual std::vector<std::set<size_t> > JacobianSparsitySet() = 0;
60  virtual std::vector<bool> JacobianSparsityBool() = 0;
61  virtual void JacobianSparsity(std::vector<size_t>& equations,
62  std::vector<size_t>& variables) = 0;
63 
71  virtual bool isHessianSparsityAvailable() = 0;
72 
79  virtual std::vector<std::set<size_t> > HessianSparsitySet() = 0;
80  virtual std::vector<bool> HessianSparsityBool() = 0;
81  virtual void HessianSparsity(std::vector<size_t>& rows,
82  std::vector<size_t>& cols) = 0;
83 
91  virtual bool isEquationHessianSparsityAvailable() = 0;
92 
99  virtual std::vector<std::set<size_t> > HessianSparsitySet(size_t i) = 0;
100  virtual std::vector<bool> HessianSparsityBool(size_t i) = 0;
101  virtual void HessianSparsity(size_t i,
102  std::vector<size_t>& rows,
103  std::vector<size_t>& cols) = 0;
104 
110  virtual size_t Domain() const = 0;
111 
117  virtual size_t Range() const = 0;
118 
126  virtual const std::vector<std::string>& getAtomicFunctionNames() = 0;
127 
139  virtual bool addAtomicFunction(atomic_base<Base>& atomic) = 0;
140 
153  virtual bool addExternalModel(GenericModel<Base>& atomic) = 0;
154 
163  inline void setAtomicEvalForwardOne4CppAD(bool evalForwardOne4CppAD) {
164  _evalAtomicForwardOne4CppAD = evalForwardOne4CppAD;
165  }
166 
167  inline bool isAtomicEvalForwardOne4CppAD() const {
168  return _evalAtomicForwardOne4CppAD;
169  }
170 
171  /***********************************************************************
172  * Forward zero
173  **********************************************************************/
174 
181  virtual bool isForwardZeroAvailable() = 0;
182 
192  template<typename VectorBase>
193  inline VectorBase ForwardZero(const VectorBase& x) {
194  VectorBase dep(Range());
195  this->ForwardZero(ArrayView<const Base>(&x[0], x.size()),
196  ArrayView<Base>(&dep[0], dep.size()));
197  return dep;
198  }
199 
200  virtual void ForwardZero(const CppAD::vector<bool>& vx,
203  ArrayView<Base> ty) = 0;
204 
214  template<typename VectorBase>
215  inline void ForwardZero(const VectorBase& x,
216  VectorBase& dep) {
217  dep.resize(Range());
218  this->ForwardZero(ArrayView<const Base>(&x[0], x.size()),
219  ArrayView<Base>(&dep[0], dep.size()));
220  }
221 
222  virtual void ForwardZero(ArrayView<const Base> x,
223  ArrayView<Base> dep) = 0;
224 
235  virtual void ForwardZero(const std::vector<const Base*> &x,
236  ArrayView<Base> dep) = 0;
237 
238  /***********************************************************************
239  * Dense Jacobian
240  **********************************************************************/
241 
248  virtual bool isJacobianAvailable() = 0;
249 
250  template<typename VectorBase>
251  inline VectorBase Jacobian(const VectorBase& x) {
252  VectorBase jac(Range() * Domain());
253  Jacobian(ArrayView<const Base>(&x[0], x.size()),
254  ArrayView<Base>(&jac[0], jac.size()));
255  return jac;
256  }
257 
258  template<typename VectorBase>
259  inline void Jacobian(const VectorBase& x,
260  VectorBase& jac) {
261  jac.resize(Range() * Domain());
262  Jacobian(ArrayView<const Base>(&x[0], x.size()),
263  ArrayView<Base>(&jac[0], jac.size()));
264  }
265 
266  virtual void Jacobian(ArrayView<const Base> x,
267  ArrayView<Base> jac) = 0;
268 
269  /***********************************************************************
270  * Dense Hessian
271  **********************************************************************/
272 
280  virtual bool isHessianAvailable() = 0;
281 
282  template<typename VectorBase>
283  inline VectorBase Hessian(const VectorBase& x,
284  const VectorBase& w) {
285  VectorBase hess(Domain() * Domain());
286  this->Hessian(ArrayView<const Base>(&x[0], x.size()),
287  ArrayView<const Base>(&w[0], w.size()),
288  ArrayView<Base>(&hess[0], hess.size()));
289  return hess;
290  }
291 
292  template<typename VectorBase>
293  inline void Hessian(const VectorBase& x,
294  const VectorBase& w,
295  VectorBase& hess) {
296  hess.resize(Domain() * Domain());
297  this->Hessian(ArrayView<const Base>(&x[0], x.size()),
298  ArrayView<const Base>(&w[0], w.size()),
299  ArrayView<Base>(&hess[0], hess.size()));
300  }
301 
303 
304  template<typename VectorBase>
305  inline VectorBase Hessian(const VectorBase& x,
306  size_t i) {
307  CPPADCG_ASSERT_KNOWN(i < Range(), "Invalid equation index");
308 
309  VectorBase w(Range());
310  w[i] = 1.0;
311  VectorBase hess(Domain() * Domain());
312  this->Hessian(ArrayView<const Base>(&x[0], x.size()),
313  ArrayView<const Base>(&w[0], w.size()),
314  ArrayView<Base>(&hess[0], hess.size()));
315  return hess;
316  }
317 
318  virtual void Hessian(ArrayView<const Base> x,
320  ArrayView<Base> hess) = 0;
321 
322  /***********************************************************************
323  * Forward one
324  **********************************************************************/
325 
333  virtual bool isForwardOneAvailable() = 0;
334 
346  template<typename VectorBase>
347  inline VectorBase ForwardOne(const VectorBase& tx) {
348  size_t m = Range();
349  const size_t k = 1;
350  VectorBase ty((k + 1) * m);
351 
352  this->ForwardOne(ArrayView<const Base>(&tx[0], tx.size()),
353  ArrayView<Base>(&ty[0], ty.size()));
354 
355  VectorBase dy(m);
356  for (size_t i = 0; i < m; i++) {
357  dy[i] = ty[i * (k + 1) + k];
358  }
359 
360  return dy;
361  }
362 
374  virtual void ForwardOne(ArrayView<const Base> tx,
375  ArrayView<Base> ty) = 0;
376 
384  virtual bool isSparseForwardOneAvailable() = 0;
385 
404  virtual void ForwardOne(ArrayView<const Base> x,
405  size_t tx1Nnz, const size_t idx[], const Base tx1[],
406  ArrayView<Base> ty1) = 0;
407 
408  /***********************************************************************
409  * Reverse one
410  **********************************************************************/
411 
419  virtual bool isReverseOneAvailable() = 0;
420 
428  template<typename VectorBase>
429  inline VectorBase ReverseOne(const VectorBase& tx,
430  const VectorBase& ty,
431  const VectorBase& py) {
432  const size_t k = 0;
433  VectorBase px((k + 1) * Domain());
434  this->ReverseOne(tx, ty, px, py);
435  return px;
436  }
437 
445  template<typename VectorBase>
446  inline void ReverseOne(const VectorBase& tx,
447  const VectorBase& ty,
448  VectorBase& px,
449  const VectorBase& py) {
450  this->ReverseOne(ArrayView<const Base>(&tx[0], tx.size()),
451  ArrayView<const Base>(&ty[0], ty.size()),
452  ArrayView<Base>(&px[0], px.size()),
453  ArrayView<const Base>(&py[0], py.size()));
454  }
455 
463  virtual bool isSparseReverseOneAvailable() = 0;
464 
472  virtual void ReverseOne(ArrayView<const Base> tx,
474  ArrayView<Base> px,
475  ArrayView<const Base> py) = 0;
476 
494  virtual void ReverseOne(ArrayView<const Base> x,
495  ArrayView<Base> px,
496  size_t pyNnz, const size_t idx[], const Base py[]) = 0;
497 
498  /***********************************************************************
499  * Reverse two
500  **********************************************************************/
501 
509  virtual bool isReverseTwoAvailable() = 0;
510 
519  template<typename VectorBase>
520  inline VectorBase ReverseTwo(const VectorBase& tx,
521  const VectorBase& ty,
522  const VectorBase& py) {
523  const size_t k = 1;
524  VectorBase px((k + 1) * Domain());
525  this->ReverseTwo(tx, ty, px, py);
526  return px;
527  }
528 
537  template<typename VectorBase>
538  inline void ReverseTwo(const VectorBase& tx,
539  const VectorBase& ty,
540  VectorBase& px,
541  const VectorBase& py) {
542  this->ReverseTwo(ArrayView<const Base>(&tx[0], tx.size()),
543  ArrayView<const Base>(&ty[0], ty.size()),
544  ArrayView<Base>(&px[0], px.size()),
545  ArrayView<const Base>(&py[0], py.size()));
546  }
547 
555  virtual bool isSparseReverseTwoAvailable() = 0;
556 
565  virtual void ReverseTwo(ArrayView<const Base> tx,
567  ArrayView<Base> px,
568  ArrayView<const Base> py) = 0;
588  virtual void ReverseTwo(ArrayView<const Base> x,
589  size_t tx1Nnz, const size_t idx[], const Base tx1[],
590  ArrayView<Base> px2,
591  ArrayView<const Base> py2) = 0;
592 
593  /***********************************************************************
594  * Sparse Jacobians
595  **********************************************************************/
596 
603  virtual bool isSparseJacobianAvailable() = 0;
604 
614  template<typename VectorBase>
615  inline VectorBase SparseJacobian(const VectorBase& x) {
616  VectorBase jac(Range() * Domain());
617  SparseJacobian(ArrayView<const Base>(&x[0], x.size()),
618  ArrayView<Base>(&jac[0], jac.size()));
619  return jac;
620  }
621 
631  template<typename VectorBase>
632  inline void SparseJacobian(const VectorBase& x,
633  VectorBase& jac) {
634  jac.resize(Range() * Domain());
635  SparseJacobian(ArrayView<const Base>(&x[0], x.size()),
636  ArrayView<Base>(&jac[0], jac.size()));
637  }
638 
648  virtual void SparseJacobian(ArrayView<const Base> x,
649  ArrayView<Base> jac) = 0;
650 
651  virtual void SparseJacobian(const std::vector<Base> &x,
652  std::vector<Base>& jac,
653  std::vector<size_t>& row,
654  std::vector<size_t>& col) = 0;
655 
656  virtual void SparseJacobian(ArrayView<const Base> x,
657  ArrayView<Base> jac,
658  size_t const** row,
659  size_t const** col) = 0;
660 
673  virtual void SparseJacobian(const std::vector<const Base*>& x,
674  ArrayView<Base> jac,
675  size_t const** row,
676  size_t const** col) = 0;
677 
678  /***********************************************************************
679  * Sparse Hessians
680  **********************************************************************/
681 
689  virtual bool isSparseHessianAvailable() = 0;
690 
691  template<typename VectorBase>
692  inline VectorBase SparseHessian(const VectorBase& x,
693  const VectorBase& w) {
694  VectorBase hess(Domain() * Domain());
695  SparseHessian(ArrayView<const Base>(&x[0], x.size()),
696  ArrayView<const Base>(&w[0], w.size()),
697  ArrayView<Base>(&hess[0], hess.size()));
698  return hess;
699  }
700 
701  template<typename VectorBase>
702  inline void SparseHessian(const VectorBase& x,
703  const VectorBase& w,
704  VectorBase& hess) {
705  hess.resize(Domain() * Domain());
706  SparseHessian(ArrayView<const Base>(&x[0], x.size()),
707  ArrayView<const Base>(&w[0], w.size()),
708  ArrayView<Base>(&hess[0], hess.size()));
709  }
710 
711  virtual void SparseHessian(ArrayView<const Base> x,
713  ArrayView<Base> hess) = 0;
714 
715  virtual void SparseHessian(const std::vector<Base> &x,
716  const std::vector<Base> &w,
717  std::vector<Base>& hess,
718  std::vector<size_t>& row,
719  std::vector<size_t>& col) = 0;
720 
721  virtual void SparseHessian(ArrayView<const Base> x,
723  ArrayView<Base> hess,
724  size_t const** row,
725  size_t const** col) = 0;
726 
741  virtual void SparseHessian(const std::vector<const Base*>& x,
743  ArrayView<Base> hess,
744  size_t const** row,
745  size_t const** col) = 0;
746 
755  if (_atomic == nullptr) {
756  _atomic = new CGAtomicGenericModel<Base>(*this);
757  }
758  return *_atomic;
759  }
760 };
761 
762 } // END cg namespace
763 } // END CppAD namespace
764 
765 #endif
VectorBase Hessian(const VectorBase &x, size_t i)
calculate Hessian for one component of f
VectorBase ForwardZero(const VectorBase &x)
virtual bool addAtomicFunction(atomic_base< Base > &atomic)=0
virtual bool isReverseTwoAvailable()=0
virtual const std::vector< std::string > & getAtomicFunctionNames()=0
virtual bool addExternalModel(GenericModel< Base > &atomic)=0
VectorBase ReverseTwo(const VectorBase &tx, const VectorBase &ty, const VectorBase &py)
virtual bool isForwardOneAvailable()=0
virtual bool isSparseHessianAvailable()=0
virtual bool isJacobianSparsityAvailable()=0
virtual bool isSparseReverseTwoAvailable()=0
virtual bool isJacobianAvailable()=0
virtual bool isForwardZeroAvailable()=0
VectorBase SparseJacobian(const VectorBase &x)
VectorBase ForwardOne(const VectorBase &tx)
virtual bool isHessianSparsityAvailable()=0
void SparseJacobian(const VectorBase &x, VectorBase &jac)
VectorBase ReverseOne(const VectorBase &tx, const VectorBase &ty, const VectorBase &py)
virtual std::vector< std::set< size_t > > HessianSparsitySet()=0
void ReverseOne(const VectorBase &tx, const VectorBase &ty, VectorBase &px, const VectorBase &py)
virtual bool isHessianAvailable()=0
virtual bool isReverseOneAvailable()=0
virtual bool isSparseJacobianAvailable()=0
virtual bool isSparseReverseOneAvailable()=0
virtual size_t Range() const =0
virtual const std::string & getName() const =0
void ReverseTwo(const VectorBase &tx, const VectorBase &ty, VectorBase &px, const VectorBase &py)
virtual CGAtomicGenericModel< Base > & asAtomic()
virtual size_t Domain() const =0
void ForwardZero(const VectorBase &x, VectorBase &dep)
virtual bool isEquationHessianSparsityAvailable()=0
virtual bool isSparseForwardOneAvailable()=0
void setAtomicEvalForwardOne4CppAD(bool evalForwardOne4CppAD)