CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
base_abstract_atomic_fun.hpp
1#ifndef CPPAD_CG_BASE_ABSTRACT_ATOMIC_FUN_INCLUDED
2#define CPPAD_CG_BASE_ABSTRACT_ATOMIC_FUN_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2019 Joao Leal
6 * Copyright (C) 2013 Ciengis
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>
28class BaseAbstractAtomicFun : public atomic_base<CppAD::cg::CG<Base> > {
29public:
31 using Arg = Argument<Base>;
32protected:
33
40 explicit BaseAbstractAtomicFun(const std::string& name) :
41 atomic_base<CGB>(name) {
42 CPPADCG_ASSERT_KNOWN(!name.empty(), "The atomic function name cannot be empty")
43 }
44
45public:
46
47 template <class ADVector>
48 void operator()(const ADVector& ax,
49 ADVector& ay,
50 size_t id = 0) {
51 this->atomic_base<CGB>::operator()(ax, ay, id);
52 }
53
54 virtual ~BaseAbstractAtomicFun() = default;
55
56protected:
57
58 static inline void appendAsArguments(typename std::vector<Arg>::iterator begin,
59 const CppAD::vector<CGB>& tx) {
60 std::vector<Arg> arguments(tx.size());
61 typename std::vector<Arg>::iterator it = begin;
62 for (size_t i = 0; i < arguments.size(); i++, ++it) {
63 if (tx[i].isParameter()) {
64 *it = Arg(tx[i].getValue());
65 } else {
66 *it = Arg(*tx[i].getOperationNode());
67 }
68 }
69 }
70
71 static inline OperationNode<Base>* makeArray(CodeHandler<Base>& handler,
72 const CppAD::vector<CGB>& tx) {
73 std::vector<Arg> arrayArgs = asArguments(tx);
74 std::vector<size_t> info; // empty
75
76 return handler.makeNode(CGOpCode::ArrayCreation, info, arrayArgs);
77 }
78
79 static inline OperationNode<Base>* makeArray(CodeHandler<Base>& handler,
80 const CppAD::vector<CGB>& tx,
81 size_t p,
82 size_t k) {
83 CPPADCG_ASSERT_UNKNOWN(k <= p)
84 size_t n = tx.size() / (p + 1);
85 std::vector<Arg> arrayArgs(n);
86 for (size_t i = 0; i < n; i++) {
87 arrayArgs[i] = asArgument(tx[i * (p + 1) + k]);
88 }
89
90 return handler.makeNode(CGOpCode::ArrayCreation,{}, arrayArgs);
91 }
92
93 static inline OperationNode<Base>* makeZeroArray(CodeHandler<Base>& handler,
94 size_t size) {
95 CppAD::vector<CGB> tx2(size);
96 std::vector<Arg> arrayArgs = asArguments(tx2);
97
98 return handler.makeNode(CGOpCode::ArrayCreation,{}, arrayArgs);
99 }
100
101 static inline OperationNode<Base>* makeEmptySparseArray(CodeHandler<Base>& handler,
102 size_t size) {
103 return handler.makeNode(CGOpCode::SparseArrayCreation,{size}, {}); //empty args
104 }
105
106 static inline OperationNode<Base>* makeSparseArray(CodeHandler<Base>& handler,
107 const CppAD::vector<CGB>& py,
108 size_t p,
109 size_t k) {
110 size_t p1 = p + 1;
111 CPPADCG_ASSERT_UNKNOWN(k < p1)
112 size_t n = py.size() / p1;
113
114 std::vector<Arg> arrayArgs;
115 std::vector<size_t> arrayIdx(1);
116 arrayIdx[0] = n; // array size
117
118 arrayArgs.reserve(py.size() / 3);
119 arrayIdx.reserve(1 + py.size() / 3);
120
121 for (size_t i = 0; i < n; i++) {
122 if (!py[i * p1 + k].isIdenticalZero()) {
123 arrayArgs.push_back(asArgument(py[i * p1 + k]));
124 arrayIdx.push_back(i);
125 }
126 }
127
128 return handler.makeNode(CGOpCode::SparseArrayCreation, arrayIdx, arrayArgs);
129 }
130
131 static inline bool isParameters(const CppAD::vector<CGB>& tx) {
132 for (size_t i = 0; i < tx.size(); i++) {
133 if (!tx[i].isParameter()) {
134 return false;
135 }
136 }
137 return true;
138 }
139
140 static inline bool isValuesDefined(const CppAD::vector<CGB>& tx) {
141 for (size_t i = 0; i < tx.size(); i++) {
142 if (!tx[i].isValueDefined()) {
143 return false;
144 }
145 }
146 return true;
147 }
148
149};
150
151} // END cg namespace
152} // END CppAD namespace
153
154#endif