31 inline constexpr
Dual() : real(T()) , eps(T()) { }
32 inline constexpr
explicit Dual(
const T& real_) : real(real_) , eps(T()) { }
33 inline constexpr Dual(
const T& real_,
const T& eps_) : real(real_) , eps(eps_) { }
44 return {left.real + right.real, left.eps + right.eps};
48 inline constexpr
Dual<T> operator+(
const Dual<T>& left,
const T& right)
50 return {left.real + right, left.eps};
54 inline constexpr
Dual<T> operator+(
const T& left,
const Dual<T>& right)
56 return {left + right.real, right.eps};
60 inline constexpr
void operator+=(
Dual<T>& left,
const Dual<T>& right)
66 inline constexpr
void operator+=(
Dual<T>& left,
const T& right)
76 return {left.real - right.real, left.eps - right.eps};
80 inline constexpr
Dual<T> operator-(
const Dual<T>& left,
const T& right)
82 return {left.real - right, left.eps};
86 inline constexpr
Dual<T> operator-(
const T& left,
const Dual<T>& right)
88 return {left - right.real, right.eps};
92 inline constexpr
void operator-=(
Dual<T>& left,
const Dual<T>& right)
98 inline constexpr
void operator-=(
Dual<T>& left,
const T& right)
106 inline constexpr
Dual<T> operator*(
const T& left,
const Dual<T>& right)
108 return {left * right.real, left * right.eps};
112 inline constexpr
Dual<T> operator*(
const Dual<T>& left,
const T& right)
114 return {left.real * right, left.eps * right};
118 inline constexpr
void operator*=(
Dual<T>& left,
const T& right)
126 return {left.real * right.real, left.real * right.eps + right.real * left.eps};
130 inline constexpr
void operator*=(
Dual<T>& left,
const Dual<T>& right)
138 inline constexpr
Dual<T> operator/(
const Dual<T>& left,
const T& right)
140 return {left.real / right, left.eps / right};
144 inline constexpr
void operator/=(
Dual<T>& left,
const T& right)
152 if (right.real == T()) {
153 if (right.eps == T()) {
155 return {std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()};
156 }
else if (left.real == T()) {
158 return Dual<T>{left.eps / right.eps, std::numeric_limits<T>::quiet_NaN()};
164 const T sign = left.real * right.eps;
165 const T signed_inf = sign * std::numeric_limits<T>::infinity();
166 return Dual<T>(signed_inf, signed_inf);
171 left.real / right.real,
172 (left.eps * right.real - left.real * right.eps) / (right.real * right.real)
178 inline constexpr
void operator/=(
Dual<T>& left,
const Dual<T>& right)
188 return {+operand.real, +operand.eps};
194 return {-operand.real, -operand.eps};
200 inline constexpr
bool operator==(
const Dual<T>& left,
const Dual<T>& right)
202 return left.real == right.real && left.eps == right.eps;
206 inline constexpr
bool operator!=(
const Dual<T>& left,
const Dual<T>& right)
208 return left.real != right.real || left.eps != right.eps;
212 inline constexpr
bool operator<(const Dual<T>& left,
const Dual<T>& right)
214 return std::make_pair(left.real, left.eps) < std::make_pair(right.real, right.eps);
218 inline constexpr
bool operator<=(const Dual<T>& left,
const Dual<T>& right)
220 return std::make_pair(left.real, left.eps) <= std::make_pair(right.real, right.eps);
224 inline constexpr
bool operator>=(
const Dual<T>& left,
const Dual<T>& right)
226 return std::make_pair(left.real, left.eps) >= std::make_pair(right.real, right.eps);
230 inline constexpr
bool operator>(
const Dual<T>& left,
const Dual<T>& right)
232 return std::make_pair(left.real, left.eps) > std::make_pair(right.real, right.eps);
238 std::ostream& operator<<(std::ostream& os, const Dual<T>& x)
240 if (x.eps == T()) {
return os << x.real; }
241 else if (x.real == T()) {
return os << x.eps <<
"ε"; }
242 else {
return os << x.real << (x.eps < 0 ?
'-' :
'+') << std::abs(x.eps) <<
"ε"; }
254 if (x.real < 0) {
return { -x.real, -x.eps }; }
255 if (x.real > 0) {
return { x.real, x.eps }; }
256 return {0, abs(x.eps)};
262 return {sin(x.real), x.eps * cos(x.real)};
268 return {cos(x.real), -x.eps * sin(x.real)};
271 template <
typename T>
274 return {log(x.real), x.eps / x.real};
277 template <
typename T>
280 return {log10(x.real), x.eps / (log(T(10)) * x.real)};
283 template <
typename T>
288 x.eps / (T(2) * sqrt(x.real))
292 template <
typename T,
typename S>
296 pow(left.real, right),
297 left.eps * T(right) * pow(left.real, right - S(1))
301 template <
typename T>
305 pow(left, right.real),
306 right.eps * log(left) * pow(left, right.real)
310 template <
typename T>
314 pow(left.real, right.real),
315 left.eps * right.real * pow(left.real, right.real - T(1)) +
316 right.eps * log(left.real) * pow(left.real, right.real)
320 template <
typename T>
323 return isfinite(left.real);
326 template <
typename T>
338 #include <Eigen/Geometry> 342 template <
typename T>
343 struct NumTraits<emilib::
Dual<T>> : GenericNumTraits<emilib::Dual<T>>
346 using Literal =
typename NumTraits<T>::Literal;
349 RequireInitialization = NumTraits<Real>::RequireInitialization,
350 ReadCost = 2 * NumTraits<Real>::ReadCost,
351 AddCost = 2 * NumTraits<Real>::AddCost,
352 MulCost = 3 * NumTraits<Real>::MulCost + NumTraits<Real>::AddCost
355 EIGEN_DEVICE_FUNC
static inline Real epsilon() {
return NumTraits<Real>::epsilon(); }
356 EIGEN_DEVICE_FUNC
static inline Real dummy_precision() {
return NumTraits<Real>::dummy_precision(); }
357 EIGEN_DEVICE_FUNC
static inline int digits10() {
return NumTraits<Real>::digits10(); }
360 template<
typename T,
typename BinaryOp>
361 struct ScalarBinaryOpTraits<T, emilib::
Dual<T>, BinaryOp>
366 template<
typename T,
typename BinaryOp>
367 struct ScalarBinaryOpTraits<emilib::
Dual<T>, T, BinaryOp>
373 #endif // DUALS_EGIEN
Definition: coroutine.hpp:18