GNU GSL Numerical Integration
(require gsl-integration) | package: gsl-integration |
Interface to GNU GSL Numerical Integration.
Library hides memory allocation and other low level C stuff.
GNU GSL has to be installed separately. Development version of gsl is preferred. In Ubuntu the package is: libgsl-dev.
Naming of functions and keywords follow GNU GSL documentation https://www.gnu.org/software/gsl/doc/html/integration.html
The source code is distributed under the GNU General Public License.
1 Example
(require gsl-integration) (define (f x) ( / (log x) (sqrt x))) (define expected (- 4.0)) (define res (qags f 0 1 #:epsrel 1e-7)) (if (= 0 (first res)) (begin (displayln (string-append "result = " (~a (second res)))) (displayln (string-append "exact result = " (~a expected))) (displayln (string-append "result = " (~a (second res)))) (displayln (string-append "estimated error = " (~a (third res)))) (displayln (string-append "actual error = " (~a (- (second res) expected))))) (error "status = " (~a (first res))))
; result = -4.000000000000085 ; exact result = -4.0 ; result = -4.000000000000085 ; estimated error = 1.354472090042691e-13 ; actual error = -8.526512829121202e-14
For more examples look at test.rkt source file.
2 Reference
The functions will always return a list.
First element is status code. Success when code = 0, otherwise error.
Success list: 0, result. Thereafter one or both (see GNU GSL documentation): abserr , neveal.
Error list: codenr, gsl-symbol, message.
procedure
→
(or/c (list/c integer? real? real? integer?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8
(0 result abserr neval)
(codenr gsl-symbol message)
procedure
→ (list/c real? real? integer?) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8
(result abserr neval)
procedure
(qag f a b [ #:epsabs epsabs #:epsrel epsrel #:limit limit #:key key])
→
(or/c (list/c integer? real? real?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000 key : exact-positive-integer? = 2
(0 result abserr)
(codenr gsl-symbol message)
procedure
(qag-r f a b [ #:epsabs epsabs #:epsrel epsrel #:limit limit #:key key]) → (list/c real? real?) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000 key : exact-positive-integer? = 2
(result abserr)
procedure
(qags f a b [ #:epsabs epsabs #:epsrel epsrel #:limit limit])
→
(or/c (list/c integer? real? real?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
The presence of an integrable singularity in the integration region causes an adaptive routine to concentrate new subintervals around the singularity. As the subintervals decrease in size the successive approximations to the integral converge in a limiting fashion. This approach to the limit can be accelerated using an extrapolation procedure. The QAGS algorithm combines adaptive bisection with the Wynn epsilon-algorithm to speed up the integration of many types of integrable singularities.
procedure
(qags-r f a b [ #:epsabs epsabs #:epsrel epsrel #:limit limit]) → (list/c real? real?) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
(result abserr)
procedure
(qagp f pts [ #:epsabs epsabs #:epsrel epsrel #:limit limit])
→
(or/c (list/c integer? real? real?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) pts : (listof real?) epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
Dublicates points will removed and the points will be sorted.
procedure
(qagp-r f pts [ #:epsabs epsabs #:epsrel epsrel #:limit limit]) → (list/c real? real?) f : (-> flonum? flonum?) pts : (listof real?) epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
(result abserr)
procedure
(qagi f [ #:epsabs epsabs #:epsrel epsrel #:limit limit])
→
(or/c (list/c integer? real? real?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
procedure
(qagi-r f [ #:epsabs epsabs #:epsrel epsrel #:limit limit]) → (list/c real? real?) f : (-> flonum? flonum?) epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
(result abserr)
procedure
(qagiu f a [ #:epsabs epsabs #:epsrel epsrel #:limit limit])
→
(or/c (list/c integer? real? real?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) a : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
procedure
(qagil f b [ #:epsabs epsabs #:epsrel epsrel #:limit limit])
→
(or/c (list/c integer? real? real?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) b : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
procedure
(qawc f a b c [ #:epsabs epsabs #:epsrel epsrel #:limit limit])
→
(or/c (list/c integer? real? real?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) a : real? b : real? c : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
procedure
(cquad f a b [ #:epsabs epsabs #:epsrel epsrel #:limit limit])
→
(or/c (list/c integer? real? real? integer?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8 limit : exact-positive-integer? = 1000
procedure
(romberg f a b [ #:epsabs epsabs #:epsrel epsrel #:n n])
→
(or/c (list/c integer? real? integer?) (list/c integer? symbol? string?)) f : (-> flonum? flonum?) a : real? b : real? epsabs : real? = 0 epsrel : real? = 1e-8 n : exact-positive-integer? = 20
3 Troubleshooting
3.1 Romberg
If you get an error that it can not find Romberg, but not error on the other functions: You have and older version of GNU GSL on our system. Romberg was added at version 2.5
3.2 ffi-lib: couldn’t open ...
If you get error: ffi-lib: couldn’t open "libgslcblas.so" (libgslcblas.so: cannot open shared object file: No such file or directory):
Solution 1: Install development version of gsl. In Ubuntu the package is: libgsl-dev.
Solution 2: Modify source code in wrap.rkt with version number. This apply if you have installed package with version number. Example: libgsl27
(define-ffi-definer gslcblas (ffi-lib "libgslcblas" #:global? #t)) (define-ffi-definer gsl (ffi-lib "libgsl" #:global? #t))
Modify this to
(define-ffi-definer gslcblas (ffi-lib "libgslcblas" '("0" #f) #:global? #t)) (define-ffi-definer gsl (ffi-lib "libgsl" '("27" #f) #:global? #t))
Solution 3: Specify absolute path in wrap.rkt without .so extension (package location may differ).
(define-ffi-definer gsl (ffi-lib "/usr/lib/x86_64-linux-gnu/libgslcblas" #:global? #t)) (define-ffi-definer gslcblas (ffi-lib "/usr/lib/x86_64-linux-gnu/libgsl" #:global? #t))
3.3 DrRacket freeze/crash
C/C++ exception’s do not mix well with Racket exception’s. Try run at command line to see what exception is raised.