Skip to content

Commit e2d6e4e

Browse files
committed
separate bigfloat-fresnel into it's own file
1 parent 69ce09d commit e2d6e4e

File tree

2 files changed

+69
-68
lines changed

2 files changed

+69
-68
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#lang typed/racket/base
2+
3+
;Bigfloat implementation:
4+
; adaptation of powerseries as shown on wikipedia
5+
; this implementation is potentially exact
6+
; but for large x (> 5!) it is really slow and needs a lot of bits in bf-precision (~2x²)!
7+
8+
9+
(require "bigfloat-struct.rkt")
10+
11+
(provide bfFresnel-S bfFresnel-RS bfFresnel-C bfFresnel-RC)
12+
13+
(define (precision-check [a : Bigfloat][maxp : Integer]) : Integer
14+
(define p (bf-precision))
15+
(define a2 (expt (bigfloat->real a) 2))
16+
(define min-precision-needed (* 2 a2))
17+
(define expected-precision-loss (* 4/5 a2))
18+
(define mp (+ 5 (round (inexact->exact (max min-precision-needed (+ p expected-precision-loss))))))
19+
(cond
20+
[(<= mp maxp) mp]
21+
[else
22+
(error (format "bfFresnel: calculation aborted
23+
Minimum precision needed for calculating ~a... is ~a
24+
This is more than the maximum allowed calculating precision ~a->~a."
25+
(bigfloat->flonum a) mp p maxp))]))
26+
(define (bfFresnel-RS [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
27+
(define p (bf-precision))
28+
(bfcopy
29+
(parameterize ([bf-precision (precision-check x maxp)])
30+
(define X3 (bfexpt x (bf 3)))
31+
(define X4 (bfexpt x (bf 4)))
32+
(define prsn (bfexpt (bf 1/2) (bf p)))
33+
(define-values (s l)
34+
(for/fold : (Values Bigfloat Bigfloat)
35+
([s : Bigfloat (bf/ X3 (bf 3))]
36+
[l : Bigfloat (bf/ X3 (bf 3))])
37+
([n (in-naturals 1)]
38+
#:break (bf< (bfabs (bf/ l s)) prsn))
39+
(define l+ (bf* (bf -1) X4 (bf* l (bf (/ (- (* 4 n) 1)
40+
(* 2 n)(+ (* 2 n) 1)(+ (* 4 n) 3))))))
41+
(values (bf+ s l+) l+)))
42+
s)))
43+
(define (bfFresnel-S [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
44+
(bf* (bfsqrt (bf/ (bf 2) pi.bf))
45+
(bfFresnel-RS (bf* (bfsqrt (bf/ pi.bf (bf 2))) x) maxp)))
46+
47+
(define (bfFresnel-RC [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
48+
(define p (bf-precision))
49+
(bfcopy
50+
(parameterize ([bf-precision (precision-check x maxp)])
51+
(define X4 (bfexpt x (bf 4)))
52+
(define prsn (bfexpt (bf 1/2) (bf (bf-precision))))
53+
(define-values (s l)
54+
(for/fold : (Values Bigfloat Bigfloat)
55+
([s : Bigfloat x]
56+
[l : Bigfloat x])
57+
([n (in-naturals 1)]
58+
#:break (bf< (bfabs (bf/ l s)) prsn))
59+
(define l+ (bf* (bf -1) X4 (bf* l (bf (/ (- (* 4 n) 3)
60+
(* 2 n)(- (* 2 n) 1)(+ (* 4 n) 1))))))
61+
(values (bf+ s l+) l+)))
62+
s)))
63+
(define (bfFresnel-C [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
64+
(bf* (bfsqrt (bf/ (bf 2) pi.bf))
65+
(bfFresnel-RC (bf* (bfsqrt (bf/ pi.bf (bf 2))) x) maxp)))

math-lib/math/private/functions/fresnel.rkt

Lines changed: 4 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ floating point implementation:
1212
adaptation of the algorithm in the fresnl.c file from Cephes,
1313
but with the limit for the rational powerseries lowered to x<1.5625 (coming from 2.5625)
1414
above x>1.6 the error becomes too big (~1e-8 x~2.5)
15-
Bigfloat implementation:
16-
adaptation of powerseries as shown on wikipedia
17-
18-
would like to extend this together with erf to the complex plane
1915
2016
|#
2117

@@ -204,73 +200,13 @@ would like to extend this together with erf to the complex plane
204200
[else (* (sqrt (/ pi 2))(complex-Fresnel-C (* (sqrt (/ 2 pi)) z)))]))
205201

206202
;------------------------------
207-
(module* bfFresnel #f
208-
(require math/bigfloat)
209-
(provide bfFresnel-S bfFresnel-RS bfFresnel-C bfFresnel-RC)
210-
;this implementation is potentially exact
211-
;but for large x (> 5!) it is really slow and needs a lot of bits in bf-precision (~2x²)!
212-
(define (precision-check [a : Bigfloat][maxp : Integer]) : Integer
213-
(define p (bf-precision))
214-
(define a2 (expt (bigfloat->real a) 2))
215-
(define min-precision-needed (* 2 a2))
216-
(define expected-precision-loss (* 4/5 a2))
217-
(define mp (+ 5 (round (inexact->exact (max min-precision-needed (+ p expected-precision-loss))))))
218-
(cond
219-
[(<= mp maxp) mp]
220-
[else
221-
(error (format "bfFresnel: calculation aborted
222-
Minimum precision needed for calculating ~a... is ~a
223-
This is more than the maximum allowed calculating precision ~a->~a."
224-
(bigfloat->flonum a) mp p maxp))]))
225-
(define (bfFresnel-RS [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
226-
(define p (bf-precision))
227-
(bfcopy
228-
(parameterize ([bf-precision (precision-check x maxp)])
229-
(define X3 (bfexpt x (bf 3)))
230-
(define X4 (bfexpt x (bf 4)))
231-
(define prsn (bfexpt (bf 1/2) (bf p)))
232-
(define-values (s l)
233-
(for/fold : (Values Bigfloat Bigfloat)
234-
([s : Bigfloat (bf/ X3 (bf 3))]
235-
[l : Bigfloat (bf/ X3 (bf 3))])
236-
([n (in-naturals 1)]
237-
#:break (bf< (bfabs (bf/ l s)) prsn))
238-
(define l+ (bf* (bf -1) X4 (bf* l (bf (/ (- (* 4 n) 1)
239-
(* 2 n)(+ (* 2 n) 1)(+ (* 4 n) 3))))))
240-
(values (bf+ s l+) l+)))
241-
s)))
242-
(define (bfFresnel-S [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
243-
(bf* (bfsqrt (bf/ (bf 2) pi.bf))
244-
(bfFresnel-RS (bf* (bfsqrt (bf/ pi.bf (bf 2))) x) maxp)))
245-
246-
(define (bfFresnel-RC [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
247-
(define p (bf-precision))
248-
(bfcopy
249-
(parameterize ([bf-precision (precision-check x maxp)])
250-
(define X4 (bfexpt x (bf 4)))
251-
(define prsn (bfexpt (bf 1/2) (bf (bf-precision))))
252-
(define-values (s l)
253-
(for/fold : (Values Bigfloat Bigfloat)
254-
([s : Bigfloat x]
255-
[l : Bigfloat x])
256-
([n (in-naturals 1)]
257-
#:break (bf< (bfabs (bf/ l s)) prsn))
258-
(define l+ (bf* (bf -1) X4 (bf* l (bf (/ (- (* 4 n) 3)
259-
(* 2 n)(- (* 2 n) 1)(+ (* 4 n) 1))))))
260-
(values (bf+ s l+) l+)))
261-
s)))
262-
(define (bfFresnel-C [x : Bigfloat][maxp : Integer (* 2 (bf-precision))])
263-
(bf* (bfsqrt (bf/ (bf 2) pi.bf))
264-
(bfFresnel-RC (bf* (bfsqrt (bf/ pi.bf (bf 2))) x) maxp)))
265-
)
266-
267-
#;(module* test #f
203+
(module* test #f
268204
;some functions to check the function.
269205
;commented out, because (partly) put in function-tests from math-test
270-
(require math/bigfloat
271-
typed/rackunit)
206+
(require typed/rackunit)
272207
(require (submod "..")
273-
(submod ".." bfFresnel))
208+
"../../bigfloat.rkt"
209+
"../bigfloat/bigfloat-fresnel.rkt")
274210

275211
(define (test [a : Flonum] #:ε [ε : Flonum 1e-15])
276212
(check-= (Fresnel-S a) (bigfloat->flonum (bfFresnel-S (bf a))) ε (format "(Fresnel-S ~a)" a))

0 commit comments

Comments
 (0)