CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
cond_exp_op.hpp
1#ifndef CPPAD_CG_COND_EXP_OP_INCLUDED
2#define CPPAD_CG_COND_EXP_OP_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
18namespace CppAD {
19
20namespace {
21
25template<class Base>
26inline bool isSameExpression(const cg::CG<Base>& trueCase,
27 const cg::CG<Base>& falseCase) {
28 return (trueCase.isParameter() && falseCase.isParameter() &&
29 trueCase.getValue() == falseCase.getValue()) ||
30 (trueCase.isVariable() && falseCase.isVariable() &&
31 trueCase.getOperationNode() == falseCase.getOperationNode());
32}
33
39template<class Base>
40inline cg::CodeHandler<Base>* findCodeHandler(const cg::CG<Base>& left,
41 const cg::CG<Base>& right,
42 const cg::CG<Base>& trueCase,
43 const cg::CG<Base>& falseCase) {
44 cg::CodeHandler<Base>* handler;
45
46 cg::CodeHandler<Base>* lh = left.getCodeHandler();
47 cg::CodeHandler<Base>* rh = right.getCodeHandler();
48 cg::CodeHandler<Base>* th = trueCase.getCodeHandler();
49 cg::CodeHandler<Base>* fh = falseCase.getCodeHandler();
50
51 if (!left.isParameter()) {
52 handler = lh;
53 } else if (!right.isParameter()) {
54 handler = rh;
55 } else if (!trueCase.isParameter()) {
56 handler = th;
57 } else if (!falseCase.isParameter()) {
58 handler = fh;
59 } else {
60 CPPAD_ASSERT_UNKNOWN(0)
61 throw cg::CGException("Unexpected error!");
62 }
63
64 if ((!right.isParameter() && rh != handler)
65 || (!trueCase.isParameter() && th != handler)
66 || (!falseCase.isParameter() && fh != handler)) {
67 throw cg::CGException("Attempting to use different source code generation handlers in the same source code generation");
68 }
69
70 return handler;
71}
72
73} // END namespace
74
79template<class Base>
80inline cg::CG<Base> CondExp(cg::CGOpCode op,
81 const cg::CG<Base>& left,
82 const cg::CG<Base>& right,
83 const cg::CG<Base>& trueCase,
84 const cg::CG<Base>& falseCase,
85 bool (*compare)(const Base&, const Base&)) {
86 using namespace CppAD::cg;
87
88 if (left.isParameter() && right.isParameter()) {
89 if (compare(left.getValue(), right.getValue()))
90 return trueCase;
91 else
92 return falseCase;
93
94
95 } else if (isSameExpression(trueCase, falseCase)) {
96 return trueCase;
97 } else {
98
99 CodeHandler<Base>* handler = findCodeHandler(left, right, trueCase, falseCase);
100
101 CG<Base> result(*handler->makeNode(op,{left.argument(), right.argument(), trueCase.argument(), falseCase.argument()}));
102
103 if (left.isValueDefined() && right.isValueDefined()) {
104 if (compare(left.getValue(), right.getValue())) {
105 if (trueCase.isValueDefined()) {
106 result.setValue(trueCase.getValue());
107 }
108 } else
109 if (falseCase.isValueDefined()) {
110 result.setValue(falseCase.getValue());
111 }
112 }
113
114 return result;
115 }
116
117}
118
122template<class Base>
124 const cg::CG<Base>& right,
125 const cg::CG<Base>& trueCase,
126 const cg::CG<Base>& falseCase) {
127
128 bool (*compare)(const Base&, const Base&) = [](const Base& l, const Base & r) {
129 return l < r;
130 };
131
132 return CondExp(cg::CGOpCode::ComLt,
133 left, right,
134 trueCase, falseCase,
135 compare);
136}
137
141template<class Base>
143 const cg::CG<Base>& right,
144 const cg::CG<Base>& trueCase,
145 const cg::CG<Base>& falseCase) {
146 bool (*comp)(const Base&, const Base&) = [](const Base& l, const Base & r) {
147 return l <= r;
148 };
149
150 return CondExp(cg::CGOpCode::ComLe,
151 left, right,
152 trueCase, falseCase,
153 comp);
154}
155
159template<class Base>
161 const cg::CG<Base>& right,
162 const cg::CG<Base>& trueCase,
163 const cg::CG<Base>& falseCase) {
164 bool (*comp)(const Base&, const Base&) = [](const Base& l, const Base & r) {
165 return l == r;
166 };
167
168 return CondExp(cg::CGOpCode::ComEq,
169 left, right,
170 trueCase, falseCase,
171 comp);
172}
173
177template<class Base>
179 const cg::CG<Base>& right,
180 const cg::CG<Base>& trueCase,
181 const cg::CG<Base>& falseCase) {
182 bool (*comp)(const Base&, const Base&) = [](const Base& l, const Base & r) {
183 return l >= r;
184 };
185
186 return CondExp(cg::CGOpCode::ComGe,
187 left, right,
188 trueCase, falseCase,
189 comp);
190}
191
195template<class Base>
197 const cg::CG<Base>& right,
198 const cg::CG<Base>& trueCase,
199 const cg::CG<Base>& falseCase) {
200 bool (*comp)(const Base&, const Base&) = [](const Base& l, const Base & r) {
201 return l > r;
202 };
203
204 return CondExp(cg::CGOpCode::ComGt,
205 left, right,
206 trueCase, falseCase,
207 comp);
208}
209
210template<class Base>
211inline cg::CG<Base> CondExpOp(enum CompareOp cop,
212 const cg::CG<Base>& left,
213 const cg::CG<Base>& right,
214 const cg::CG<Base>& trueCase,
215 const cg::CG<Base>& falseCase) {
216 switch (cop) {
217 case CompareLt:
218 return CondExpLt(left, right, trueCase, falseCase);
219
220 case CompareLe:
221 return CondExpLe(left, right, trueCase, falseCase);
222
223 case CompareEq:
224 return CondExpEq(left, right, trueCase, falseCase);
225
226 case CompareGe:
227 return CondExpGe(left, right, trueCase, falseCase);
228
229 case CompareGt:
230 return CondExpGt(left, right, trueCase, falseCase);
231
232 default:
233 CPPAD_ASSERT_UNKNOWN(0)
234 return trueCase;
235 }
236}
237
238} // END CppAD namespace
239
240#endif
void setValue(const Base &val)
Definition variable.hpp:54
const Base & getValue() const
Definition variable.hpp:45
bool isValueDefined() const
Definition variable.hpp:40
bool isParameter() const
Definition variable.hpp:35
cg::CG< Base > CondExpLt(const cg::CG< Base > &left, const cg::CG< Base > &right, const cg::CG< Base > &trueCase, const cg::CG< Base > &falseCase)
cg::CG< Base > CondExpEq(const cg::CG< Base > &left, const cg::CG< Base > &right, const cg::CG< Base > &trueCase, const cg::CG< Base > &falseCase)
cg::CG< Base > CondExpGt(const cg::CG< Base > &left, const cg::CG< Base > &right, const cg::CG< Base > &trueCase, const cg::CG< Base > &falseCase)
cg::CG< Base > CondExpGe(const cg::CG< Base > &left, const cg::CG< Base > &right, const cg::CG< Base > &trueCase, const cg::CG< Base > &falseCase)
cg::CG< Base > CondExp(cg::CGOpCode op, const cg::CG< Base > &left, const cg::CG< Base > &right, const cg::CG< Base > &trueCase, const cg::CG< Base > &falseCase, bool(*compare)(const Base &, const Base &))
cg::CG< Base > CondExpLe(const cg::CG< Base > &left, const cg::CG< Base > &right, const cg::CG< Base > &trueCase, const cg::CG< Base > &falseCase)