1
- using Base. Math: sin_kernel, cos_kernel, rem_pio2_kernel, DoubleFloat64, DoubleFloat32
2
- function sin_double (n,y)
3
- n = n& 3
1
+ using Base. Math: sin_kernel, cos_kernel, sincos_kernel, rem_pio2_kernel, DoubleFloat64, DoubleFloat32
2
+
3
+ """
4
+ computes sin(sum(xs)) where xs are sorted by absolute value
5
+ Doing this is much more accurate than the naive sin(sum(xs))
6
+ """
7
+ function sin_sum (xs:: Vararg{T} ):: T where T<: Base.IEEEFloat
8
+ n, y = rem_pio2_sum (xs... )
9
+ n &= 3
4
10
if n == 0
5
11
return sin_kernel (y)
6
12
elseif n == 1
@@ -13,21 +19,42 @@ function sin_double(n,y)
13
19
end
14
20
15
21
"""
16
- computes sin(sum(xs)+sum(xlos)) where xs, xlos are sorted by absolute value
17
- and xlos are all <=pi/4 (and therefore don't need to be reduced)
18
- Doing this is much more accurate than the naive sin(sum(xs)+sum(xlos))
22
+ computes sincos(sum(xs)) where xs are sorted by absolute value
23
+ Doing this is much more accurate than the naive sincos(sum(xs))
19
24
"""
20
- function sin_sum (xs:: Tuple{Vararg{Float64}} , xlos:: Tuple{Vararg{Float64}} )
25
+ function sincos_sum (xs:: Vararg{T} ):: T where T<: Base.IEEEFloat
26
+ n, y = rem_pio2_sum (xs... )
27
+ n &= 3
28
+ si, co = sincos_kernel (y)
29
+ if n == 0
30
+ return si, co
31
+ elseif n == 1
32
+ return co, - si
33
+ elseif n == 2
34
+ return - si, - co
35
+ else
36
+ return - co, si
37
+ end
38
+ end
39
+
40
+ function rem_pio2_sum (xs:: Vararg{Float64} )
21
41
n = 0
22
42
hi, lo = 0.0 , 0.0
23
- for x in xs
43
+ small_start = length (xs)+ 1
44
+ for i in eachindex (xs)
45
+ x = xs[i]
46
+ if abs (x) <= pi / 4
47
+ small_start = i
48
+ break
49
+ end
24
50
n_i, y = rem_pio2_kernel (x)
25
51
n += n_i
26
52
s = y. hi + hi
27
53
lo += (y. hi - (s - hi)) + y. lo
28
54
hi = s
29
55
end
30
- for x in xlos
56
+ for i in small_start: length (xs)
57
+ x = xs[i]
31
58
s = x + hi
32
59
lo += (x - (s - hi))
33
60
hi = s
@@ -42,28 +69,10 @@ function sin_sum(xs::Tuple{Vararg{Float64}}, xlos::Tuple{Vararg{Float64}})
42
69
lo += 6.123233995736766e-17
43
70
n -= 1
44
71
end
45
- sin_double (n, DoubleFloat64 (hi, lo) )
72
+ return n, DoubleFloat64 (hi, lo)
46
73
end
47
74
48
- function sin_sum (xs:: Tuple{Vararg{Float32}} , xlos:: Tuple{Vararg{Float32}} )
49
- n = 0
50
- y = 0.0
51
- for x in xs
52
- n_i, y_i = rem_pio2_kernel (x)
53
- n += n_i
54
- y += y_i. hi
55
- end
56
- for x in xlos
57
- y += x
58
- end
59
- while y > pi / 4
60
- y -= pi / 2
61
- n += 1
62
- end
63
- while y < - pi / 4
64
- y += pi / 2
65
- n -= 1
66
- end
67
-
68
- sin_double (n,DoubleFloat32 (y))
75
+ function rem_pio2_sum (xs:: Vararg{Union{Float32,Float64}} )
76
+ n, y = rem_pio2_kernel (sum (Float64, xs))
77
+ return n, DoubleFloat32 (y. hi)
69
78
end
0 commit comments