-
Notifications
You must be signed in to change notification settings - Fork 0
/
PruferTransformer.cpp
91 lines (86 loc) · 2.25 KB
/
PruferTransformer.cpp
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
#include "PruferTransformer.h"
#include "math.h"
PruferTransformer::PruferTransformer(polynomial& u, vector<polynomial>& coeff_ODE)
{
polynomial derivate_u = derivate(u);
polynomial p(coeff_ODE.at(0));
polynomial q(coeff_ODE.at(1));
polynomial r(coeff_ODE.at(2));
theta_x = [=](mpf_class x) mutable{
mpf_class res(0,precision);
if (abs(r(x)) < zero_eps|| abs(u(x)) < zero_eps) {
res = pi/mpf_class(2.0,precision);
}
else {
mpf_class part1 = sqrt(p(x)/r(x));
mpf_class part2 = derivate_u(x)/u(x);
mpf_class mul = part1*part2;
//we use atan function in std, which reduces the precision
// we only use this function for RungeKutta.
res = atan(mul.get_d());
}
return res;
};
dx_dtheta = [=](mpf_class theta,mpf_class x) mutable{
polynomial derivate_p = derivate(p);
polynomial derivate_r = derivate(r);
polynomial tmp1 = derivate_r*p - derivate_p*r + 2*r*q;
mpf_class rx = r(x), px = p(x),tmp1x = tmp1(x);
mpf_class part1(0,precision),part2(0,precision);
mpf_class part3(0,precision),part4(0,precision);
mpf_class denominator(0,precision);
if (abs(rx) < zero_eps) {
part1 = 0;
}
else if (abs(px) < zero_eps) {
part1 = infinity;
// denominator = infinity;
}
else {
part1 = sqrt(r(x)/p(x));
}
part2 = tmp1x*sin(2*theta.get_d());
part3 = 4*rx*px;
if (abs(part2) < zero_eps) {
part4 = 0;
}
else if (abs(part3) < zero_eps) {
part4 = infinity;
// denominator = infinity;
}
else {
part4 = part2/part3;
}
// if(denominator == 0)
// {
denominator = part1 + part4;
// }
mpf_class res;
if (abs(denominator) < zero_eps) {
res = -infinity;
}
else if (denominator >= infinity) {
res = 0;
}
else {
res = -mpf_class(1,precision)/denominator;
}
return res;
};
}
function<mpf_class(mpf_class)> PruferTransformer::get_theta_x()
{
return theta_x;
}
function<mpf_class(mpf_class,mpf_class)> PruferTransformer::get_dx_dtheta()
{
return dx_dtheta;
}
mpf_class PruferTransformer::theta_x_value(mpf_class x)
{
return theta_x(x);
};
mpf_class PruferTransformer::dx_dtheta_value(mpf_class theta,mpf_class x)
{
return dx_dtheta(theta,x);
};