1 #ifndef CPPAD_CG_ARITHMETIC_INCLUDED
2 #define CPPAD_CG_ARITHMETIC_INCLUDED
22 CodeHandler<Base>* getHandler(
const CG<Base>& left,
23 const CG<Base>& right) {
25 CPPADCG_ASSERT_UNKNOWN(!left.isParameter() || !right.isParameter());
27 CodeHandler<Base>* lh = left.getCodeHandler();
28 CodeHandler<Base>* rh = right.getCodeHandler();
32 }
else if (rh ==
nullptr) {
36 throw CGException(
"Attempting to use several source code generation handlers in the same source code generation");
43 inline CG<Base> operator+(
const CG<Base>& left,
const CG<Base>& right) {
44 if (left.isParameter() && right.isParameter()) {
45 return CG<Base> (left.getValue() + right.getValue());
48 if (left.isParameter()) {
49 if (left.isIdenticalZero()) {
52 }
else if (right.isParameter()) {
53 if (right.isIdenticalZero()) {
58 CodeHandler<Base>* handler = getHandler(left, right);
60 CG<Base> result(*handler->makeNode(CGOpCode::Add,{left.argument(), right.argument()}));
61 if (left.isValueDefined() && right.isValueDefined()) {
62 result.setValue(left.getValue() + right.getValue());
69 inline CG<Base> operator-(
const CG<Base>& left,
const CG<Base>& right) {
70 if (left.isParameter() && right.isParameter()) {
71 return CG<Base> (left.getValue() - right.getValue());
74 if (right.isParameter()) {
75 if (right.isIdenticalZero()) {
80 CodeHandler<Base>* handler = getHandler(left, right);
82 CG<Base> result(*handler->makeNode(CGOpCode::Sub,{left.argument(), right.argument()}));
83 if (left.isValueDefined() && right.isValueDefined()) {
84 result.setValue(left.getValue() - right.getValue());
91 inline CG<Base> operator*(
const CG<Base>& left,
const CG<Base>& right) {
92 if (left.isParameter() && right.isParameter()) {
93 return CG<Base> (left.getValue() * right.getValue());
96 if (left.isParameter()) {
97 if (left.isIdenticalZero()) {
98 return CG<Base> (Base(0.0));
99 }
else if (left.isIdenticalOne()) {
102 }
else if (right.isParameter()) {
103 if (right.isIdenticalZero()) {
104 return CG<Base> (Base(0.0));
105 }
else if (right.isIdenticalOne()) {
110 CodeHandler<Base>* handler = getHandler(left, right);
112 CG<Base> result(*handler->makeNode(CGOpCode::Mul,{left.argument(), right.argument()}));
113 if (left.isValueDefined() && right.isValueDefined()) {
114 result.setValue(left.getValue() * right.getValue());
121 inline CG<Base> operator/(
const CG<Base>& left,
const CG<Base>& right) {
122 if (left.isParameter() && right.isParameter()) {
123 return CG<Base> (left.getValue() / right.getValue());
126 if (left.isParameter()) {
127 if (left.isIdenticalZero()) {
128 return CG<Base> (Base(0.0));
130 }
else if (right.isParameter()) {
131 if (right.isIdenticalOne()) {
134 }
else if (left.getOperationNode() == right.getOperationNode()) {
135 return CG<Base>(Base(1.0));
138 CodeHandler<Base>* handler = getHandler(left, right);
140 CG<Base> result(*handler->makeNode(CGOpCode::Div,{left.argument(), right.argument()}));
141 if (left.isValueDefined() && right.isValueDefined()) {
142 result.setValue(left.getValue() / right.getValue());
149 inline CG<Base> operator+(
const Base& left,
const CG<Base>& right) {
150 return CG<Base>(left) + right;
154 inline CG<Base> operator+(
const CG<Base>& left,
const Base& right) {
155 return left + CG<Base>(right);
159 inline CG<Base> operator-(
const Base& left,
const CG<Base>& right) {
160 return CG<Base>(left) - right;
164 inline CG<Base> operator-(
const CG<Base>& left,
const Base& right) {
165 return left - CG<Base>(right);
169 inline CG<Base> operator/(
const Base& left,
const CG<Base>& right) {
170 return CG<Base>(left) / right;
174 inline CG<Base> operator/(
const CG<Base>& left,
const Base& right) {
175 return left / CG<Base>(right);
179 inline CG<Base> operator*(
const Base& left,
const CG<Base>& right) {
180 return CG<Base>(left) * right;
184 inline CG<Base> operator*(
const CG<Base>& left,
const Base& right) {
185 return left * CG<Base>(right);
192 template<
class Base,
class T>
194 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
195 operator+(
const T& left,
const CG<Base>& right) {
196 return CG<Base>(Base(left)) + right;
199 template<
class Base,
class T>
201 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
202 operator+(
const CG<Base>& left,
const T& right) {
203 return left + CG<Base>(Base(right));
206 template<
class Base,
class T>
208 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
209 operator-(
const T& left,
const CG<Base>& right) {
210 return CG<Base>(Base(left)) - right;
213 template<
class Base,
class T>
215 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
216 operator-(
const CG<Base>& left,
const T& right) {
217 return left - CG<Base>(Base(right));
220 template<
class Base,
class T>
222 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
223 operator/(
const T& left,
const CG<Base>& right) {
224 return CG<Base>(Base(left)) / right;
227 template<
class Base,
class T>
229 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
230 operator/(
const CG<Base>& left,
const T& right) {
231 return left / CG<Base>(Base(right));
234 template<
class Base,
class T>
236 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
237 operator*(
const T& left,
const CG<Base>& right) {
238 return CG<Base>(Base(left)) * right;
241 template<
class Base,
class T>
243 typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
244 operator*(
const CG<Base>& left,
const T& right) {
245 return left * CG<Base>(Base(right));