CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
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 
18 namespace CppAD {
19 namespace cg {
20 
21 template<class Base>
22 inline 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 
59 template<class Base>
60 inline 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 
92 template<class Base>
93 inline 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 
135 template<class Base>
136 inline 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 
172 template<class Base>
173 inline CG<Base>& CG<Base>::operator+=(const Base &right) {
174  return operator+=(CG<Base> (right));
175 }
176 
177 template<class Base>
178 inline CG<Base>& CG<Base>::operator-=(const Base &right) {
179  return operator-=(CG<Base> (right));
180 }
181 
182 template<class Base>
183 inline CG<Base>& CG<Base>::operator/=(const Base &right) {
184  return operator/=(CG<Base> (right));
185 }
186 
187 template<class Base>
188 inline CG<Base>& CG<Base>::operator*=(const Base &right) {
189  return operator*=(CG<Base> (right));
190 }
191 
192 template<class Base>
193 template<class T>
194 inline CG<Base>& CG<Base>::operator+=(const T &right) {
195  return operator+=(CG<Base> (right));
196 }
197 
198 template<class Base>
199 template<class T>
200 inline CG<Base>& CG<Base>::operator-=(const T &right) {
201  return operator-=(CG<Base> (right));
202 }
203 
204 template<class Base>
205 template<class T>
206 inline CG<Base>& CG<Base>::operator/=(const T &right) {
207  return operator/=(CG<Base> (right));
208 }
209 
210 template<class Base>
211 template<class T>
212 inline 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