-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
90 lines (75 loc) · 2.18 KB
/
Copy pathmain.cpp
File metadata and controls
90 lines (75 loc) · 2.18 KB
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
#include <cmath>
#include <iostream>
namespace ad
{
class DualNum
{
public:
explicit DualNum(double real, double dual) : real_(real), dual_(dual) {}
double get_real() const { return real_; }
double get_dual() const { return dual_; }
DualNum(double real) : real_(real), dual_(0) {}
DualNum operator-() const { return DualNum(-real_, -dual_); }
private:
double real_;
double dual_;
};
DualNum operator+(const DualNum& d1, const DualNum& d2)
{
return DualNum(d1.get_real() + d2.get_real(), d1.get_dual() + d2.get_dual());
}
DualNum operator*(const DualNum& d1, const DualNum& d2)
{
return DualNum(d1.get_real() * d2.get_real(),
d1.get_real() * d2.get_dual() + d1.get_dual() * d2.get_real());
}
DualNum operator-(const DualNum& d1, const DualNum& d2)
{
return DualNum(d1.get_real() - d2.get_real(), d1.get_dual() - d2.get_dual());
}
DualNum operator/(const DualNum& d1, const DualNum& d2)
{
return DualNum(
d1.get_real() / d2.get_real(), // real
(d1.get_dual() * d2.get_real() - d1.get_real() * d2.get_dual()) /
(d2.get_real() * d2.get_real()) // dual
);
}
DualNum sin(const DualNum& d)
{ // eps**2 = 0 && eps != 0
return DualNum( // sin (a + b*eps) = sin(a) + cos(a) * b * eps
std::sin(d.get_real()), // real
std::cos(d.get_real()) * d.get_dual()); // dual
}
DualNum cos(const DualNum& d)
{
return DualNum( // see sin for more information
std::cos(d.get_real()), // real
-std::sin(d.get_real()) * d.get_dual()); // dual
}
DualNum exp(const DualNum& d)
{
return DualNum(std::exp(d.get_real()), // real
std::exp(d.get_real()) * d.get_dual() // dual
);
}
DualNum log(const DualNum& d)
{
return DualNum(std::log(d.get_real()), // real
d.get_dual() / d.get_real() // dual
);
}
template <typename F>
double diff(F func, double x)
{
return func(DualNum(x, 1)).get_dual();
}
} // namespace ad
int main()
{
using namespace ad;
auto f = [](auto x) { return x * x + 4 * x + 8; };
double slope = diff(f, 3.0);
std::cout << slope << "\n";
return 0;
}