aboutsummaryrefslogtreecommitdiff
path: root/src/interp/sfsfun.boot.pamphlet
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2007-11-01 15:54:26 +0000
committerdos-reis <gdr@axiomatics.org>2007-11-01 15:54:26 +0000
commit7eb57494dfe94c4bdf09c445f45515b1890f3516 (patch)
tree68ce4fb10d0a7c2db9e670eb91c4ff439b449039 /src/interp/sfsfun.boot.pamphlet
parentd25ed262488778447a0364f45096b3b46a9912e0 (diff)
downloadopen-axiom-7eb57494dfe94c4bdf09c445f45515b1890f3516.tar.gz
remove more pamphlet
Diffstat (limited to 'src/interp/sfsfun.boot.pamphlet')
-rw-r--r--src/interp/sfsfun.boot.pamphlet1031
1 files changed, 0 insertions, 1031 deletions
diff --git a/src/interp/sfsfun.boot.pamphlet b/src/interp/sfsfun.boot.pamphlet
deleted file mode 100644
index 50bd7b5b..00000000
--- a/src/interp/sfsfun.boot.pamphlet
+++ /dev/null
@@ -1,1031 +0,0 @@
-\documentclass{article}
-\usepackage{axiom}
-\begin{document}
-\title{\$SPAD/src/interp sfsfun.boot}
-\author{The Axiom Team}
-\maketitle
-\begin{abstract}
-\end{abstract}
-\eject
-\tableofcontents
-\eject
-\begin{verbatim}
-NOTEfrom TTT: at least BesselJAsymptOrder needs work
-
-1. This file contains the contents of BWC's original files:
- floaterrors.boot
- floatutils.boot
- rgamma.boot
- cgamma.boot
- rpsi.boot
- cpsi.boot
- f01.boot
- chebf01cmake.boot
- chebevalsf.boot
- besselIJ.boot
-
-2. All declarations have been commented out with "--@@"
- since the boot translator is generating bad lisp code from them.
-
-3. The functions PsiAsymptotic, PsiEps and PsiAsymptoticOrder
- had inconpatible definitions in rpsi.boot and cpsi.boot --
- the local variables were declared float in one file and COMPLEX in
- the other. The type declarations have been commented out and the
- duplicate definitions have been deleted.
-
-4. BesselIJ was not compiling. I have modified the code from that
- file to make it compile. It should be checked for correctness.
-
-SMW June 25, 1991
-
-"Fixes" to BesselJ, B. Char June 14, 1992. Needs extensive testing and
- further fixes to BesselI and BesselJ.
-More fixes to BesselJ, T. Tsikas 24 Feb, 1995.
-
-\end{verbatim}
-\section{License}
-<<license>>=
--- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--- All rights reserved.
---
--- Redistribution and use in source and binary forms, with or without
--- modification, are permitted provided that the following conditions are
--- met:
---
--- - Redistributions of source code must retain the above copyright
--- notice, this list of conditions and the following disclaimer.
---
--- - Redistributions in binary form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in
--- the documentation and/or other materials provided with the
--- distribution.
---
--- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
--- names of its contributors may be used to endorse or promote products
--- derived from this software without specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-@
-<<*>>=
-<<license>>
-
--- Used to be SPECFNSF
-)package "BOOT"
-
-FloatError(formatstring,arg) ==
--- ERROR(formatstring,arg)
- ERROR FORMAT([],formatstring,arg)
-
-nangenericcomplex () ==
- 1.0/COMPLEX(0.0)
-
-
-
-fracpart(x) ==
- CADR(MULTIPLE_-VALUE_-LIST(FLOOR(x)))
-
-intpart(x) ==
- CAR(MULTIPLE_-VALUE_-LIST(FLOOR(x)))
-
-negintp(x) ==
- if ZEROP IMAGPART(x) and x<0.0 and ZEROP fracpart(x)
- then
- true
- else
- false
-
---- Small float implementation of Gamma function. Valid for
---- real arguments. Maximum error (relative) seems to be
---- 2-4 ulps for real x 2<x<9, and up to ten ulps for larger x
---- up to overflow. See Hart & Cheney.
---- Bruce Char, April, 1990.
-
-horner(l,x) ==
- result := 0
- for el in l repeat
- result := result *x + el
- return result
-
-rgamma (x) ==
- if COMPLEXP(x) then FloatError('"Gamma not implemented for complex value ~D",x)
- ZEROP (x-1.0) => 1.0
- if x>20 then gammaStirling(x) else gammaRatapprox(x)
-
-lnrgamma (x) ==
- if x>20 then lnrgammaRatapprox(x) else LOG(gammaRatapprox(x))
-
-cbeta(z,w) ==
- cgamma(z)*cgamma(w)/(cgamma(z+w))
-
-gammaStirling(x) ==
- EXP(lnrgamma(x))
-
-lnrgammaRatapprox(x) ==
- (x-.5)*LOG(x) - x + LOG(SQRT(2.0*PI)) + phiRatapprox(x)
-
-phiRatapprox(x) ==
- arg := 1/(x**2)
- p := horner([.0666629070402007526,_
- .6450730291289920251389,_
- .670827838343321349614617,_
- .12398282342474941538685913],arg);
- q := horner([1.0,7.996691123663644194772,_
- 8.09952718948975574728214,_
- 1.48779388109699298468156],arg);
- result := p/(x*q)
- result
-
-gammaRatapprox (x) ==
- if (x>=2 and x<=3)
- then
- result := gammaRatkernel(x)
- else
- if x>3
- then
- n := FLOOR(x)-2
- a := x-n-2
- reducedarg := 2+a
- prod := */[reducedarg+i for i in 0..n-1]
- result := prod* gammaRatapprox(reducedarg)
- else
- if (2>x and x>0)
- then
- n := 2-FLOOR(x)
- a := x-FLOOR(x)
- reducedarg := 2+a
- prod := */[x+i for i in 0..n-1]
- result := gammaRatapprox(reducedarg)/prod
- else
- Pi := PI
- lx := MULTIPLE_-VALUE_-LIST(FLOOR(x))
- intpartx := CAR(lx)+1
- restx := CADR(lx)
- if ZEROP restx -- case of negative non-integer value
- then
- FloatError ('"Gamma undefined for non-positive integers: ~D",x)
- result := nangenericcomplex ()
- else
- result := Pi/(gammaRatapprox(1.0-x)*(-1.0)**(intpartx+1)*SIN(restx*Pi))
- result
-
-gammaRatkernel(x) ==
- p := horner(REVERSE([3786.01050348257245475108,_
- 2077.45979389418732098416,_
- 893.58180452374981423868,_
- 222.1123961680117948396,_
- 48.95434622790993805232,_
- 6.12606745033608429879,_
- .778079585613300575867]),x-2)
- q := horner(REVERSE([3786.01050348257187258861,_
- 476.79386050368791516095,_
- -867.23098753110299445707,_
- 83.55005866791976957459,_
- 50.78847532889540973716,_
- -13.40041478578134826274,_
- 1]),x-2.0)
- p/q
-
--- cgamma(z) Gamma function for complex arguments.
--- Bruce Char April-May, 1990.
---
--- Our text for complex gamma is H. Kuki's paper Complex Gamma
--- Function with Error Control", CACM vol. 15, no. 4, ppp. 262-267.
--- (April, 1972.) It uses the reflection formula and the basic
--- z+1 recurrence to transform the argument into something that
--- Stirling's asymptotic formula can handle.
---
--- However along the way it does a few tricky things to reduce
--- problems due to roundoff/cancellation error for particular values.
-
--- cgammat is auxiliary "t" function (see p. 263 Kuki)
-cgammat(x) ==
- MAX(0.1, MIN(10.0, 10.0*SQRT(2.0) - ABS(x)))
-
-cgamma (z) ==
- z2 := IMAGPART(z)
- z1 := REALPART(z) --- call real valued gamma if z is real
- if ZEROP z2
- then result := rgamma(z1)
- else
- result := clngamma(z1,z2,z)
- result := EXP(result)
- result
-
-lncgamma(z) ==
- clngamma(REALPART z, IMAGPART z, z)
-
-clngamma(z1,z2,z) ==
- --- conjugate of gamma is gamma of conjugate. map 2nd and 4th quads
- --- to first and third quadrants
- if z1<0.0
- then if z2 > 0.0
- then result := CONJUGATE(clngammacase1(z1,-z2,COMPLEX(z1,-z2)))
- else result := clngammacase1(z1,z2,z)
- else if z2 < 0.0
- then result := CONJUGATE(clngammacase23(z1,-z2,_
- COMPLEX(z1,-z2)))
- else result := clngammacase23(z1,z2,z)
- result
-
-clngammacase1(z1,z2,z) ==
- result1 := PiMinusLogSinPi(z1,z2,z)
- result2 := clngamma(1.0-z1,-z2,1.0-z)
- result1-result2
-
-PiMinusLogSinPi(z1,z2,z) ==
- cgammaG(z1,z2) - logH(z1,z2,z)
-
-cgammaG(z1,z2) ==
- LOG(2*PI) + PI*z2 - COMPLEX(0.0,1.0)*PI*(z1-.5)
-
-logH(z1,z2,z) ==
- z1bar := CADR(MULTIPLE_-VALUE_-LIST(FLOOR(z1))) ---frac part of z1
- piz1bar := PI*z1bar
- piz2 := PI*z2
- twopiz2 := 2.0*piz2
- i := COMPLEX(0.0,1.0)
- part2 := EXP(twopiz2)*(2.0*SIN(piz1bar)**2 + SIN(2.0*piz1bar)*i)
- part1 := -TANH(piz2)*(1.0+EXP(twopiz2))
---- part1 is another way of saying 1 - exp(2*Pi*z1bar)
- LOG(part1+part2)
-
-clngammacase23(z1,z2,z) ==
- tz2 := cgammat(z2)
- if (z1 < tz2)
- then result:= clngammacase2(z1,z2,tz2,z)
- else result:= clngammacase3(z)
- result
-
-clngammacase2(z1,z2,tz2,z) ==
- n := float(CEILING(tz2-z1))
- zpn := z+n
- (z-.5)*LOG(zpn) - (zpn) + cgammaBernsum(zpn) - cgammaAdjust(logS(z1,z2,z,n,zpn))
-
-logS(z1,z2,z,n,zpn) ==
- sum := 0.0
- for k in 0..(n-1) repeat
- if z1+k < 5.0 - 0.6*z2
- then sum := sum + LOG((z+k)/zpn)
- else sum := sum + LOG(1.0 - (n-k)/zpn)
- sum
-
---- on p. 265, Kuki, logS result should have its imaginary part
---- adjusted by 2 Pi if it is negative.
-cgammaAdjust(z) ==
- if IMAGPART(z)<0.0
- then result := z + COMPLEX(0.0, 2.0*PI)
- else result := z
- result
-
-clngammacase3(z) ==
- (z- .5)*LOG(z) - z + cgammaBernsum(z)
-
-cgammaBernsum (z) ==
- sum := LOG(2.0*PI)/2.0
- zterm := z
- zsquaredinv := 1.0/(z*z)
- l:= [.083333333333333333333, -.0027777777777777777778,_
- .00079365079365079365079, -.00059523809523809523810,_
- .00084175084175084175084, -.0019175269175269175269,_
- .0064102564102564102564]
- for m in 1..7 for el in l repeat
- zterm := zterm*zsquaredinv
- sum := sum + el*zterm
- sum
-
-
-
-
---- nth derivatives of ln gamma for real x, n = 0,1,....
---- requires files floatutils, rgamma
-$PsiAsymptoticBern := VECTOR(0.0, 0.1666666666666667, -0.03333333333333333, 0.02380952380952381,_
- -0.03333333333333333, 0.07575757575757576, -0.2531135531135531, 1.166666666666667,_
- -7.092156862745098, 54.97117794486216, -529.1242424242424, 6192.123188405797,_
- -86580.25311355311, 1425517.166666667, -27298231.06781609, 601580873.9006424,_
- -15116315767.09216, 429614643061.1667, -13711655205088.33, 488332318973593.2,_
- -19296579341940070.0, 841693047573682600.0, -40338071854059460000.0)
-
-
-PsiAsymptotic(n,x) ==
- xn := x**n
- xnp1 := xn*x
- xsq := x*x
- xterm := xsq
- factterm := rgamma(n+2)/2.0/rgamma(float(n+1))
- --- initialize to 1/n!
- sum := AREF($PsiAsymptoticBern,1)*factterm/xterm
- for k in 2..22 repeat
- xterm := xterm * xsq
- if n=0 then factterm := 1.0/float(2*k)
- else if n=1 then factterm := 1
- else factterm := factterm * float(2*k+n-1)*float(2*k+n-2)/(float(2*k)*float(2*k-1))
- sum := sum + AREF($PsiAsymptoticBern,k)*factterm/xterm
- PsiEps(n,x) + 1.0/(2.0*xnp1) + 1.0/xn * sum
-
-
-PsiEps(n,x) ==
- if n = 0
- then
- result := -LOG(x)
- else
- result := 1.0/(float(n)*(x**n))
- result
-
-PsiAsymptoticOrder(n,x,nterms) ==
- sum := 0
- xterm := 1.0
- np1 := n+1
- for k in 0..nterms repeat
- xterm := (x+float(k))**np1
- sum := sum + 1.0/xterm
- sum
-
-
-rPsi(n,x) ==
- if x<=0.0
- then
- if ZEROP fracpart(x)
- then FloatError('"singularity encountered at ~D",x)
- else
- m := MOD(n,2)
- sign := (-1)**m
- if fracpart(x)=.5
- then
- skipit := 1
- else
- skipit := 0
- sign*((PI**(n+1))*cotdiffeval(n,PI*(-x),skipit) + rPsi(n,1.0-x))
- else if n=0
- then
- - rPsiW(n,x)
- else
- rgamma(float(n+1))*rPsiW(n,x)*(-1)**MOD(n+1,2)
-
----Amos' w function, with w(0,x) picked to be -psi(x) for x>0
-rPsiW(n,x) ==
- if (x <=0 or n < 0)
- then
- HardError('"rPsiW not implemented for negative n or non-positive x")
- nd := 6 -- magic number for number of digits in a word?
- alpha := 3.5 + .40*nd
- beta := 0.21 + (.008677e-3)*(nd-3) + (.0006038e-4)*(nd-3)**2
- xmin := float(FLOOR(alpha + beta*n) + 1)
- if n>0
- then
- a := MIN(0,1.0/float(n)*LOG(DOUBLE_-FLOAT_-EPSILON/MIN(1.0,x)))
- c := EXP(a)
- if ABS(a) >= 0.001
- then
- fln := x/c*(1.0-c)
- else
- fln := -x*a/c
- bign := FLOOR(fln) + 1
---- Amos says to use alternative series for large order if ordinary
---- backwards recurrence too expensive
- if (bign < 15) and (xmin > 7.0+x)
- then
- return PsiAsymptoticOrder(n,x,bign)
- if x>= xmin
- then
- return PsiAsymptotic(n,x)
----ordinary case -- use backwards recursion
- PsiBack(n,x,xmin)
-
-PsiBack(n,x,xmin) ==
- xintpart := PsiIntpart(x)
- x0 := x-xintpart ---frac part of x
- result := PsiAsymptotic(n,x0+xmin+1.0)
- for k in xmin..xintpart by -1 repeat
---- Why not decrement from x? See Amos p. 498
- result := result + 1.0/((x0 + float(k))**(n+1))
- result
-
-
-PsiIntpart(x) ==
- if x<0
- then
- result := -PsiInpart(-x)
- else
- result := FLOOR(x)
- return result
-
-
----Code for computation of derivatives of cot(z), necessary for
---- polygamma reflection formula. If you want to compute n-th derivatives of
----cot(Pi*x), you have to multiply the result of cotdiffeval by Pi**n.
-
--- MCD: This is defined at the Lisp Level.
--- COT(z) ==
--- 1.0/TAN(z)
-
-cotdiffeval(n,z,skipit) ==
----skip=1 if arg z is known to be an exact multiple of Pi/2
- a := MAKE_-ARRAY(n+2)
- SETF(AREF(a,0),0.0)
- SETF(AREF(a,1),1.0)
- for i in 2..n repeat
- SETF(AREF(a,i),0.0)
- for l in 1..n repeat
- m := MOD(l+1,2)
- for k in m..l+1 by 2 repeat
- if k<1
- then
- t1 := 0
- else
- t1 := -AREF(a,k-1)*(k-1)
- if k>l
- then
- t2 := 0
- else
- t2 := -AREF(a,k+1)*(k+1)
- SETF(AREF(a,k), t1+t2)
- --- evaluate d^N/dX^N cot(z) via Horner-like rule
- v := COT(z)
- sq := v**2
- s := AREF(a,n+1)
- for i in (n-1)..0 by -2 repeat
- s := s*sq + AREF(a,i)
- m := MOD(n,2)
- if m=0
- then
- s := s*v
- if skipit=1
- then
- if m=0
- then
- return 0
- else
- return AREF(a,0)
- else
- return s
---- nth derivatives of ln gamma for complex z, n=0,1,...
---- requires files rpsi (and dependents), floaterrors
---- currently defined only in right half plane until reflection formula
---- works
-
---- B. Char, June, 1990.
-
-cPsi(n,z) ==
- x := REALPART(z)
- y := IMAGPART(z)
- if ZEROP y
- then --- call real function if real
- return rPsi(n,x)
- if y<0.0
- then -- if imagpart(z) negative, take conjugate of conjugate
- conjresult := cPsi(n,COMPLEX(x,-y))
- return COMPLEX(REALPART(conjresult),-IMAGPART(conjresult))
- nterms := 22
- bound := 10.0
- if x<0.0 --- and ABS(z)>bound and ABS(y)<bound
- then
- FloatError('"Psi implementation can't compute at ~S ",[n,z])
---- return cpsireflect(n,x,y,z)
- else if (x>0.0 and ABS(z)>bound ) --- or (x<0.0 and ABS(y)>bound)
- then
- return PsiXotic(n,PsiAsymptotic(n,z))
- else --- use recursion formula
- m := CEILING(SQRT(bound*bound - y*y) - x + 1.0)
- result := COMPLEX(0.0,0.0)
- for k in 0..(m-1) repeat
- result := result + 1.0/((z + float(k))**(n+1))
- return PsiXotic(n,result+PsiAsymptotic(n,z+m))
-
-PsiXotic(n,result) ==
- rgamma(float(n+1))*(-1)**MOD(n+1,2)*result
-
-cpsireflect(n,z) ==
- m := MOD(n,2)
- sign := (-1)**m
- sign*PI**(n+1)*cotdiffeval(n,PI*z,0) + cPsi(n,1.0-z)
-
---- c parameter to 0F1, possibly complex
---- z argument to 0F1
---- Depends on files floaterror, floatutils
-
---- Program transcribed from Fortran,, p. 80 Luke 1977
-
-chebf01 (c,z) ==
---- w scale factor so that 0<z/w<1
---- n n+2 coefficients will be produced stored in an array
---- indexed from 0 to n+1.
---- See Luke's books for further explanation
- n := 75 --- ad hoc decision
---- if ABS(z)/ABS(c) > 200.0 and ABS(z)>10000.0
---- then
---- FloatError('"cheb0F1 not implemented for ~S < 1",[c,z])
- w := 2.0*z
---- arr will be used to store the Cheb. series coefficients
- four:= 4.0
- start := EXPT(10.0, -200)
- n1 := n+1
- n2 := n+2
- a3 := 0.0
- a2 := 0.0
- a1 := start -- arbitrary starting value
- z1 := four/w
- ncount := n1
- arr := MAKE_-ARRAY(n2)
- SETF(AREF(arr,ncount) , start) -- start off
- x1 := n2
- c1 := 1.0 - c
- for ncount in n..0 by -1 repeat
- divfac := 1.0/x1
- x1 := x1 -1.0
- SETF(AREF(arr,ncount) ,_
- x1*((divfac+z1*(x1-c1))*a1 +_
- (1.0/x1 + z1*(x1+c1+1.0))*a2-divfac*a3))
- a3 := a2
- a2 := a1
- a1 := AREF(arr,ncount)
- SETF(AREF(arr,0),AREF(arr,0)/2.0)
--- compute scale factor
- rho := AREF(arr,0)
- sum := rho
- p := 1.0
- for i in 1..n1 repeat
- rho := rho - p*AREF(arr,i)
- sum := sum+AREF(arr,i)
- p := -p
- for l in 0..n1 repeat
- SETF(AREF(arr,l), AREF(arr,l)/rho)
- sum := sum/rho
---- Now evaluate array at argument
- b := 0.0
- temp := 0.0
- for i in (n+1)..0 by -1 repeat
- cc := b
- b := temp
- temp := -cc + AREF(arr,i)
- temp
-
-
-brutef01(c,z) ==
--- Use series definition. Won't work well if cancellation occurs
- term := 1.0
- sum := term
- n := 0.0
- oldsum := 0.0
- maxnterms := 10000
- for i in 0..maxnterms until oldsum=sum repeat
- oldsum := sum
- term := term*z/(c+n)/(n+1.0)
- sum := sum + term
- n := n+1.0
- sum
-
-f01(c,z)==
- if negintp(c)
- then
- FloatError('"0F1 not defined for negative integer parameter value ~S",c)
--- conditions when we'll permit the computation
- else if ABS(c)<1000.0 and ABS(z)<1000.0
- then
- brutef01(c,z)
- else if ZEROP IMAGPART(z) and ZEROP IMAGPART(c) and z>=0.0 and c>=0.0
- then
- brutef01(c,z)
---- else
---- t := SQRT(-z)
---- c1 := c-1.0
---- p := PHASE(c)
---- if ABS(c)>10.0*ABS(t) and p>=0.0 and PHASE(c)<.90*PI
---- then BesselJAsymptOrder(c1,2*t)*cgamma(c/(t**(c1)))
---- else if ABS(t)>10.0*ABS(c) and ABS(t)>50.0
---- then BesselJAsympt(c1,2*t)*cgamma(c/(t**(c1)))
---- else
---- FloatError('"0F1 not implemented for ~S",[c,z])
- else if (10.0*ABS(c)>ABS(z)) and ABS(c)<1.0E4 and ABS(z)<1.0E4
- then
- brutef01(c,z)
- else
- FloatError('"0F1 not implemented for ~S",[c,z])
-
---- c parameter to 0F1
---- w scale factor so that 0<z/w<1
---- n n+2 coefficients will be produced stored in an array
---- indexed from 0 to n+1.
---- See Luke's books for further explanation
-
---- Program transcribed from Fortran,, p. 80 Luke 1977
-chebf01coefmake (c,w,n) ==
---- arr will be used to store the Cheb. series coefficients
- four:= 4.0
- start := EXPT(10.0, -200)
- n1 := n+1
- n2 := n+2
- a3 := 0.0
- a2 := 0.0
- a1 := start -- arbitrary starting value
- z1 := four/w
- ncount := n1
- arr := MAKE_-ARRAY(n2)
- SETF(AREF(arr,ncount) , start) -- start off
- x1 := n2
- c1 := 1.0 - c
- for ncount in n..0 by -1 repeat
- divfac := 1.0/x1
- x1 := x1 -1.0
- SETF(AREF(arr,ncount) ,_
- x1*((divfac+z1*(x1-c1))*a1 +_
- (1.0/x1 + z1*(x1+c1+1.0))*a2-divfac*a3))
- a3 := a2
- a2 := a1
- a1 := AREF(arr,ncount)
- SETF(AREF(arr,0),AREF(arr,0)/2.0)
--- compute scale factor
- rho := AREF(arr,0)
- sum := rho
- p := 1.0
- for i in 1..n1 repeat
- rho := rho - p*AREF(arr,i)
- sum := sum+AREF(arr,i)
- p := -p
- for l in 0..n1 repeat
- SETF(AREF(arr,l), AREF(arr,l)/rho)
- sum := sum/rho
- return([sum,arr])
-
-
-
-
----evaluation of Chebychev series of degree n at x, where the series's
----coefficients are given by the list in descending order (coef. of highest
----power first)
-
----May be numerically unstable for certain lists of coefficients;
---- could possibly reverse sequence of coefficients
-
---- Cheney and Hart p. 15.
-
---- B. Char, March 1990
-
-chebeval (coeflist,x) ==
- b := 0;
- temp := 0;
- y := 2*x;
-
- for el in coeflist repeat
- c := b;
- b := temp
- temp := y*b -c + el
- (temp -c)/2
-
-
-chebevalarr(coefarr,x,n) ==
- b := 0;
- temp := 0;
- y := 2*x;
-
- for i in 1..n repeat
- c := b;
- b := temp
- temp := y*b -c + coefarr.i
- (temp -c)/2
-
---- If plist is a list of coefficients for the Chebychev approximation
---- of a function f(x), then chebderiveval computes the Chebychev approximation
---- of f'(x). See Luke, "Special Functions and their approximations, vol. 1
---- Academic Press 1969., p. 329 (from Clenshaw and Cooper)
-
---- < definition to be supplied>
-
---- chebstareval(plist,n) computes a Chebychev approximation from a
---- coefficient list, using shifted Chebychev polynomials of the first kind
---- The defining relation is that T*(n,x) = T(n,2*x-1). Thus the interval
---- [0,1] of T*n is the interval [-1,1] of Tn.
-
-chebstareval(coeflist,x) == -- evaluation of T*(n,x)
- b := 0
- temp := 0
- y := 2*(2*x-1)
-
- for el in coeflist repeat
- c := b;
- b := temp
- temp := y*b -c + el
- temp - y*b/2
-
-
-chebstarevalarr(coefarr,x,n) == -- evaluation of sum(C(n)*T*(n,x))
-
- b := 0
- temp := 0
- y := 2*(2*x-1)
-
- for i in (n+1)..0 by -1 repeat
- c := b
- b := temp
- temp := y*b -c + AREF(coefarr,i)
- temp - y*b/2
-
---Float definitions for Bessel functions I and J.
---External references: cgamma, rgamma, chebf01coefmake, chebevalstarsf
--- floatutils
-
----BesselJ works for complex and real values of v and z
-BesselJ(v,z) ==
----Ad hoc boundaries for approximation
- B1:= 10
- B2:= 10
- n := 50 --- number of terms in Chebychev series.
- --- tests for negative integer order
- (FLOATP(v) and ZEROP fracpart(v) and (v<0)) or (COMPLEXP(v) and ZEROP IMAGPART(v) and ZEROP fracpart(REALPART(v)) and REALPART(v)<0.0) =>
- --- odd or even according to v (9.1.5 A&S)
- --- $J_{-n}(z)=(-1)^{n} J_{n}(z)$
- BesselJ(-v,z)*EXPT(-1.0,v)
- (FLOATP(z) and (z<0)) or (COMPLEXP(z) and REALPART(z)<0.0) =>
- --- negative argument (9.1.35 A&S)
- --- $J_{\nu}(z e^{m \pi i}) = e^{m \nu \pi i} J_{\nu}(z)$
- BesselJ(v,-z)*EXPT(-1.0,v)
- ZEROP z and ((FLOATP(v) and (v>=0.0)) or (COMPLEXP(v) and
- ZEROP IMAGPART(v) and REALPART(v)>=0.0)) => --- zero arg, pos. real order
- ZEROP v => 1.0 --- J(0,0)=1
- 0.0 --- J(v,0)=0 for real v>0
- rv := ABS(v)
- rz := ABS(z)
- (rz>B1) and (rz > B2*rv) => --- asymptotic argument
- BesselJAsympt(v,z)
- (rv>B1) and (rv > B2*rz) => --- asymptotic order
- BesselJAsymptOrder(v,z)
- (rz< B1) and (rv<B1) => --- small order and argument
- arg := -(z*z)/4.0
- w := 2.0*arg
- vp1 := v+1.0
- [sum,arr] := chebf01coefmake(vp1,w,n)
- ---if we get NaNs then half n
- while not _=(sum,sum) repeat
- n:=FLOOR(n/2)
- [sum,arr] := chebf01coefmake(vp1,w,n)
- ---now n is safe, can we increase it (we know that 2*n is bad)?
- chebstarevalarr(arr,arg/w,n)/cgamma(vp1)*EXPT(z/2.0,v)
- true => BesselJRecur(v,z)
- FloatError('"BesselJ not implemented for ~S", [v,z])
-
-BesselJRecur(v,z) ==
- -- boost order
- --Numerical.Recipes. suggest so:=v+sqrt(n.s.f.^2*v)
- so:=15.0*z
- -- reduce order until non-zero
- while ZEROP ABS(BesselJAsymptOrder(so,z)) repeat so:=so/2.0
- if ABS(so)<ABS(z) then so:=v+18.*SQRT(v)
- m:= FLOOR(ABS(so-v))+1
- w:=MAKE_-ARRAY(m)
- SETF(AREF(w,m-1),BesselJAsymptOrder(v+m-1,z))
- SETF(AREF(w,m-2),BesselJAsymptOrder(v+m-2,z))
- for i in m-3 .. 0 by -1 repeat
- SETF(AREF(w,i), 2.0 * (v+i+1.0) * AREF(w,i+1) /z -AREF(w,i+2))
- AREF(w,0)
-
-BesselI(v,z) ==
- B1 := 15.0
- B2 := 10.0
- ZEROP(z) and FLOATP(v) and (v>=0.0) => --- zero arg, pos. real order
- ZEROP(v) => 1.0 --- I(0,0)=1
- 0.0 --- I(v,0)=0 for real v>0
---- Transformations for negative integer orders
- FLOATP(v) and ZEROP(fracpart(v)) and (v<0) => BesselI(-v,z)
---- Halfplane transformations for Re(z)<0
- REALPART(z)<0.0 => BesselI(v,-z)*EXPT(-1.0,v)
---- Conjugation for complex order and real argument
- REALPART(v)<0.0 and not ZEROP IMAGPART(v) and FLOATP(z) =>
- CONJUGATE(BesselI(CONJUGATE(v),z))
----We now know that Re(z)>= 0.0
- ABS(z) > B1 => --- asymptotic argument case
- FloatError('"BesselI not implemented for ~S",[v,z])
- ABS(v) > B1 =>
- FloatError('"BesselI not implemented for ~S",[v,z])
---- case of small argument and order
- REALPART(v)>= 0.0 => besselIback(v,z)
- REALPART(v)< 0.0 =>
- chebterms := 50
- besselIcheb(z,v,chebterms)
- FloatError('"BesselI not implemented for ~S",[v,z])
-
---- Compute n terms of the chebychev series for f01
-besselIcheb(z,v,n) ==
- arg := (z*z)/4.0
- w := 2.0*arg;
- vp1 := v+1.0;
- [sum,arr] := chebf01coefmake(vp1,w,n)
- result := chebstarevalarr(arr,arg/w,n)/cgamma(vp1)*EXPT(z/2.0,v)
-
-besselIback(v,z) ==
- ipv := IMAGPART(v)
- rpv := REALPART(v)
- lm := MULTIPLE_-VALUE_-LIST(FLOOR(rpv))
- m := CAR(lm) --- floor of real part of v
- n := 2*MAX(20,m+10) --- how large the back recurrence should be
- tv := CADR(lm)+(v-rpv) --- fractional part of real part of v
- --- plus imaginary part of v
- vp1 := tv+1.0;
- result := BesselIBackRecur(v,m,tv,z,'"I",n)
- result := result/cgamma(vp1)*EXPT(z/2.0,tv)
-
---- Backward recurrence for Bessel functions. Luke (1975), p. 247.
---- works for -Pi< arg z <= Pi and -Pi < arg v <= Pi
-BesselIBackRecur(largev,argm,v,z,type,n) ==
---- v + m = largev
- one := 1.0
- two := 2.0
- zero := 0.0
- start := EXPT(10.0,-40)
- z2 := two/z
- m2 := n+3
- w:=MAKE_-ARRAY(m2+1)
- SETF(AREF(w,m2), zero) --- start off
- if type = '"I"
- then
- val := one
- else
- val := -one
- m1 := n+2
- SETF(AREF(w,m1), start)
- m := n+1
- xm := float(m)
- ct1 := z2*(xm+v)
- --- initialize
- for m in (n+1)..1 by -1 repeat
- SETF(AREF(w,m), AREF(w,m+1)*ct1 + val*AREF(w,m+2))
- ct1 := ct1 - z2
- m := 1 + FLOOR(n/2)
- m2 := m + m -1
- if (v=0)
- then
- pn := AREF(w, m2 + 2)
- for m2 in (2*m-1)..3 by -2 repeat
- pn := AREF(w, m2) - val *pn
- pn := AREF(w,1) - val*(pn+pn)
- else
- v1 := v-one
- xm := float(m)
- ct1 := v + xm + xm
- pn := ct1*AREF(w, m2 + 2)
- for m2 in (m+m -1)..3 by -2 repeat
- ct1 := ct1 - two
- pn := ct1*AREF(w,m2) - val*pn/xm*(v1+xm)
- xm := xm - one
- pn := AREF(w,1) - val * pn
- m1 := n+2
- for m in 1..m1 repeat
- SETF(AREF(w,m), AREF(w,m)/pn)
- AREF(w,argm+1)
-
-
-
-
----Asymptotic functions for large values of z. See p. 204 Luke 1969 vol. 1.
-
---- mu is 4*v**2
---- zsqr is z**2
---- zfth is z**4
-
-BesselasymptA(mu,zsqr,zfth) ==
- (mu -1)/(16.0*zsqr) * (1 + (mu - 13.0)/(8.0*zsqr) + _
- (mu**2 - 53.0*mu + 412.0)/(48.0*zfth))
-
-BesselasymptB(mu,z,zsqr,zfth) ==
- musqr := mu*mu
- z + (mu-1.0)/(8.0*z) *(1.0 + (mu - 25.0)/(48.0*zsqr) + _
- (musqr - 114.0*mu + 1073.0)/(640.0*zfth) +_
- (5.0*mu*musqr - 1535.0*musqr + 54703.0*mu - 375733.0)/(128.0*zsqr*zfth))
-
---- Asymptotic series only works when |v| < |z|.
-
-BesselJAsympt (v,z) ==
- pi := PI
- mu := 4.0*v*v
- zsqr := z*z
- zfth := zsqr*zsqr
- SQRT(2.0/(pi*z))*EXP(BesselasymptA(mu,zsqr,zfth))*_
- COS(BesselasymptB(mu,z,zsqr,zfth) - pi*v/2.0 - pi/4.0)
-
-
----Asymptotic series for I. See Whittaker, p. 373.
---- valid for -3/2 Pi < arg z < 1/2 Pi
-
-BesselIAsympt(v,z,n) ==
- i := COMPLEX(0.0, 1.0)
- if (REALPART(z) = 0.0)
- then return EXPT(i,v)*BesselJ(v,-IMAGPART(z))
- sum1 := 0.0
- sum2 := 0.0
- fourvsq := 4.0*v**2
- two := 2.0
- eight := 8.0
- term1 := 1.0
---- sum1, sum2, fourvsq,two,i,eight,term1])
- for r in 1..n repeat
- term1 := -term1 *(fourvsq-(two*float(r)-1.0)**2)/_
- (float(r)*eight*z)
- sum1 := sum1 + term1
- sum2 := sum2 + ABS(term1)
- sqrttwopiz := SQRT(two*PI*z)
- EXP(z)/sqrttwopiz*(1.0 + sum1 ) +_
- EXP(-(float(n)+.5)*PI*i)*EXP(-z)/sqrttwopiz*(1.0+ sum2)
-
-
----Asymptotic formula for BesselJ when order is large comes from
----Debye (1909). See Olver, Asymptotics and Special Functions, p. 134.
----Expansion good for 0<=phase(v)<Pi
----A&S recommend "uniform expansion" with complicated coefficients and Airy function.
----Debye's Formula is in 9.3.7,9.3.9,9.3.10 of A&S
----AXIOM recurrence for u_{k}
----f(0)==1::EXPR INT
----f(n)== (t^2)*(1-t^2)*D(f(n-1),t)/2 + (1/8)*integrate( (1-5*t^2)*f(n-1),t)
-BesselJAsymptOrder(v,z) ==
- sechalpha := z/v
- alpha := ACOSH(1.0/sechalpha)
- tanhalpha := SQRT(1.0-(sechalpha*sechalpha))
- -- cothalpha := 1.0/tanhalpha
- ca := 1.0/tanhalpha
-
- Pi := PI
- ca2:=ca*ca
- ca4:=ca2*ca2
- ca8:=ca4*ca4
- EXP(-v*(alpha-tanhalpha))/SQRT(2.0*Pi*v*tanhalpha)*_
- (1.0+_
- horner([ -5.0, 3.0],_
- ca2)*ca/(v*24.0)+_
- horner([ 385.0, -462.0, 81.0],_
- ca2)*ca2/(1152.0*v*v)+_
- horner([ -425425.0, 765765.0, -369603.0, 30375.0],_
- ca2)*ca2*ca/(414720.0*v*v*v)+_
- horner([ 185910725.0, -446185740.0, 349922430.0, -94121676.0, 4465125.0],_
- ca2)*ca4/(39813120.0*v*v*v*v)+_
- horner([ -188699385875.0, 566098157625.0, -614135872350.0, 284499769554.0, -49286948607.0, 1519035525.0],_
- ca2)*ca4*ca/(6688604160.0*v*v*v*v*v)+_
- horner([1023694168371875.0,-3685299006138750.0,5104696716244125.0,-3369032068261860.0,1050760774457901.0,-127577298354750.0,2757049477875.0],_
- ca2)*ca4*ca2/(4815794995200.0*v*v*v*v*v*v))
-
-
---- See Olver, p. 376-382.
-BesselIAsymptOrder(v,vz) ==
- z := vz/v
- Pi := PI
---- Use reflection formula (Atlas, p. 492) if v not in right half plane; Is this always accurate?
- if REALPART(v)<0.0
- then return BesselIAsymptOrder(-v,vz) + 2.0/Pi*SIN(-v*Pi)*BesselKAsymptOrder(-v,vz)
---- Use the reflection formula (Atlas, p. 496) if z not in right half plane;
- if REALPART(vz) < 0.0
- then return EXPT(-1.0,v)*BesselIAsymptOrder(v,-vz)
- vinv := 1.0/v
- opzsqroh := SQRT(1.0+z*z)
- eta := opzsqroh + LOG(z/(1.0+opzsqroh))
- p := 1.0/opzsqroh
- p2 := p*p
- p4 := p2*p2
- u0p := 1.
- u1p := 1.0/8.0*p-5.0/24.0*p*p2
- u2p := (9.0/128.0+(-77.0/192.0+385.0/1152.0*p2)*p2)*p2
- u3p := (75.0/1024.0+(-4563.0/5120.0+(17017.0/9216.0-85085.0/82944.0*p2)_
- *p2)*p2)*p2*p
- u4p := (3675.0/32768.0+(-96833.0/40960.0+(144001.0/16384.0+(-7436429.0/663552.0+37182145.0/7962624.0*p2)*p2)*p2)*p2)*p4
- u5p := (59535.0/262144.0+(-67608983.0/9175040.0+(250881631.0/5898240.0+(-108313205.0/1179648.0+(5391411025.0/63700992.0-5391411025.0/191102976.0*p2)*p2)*p2)*p2)*p2)*p4*p
- hornerresult := horner([u5p,u4p,u3p,u2p,u1p,u0p],vinv)
- EXP(v*eta)/(SQRT(2.0*Pi*v)*SQRT(opzsqroh))*hornerresult
-
-
----See also Olver, pp. 376-382
-BesselKAsymptOrder (v,vz) ==
- z := vz/v
- vinv := 1.0/v
- opzsqroh := SQRT(1.0+z*z)
- eta := opzsqroh + LOG(z/(1.0+opzsqroh))
- p := 1.0/opzsqroh
- p2 := p**2
- p4 := p2**2
- u0p := 1.
- u1p := (1.0/8.0*p-5.0/24.0*p**3)*(-1.0)
- u2p := (9.0/128.0+(-77.0/192.0+385.0/1152.0*p2)*p2)*p2
- u3p := ((75.0/1024.0+(-4563.0/5120.0+(17017.0/9216.0-85085.0/82944.0*p2)_
- *p2)*p2)*p2*p)*(-1.0)
- u4p := (3675.0/32768.0+(-96833.0/40960.0+(144001.0/16384.0+(-7436429.0/663552.0+37182145.0/7962624.0*p2)*p2)*p2)*p2)*p4
- u5p := ((59535.0/262144.0+(-67608983.0/9175040.0+(250881631.0/5898240.0+(-108313205.0/1179648.0+(5391411025.0/63700992.0-5391411025.0/191102976.0*p2)*p2)*p2)*p2)*p2)*p4*p)*(-1.0)
- hornerresult := horner([u5p,u4p,u3p,u2p,u1p,u0p],vinv)
- SQRT(PI/(2.0*v))*EXP(-v*eta)/(SQRT(opzsqroh))*hornerresult
-
-
-
-
-
-
-
-@
-\eject
-\begin{thebibliography}{99}
-\bibitem{1} nothing
-\end{thebibliography}
-\end{document}