forked from nitadori/HighOrder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrsqrt.cpp
More file actions
109 lines (89 loc) · 2.45 KB
/
rsqrt.cpp
File metadata and controls
109 lines (89 loc) · 2.45 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// To compile in MacOS:
// g++ -O2 -Wall -mfma -Wa,-q --std=c++11 rsqrt.cpp -I . libqd.a
#include <iostream>
#include <cstdlib>
#include <qd/dd_real.h>
#include <qd/dd_inline.h>
#include <qd/qd_real.h>
#include <qd/qd_inline.h>
dd_real rsqrt1(const dd_real &x){
double y0 = 1.0 / sqrt(to_double(x));
return dd_real(y0);
}
dd_real rsqrt2(const dd_real &x){
// d * d -> dd
// dd * dd -> dd
// d - dd -> d
// d * dd -> dd
// d + d -> dd
double y0 = 1.0 / sqrt(to_double(x));
double h = (1.0 - x * dd_real::sqr(y0)).x[0];
// dd_real y1 = y0 + y0 * mul_pwr2(h, 0.5);
dd_real y1 = dd_real::add(y0, (0.5 * y0) * h);
return y1;
}
dd_real rsqrt3(const dd_real &x){
// d * d -> dd
// dd * dd -> dd
// d - dd -> dd
// d * dd -> dd
double y0 = 1.0 / sqrt(to_double(x));
dd_real c = 3.0 - x * dd_real::sqr(y0);
dd_real y1 = (0.5 * y0) * c;
return y1;
}
dd_real rsqrt4(const dd_real &x){
// d * d -> dd
// dd * dd -> dd
// d - dd -> dd
// d + dd -> dd
// d * dd -> dd
double y0 = 1.0 / sqrt(to_double(x));
dd_real h = 1.0 - x * dd_real::sqr(y0);
dd_real c = dd_real(0.5, (3./8.) * to_double(h));
// dd_real y1 = y0 + y0 * h * c;
dd_real y1 = y0 * (1.0 + h * c);
return y1;
}
dd_real rsqrt5(const dd_real &x){
double y0 = 1.0 / sqrt(to_double(x));
double h = to_double(1.0 - x * dd_real::sqr(y0));
dd_real y1 = dd_real::add( y0, y0 * (h * (0.5 + h * (3./8.))) );
return y1;
}
dd_real rsqrt_qd(const dd_real &x){
return to_dd_real(1.0 / sqrt(qd_real(x)));
}
template <typename F>
void accruracy_check(const dd_real &x, F fun){
dd_real y = fun(x);
dd_real h = 1.0 - x * sqr(y);
qd_real yq = 1.0 / sqrt(qd_real(x));
double qerr = to_double(y - yq) * sqrt(to_double(x));
double derr = to_double(y - to_dd_real(yq)) * sqrt(to_double(x));
printf("%A %A\n", y.x[0], y.x[1]);
std::cout << y << " " << h << " " << qerr << " " << derr << std::endl;
}
int main(){
using std::cout;
using std::endl;
srand(20170728);
for(int i=0; i<10; i++){
dd_real x = ddrand();
cout.precision(32);
cout << x << endl;
cout << std::scientific << to_double(x) << endl;
/*
dd_real y = 1.0 / sqrt(x);
dd_real h = 1.0 - x * sqr(y);
cout << y << " " << h << endl;
*/
// accruracy_check(x, rsqrt1);
accruracy_check(x, [](const dd_real &x){ return 1.0 / sqrt(x); });
accruracy_check(x, rsqrt2);
// accruracy_check(x, rsqrt3);
// accruracy_check(x, rsqrt4);
accruracy_check(x, rsqrt5);
accruracy_check(x, rsqrt_qd);
}
}