1#ifndef CPPAD_CG_ARITHMETIC_INCLUDED
2#define CPPAD_CG_ARITHMETIC_INCLUDED
22CodeHandler<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");
43inline 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());
69inline 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());
91inline 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());
121inline 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());
149inline CG<Base> operator+(
const Base& left,
const CG<Base>& right) {
150 return CG<Base>(left) + right;
154inline CG<Base> operator+(
const CG<Base>& left,
const Base& right) {
155 return left + CG<Base>(right);
159inline CG<Base> operator-(
const Base& left,
const CG<Base>& right) {
160 return CG<Base>(left) - right;
164inline CG<Base> operator-(
const CG<Base>& left,
const Base& right) {
165 return left - CG<Base>(right);
169inline CG<Base> operator/(
const Base& left,
const CG<Base>& right) {
170 return CG<Base>(left) / right;
174inline CG<Base> operator/(
const CG<Base>& left,
const Base& right) {
175 return left / CG<Base>(right);
179inline CG<Base> operator*(
const Base& left,
const CG<Base>& right) {
180 return CG<Base>(left) * right;
184inline CG<Base> operator*(
const CG<Base>& left,
const Base& right) {
185 return left * CG<Base>(right);
192template<
class Base,
class T>
194typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
195operator+(
const T& left,
const CG<Base>& right) {
196 return CG<Base>(Base(left)) + right;
199template<
class Base,
class T>
201typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
202operator+(
const CG<Base>& left,
const T& right) {
203 return left + CG<Base>(Base(right));
206template<
class Base,
class T>
208typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
209operator-(
const T& left,
const CG<Base>& right) {
210 return CG<Base>(Base(left)) - right;
213template<
class Base,
class T>
215typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
216operator-(
const CG<Base>& left,
const T& right) {
217 return left - CG<Base>(Base(right));
220template<
class Base,
class T>
222typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
223operator/(
const T& left,
const CG<Base>& right) {
224 return CG<Base>(Base(left)) / right;
227template<
class Base,
class T>
229typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
230operator/(
const CG<Base>& left,
const T& right) {
231 return left / CG<Base>(Base(right));
234template<
class Base,
class T>
236typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
237operator*(
const T& left,
const CG<Base>& right) {
238 return CG<Base>(Base(left)) * right;
241template<
class Base,
class T>
243typename std::enable_if<std::is_constructible<Base, const T&>::value, CG<Base> >::type
244operator*(
const CG<Base>& left,
const T& right) {
245 return left * CG<Base>(Base(right));