| 1 | ;; Chebyshev Approximations |
|---|
| 2 | ;; Liam Healy Sat Nov 17 2007 - 20:36 |
|---|
| 3 | ;; Time-stamp: <2008-02-17 18:02:26EST chebyshev.lisp> |
|---|
| 4 | ;; $Id$ |
|---|
| 5 | |
|---|
| 6 | (in-package :gsl) |
|---|
| 7 | |
|---|
| 8 | ;;;;**************************************************************************** |
|---|
| 9 | ;;;; Creation and calculation of Chebyshev series |
|---|
| 10 | ;;;;**************************************************************************** |
|---|
| 11 | |
|---|
| 12 | (defgo-s (chebyshev order function lower-limit upper-limit) |
|---|
| 13 | allocate-chebyshev free-chebyshev initialize-chebyshev) |
|---|
| 14 | |
|---|
| 15 | (defmfun allocate-chebyshev (order) |
|---|
| 16 | "gsl_cheb_alloc" |
|---|
| 17 | ((order size)) |
|---|
| 18 | :c-return :pointer |
|---|
| 19 | :export nil |
|---|
| 20 | :index (letm chebyshev) |
|---|
| 21 | :documentation ; FDL |
|---|
| 22 | "Allocate a Chebyshev series of specified order |
|---|
| 23 | and return a pointer to it.") |
|---|
| 24 | |
|---|
| 25 | (defmfun free-chebyshev (chebyshev) |
|---|
| 26 | "gsl_cheb_free" |
|---|
| 27 | ((chebyshev :pointer)) |
|---|
| 28 | :c-return :void |
|---|
| 29 | :export nil |
|---|
| 30 | :index (letm chebyshev) |
|---|
| 31 | :documentation ; FDL |
|---|
| 32 | "Free a previously allocated Chebyshev series.") |
|---|
| 33 | |
|---|
| 34 | (defmfun initialize-chebyshev (chebyshev function lower-limit upper-limit) |
|---|
| 35 | "gsl_cheb_init" |
|---|
| 36 | ((chebyshev :pointer) (function :pointer) |
|---|
| 37 | (lower-limit :double) (upper-limit :double)) |
|---|
| 38 | :export nil |
|---|
| 39 | :index (letm chebyshev) |
|---|
| 40 | :documentation ; FDL |
|---|
| 41 | "Compute the Chebyshev approximation for the function over the range |
|---|
| 42 | (lower-limit, upper-limit) to the previously specified order. The |
|---|
| 43 | computation of the Chebyshev approximation is an O(n^2) |
|---|
| 44 | process, and requires n function evaluations.") |
|---|
| 45 | |
|---|
| 46 | ;;;;**************************************************************************** |
|---|
| 47 | ;;;; Chebyshev series evaluation |
|---|
| 48 | ;;;;**************************************************************************** |
|---|
| 49 | |
|---|
| 50 | ;;; The functions that don't return are defined, but it is recommended |
|---|
| 51 | ;;; to use the functions that do return error (and ignore it if |
|---|
| 52 | ;;; desired) in the form of #'evaluate-chebyshev. |
|---|
| 53 | |
|---|
| 54 | (defmfun evaluate-chebyshev-noerror (chebyshev x) |
|---|
| 55 | "gsl_cheb_eval" |
|---|
| 56 | ((chebyshev :pointer) (x :double)) |
|---|
| 57 | :c-return :double |
|---|
| 58 | :index evaluate-chebyshev |
|---|
| 59 | :export nil |
|---|
| 60 | :documentation ; FDL |
|---|
| 61 | "Evaluate the Chebyshev series at a point x.") |
|---|
| 62 | |
|---|
| 63 | (defmfun evaluate-chebyshev-noerror-order (chebyshev x order) |
|---|
| 64 | "gsl_cheb_eval_n" |
|---|
| 65 | ((chebyshev :pointer) (order size) (x :double)) |
|---|
| 66 | :c-return :double |
|---|
| 67 | :index evaluate-chebyshev |
|---|
| 68 | :export nil |
|---|
| 69 | :documentation ; FDL |
|---|
| 70 | "Evaluate the Chebyshev series at a point x to at most the given order.") |
|---|
| 71 | |
|---|
| 72 | (defmfun evaluate-chebyshev-full (chebyshev x) |
|---|
| 73 | "gsl_cheb_eval_err" |
|---|
| 74 | ((chebyshev :pointer) (x :double) (result :double) (abserr :double)) |
|---|
| 75 | :index evaluate-chebyshev |
|---|
| 76 | :export nil |
|---|
| 77 | :documentation ; FDL |
|---|
| 78 | "Evaluate the Chebyshev series at a point x, returning result and |
|---|
| 79 | an estimate of its absolute error.") |
|---|
| 80 | |
|---|
| 81 | (defmfun evaluate-chebyshev-order (chebyshev x order) |
|---|
| 82 | "gsl_cheb_eval_n_err" |
|---|
| 83 | ((chebyshev :pointer) (order size) (x :double) (result :double) (abserr :double)) |
|---|
| 84 | :index evaluate-chebyshev |
|---|
| 85 | :export nil |
|---|
| 86 | :documentation ; FDL |
|---|
| 87 | "Evaluate the Chebyshev series at a point x to at most the given order, |
|---|
| 88 | returning result and an estimate of its absolute error.") |
|---|
| 89 | |
|---|
| 90 | (export 'evaluate-chebyshev) |
|---|
| 91 | (defun-optionals evaluate-chebyshev (chebyshev x &optional order) |
|---|
| 92 | -full -order ; FDL |
|---|
| 93 | "Evaluate the Chebyshev series at a point x to at most the given order, |
|---|
| 94 | returning result and an estimate of its absolute error.") |
|---|
| 95 | |
|---|
| 96 | ;;;;**************************************************************************** |
|---|
| 97 | ;;;; Derivatives and integrals |
|---|
| 98 | ;;;;**************************************************************************** |
|---|
| 99 | |
|---|
| 100 | (defmfun derivative-chebyshev (derivative chebyshev) |
|---|
| 101 | "gsl_cheb_calc_deriv" |
|---|
| 102 | ((derivative :pointer) (chebyshev :pointer)) |
|---|
| 103 | :documentation ; FDL |
|---|
| 104 | "Compute the derivative of the Chebyshev series, storing |
|---|
| 105 | the derivative coefficients in the previously allocated series. |
|---|
| 106 | The two series must have been allocated with the same order.") |
|---|
| 107 | |
|---|
| 108 | (defmfun integral-chebyshev (integral chebyshev) |
|---|
| 109 | "gsl_cheb_calc_integ" |
|---|
| 110 | ((integral :pointer) (chebyshev :pointer)) |
|---|
| 111 | :documentation ; FDL |
|---|
| 112 | "Compute the integral of the Chebyshev series, storing |
|---|
| 113 | the integral coefficients in the previously allocated series. |
|---|
| 114 | The two series must have been allocated with the same order. |
|---|
| 115 | The lower limit of the integration is taken to be the left hand |
|---|
| 116 | end of the range lower-limit.") |
|---|
| 117 | |
|---|
| 118 | ;;;;**************************************************************************** |
|---|
| 119 | ;;;; Example |
|---|
| 120 | ;;;;**************************************************************************** |
|---|
| 121 | |
|---|
| 122 | ;;; From Chap. 28.5, except I have set steps = 100 instead of 10000 |
|---|
| 123 | ;;; to keep things sane. |
|---|
| 124 | |
|---|
| 125 | (defun-single chebyshev-step (x) (if (< x 0.5d0) 0.25d0 0.75d0)) |
|---|
| 126 | |
|---|
| 127 | (defun chebyshev-table-example () |
|---|
| 128 | (let ((steps 100)) |
|---|
| 129 | (letm ((cheb (chebyshev 40 chebyshev-step 0.0d0 1.0d0))) |
|---|
| 130 | (dotimes (i steps) |
|---|
| 131 | (let ((x (coerce (/ i steps) 'double-float))) |
|---|
| 132 | (format t "~&~a ~a ~a ~a" |
|---|
| 133 | x |
|---|
| 134 | (chebyshev-step x) |
|---|
| 135 | (evaluate-chebyshev cheb x 10) |
|---|
| 136 | (evaluate-chebyshev cheb x))))))) |
|---|
| 137 | |
|---|
| 138 | (defun chebyshev-point-example (x) |
|---|
| 139 | (check-type x double-float) |
|---|
| 140 | (letm ((cheb (chebyshev 40 chebyshev-step 0.0d0 1.0d0)) |
|---|
| 141 | (deriv (chebyshev 40)) |
|---|
| 142 | (integ (chebyshev 40))) |
|---|
| 143 | (derivative-chebyshev deriv cheb) |
|---|
| 144 | (integral-chebyshev integ cheb) |
|---|
| 145 | (list |
|---|
| 146 | (evaluate-chebyshev cheb x) |
|---|
| 147 | (evaluate-chebyshev deriv x) |
|---|
| 148 | (evaluate-chebyshev integ x)))) |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | #| |
|---|
| 152 | (make-tests chebyshev |
|---|
| 153 | (chebyshev-point-example 0.55d0)) |
|---|
| 154 | |# |
|---|
| 155 | |
|---|
| 156 | (LISP-UNIT:DEFINE-TEST CHEBYSHEV |
|---|
| 157 | (LISP-UNIT::ASSERT-NUMERICAL-EQUAL |
|---|
| 158 | (LIST |
|---|
| 159 | (LIST 0.7159209901689866d0 -1.5019966658054353d0 |
|---|
| 160 | 0.17239719403979925d0)) |
|---|
| 161 | (MULTIPLE-VALUE-LIST (CHEBYSHEV-POINT-EXAMPLE 0.55d0)))) |
|---|
| 162 | |
|---|