-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathchebyshev.lisp
132 lines (112 loc) · 4.48 KB
/
chebyshev.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;; Chebyshev Approximations
;; Liam Healy Sat Nov 17 2007 - 20:36
;; Time-stamp: <2009-05-25 09:44:54EDT chebyshev.lisp>
;; $Id$
(in-package :gsl)
;;; /usr/include/gsl/gsl_chebyshev.h
;;;;****************************************************************************
;;;; Creation and calculation of Chebyshev series
;;;;****************************************************************************
(defmobject chebyshev "gsl_cheb"
((order sizet))
"Chebyshev series"
:documentation ; FDL
"Make a Chebyshev series of specified order."
:callbacks
(callback fnstruct nil (function :double (:input :double) :slug))
:initialize-suffix "init"
:initialize-args
((callback :pointer) (lower-limit :double) (upper-limit :double))
:singular (function))
(defmfun order ((object chebyshev))
"gsl_cheb_order"
(((mpointer object) :pointer))
:definition :method
:c-return sizet
:gsl-version (1 12))
(defmfun size ((chebyshev chebyshev))
"gsl_cheb_size"
(((mpointer chebyshev) :pointer))
:definition :method
:c-return sizet
:gsl-version (1 12))
(defmfun coefficients (chebyshev)
"gsl_cheb_coeffs"
(((mpointer chebyshev) :pointer))
:c-return sizet
:gsl-version (1 12))
;;;;****************************************************************************
;;;; Chebyshev series evaluation
;;;;****************************************************************************
;;; The functions that don't return are defined, but it is recommended
;;; to use the functions that do return error (and ignore it if
;;; desired) in the form of #'evaluate.
(defmfun evaluate ((object chebyshev) x &key order)
("gsl_cheb_eval" "gsl_cheb_eval_n")
((((mpointer object) :pointer) (x :double))
(((mpointer object) :pointer) (order sizet) (x :double)))
:definition :method
:callback-object object
:c-return :double
:documentation ; FDL
"Evaluate the Chebyshev series at a point x. If order is supplied,
evaluate to at most the given order.")
(defmfun evaluate-chebyshev-error (chebyshev x &optional order)
("gsl_cheb_eval_err" "gsl_cheb_eval_n_err")
((((mpointer chebyshev) :pointer) (x :double)
(result (:pointer :double)) (abserr (:pointer :double)))
(((mpointer chebyshev) :pointer) (order sizet) (x :double)
(result (:pointer :double)) (abserr (:pointer :double))))
:documentation ; FDL
"Evaluate the Chebyshev series at a point x, returning result and
an estimate of its absolute error. If order is supplied,
evaluate to at most the given order.")
;;;;****************************************************************************
;;;; Derivatives and integrals
;;;;****************************************************************************
(defmfun derivative-chebyshev (derivative chebyshev)
"gsl_cheb_calc_deriv"
(((mpointer derivative) :pointer) ((mpointer chebyshev) :pointer))
:documentation ; FDL
"Compute the derivative of the Chebyshev series, storing
the derivative coefficients in the previously allocated series.
The two series must have been allocated with the same order.")
(defmfun integral-chebyshev (integral chebyshev)
"gsl_cheb_calc_integ"
(((mpointer integral) :pointer) ((mpointer chebyshev) :pointer))
:documentation ; FDL
"Compute the integral of the Chebyshev series, storing
the integral coefficients in the previously allocated series.
The two series must have been allocated with the same order.
The lower limit of the integration is taken to be the left hand
end of the range lower-limit.")
;;;;****************************************************************************
;;;; Example
;;;;****************************************************************************
;;; From Chap. 28.5, except I have set steps = 100 instead of 10000
;;; to keep things sane.
(defun chebyshev-step (x) (if (< x 0.5d0) 0.25d0 0.75d0))
(defun chebyshev-table-example ()
(let ((steps 100))
(let ((cheb (make-chebyshev 40 'chebyshev-step 0.0d0 1.0d0)))
(dotimes (i steps)
(let ((x (coerce (/ i steps) 'double-float)))
(format t "~&~a ~a ~a ~a"
x
(chebyshev-step x)
(evaluate cheb x :order 10)
(evaluate cheb x)))))))
(defun chebyshev-point-example (x)
(check-type x double-float)
(let ((cheb (make-chebyshev 40 'chebyshev-step 0.0d0 1.0d0))
(deriv (make-chebyshev 40))
(integ (make-chebyshev 40)))
(derivative-chebyshev deriv cheb)
(integral-chebyshev integ cheb)
(list
(evaluate cheb x)
(evaluate deriv x)
(evaluate integ x))))
;;; Unit test
(save-test chebyshev
(chebyshev-point-example 0.55d0))