root/trunk/series-acceleration.lisp

Revision 34, 5.0 kB (checked in by lhealy, 7 months ago)

The classes/types in the different contexts are now gathered together
in one place, in *type-names* for the types and in *data-class-name*
for data classes, populated by #'add-data-class. Both defdata and
defmfun-all use the table and so mapping between various names is
consistent. The data class names are now different, *-double-float
and *-single-float replaces *-double and *-single. The regression
tests give the same results as before.

  • Property svn:keywords set to Id
Line 
1;; Series acceleration.
2;; Liam Healy, Wed Nov 21 2007 - 18:41
3;; Time-stamp: <2008-03-09 19:21:47EDT series-acceleration.lisp>
4;; $Id$
5
6(in-package :gsl)
7
8;;;;****************************************************************************
9;;;; Creation and calculation of Levin series acceleration
10;;;;****************************************************************************
11
12(cffi:defcstruct levin
13  "The definition of Levin series acceleration for GSL."
14  (size size)
15  (position-in-array size)
16  (terms-used size)
17  (sum-plain :double)
18  (q-num :pointer)
19  (q-den :pointer)
20  (dq-num :pointer)
21  (dq-den :pointer)
22  (dsum :pointer))
23
24(defgo-s (levin order) allocate-levin free-levin)
25
26(defmfun allocate-levin (order)
27  "gsl_sum_levin_u_alloc"
28  ((order size))
29  :c-return :pointer
30  :export nil
31  :index (letm levin)
32  :documentation                        ; FDL
33  "Allocate a workspace for a Levin u-transform of n
34   terms.  The size of the workspace is O(2n^2 + 3n).")
35
36(defmfun free-levin (levin)
37  "gsl_sum_levin_u_free"
38  ((levin :pointer))
39  :c-return :void               ; Error in GSL manual, should be void?
40  :export nil
41  :index (letm levin)
42  :documentation                        ; FDL
43  "Free a previously allocated Levin acceleration.")
44
45(defmfun accelerate (array levin)
46  "gsl_sum_levin_u_accel"
47  (((gsl-array array) :pointer) ((dim0 array) size) (levin :pointer)
48   (accelerated-sum :double) (absolute-error :double))
49  :documentation                        ; FDL
50  "From the terms of a series in array, compute the extrapolated
51   limit of the series using a Levin u-transform.  Additional
52   working space must be provided in levin.  The extrapolated sum is
53   returned with an estimate of the absolute error.  The actual
54   term-by-term sum is returned in
55   w->sum_plain. The algorithm calculates the truncation error
56   (the difference between two successive extrapolations) and round-off
57   error (propagated from the individual terms) to choose an optimal
58   number of terms for the extrapolation.")
59
60;;;;****************************************************************************
61;;;; Acceleration with error estimation from truncation
62;;;;****************************************************************************
63
64(defgo-s (levin-truncated order) allocate-levin-truncated free-levin-truncated)
65
66(defmfun allocate-levin-truncated (order)
67  "gsl_sum_levin_utrunc_alloc"
68  ((order size))
69  :c-return :pointer
70  :export nil
71  :index (letm levin-truncated)
72  :documentation                        ; FDL
73  "Allocate a workspace for a Levin u-transform of n
74   terms, without error estimation.  The size of the workspace is
75   O(3n).")
76
77(defmfun free-levin-truncated (levin)
78  "gsl_sum_levin_utrunc_free"
79  ((levin :pointer))
80  :export nil
81  :index (letm levin-truncated)
82  :documentation                        ; FDL
83  "Free a previously allocated Levin acceleration.")
84
85(defmfun accelerate-truncated (array levin)
86  "gsl_sum_levin_utrunc_accel"
87  (((gsl-array array) :pointer) ((dim0 array) size) (levin :pointer)
88   (accelerated-sum :double) (absolute-error :double))
89  :documentation                        ; FDL
90  "From the terms of a series in array, compute the extrapolated
91   limit of the series using a Levin u-transform.  Additional
92   working space must be provided in levin.  The extrapolated sum is
93   returned with an estimate of the absolute error.  The actual
94   term-by-term sum is returned in w->sum_plain. The algorithm
95   terminates when the difference between two successive extrapolations
96   reaches a minimum or is sufficiently small. The difference between
97   these two values is used as estimate of the error and is stored in
98   abserr_trunc.  To improve the reliability of the algorithm the
99   extrapolated values are replaced by moving averages when calculating
100   the truncation error, smoothing out any fluctuations.")
101
102;;;;****************************************************************************
103;;;; Example
104;;;;****************************************************************************
105
106;;; From Sec. 29.3 in the GSL manual.
107
108(defun acceleration-example ()
109  (let ((maxterms 20)
110        (sum 0.0d0)
111        (zeta2 (/ (expt pi 2) 6)))
112    (letm ((levin (levin maxterms))
113           (array (vector-double-float maxterms)))
114      (dotimes (n maxterms)
115        (setf (maref array n) (coerce (/ (expt (1+ n) 2)) 'double-float))
116        (incf sum (maref array n)))
117      (multiple-value-bind (accelerated-sum error)
118          (accelerate array levin)
119        (format t "~&term-by-term sum =~f using ~d terms" sum maxterms)
120        (format t "~&term-by-term sum =~f using ~d terms"
121                (cffi:foreign-slot-value levin 'levin 'sum-plain)
122                (cffi:foreign-slot-value levin 'levin 'terms-used))
123        (format t "~&exact value     = ~f" zeta2)
124        (format t "~&accelerated sum = ~f using ~d terms"
125                accelerated-sum
126                (cffi:foreign-slot-value levin 'levin 'terms-used))
127        (format t "~&estimated error = ~f" error)
128        (format t "~&actual error = ~f" (- accelerated-sum zeta2))))))
129
130;; term-by-term sum =1.5961632439130233 using 20 terms
131;; term-by-term sum =1.5759958390005426 using 13 terms
132;; exact value     = 1.6449340668482264
133;; accelerated sum = 1.6449340669228176 using 13 terms
134;; estimated error = 0.00000000008883604962761638
135;; actual error = 0.00000000007459122208786084
Note: See TracBrowser for help on using the browser.