CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
arithmetic_assign.hpp
1#ifndef CPPAD_CG_ARITHMETIC_ASSIGN_INCLUDED
2#define CPPAD_CG_ARITHMETIC_ASSIGN_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 {
19namespace cg {
20
21template<class Base>
22inline CG<Base>& CG<Base>::operator+=(const CG<Base> &right) {
23 if (isParameter() && right.isParameter()) {
24 *value_ += *right.value_;
25
26 } else {
27 CodeHandler<Base>* handler;
28 if (isParameter()) {
29 if (isIdenticalZero()) {
30 *this = right;
31 return *this;
32 }
33
34 handler = right.node_->getCodeHandler();
35
36 } else if (right.isParameter()) {
37 if (right.isIdenticalZero()) {
38 return *this; // nothing to do
39 }
40
41 handler = node_->getCodeHandler();
42
43 } else { // both left and right hand sides are variables
44 CPPADCG_ASSERT_UNKNOWN(node_->getCodeHandler() == right.node_->getCodeHandler());
45 handler = node_->getCodeHandler();
46 }
47
48 std::unique_ptr<Base> value;
49 if (isValueDefined() && right.isValueDefined()) {
50 value.reset(new Base(getValue() + right.getValue()));
51 }
52
53 makeVariable(*handler->makeNode(CGOpCode::Add,{argument(), right.argument()}), value);
54 }
55
56 return *this;
57}
58
59template<class Base>
60inline CG<Base>& CG<Base>::operator-=(const CG<Base> &right) {
61 if (isParameter() && right.isParameter()) {
62 *value_ -= *right.value_;
63
64 } else {
65 CodeHandler<Base>* handler;
66 if (isParameter()) {
67 handler = right.node_->getCodeHandler();
68
69 } else if (right.isParameter()) {
70 if (right.isIdenticalZero()) {
71 return *this; // nothing to do
72 }
73
74 handler = node_->getCodeHandler();
75
76 } else { // both left and right hand sides are variables
77 CPPADCG_ASSERT_UNKNOWN(node_->getCodeHandler() == right.node_->getCodeHandler());
78 handler = node_->getCodeHandler();
79 }
80
81 std::unique_ptr<Base> value;
82 if (isValueDefined() && right.isValueDefined()) {
83 value.reset(new Base(getValue() - right.getValue()));
84 }
85
86 makeVariable(*handler->makeNode(CGOpCode::Sub,{argument(), right.argument()}), value);
87 }
88
89 return *this;
90}
91
92template<class Base>
93inline CG<Base>& CG<Base>::operator*=(const CG<Base> &right) {
94 if (isParameter() && right.isParameter()) {
95 *value_ *= *right.value_;
96
97 } else {
98 CodeHandler<Base>* handler;
99 if (isParameter()) {
100 if (isIdenticalZero()) {
101 return *this; // nothing to do (does not consider that right might be infinity)
102 } else if (isIdenticalOne()) {
103 *this = right;
104 return *this;
105 }
106
107 handler = right.node_->getCodeHandler();
108
109 } else if (right.isParameter()) {
110 if (right.isIdenticalZero()) {
111 makeParameter(Base(0.0)); // does not consider that left might be infinity
112 return *this;
113 } else if (right.isIdenticalOne()) {
114 return *this; // nothing to do
115 }
116
117 handler = node_->getCodeHandler();
118
119 } else { // both left and right hand sides are variables
120 CPPADCG_ASSERT_UNKNOWN(node_->getCodeHandler() == right.node_->getCodeHandler());
121 handler = node_->getCodeHandler();
122 }
123
124 std::unique_ptr<Base> value;
125 if (isValueDefined() && right.isValueDefined()) {
126 value.reset(new Base(getValue() * right.getValue()));
127 }
128
129 makeVariable(*handler->makeNode(CGOpCode::Mul,{argument(), right.argument()}), value);
130 }
131
132 return *this;
133}
134
135template<class Base>
136inline CG<Base>& CG<Base>::operator/=(const CG<Base> &right) {
137 if (isParameter() && right.isParameter()) {
138 *value_ /= *right.value_;
139
140 } else {
141 CodeHandler<Base>* handler;
142 if (isParameter()) {
143 if (isIdenticalZero()) {
144 return *this; // nothing to do (does not consider that right might be infinity or zero)
145 }
146
147 handler = right.node_->getCodeHandler();
148
149 } else if (right.isParameter()) {
150 if (right.isIdenticalOne()) {
151 return *this; // nothing to do
152 }
153
154 handler = node_->getCodeHandler();
155
156 } else { // both left and right hand sides are variables
157 CPPADCG_ASSERT_UNKNOWN(node_->getCodeHandler() == right.node_->getCodeHandler());
158 handler = node_->getCodeHandler();
159 }
160
161 std::unique_ptr<Base> value;
162 if (isValueDefined() && right.isValueDefined()) {
163 value.reset(new Base(getValue() / right.getValue()));
164 }
165
166 makeVariable(*handler->makeNode(CGOpCode::Div,{argument(), right.argument()}), value);
167 }
168
169 return *this;
170}
171
172template<class Base>
173inline CG<Base>& CG<Base>::operator+=(const Base &right) {
174 return operator+=(CG<Base> (right));
175}
176
177template<class Base>
178inline CG<Base>& CG<Base>::operator-=(const Base &right) {
179 return operator-=(CG<Base> (right));
180}
181
182template<class Base>
183inline CG<Base>& CG<Base>::operator/=(const Base &right) {
184 return operator/=(CG<Base> (right));
185}
186
187template<class Base>
188inline CG<Base>& CG<Base>::operator*=(const Base &right) {
189 return operator*=(CG<Base> (right));
190}
191
192template<class Base>
193template<class T>
194inline CG<Base>& CG<Base>::operator+=(const T &right) {
195 return operator+=(CG<Base> (right));
196}
197
198template<class Base>
199template<class T>
200inline CG<Base>& CG<Base>::operator-=(const T &right) {
201 return operator-=(CG<Base> (right));
202}
203
204template<class Base>
205template<class T>
206inline CG<Base>& CG<Base>::operator/=(const T &right) {
207 return operator/=(CG<Base> (right));
208}
209
210template<class Base>
211template<class T>
212inline CG<Base>& CG<Base>::operator*=(const T &right) {
213 return operator*=(CG<Base> (right));
214}
215
216} // END cg namespace
217} // END CppAD namespace
218
219#endif
220