| 1 | ;;;; -*- Mode: lisp -*- |
|---|
| 2 | ;;;; |
|---|
| 3 | ;;;; Copyright (c) 2011 Raymond Toy |
|---|
| 4 | ;;;; Permission is hereby granted, free of charge, to any person |
|---|
| 5 | ;;;; obtaining a copy of this software and associated documentation |
|---|
| 6 | ;;;; files (the "Software"), to deal in the Software without |
|---|
| 7 | ;;;; restriction, including without limitation the rights to use, |
|---|
| 8 | ;;;; copy, modify, merge, publish, distribute, sublicense, and/or sell |
|---|
| 9 | ;;;; copies of the Software, and to permit persons to whom the |
|---|
| 10 | ;;;; Software is furnished to do so, subject to the following |
|---|
| 11 | ;;;; conditions: |
|---|
| 12 | ;;;; |
|---|
| 13 | ;;;; The above copyright notice and this permission notice shall be |
|---|
| 14 | ;;;; included in all copies or substantial portions of the Software. |
|---|
| 15 | ;;;; |
|---|
| 16 | ;;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|---|
| 17 | ;;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
|---|
| 18 | ;;;; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|---|
| 19 | ;;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|---|
| 20 | ;;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|---|
| 21 | ;;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|---|
| 22 | ;;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
|---|
| 23 | ;;;; OTHER DEALINGS IN THE SOFTWARE. |
|---|
| 24 | |
|---|
| 25 | (in-package #:oct) |
|---|
| 26 | |
|---|
| 27 | ;;; References: |
|---|
| 28 | ;;; |
|---|
| 29 | ;;; [1] Borwein, Borwein, Crandall, "Effective Laguerre Asymptotics", |
|---|
| 30 | ;;; http://people.reed.edu/~crandall/papers/Laguerre-f.pdf |
|---|
| 31 | ;;; |
|---|
| 32 | ;;; [2] Borwein, Borwein, Chan, "The Evaluation of Bessel Functions |
|---|
| 33 | ;;; via Exp-Arc Integrals", http://web.cs.dal.ca/~jborwein/bessel.pdf |
|---|
| 34 | ;;; |
|---|
| 35 | |
|---|
| 36 | (defvar *debug-exparc* nil) |
|---|
| 37 | |
|---|
| 38 | ;; B[k](p) = 1/2^(k+3/2)*integrate(exp(-p*u)*u^(k-1/2),u,0,1) |
|---|
| 39 | ;; = 1/2^(k+3/2)/p^(k+1/2)*integrate(t^(k-1/2)*exp(-t),t,0,p) |
|---|
| 40 | ;; = 1/2^(k+3/2)/p^(k+1/2) * g(k+1/2, p) |
|---|
| 41 | ;; |
|---|
| 42 | ;; where g(a,z) is the lower incomplete gamma function. |
|---|
| 43 | ;; |
|---|
| 44 | ;; There is the continued fraction expansion for g(a,z) (see |
|---|
| 45 | ;; cf-incomplete-gamma in qd-gamma.lisp): |
|---|
| 46 | ;; |
|---|
| 47 | ;; g(a,z) = z^a*exp(-z)/ CF |
|---|
| 48 | ;; |
|---|
| 49 | ;; So |
|---|
| 50 | ;; |
|---|
| 51 | ;; B[k](p) = 1/2^(k+3/2)/p^(k+1/2)*p^(k+1/2)*exp(-p)/CF |
|---|
| 52 | ;; = exp(-p)/2^(k+3/2)/CF |
|---|
| 53 | ;; |
|---|
| 54 | ;; |
|---|
| 55 | ;; Note also that [2] gives a recurrence relationship for B[k](p) in |
|---|
| 56 | ;; eq (2.6), but there is an error there. The correct relationship is |
|---|
| 57 | ;; |
|---|
| 58 | ;; B[k](p) = -exp(-p)/(p*sqrt(2)*2^(k+1)) + (k-1/2)*B[k-1](p)/(2*p) |
|---|
| 59 | ;; |
|---|
| 60 | ;; The paper is missing the division by p in the term containing |
|---|
| 61 | ;; B[k-1](p). This is easily derived from the recurrence relationship |
|---|
| 62 | ;; for the (lower) incomplete gamma function. |
|---|
| 63 | ;; |
|---|
| 64 | ;; Note too that as k increases, the recurrence appears to be unstable |
|---|
| 65 | ;; and B[k](p) begins to increase even though it is strictly bounded. |
|---|
| 66 | ;; (This is also easy to see from the integral.) Hence, we do not use |
|---|
| 67 | ;; the recursion. However, it might be stable for use with |
|---|
| 68 | ;; double-float precision; this has not been tested. |
|---|
| 69 | ;; |
|---|
| 70 | (defun bk (k p) |
|---|
| 71 | (/ (exp (- p)) |
|---|
| 72 | (* (sqrt (float 2 (realpart p))) (ash 1 (+ k 1))) |
|---|
| 73 | (let ((a (float (+ k 1/2) (realpart p)))) |
|---|
| 74 | (lentz #'(lambda (n) |
|---|
| 75 | (+ n a)) |
|---|
| 76 | #'(lambda (n) |
|---|
| 77 | (if (evenp n) |
|---|
| 78 | (* (ash n -1) p) |
|---|
| 79 | (- (* (+ a (ash n -1)) p)))))))) |
|---|
| 80 | |
|---|
| 81 | ;; exp-arc I function, as given in the Laguerre paper |
|---|
| 82 | ;; |
|---|
| 83 | ;; I(p, q) = 4*exp(p) * sum(g[k](-2*%i*q)/(2*k)!*B[k](p), k, 0, inf) |
|---|
| 84 | ;; |
|---|
| 85 | ;; where g[k](p) = product(p^2+(2*j-1)^2, j, 1, k) and B[k](p) as above. |
|---|
| 86 | ;; |
|---|
| 87 | ;; For computation, note that g[k](p) = g[k-1](p) * (p^2 + (2*k-1)^2) |
|---|
| 88 | ;; and (2*k)! = (2*k-2)! * (2*k-1) * (2*k). Then, let |
|---|
| 89 | ;; |
|---|
| 90 | ;; R[k](p) = g[k](p)/(2*k)! |
|---|
| 91 | ;; |
|---|
| 92 | ;; Then |
|---|
| 93 | ;; |
|---|
| 94 | ;; R[k](p) = g[k](p)/(2*k)! |
|---|
| 95 | ;; = g[k-1](p)/(2*k-2)! * (p^2 + (2*k-1)^2)/((2*k-1)*(2*k) |
|---|
| 96 | ;; = R[k-1](p) * (p^2 + (2*k-1)^2)/((2*k-1)*(2*k) |
|---|
| 97 | ;; |
|---|
| 98 | ;; In the exp-arc paper, the function is defined (equivalently) as |
|---|
| 99 | ;; |
|---|
| 100 | ;; I(p, q) = 2*%i*exp(p)/q * sum(r[2*k+1](-2*%i*q)/(2*k)!*B[k](p), k, 0, inf) |
|---|
| 101 | ;; |
|---|
| 102 | ;; where r[2*k+1](p) = p*product(p^2 + (2*j-1)^2, j, 1, k) |
|---|
| 103 | ;; |
|---|
| 104 | ;; Let's note some properties of I(p, q). |
|---|
| 105 | ;; |
|---|
| 106 | ;; I(-%i*z, v) = 2*%i*exp(-%i*z)/q * sum(r[2*k+1](-2*%i*v)/(2*k)!*B[k](-%i*z)) |
|---|
| 107 | ;; |
|---|
| 108 | ;; Note thate B[k](-%i*z) = 1/2^(k+3/2)*integrate(exp(%i*z*u)*u^(k-1/2),u,0,1) |
|---|
| 109 | ;; = conj(B[k](%i*z). |
|---|
| 110 | ;; |
|---|
| 111 | ;; Hence I(-%i*z, v) = conj(I(%i*z, v)) when both z and v are real. |
|---|
| 112 | (defun exp-arc-i (p q) |
|---|
| 113 | (let* ((sqrt2 (sqrt (float 2 (realpart p)))) |
|---|
| 114 | (exp/p/sqrt2 (/ (exp (- p)) p sqrt2)) |
|---|
| 115 | (v (* #c(0 -2) q)) |
|---|
| 116 | (v2 (expt v 2)) |
|---|
| 117 | (eps (epsilon (realpart p)))) |
|---|
| 118 | (when *debug-exparc* |
|---|
| 119 | (format t "sqrt2 = ~S~%" sqrt2) |
|---|
| 120 | (format t "exp/p/sqrt2 = ~S~%" exp/p/sqrt2)) |
|---|
| 121 | (do* ((k 0 (1+ k)) |
|---|
| 122 | (bk (/ (incomplete-gamma 1/2 p) |
|---|
| 123 | 2 sqrt2 (sqrt p)) |
|---|
| 124 | (- (/ (* bk (- k 1/2)) 2 p) |
|---|
| 125 | (/ exp/p/sqrt2 (ash 1 (+ k 1))))) |
|---|
| 126 | ;; ratio[k] = r[2*k+1](v)/(2*k)!. |
|---|
| 127 | ;; r[1] = v and r[2*k+1](v) = r[2*k-1](v)*(v^2 + (2*k-1)^2) |
|---|
| 128 | ;; ratio[0] = v |
|---|
| 129 | ;; and ratio[k] = r[2*k-1](v)*(v^2+(2*k-1)^2) / ((2*k-2)! * (2*k-1) * 2*k) |
|---|
| 130 | ;; = ratio[k]*(v^2+(2*k-1)^2)/((2*k-1) * 2 * k) |
|---|
| 131 | (ratio v |
|---|
| 132 | (* ratio (/ (+ v2 (expt (1- (* 2 k)) 2)) |
|---|
| 133 | (* 2 k (1- (* 2 k)))))) |
|---|
| 134 | (term (* ratio bk) |
|---|
| 135 | (* ratio bk)) |
|---|
| 136 | (sum term (+ sum term))) |
|---|
| 137 | ((< (abs term) (* (abs sum) eps)) |
|---|
| 138 | (* sum #c(0 2) (/ (exp p) q))) |
|---|
| 139 | (when *debug-exparc* |
|---|
| 140 | (format t "k = ~D~%" k) |
|---|
| 141 | (format t " bk = ~S~%" bk) |
|---|
| 142 | (format t " ratio = ~S~%" ratio) |
|---|
| 143 | (format t " term = ~S~%" term) |
|---|
| 144 | (format t " sum - ~S~%" sum))))) |
|---|
| 145 | |
|---|
| 146 | (defun exp-arc-i-2 (p q) |
|---|
| 147 | (let* ((sqrt2 (sqrt (float 2 (realpart p)))) |
|---|
| 148 | (exp/p/sqrt2 (/ (exp (- p)) p sqrt2)) |
|---|
| 149 | (v (* #c(0 -2) q)) |
|---|
| 150 | (v2 (expt v 2)) |
|---|
| 151 | (eps (epsilon (realpart p)))) |
|---|
| 152 | (when *debug-exparc* |
|---|
| 153 | (format t "sqrt2 = ~S~%" sqrt2) |
|---|
| 154 | (format t "exp/p/sqrt2 = ~S~%" exp/p/sqrt2)) |
|---|
| 155 | (do* ((k 0 (1+ k)) |
|---|
| 156 | (bk (bk 0 p) |
|---|
| 157 | (bk k p)) |
|---|
| 158 | (ratio v |
|---|
| 159 | (* ratio (/ (+ v2 (expt (1- (* 2 k)) 2)) |
|---|
| 160 | (* 2 k (1- (* 2 k)))))) |
|---|
| 161 | (term (* ratio bk) |
|---|
| 162 | (* ratio bk)) |
|---|
| 163 | (sum term (+ sum term))) |
|---|
| 164 | ((< (abs term) (* (abs sum) eps)) |
|---|
| 165 | (* sum #c(0 2) (/ (exp p) q))) |
|---|
| 166 | (when *debug-exparc* |
|---|
| 167 | (format t "k = ~D~%" k) |
|---|
| 168 | (format t " bk = ~S~%" bk) |
|---|
| 169 | (format t " ratio = ~S~%" ratio) |
|---|
| 170 | (format t " term = ~S~%" term) |
|---|
| 171 | (format t " sum - ~S~%" sum))))) |
|---|
| 172 | |
|---|
| 173 | |
|---|
| 174 | ;; This currently only works for v an integer. |
|---|
| 175 | ;; |
|---|
| 176 | (defun integer-bessel-j-exp-arc (v z) |
|---|
| 177 | (let* ((iz (* #c(0 1) z)) |
|---|
| 178 | (i+ (exp-arc-i-2 iz v)) |
|---|
| 179 | (i- (exp-arc-i-2 (- iz ) v))) |
|---|
| 180 | (/ (+ (* (cis (* v (float-pi i+) -1/2)) |
|---|
| 181 | i+) |
|---|
| 182 | (* (cis (* v (float-pi i+) 1/2)) |
|---|
| 183 | i-)) |
|---|
| 184 | (float-pi i+) |
|---|
| 185 | 2))) |
|---|
| 186 | |
|---|
| 187 | (defun paris-series (v z n) |
|---|
| 188 | (labels ((pochhammer (a k) |
|---|
| 189 | (/ (gamma (+ a k)) |
|---|
| 190 | (gamma a))) |
|---|
| 191 | (a (v k) |
|---|
| 192 | (* (/ (pochhammer (+ 1/2 v) k) |
|---|
| 193 | (gamma (float (1+ k) z))) |
|---|
| 194 | (pochhammer (- 1/2 v) k)))) |
|---|
| 195 | (* (loop for k from 0 below n |
|---|
| 196 | sum (* (/ (a v k) |
|---|
| 197 | (expt (* 2 z) k)) |
|---|
| 198 | (/ (cf-incomplete-gamma (+ k v 1/2) (* 2 z)) |
|---|
| 199 | (gamma (+ k v 1/2))))) |
|---|
| 200 | (/ (exp z) |
|---|
| 201 | (sqrt (* 2 (float-pi z) z)))))) |
|---|
| 202 | |
|---|