CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
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 * Copyright (C) 2020 Joao Leal
7 *
8 * CppADCodeGen is distributed under multiple licenses:
9 *
10 * - Eclipse Public License Version 1.0 (EPL1), and
11 * - GNU General Public License Version 3 (GPL3).
12 *
13 * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
14 * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
15 * ----------------------------------------------------------------------------
16 * Author: Joao Leal
17 */
18
19namespace CppAD {
20namespace cg {
21
27template<class Base>
29protected:
31 // whether or not to evaluate forward mode of atomics during a reverse sweep
32 bool _evalAtomicForwardOne4CppAD;
33public:
34
35 GenericModel() :
36 _atomic(nullptr),
37 _evalAtomicForwardOne4CppAD(true) {
38 }
39
40 inline virtual ~GenericModel() {
41 delete _atomic;
42 }
43
49 virtual const std::string& getName() const = 0;
50
51
57 virtual bool isJacobianSparsityAvailable() = 0;
58
59 // Jacobian sparsity
60 virtual std::vector<std::set<size_t> > JacobianSparsitySet() = 0;
61 virtual std::vector<bool> JacobianSparsityBool() = 0;
62 virtual void JacobianSparsity(std::vector<size_t>& equations,
63 std::vector<size_t>& variables) = 0;
64
72 virtual bool isHessianSparsityAvailable() = 0;
73
80 virtual std::vector<std::set<size_t> > HessianSparsitySet() = 0;
81 virtual std::vector<bool> HessianSparsityBool() = 0;
82 virtual void HessianSparsity(std::vector<size_t>& rows,
83 std::vector<size_t>& cols) = 0;
84
93
100 virtual std::vector<std::set<size_t> > HessianSparsitySet(size_t i) = 0;
101 virtual std::vector<bool> HessianSparsityBool(size_t i) = 0;
102 virtual void HessianSparsity(size_t i,
103 std::vector<size_t>& rows,
104 std::vector<size_t>& cols) = 0;
105
111 virtual size_t Domain() const = 0;
112
118 virtual size_t Range() const = 0;
119
127 virtual const std::vector<std::string>& getAtomicFunctionNames() = 0;
128
140 virtual bool addAtomicFunction(atomic_base<Base>& atomic) = 0;
141
154 virtual bool addExternalModel(GenericModel<Base>& atomic) = 0;
155
164 inline void setAtomicEvalForwardOne4CppAD(bool evalForwardOne4CppAD) {
165 _evalAtomicForwardOne4CppAD = evalForwardOne4CppAD;
166 }
167
168 inline bool isAtomicEvalForwardOne4CppAD() const {
169 return _evalAtomicForwardOne4CppAD;
170 }
171
172 /***********************************************************************
173 * Forward zero
174 **********************************************************************/
175
182 virtual bool isForwardZeroAvailable() = 0;
183
193 template<typename VectorBase>
194 inline VectorBase ForwardZero(const VectorBase& x) {
195 VectorBase dep(Range());
196 this->ForwardZero(ArrayView<const Base>(&x[0], x.size()),
197 ArrayView<Base>(&dep[0], dep.size()));
198 return dep;
199 }
200
201 virtual void ForwardZero(const CppAD::vector<bool>& vx,
204 ArrayView<Base> ty) = 0;
205
215 template<typename VectorBase>
216 inline void ForwardZero(const VectorBase& x,
217 VectorBase& dep) {
218 dep.resize(Range());
219 this->ForwardZero(ArrayView<const Base>(&x[0], x.size()),
220 ArrayView<Base>(&dep[0], dep.size()));
221 }
222
223 virtual void ForwardZero(ArrayView<const Base> x,
224 ArrayView<Base> dep) = 0;
225
236 virtual void ForwardZero(const std::vector<const Base*> &x,
237 ArrayView<Base> dep) = 0;
238
239 /***********************************************************************
240 * Dense Jacobian
241 **********************************************************************/
242
249 virtual bool isJacobianAvailable() = 0;
250
251 template<typename VectorBase>
252 inline VectorBase Jacobian(const VectorBase& x) {
253 VectorBase jac(Range() * Domain());
254 Jacobian(ArrayView<const Base>(&x[0], x.size()),
255 ArrayView<Base>(&jac[0], jac.size()));
256 return jac;
257 }
258
259 template<typename VectorBase>
260 inline void Jacobian(const VectorBase& x,
261 VectorBase& jac) {
262 jac.resize(Range() * Domain());
263 Jacobian(ArrayView<const Base>(&x[0], x.size()),
264 ArrayView<Base>(&jac[0], jac.size()));
265 }
266
267 virtual void Jacobian(ArrayView<const Base> x,
268 ArrayView<Base> jac) = 0;
269
270 /***********************************************************************
271 * Dense Hessian
272 **********************************************************************/
273
281 virtual bool isHessianAvailable() = 0;
282
283 template<typename VectorBase>
284 inline VectorBase Hessian(const VectorBase& x,
285 const VectorBase& w) {
286 VectorBase hess(Domain() * Domain());
287 this->Hessian(ArrayView<const Base>(&x[0], x.size()),
288 ArrayView<const Base>(&w[0], w.size()),
289 ArrayView<Base>(&hess[0], hess.size()));
290 return hess;
291 }
292
293 template<typename VectorBase>
294 inline void Hessian(const VectorBase& x,
295 const VectorBase& w,
296 VectorBase& hess) {
297 hess.resize(Domain() * Domain());
298 this->Hessian(ArrayView<const Base>(&x[0], x.size()),
299 ArrayView<const Base>(&w[0], w.size()),
300 ArrayView<Base>(&hess[0], hess.size()));
301 }
302
304
305 template<typename VectorBase>
306 inline VectorBase Hessian(const VectorBase& x,
307 size_t i) {
308 CPPADCG_ASSERT_KNOWN(i < Range(), "Invalid equation index")
309
310 VectorBase w(Range());
311 w[i] = 1.0;
312 VectorBase hess(Domain() * Domain());
313 this->Hessian(ArrayView<const Base>(&x[0], x.size()),
314 ArrayView<const Base>(&w[0], w.size()),
315 ArrayView<Base>(&hess[0], hess.size()));
316 return hess;
317 }
318
319 virtual void Hessian(ArrayView<const Base> x,
321 ArrayView<Base> hess) = 0;
322
323 /***********************************************************************
324 * Forward one
325 **********************************************************************/
326
334 virtual bool isForwardOneAvailable() = 0;
335
347 template<typename VectorBase>
348 inline VectorBase ForwardOne(const VectorBase& tx) {
349 size_t m = Range();
350 const size_t k = 1;
351 VectorBase ty((k + 1) * m);
352
353 this->ForwardOne(ArrayView<const Base>(&tx[0], tx.size()),
354 ArrayView<Base>(&ty[0], ty.size()));
355
356 VectorBase dy(m);
357 for (size_t i = 0; i < m; i++) {
358 dy[i] = ty[i * (k + 1) + k];
359 }
360
361 return dy;
362 }
363
376 ArrayView<Base> ty) = 0;
377
385 virtual bool isSparseForwardOneAvailable() = 0;
386
406 size_t tx1Nnz, const size_t idx[], const Base tx1[],
407 ArrayView<Base> ty1) = 0;
408
409 /***********************************************************************
410 * Reverse one
411 **********************************************************************/
412
420 virtual bool isReverseOneAvailable() = 0;
421
429 template<typename VectorBase>
430 inline VectorBase ReverseOne(const VectorBase& tx,
431 const VectorBase& ty,
432 const VectorBase& py) {
433 const size_t k = 0;
434 VectorBase px((k + 1) * Domain());
435 this->ReverseOne(tx, ty, px, py);
436 return px;
437 }
438
446 template<typename VectorBase>
447 inline void ReverseOne(const VectorBase& tx,
448 const VectorBase& ty,
449 VectorBase& px,
450 const VectorBase& py) {
451 this->ReverseOne(ArrayView<const Base>(&tx[0], tx.size()),
452 ArrayView<const Base>(&ty[0], ty.size()),
453 ArrayView<Base>(&px[0], px.size()),
454 ArrayView<const Base>(&py[0], py.size()));
455 }
456
464 virtual bool isSparseReverseOneAvailable() = 0;
465
476 ArrayView<const Base> py) = 0;
477
497 size_t pyNnz, const size_t idx[], const Base py[]) = 0;
498
499 /***********************************************************************
500 * Reverse two
501 **********************************************************************/
502
510 virtual bool isReverseTwoAvailable() = 0;
511
520 template<typename VectorBase>
521 inline VectorBase ReverseTwo(const VectorBase& tx,
522 const VectorBase& ty,
523 const VectorBase& py) {
524 const size_t k = 1;
525 VectorBase px((k + 1) * Domain());
526 this->ReverseTwo(tx, ty, px, py);
527 return px;
528 }
529
538 template<typename VectorBase>
539 inline void ReverseTwo(const VectorBase& tx,
540 const VectorBase& ty,
541 VectorBase& px,
542 const VectorBase& py) {
543 this->ReverseTwo(ArrayView<const Base>(&tx[0], tx.size()),
544 ArrayView<const Base>(&ty[0], ty.size()),
545 ArrayView<Base>(&px[0], px.size()),
546 ArrayView<const Base>(&py[0], py.size()));
547 }
548
556 virtual bool isSparseReverseTwoAvailable() = 0;
557
569 ArrayView<const Base> py) = 0;
590 size_t tx1Nnz, const size_t idx[], const Base tx1[],
591 ArrayView<Base> px2,
592 ArrayView<const Base> py2) = 0;
593
594 /***********************************************************************
595 * Sparse Jacobians
596 **********************************************************************/
597
604 virtual bool isSparseJacobianAvailable() = 0;
605
615 template<typename VectorBase>
616 inline VectorBase SparseJacobian(const VectorBase& x) {
617 VectorBase jac(Range() * Domain());
618 SparseJacobian(ArrayView<const Base>(&x[0], x.size()),
619 ArrayView<Base>(&jac[0], jac.size()));
620 return jac;
621 }
622
632 template<typename VectorBase>
633 inline void SparseJacobian(const VectorBase& x,
634 VectorBase& jac) {
635 jac.resize(Range() * Domain());
636 SparseJacobian(ArrayView<const Base>(&x[0], x.size()),
637 ArrayView<Base>(&jac[0], jac.size()));
638 }
639
650 ArrayView<Base> jac) = 0;
651
652 virtual void SparseJacobian(const std::vector<Base> &x,
653 std::vector<Base>& jac,
654 std::vector<size_t>& row,
655 std::vector<size_t>& col) = 0;
656
658 ArrayView<Base> jac,
659 size_t const** row,
660 size_t const** col) = 0;
661
674 virtual void SparseJacobian(const std::vector<const Base*>& x,
675 ArrayView<Base> jac,
676 size_t const** row,
677 size_t const** col) = 0;
678
679 /***********************************************************************
680 * Sparse Hessians
681 **********************************************************************/
682
690 virtual bool isSparseHessianAvailable() = 0;
691
692 template<typename VectorBase>
693 inline VectorBase SparseHessian(const VectorBase& x,
694 const VectorBase& w) {
695 VectorBase hess(Domain() * Domain());
696 SparseHessian(ArrayView<const Base>(&x[0], x.size()),
697 ArrayView<const Base>(&w[0], w.size()),
698 ArrayView<Base>(&hess[0], hess.size()));
699 return hess;
700 }
701
702 template<typename VectorBase>
703 inline void SparseHessian(const VectorBase& x,
704 const VectorBase& w,
705 VectorBase& hess) {
706 hess.resize(Domain() * Domain());
707 SparseHessian(ArrayView<const Base>(&x[0], x.size()),
708 ArrayView<const Base>(&w[0], w.size()),
709 ArrayView<Base>(&hess[0], hess.size()));
710 }
711
712 virtual void SparseHessian(ArrayView<const Base> x,
713 ArrayView<const Base> w,
714 ArrayView<Base> hess) = 0;
715
716 virtual void SparseHessian(const std::vector<Base> &x,
717 const std::vector<Base> &w,
718 std::vector<Base>& hess,
719 std::vector<size_t>& row,
720 std::vector<size_t>& col) = 0;
721
722 virtual void SparseHessian(ArrayView<const Base> x,
723 ArrayView<const Base> w,
724 ArrayView<Base> hess,
725 size_t const** row,
726 size_t const** col) = 0;
727
742 virtual void SparseHessian(const std::vector<const Base*>& x,
744 ArrayView<Base> hess,
745 size_t const** row,
746 size_t const** col) = 0;
747
756 if (_atomic == nullptr) {
757 _atomic = new CGAtomicGenericModel<Base>(*this);
758 }
759 return *_atomic;
760 }
761};
762
763} // END cg namespace
764} // END CppAD namespace
765
766#endif
virtual size_t Range() const =0
VectorBase ForwardZero(const VectorBase &x)
virtual void SparseHessian(const std::vector< const Base * > &x, ArrayView< const Base > w, ArrayView< Base > hess, size_t const **row, size_t const **col)=0
VectorBase Hessian(const VectorBase &x, size_t i)
calculate Hessian for one component of f
void setAtomicEvalForwardOne4CppAD(bool evalForwardOne4CppAD)
virtual bool isReverseOneAvailable()=0
virtual bool isJacobianSparsityAvailable()=0
virtual void ReverseTwo(ArrayView< const Base > x, size_t tx1Nnz, const size_t idx[], const Base tx1[], ArrayView< Base > px2, ArrayView< const Base > py2)=0
VectorBase ReverseTwo(const VectorBase &tx, const VectorBase &ty, const VectorBase &py)
void ReverseTwo(const VectorBase &tx, const VectorBase &ty, VectorBase &px, const VectorBase &py)
VectorBase ReverseOne(const VectorBase &tx, const VectorBase &ty, const VectorBase &py)
virtual void SparseJacobian(const std::vector< const Base * > &x, ArrayView< Base > jac, size_t const **row, size_t const **col)=0
virtual bool isSparseReverseOneAvailable()=0
virtual std::vector< std::set< size_t > > HessianSparsitySet(size_t i)=0
virtual bool isForwardZeroAvailable()=0
virtual bool isSparseJacobianAvailable()=0
virtual void ReverseOne(ArrayView< const Base > tx, ArrayView< const Base > ty, ArrayView< Base > px, ArrayView< const Base > py)=0
virtual size_t Domain() const =0
virtual void ForwardOne(ArrayView< const Base > x, size_t tx1Nnz, const size_t idx[], const Base tx1[], ArrayView< Base > ty1)=0
virtual bool isJacobianAvailable()=0
virtual bool addExternalModel(GenericModel< Base > &atomic)=0
virtual bool isSparseForwardOneAvailable()=0
virtual void ReverseOne(ArrayView< const Base > x, ArrayView< Base > px, size_t pyNnz, const size_t idx[], const Base py[])=0
virtual bool isEquationHessianSparsityAvailable()=0
VectorBase SparseJacobian(const VectorBase &x)
virtual bool isHessianSparsityAvailable()=0
virtual void SparseJacobian(ArrayView< const Base > x, ArrayView< Base > jac)=0
virtual bool isSparseReverseTwoAvailable()=0
virtual bool isReverseTwoAvailable()=0
virtual bool addAtomicFunction(atomic_base< Base > &atomic)=0
void ReverseOne(const VectorBase &tx, const VectorBase &ty, VectorBase &px, const VectorBase &py)
void ForwardZero(const VectorBase &x, VectorBase &dep)
virtual bool isSparseHessianAvailable()=0
virtual bool isHessianAvailable()=0
virtual void ForwardOne(ArrayView< const Base > tx, ArrayView< Base > ty)=0
virtual void ReverseTwo(ArrayView< const Base > tx, ArrayView< const Base > ty, ArrayView< Base > px, ArrayView< const Base > py)=0
virtual std::vector< std::set< size_t > > HessianSparsitySet()=0
virtual void ForwardZero(const std::vector< const Base * > &x, ArrayView< Base > dep)=0
void SparseJacobian(const VectorBase &x, VectorBase &jac)
virtual bool isForwardOneAvailable()=0
virtual const std::string & getName() const =0
virtual CGAtomicGenericModel< Base > & asAtomic()
VectorBase ForwardOne(const VectorBase &tx)
virtual const std::vector< std::string > & getAtomicFunctionNames()=0