-
Notifications
You must be signed in to change notification settings - Fork 5
/
tiny_dual.h
106 lines (91 loc) · 3.25 KB
/
tiny_dual.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _TINYDUAL_H_
#define _TINYDUAL_H_
template <typename Scalar>
class TinyDual {
public:
explicit TinyDual(Scalar real = Scalar(), Scalar dual = Scalar())
: m_real(real), m_dual(dual) {}
Scalar real() const { return m_real; }
Scalar dual() const { return m_dual; }
inline friend TinyDual operator+(const TinyDual& lhs, const TinyDual& rhs) {
return TinyDual(lhs.real() + rhs.real(), lhs.dual() + rhs.dual());
}
inline friend TinyDual operator-(const TinyDual& lhs, const TinyDual& rhs) {
return TinyDual(lhs.real() - rhs.real(), lhs.dual() - rhs.dual());
}
inline friend TinyDual operator*(const TinyDual& lhs, const TinyDual& rhs) {
return TinyDual(rhs.real() * lhs.real(),
rhs.dual() * lhs.real() + rhs.real() * lhs.dual());
}
inline friend TinyDual operator/(const TinyDual& lhs, const TinyDual& rhs) {
return TinyDual(lhs.real() / rhs.real(),
(lhs.dual() * rhs.real() - lhs.real() * rhs.dual()) /
(rhs.real() * rhs.real()));
}
inline friend bool operator<(const TinyDual& lhs, const TinyDual& rhs) {
return lhs.real() < rhs.real();
}
inline friend bool operator<=(const TinyDual& lhs, const TinyDual& rhs) {
return lhs.real() <= rhs.real();
}
inline friend bool operator>(const TinyDual& lhs, const TinyDual& rhs) {
return lhs.real() > rhs.real();
}
inline friend bool operator==(const TinyDual& lhs, const TinyDual& rhs) {
return lhs.real() == rhs.real();
}
inline friend bool operator!=(const TinyDual& lhs, const TinyDual& rhs) {
return lhs.real() != rhs.real();
}
inline friend TinyDual operator-(const TinyDual& rhs) {
return TinyDual(-rhs.real(), -rhs.dual());
}
inline TinyDual& operator+=(const TinyDual& lhs) {
m_real += lhs.real();
m_dual += lhs.dual();
return *this;
}
inline TinyDual& operator-=(const TinyDual& lhs) {
m_real -= lhs.real();
m_dual -= lhs.dual();
return *this;
}
inline TinyDual& operator*=(const TinyDual& rhs) {
m_dual = rhs.dual() * m_real + rhs.real() * m_dual;
m_real *= rhs.real();
return *this;
}
inline TinyDual& operator/=(const TinyDual& rhs) {
m_dual =
(m_dual * rhs.real() - m_real * rhs.dual()) / (rhs.real() * rhs.real());
m_real /= rhs.real();
return *this;
}
private:
Scalar m_real;
Scalar m_dual;
};
template <typename Scalar>
inline TinyDual<Scalar> sin(const TinyDual<Scalar>& z) {
return TinyDual<Scalar>(sin(z.real()), z.dual() * cos(z.real()));
}
template <typename Scalar>
inline TinyDual<Scalar> cos(const TinyDual<Scalar>& z) {
return TinyDual<Scalar>(cos(z.real()), -z.dual() * sin(z.real()));
}
#endif // _TINYDUAL_H_