Numerical integration/Gauss-Legendre Quadrature: Difference between revisions

Line 734:
Computation of the Legendre polynomials and derivatives:
 
<lang schemeracket>
(define (LegendreP n x)
(let compute ([n n] [Pn-1 x] [Pn-2 1])
Line 753:
Computation of the Legendre polynomial roots:
 
<lang schemeracket>
(define (LegendreP-root n i)
; newton-raphson step
(define (newton-step x)
(- x (/ (LegendreP n x) (LegendreP′LegendreP n x))))
; initial guess
(define x0 (cos (* pi (/ (- i 1/4) (+ n 1/2)))))
Line 766:
(if (< (abs (/ (- x′ x) (+ x′ x))) 1e-15)
x′
(next (newton-step x′) x′x)))))
</lang>
 
Computation of Gauss-Legendre nodes and weights
 
<lang schemeracket>
(define (Gauss-Legendre-quadrature n)
;; positive roots
(define roots
(for/list ([i (in-range (floor (/ n 2)))])
(LegendreP-root n (+ i 1))))
;; weights for positive roots
(define weights
(for/list ([x (in-list roots)])
(/ 2 (- 1 (sqr x)) (sqr (LegendreP′ n x)))))
;; all roots and weights
(values (append (map - roots)
(appendif (mapodd? -n) roots(list 0) '())
(if (odd? n) (list 0) ' (reverse roots))
(reverseappend roots))weights
(if (odd? n) (list (/ 2 (-sqr (expLegendreP′ 3)n (exp -3)))0)))) '())
(append weights
(if (odd? n) (list (/ 2 (sqr (LegendreP′reverse n 0weights)))) '())
(reverse weights))))
</lang>
 
Integration using Gauss-Legendre quadratures:
 
<lang schemeracket>
(define (integrate f a b #:nodes (n 5))
(define m (/ (+ a b) 2))
(define d (/ (- b a) 2))
(define-values ([x w)] (Gauss-Legendre-quadrature n))
(define (g x) (f (+ m (* d x))))
(* d (+ (apply + (map * w (map g x))))))
</lang>
 
Usage:
 
<lang schemeracket>
> (Gauss-Legendre-quadrature 5)
'(-0.906179845938664 -0.5384693101056831 0 0.5384693101056831 0.906179845938664)
Line 818 ⟶ 817:
Accuracy of the method:
 
<lang schemeracket>
> (require plot)
> (parameterize ([plot-x-label "Number of Gaussian nodes"]
[plot-y-label "Integration error"]
[plot-y-transform log-transform]
[plot-y-ticks (log-ticks #:base 10)])
(plot (points (for/list ([n (in-range 2 11)])
(list n (abs (- (integrate exp -3 3 #:nodes n)
(points
(- (exp 3) (exp -3)))))))))
(for/list ([n (in-range 2 11)])
(list n (abs (- (integrate exp -3 3 #:nodes n)
(- (exp 3) (exp -3)))))))))
</lang>
[[File:gauss.png]]