The following file contains a logfact function that uses loggamma
It's pretty old so might need revamping!
--------------------------------------------------------------------------------------------
NB. J.E.H.Shaw probability distributions library
NB.---------------------------------------------
NB. Created 5-Feb-1998
NB. Last modified 11-Aug-1999
NB.
NB. <dist>c = cdf of <dist> at y. [optional pars x.]
NB. <dist>f = pdf/pmf of <dist> at y. [optional pars x.]
NB. <dist>q = inverse cdf (quantiles) of <dist> at y. [optional pars x.]
NB. <dist>r = y. pseudorandom numbers from <dist> [optional pars x.]
NB. <dist>s = survivor function (1-cdf) of <dist> at y. [optional pars x.]
NB.
NB. ====================================================================
NB. Main Reference Books:
NB.
NB. Abramowitz, M. & Stegun, I.A. (1970)
NB. "Handbook of Mathematical Functions"
NB. Dover, New York [A&S]
NB.
NB. Fishman, G.S. (1996)
NB. 'Monte Carlo'
NB. Springer, Berlin [F]
NB.
NB. Press, W.H., Flannery, B.P., Teukolsky, S.A. & Vetterling, W.T. (1986)
NB. 'Numerical Recipes: The Art of Scientific Computing',
NB. Cambridge University Press, Cambridge [PFTV]
NB.
NB. ====================================================================
NB. Constants
NB.
RSQRT2PI=: % %: 2p1
HL2PI=: - ^. RSQRT2PI
NB. ====================================================================
NB. Utilities
NB.
NB. merge see "J Phrases" 3B
NB. underravel apply verb x. to ravelled y., then reshape
NB.
merge=: /:@/:@[ { ]
underravel=: adverb def '$@] $ x.@,'
NB. ====================================================================
NB. Standard mathematical functions
NB.
NB. beta beta function Beta (x. , y.)
NB. erf error function
NB. erfc complementary error function
NB. gamma gamma function Gamma (y.)
NB. ibp incomplete beta function (int from 0 to y.)
NB. ibq incomplete beta function (int from y. to 1)
NB. igp incomplete gamma function (int from -\infty to y.)
NB. igq incomplete gamma function (int from y. to +\infty)
NB. logbeta log(beta) OK for large arguments
NB. logcomb ^. x.!y. OK for large arguments
NB. logfact ^. !y. OK for large arguments
NB. loggamma log(gamma) OK for large arguments
NB. loggamma0 log(gamma) for scalar y.
NB.
NB. Subsidiary functions:
NB. exog '(^-y.) * (y.^x.) % gamma(x.)' OK for large arguments
NB. gt100 1 iff abs(y.) > 100
NB. ibcf continued fraction part of Incomplete Beta [PFTV sec.6.3]
NB. ibcfn ~ number of terms in continued fraction to evaluate ibcf
NB. igq1 continued fraction part of Gamma(x.,y.) [PFTV sec.6.2]
NB. igqn ~ number of terms in continued fraction to evaluate igq
NB. lgbig log(gamma) for large arguments
NB. x1mxob '(y.^{.x.) * ((1-y.)^{:x.) % ({.x.)beta({:x.)' OK for large x.
NB.
NB. Comments
NB. loggamma takes 2x as long as loggamma0 for scalar y.
NB. but is 5x as fast as loggamma"0 for y.= 90 + i. 2 3 4
NB.
gamma=: ! & <:
beta=: *&gamma % gamma@+
gt100=: | > 100"_
lgbig=: HL2PI"_ - ] - ([: % 12&*) - ([: % 360"_ * ^&3) - -&0.5 * ^.
loggamma0=: ((^.@gamma)`lgbig) @. (| > 100"_)
loggamma=: (] (] merge ^.@:gamma@:(#~ -.) , lgbig@:#~) gt100) underravel
logbeta=: +&:loggamma - loggamma@:+
logcomb=: [: - ^.@:>:@:] + [ logbeta&:>: -~
logfact=: loggamma@:>:
exog=: ([: ^ -@:] + (*^.) - loggamma@:[)`0: @. (] <: 0:)
igp=: dyad def '(x. exog"0 y.) * (((1 1 H. (1,x.)) y.) - 1) % y.'
igqn=: [: >. 4: + (60"_ + 16"_ * [: | [ - 4:) % ]
igq1=: [: (%`+)/ 1: , ] , [: , ([: }.@:i. igqn) ((-{.) ,. 1: ,. [ ,. {:@:]) ,
igq2=: exog * igq1
igq=: (-.@:igp)`igq2 @. ((> (+ 3: * %:))~)"0
erf=: 0.5"_ igp *:
erfc=: 0.5"_ igq *:
x1mxob=: [: ^ +/@:(* ^.@(,-.)) - logbeta/@:[
ibcfn=: [: >. 2: * [: %: 20"_ + >./
ibcf=: dyad define
'a b'=. x. [ m=. i. ibcfn x.
dodd=. -(a+m)*(a+b+m)*y. % (* >:) ap2m=. a (+ +:) m
deven=. m*(b-m)*y. % (* <:) ap2m
((x. x1mxob y.) % a) * (%`+)/ 1 , }. , deven,.1,.dodd,.1
)
ibp=: dyad define
if. y.<:0 do. 0
elseif. y.>:1 do. 1
elseif. 1 do.
if. y. < (>:@{. % >:@+/) x. do. x. ibcf y.
else. -. (|. x.) ibcf -. y.
end.
end.
)
ibq=: |.@[ ibp -.@]
NB. ====================================================================
NB. Pseudorandom Number Generation
NB.
NB. getrl get random link
NB. initrl initialize random link based on time+day
NB. (suffers from year 187213506 bug!)
NB. setrl set random link [y. integer; 0 < y. < _2+2^31]
NB.
getrl=: 9!:0
setrl=: 9!:1
initrl=: setrl @ <. @ ([: (0 60 60 24 31 12"_ #. |.) 6!:0)
NB. ====================================================================
NB. Scaling
NB.
NB. lrscale scale y. where x. = (left lim, right lim)
NB. lsfmv location,scale from mean,variance
NB. lsscale scale y. where x. = (location, scale)
NB. lssd (adverb) location/scale tran for c.d.f.
NB. lssf (adverb) location/scale tran for p.d.f.
NB. lssq (adverb) location/scale tran for quantiles (inverse c.d.f.)
NB.
lrscale=: {.@[ - -/@[ * ]
lsscale=: {.@[ + {:@[ * ]
lssd=: @ ((] - {.@[) % {:@[)
lssf=: lssd % {:@[
lssq=: adverb define
:
({. x.) + ({: x.) * u. y.
)
lsfmv=: ^&1 0.5
NB. ====================================================================
NB. Approximations to N(0,1) c.d.f. and inverse c.d.f.
NB.
NB. n01u upper tail probability of N(0,1) [PFTV]
NB. n01q1 approximate N(0,1) quantiles [A&S]
NB.
n01u=: -: @: erfc @: % %:@:2:
n01q1=: monad define
s=. * y. - 0.5 [ t=. %: _2 * ^. (<. -. ) y.
s * t - (2.515517 0.802853 0.010328 p. t) % 1 1.432788 0.189269 0.001308 p. t
)
NB. ====================================================================
NB. Univariate Discrete Distributions
NB.
NB. bin* binomial, n={.x., p={:x. [PFTV 6.3]
NB. pois* Poisson, mean=x. [PFTV 6.2]
NB.
NB. Subsidiary functions:
NB. binf[01] binf for [small,large] n={.x. or y.
NB. poisf[01] poisf for [small,large] x. or y.
NB.
binc=: (>:@] , {.@[ - ]) ibq {:@[
binf0=: (! {.)~ * (^~ {:)~ * -.@{:@[ ^ (-~ {.)~
binf1=: [: ^ (logcomb {.)~ + (* ^.@{:)~ + (-~ {.)~ * ^.@-.@{:@[
bins=: (>:@] , {.@[ - ]) ibp {:@[
poisc=: igq~
poisf0=: ^ * ^@-@[ % !@]
poisf1=: [: ^ (* ^.)~ - (+ logfact)
poisf=: poisf0`poisf1 @. ([: +./ , > 140"_)
poiss=: igp~
NB. ====================================================================
NB. Univariate Continuous Distributions
NB.
NB. beta* beta (default 1 1)
NB. cauchy* cauchy (i.e. 1&t)
NB. chisq* chi-squared (x. = df; default 1) [PFTV 6.2]
NB. exp* exponential, mean %x.
NB. f* F (x. = dfs; default 1 1) [PFTV 6.3]
NB. gamma* gamma (default 1 1)
NB. norm* Normal (x. = mean,var; default 0 1)
NB. t* t (x. = df; default 1) [PFTV 6.3]
NB. unif* uniform (rectangular) - U(0,1) by default
NB.
NB. normq uses 2 Newton-Raphson iterations
NB.
cauchyc=: (0.5"_ + _3&o. % 1p1"_) : (cauchyc lssd)
cauchys=: -.@cauchyc
chisqc=: -:@[ igp -:@]
chisqf=: verb def ('1 chisqf y.' ; ':' ; '(-: x.,1) gammaf y.')
chisqs=: -:@[ igq -:@]
expr=: -@^.@unifr : (%~ -@^.@unifr)
fc=: -:@|.@[ ibq {:@[ % [: +/ (* ,&1)
ff=: verb define
1 1 ff y.
:
'm2 n2'=. -: x.
y=. 0 >. y.
c=. (m2^m2) * (n2^n2) % m2 beta n2
(y.>:0) * c * (y ^ m2-1) % (n2+m2*y)^m2+n2
)
fs=: -:@|.@[ ibp {:@[ % [: +/ (* ,&1)
gammaf=: verb define
1 1 gammaf y.
:
'a b'=. x.
y=. 0 >. y.
c=. (b^a) % gamma a
(y.>:0) * c * (y^a-1) * ^ -b*y.
)
normc=: (0.5"_ + * * 0.5"_ - n01u@|) : (lsfmv@[ normc lssd ])
normf=: (RSQRT2PI&* @ ^ @ - @ -: @ *:) : (lsfmv@[ normf lssf ])
normq=: ((] + (- normd) % normf@])^:2 n01q1) : (lsfmv@[ normq lssq ])
ttail=: [: -: ([: -: [ , 1:) ibp [ % (+ *:)
tc=: ttail`(1:-ttail) @. (] > 0:)
tf=: verb define
1 tf y.
:
c=. (gamma 0.5*x.+1) % (%: o. x.) * gamma 0.5*x.
c * (1 + (*: y.)%x.) ^ -0.5*x.+1
)
ts=: (1:-ttail)`ttail @. (] > 0:)
unifc=: (0: >. <.&1) : (0: >. 1: <. (- {.)~ % -@:-/@[)
uniff=: (>&0 *. <&1) : (((> {.) *. (< {:))~ % -@-/@[)
unifq=: ] : (lrscale unifq)
unifr=: (([: >:@:? $&2147483647) % 2147483648"_) : (lrscale unifr)
unifs=: 1: - unifc
NB. ====================================================================
NB. TO DO
NB. speed up logcomb etc.
NB. Make cauchy[cs] more accurate for large args
--------------------------------------------------------------------------------------------
Ewart Shaw (Dr. J.E.H.Shaw) Department of Statistics, University of
Warwick.
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm