Mercurial > hg > octave-nkf
view liboctave/numeric/lo-specfun.cc @ 15271:648dabbb4c6b
build: Refactor liboctave into multiple subdirectories. Move libcruft into liboctave.
* array/Array-C.cc, array/Array-b.cc, array/Array-ch.cc, array/Array-d.cc,
array/Array-f.cc, array/Array-fC.cc, array/Array-i.cc, array/Array-idx-vec.cc,
array/Array-s.cc, array/Array-str.cc, array/Array-util.cc, array/Array-util.h,
array/Array-voidp.cc, array/Array.cc, array/Array.h, array/Array2.h,
array/Array3.h, array/ArrayN.h, array/CColVector.cc, array/CColVector.h,
array/CDiagMatrix.cc, array/CDiagMatrix.h, array/CMatrix.cc, array/CMatrix.h,
array/CNDArray.cc, array/CNDArray.h, array/CRowVector.cc, array/CRowVector.h,
array/CSparse.cc, array/CSparse.h, array/DiagArray2.cc, array/DiagArray2.h,
array/MArray-C.cc, array/MArray-d.cc, array/MArray-decl.h, array/MArray-defs.h,
array/MArray-f.cc, array/MArray-fC.cc, array/MArray-i.cc, array/MArray-s.cc,
array/MArray.cc, array/MArray.h, array/MArray2.h, array/MArrayN.h,
array/MDiagArray2.cc, array/MDiagArray2.h, array/MSparse-C.cc,
array/MSparse-d.cc, array/MSparse-defs.h, array/MSparse.cc, array/MSparse.h,
array/Matrix.h, array/MatrixType.cc, array/MatrixType.h, array/PermMatrix.cc,
array/PermMatrix.h, array/Range.cc, array/Range.h, array/Sparse-C.cc,
array/Sparse-b.cc, array/Sparse-d.cc, array/Sparse.cc, array/Sparse.h,
array/boolMatrix.cc, array/boolMatrix.h, array/boolNDArray.cc,
array/boolNDArray.h, array/boolSparse.cc, array/boolSparse.h,
array/chMatrix.cc, array/chMatrix.h, array/chNDArray.cc, array/chNDArray.h,
array/dColVector.cc, array/dColVector.h, array/dDiagMatrix.cc,
array/dDiagMatrix.h, array/dMatrix.cc, array/dMatrix.h, array/dNDArray.cc,
array/dNDArray.h, array/dRowVector.cc, array/dRowVector.h, array/dSparse.cc,
array/dSparse.h, array/dim-vector.cc, array/dim-vector.h, array/fCColVector.cc,
array/fCColVector.h, array/fCDiagMatrix.cc, array/fCDiagMatrix.h,
array/fCMatrix.cc, array/fCMatrix.h, array/fCNDArray.cc, array/fCNDArray.h,
array/fCRowVector.cc, array/fCRowVector.h, array/fColVector.cc,
array/fColVector.h, array/fDiagMatrix.cc, array/fDiagMatrix.h,
array/fMatrix.cc, array/fMatrix.h, array/fNDArray.cc, array/fNDArray.h,
array/fRowVector.cc, array/fRowVector.h, array/idx-vector.cc,
array/idx-vector.h, array/int16NDArray.cc, array/int16NDArray.h,
array/int32NDArray.cc, array/int32NDArray.h, array/int64NDArray.cc,
array/int64NDArray.h, array/int8NDArray.cc, array/int8NDArray.h,
array/intNDArray.cc, array/intNDArray.h, array/module.mk,
array/uint16NDArray.cc, array/uint16NDArray.h, array/uint32NDArray.cc,
array/uint32NDArray.h, array/uint64NDArray.cc, array/uint64NDArray.h,
array/uint8NDArray.cc, array/uint8NDArray.h:
Moved from liboctave dir to array subdirectory.
* cruft/Makefile.am, cruft/amos/README, cruft/amos/cacai.f, cruft/amos/cacon.f,
cruft/amos/cairy.f, cruft/amos/casyi.f, cruft/amos/cbesh.f, cruft/amos/cbesi.f,
cruft/amos/cbesj.f, cruft/amos/cbesk.f, cruft/amos/cbesy.f, cruft/amos/cbinu.f,
cruft/amos/cbiry.f, cruft/amos/cbknu.f, cruft/amos/cbuni.f, cruft/amos/cbunk.f,
cruft/amos/ckscl.f, cruft/amos/cmlri.f, cruft/amos/crati.f, cruft/amos/cs1s2.f,
cruft/amos/cseri.f, cruft/amos/cshch.f, cruft/amos/cuchk.f, cruft/amos/cunhj.f,
cruft/amos/cuni1.f, cruft/amos/cuni2.f, cruft/amos/cunik.f, cruft/amos/cunk1.f,
cruft/amos/cunk2.f, cruft/amos/cuoik.f, cruft/amos/cwrsk.f,
cruft/amos/dgamln.f, cruft/amos/gamln.f, cruft/amos/module.mk,
cruft/amos/xzabs.f, cruft/amos/xzexp.f, cruft/amos/xzlog.f,
cruft/amos/xzsqrt.f, cruft/amos/zacai.f, cruft/amos/zacon.f,
cruft/amos/zairy.f, cruft/amos/zasyi.f, cruft/amos/zbesh.f, cruft/amos/zbesi.f,
cruft/amos/zbesj.f, cruft/amos/zbesk.f, cruft/amos/zbesy.f, cruft/amos/zbinu.f,
cruft/amos/zbiry.f, cruft/amos/zbknu.f, cruft/amos/zbuni.f, cruft/amos/zbunk.f,
cruft/amos/zdiv.f, cruft/amos/zkscl.f, cruft/amos/zmlri.f, cruft/amos/zmlt.f,
cruft/amos/zrati.f, cruft/amos/zs1s2.f, cruft/amos/zseri.f, cruft/amos/zshch.f,
cruft/amos/zuchk.f, cruft/amos/zunhj.f, cruft/amos/zuni1.f, cruft/amos/zuni2.f,
cruft/amos/zunik.f, cruft/amos/zunk1.f, cruft/amos/zunk2.f, cruft/amos/zuoik.f,
cruft/amos/zwrsk.f, cruft/blas-xtra/cconv2.f, cruft/blas-xtra/cdotc3.f,
cruft/blas-xtra/cmatm3.f, cruft/blas-xtra/csconv2.f, cruft/blas-xtra/dconv2.f,
cruft/blas-xtra/ddot3.f, cruft/blas-xtra/dmatm3.f, cruft/blas-xtra/module.mk,
cruft/blas-xtra/sconv2.f, cruft/blas-xtra/sdot3.f, cruft/blas-xtra/smatm3.f,
cruft/blas-xtra/xcdotc.f, cruft/blas-xtra/xcdotu.f, cruft/blas-xtra/xddot.f,
cruft/blas-xtra/xdnrm2.f, cruft/blas-xtra/xdznrm2.f, cruft/blas-xtra/xerbla.f,
cruft/blas-xtra/xscnrm2.f, cruft/blas-xtra/xsdot.f, cruft/blas-xtra/xsnrm2.f,
cruft/blas-xtra/xzdotc.f, cruft/blas-xtra/xzdotu.f, cruft/blas-xtra/zconv2.f,
cruft/blas-xtra/zdconv2.f, cruft/blas-xtra/zdotc3.f, cruft/blas-xtra/zmatm3.f,
cruft/daspk/datv.f, cruft/daspk/dcnst0.f, cruft/daspk/dcnstr.f,
cruft/daspk/ddasic.f, cruft/daspk/ddasid.f, cruft/daspk/ddasik.f,
cruft/daspk/ddaspk.f, cruft/daspk/ddstp.f, cruft/daspk/ddwnrm.f,
cruft/daspk/dfnrmd.f, cruft/daspk/dfnrmk.f, cruft/daspk/dhels.f,
cruft/daspk/dheqr.f, cruft/daspk/dinvwt.f, cruft/daspk/dlinsd.f,
cruft/daspk/dlinsk.f, cruft/daspk/dmatd.f, cruft/daspk/dnedd.f,
cruft/daspk/dnedk.f, cruft/daspk/dnsd.f, cruft/daspk/dnsid.f,
cruft/daspk/dnsik.f, cruft/daspk/dnsk.f, cruft/daspk/dorth.f,
cruft/daspk/dslvd.f, cruft/daspk/dslvk.f, cruft/daspk/dspigm.f,
cruft/daspk/dyypnw.f, cruft/daspk/module.mk, cruft/dasrt/ddasrt.f,
cruft/dasrt/drchek.f, cruft/dasrt/droots.f, cruft/dasrt/module.mk,
cruft/dassl/ddaini.f, cruft/dassl/ddajac.f, cruft/dassl/ddanrm.f,
cruft/dassl/ddaslv.f, cruft/dassl/ddassl.f, cruft/dassl/ddastp.f,
cruft/dassl/ddatrp.f, cruft/dassl/ddawts.f, cruft/dassl/module.mk,
cruft/fftpack/cfftb.f, cruft/fftpack/cfftb1.f, cruft/fftpack/cfftf.f,
cruft/fftpack/cfftf1.f, cruft/fftpack/cffti.f, cruft/fftpack/cffti1.f,
cruft/fftpack/fftpack.doc, cruft/fftpack/module.mk, cruft/fftpack/passb.f,
cruft/fftpack/passb2.f, cruft/fftpack/passb3.f, cruft/fftpack/passb4.f,
cruft/fftpack/passb5.f, cruft/fftpack/passf.f, cruft/fftpack/passf2.f,
cruft/fftpack/passf3.f, cruft/fftpack/passf4.f, cruft/fftpack/passf5.f,
cruft/fftpack/zfftb.f, cruft/fftpack/zfftb1.f, cruft/fftpack/zfftf.f,
cruft/fftpack/zfftf1.f, cruft/fftpack/zffti.f, cruft/fftpack/zffti1.f,
cruft/fftpack/zpassb.f, cruft/fftpack/zpassb2.f, cruft/fftpack/zpassb3.f,
cruft/fftpack/zpassb4.f, cruft/fftpack/zpassb5.f, cruft/fftpack/zpassf.f,
cruft/fftpack/zpassf2.f, cruft/fftpack/zpassf3.f, cruft/fftpack/zpassf4.f,
cruft/fftpack/zpassf5.f, cruft/lapack-xtra/crsf2csf.f,
cruft/lapack-xtra/module.mk, cruft/lapack-xtra/xclange.f,
cruft/lapack-xtra/xdlamch.f, cruft/lapack-xtra/xdlange.f,
cruft/lapack-xtra/xilaenv.f, cruft/lapack-xtra/xslamch.f,
cruft/lapack-xtra/xslange.f, cruft/lapack-xtra/xzlange.f,
cruft/lapack-xtra/zrsf2csf.f, cruft/link-deps.mk, cruft/misc/blaswrap.c,
cruft/misc/cquit.c, cruft/misc/d1mach-tst.for, cruft/misc/d1mach.f,
cruft/misc/f77-extern.cc, cruft/misc/f77-fcn.c, cruft/misc/f77-fcn.h,
cruft/misc/i1mach.f, cruft/misc/lo-error.c, cruft/misc/lo-error.h,
cruft/misc/module.mk, cruft/misc/quit.cc, cruft/misc/quit.h,
cruft/misc/r1mach.f, cruft/mkf77def.in, cruft/odepack/cfode.f,
cruft/odepack/dlsode.f, cruft/odepack/ewset.f, cruft/odepack/intdy.f,
cruft/odepack/module.mk, cruft/odepack/prepj.f, cruft/odepack/scfode.f,
cruft/odepack/sewset.f, cruft/odepack/sintdy.f, cruft/odepack/slsode.f,
cruft/odepack/solsy.f, cruft/odepack/sprepj.f, cruft/odepack/ssolsy.f,
cruft/odepack/sstode.f, cruft/odepack/stode.f, cruft/odepack/svnorm.f,
cruft/odepack/vnorm.f, cruft/ordered-qz/README, cruft/ordered-qz/dsubsp.f,
cruft/ordered-qz/exchqz.f, cruft/ordered-qz/module.mk,
cruft/ordered-qz/sexchqz.f, cruft/ordered-qz/ssubsp.f, cruft/quadpack/dqagi.f,
cruft/quadpack/dqagie.f, cruft/quadpack/dqagp.f, cruft/quadpack/dqagpe.f,
cruft/quadpack/dqelg.f, cruft/quadpack/dqk15i.f, cruft/quadpack/dqk21.f,
cruft/quadpack/dqpsrt.f, cruft/quadpack/module.mk, cruft/quadpack/qagi.f,
cruft/quadpack/qagie.f, cruft/quadpack/qagp.f, cruft/quadpack/qagpe.f,
cruft/quadpack/qelg.f, cruft/quadpack/qk15i.f, cruft/quadpack/qk21.f,
cruft/quadpack/qpsrt.f, cruft/quadpack/xerror.f, cruft/ranlib/Basegen.doc,
cruft/ranlib/HOWTOGET, cruft/ranlib/README, cruft/ranlib/advnst.f,
cruft/ranlib/genbet.f, cruft/ranlib/genchi.f, cruft/ranlib/genexp.f,
cruft/ranlib/genf.f, cruft/ranlib/gengam.f, cruft/ranlib/genmn.f,
cruft/ranlib/genmul.f, cruft/ranlib/gennch.f, cruft/ranlib/gennf.f,
cruft/ranlib/gennor.f, cruft/ranlib/genprm.f, cruft/ranlib/genunf.f,
cruft/ranlib/getcgn.f, cruft/ranlib/getsd.f, cruft/ranlib/ignbin.f,
cruft/ranlib/ignlgi.f, cruft/ranlib/ignnbn.f, cruft/ranlib/ignpoi.f,
cruft/ranlib/ignuin.f, cruft/ranlib/initgn.f, cruft/ranlib/inrgcm.f,
cruft/ranlib/lennob.f, cruft/ranlib/mltmod.f, cruft/ranlib/module.mk,
cruft/ranlib/phrtsd.f, cruft/ranlib/qrgnin.f, cruft/ranlib/randlib.chs,
cruft/ranlib/randlib.fdoc, cruft/ranlib/ranf.f, cruft/ranlib/setall.f,
cruft/ranlib/setant.f, cruft/ranlib/setgmn.f, cruft/ranlib/setsd.f,
cruft/ranlib/sexpo.f, cruft/ranlib/sgamma.f, cruft/ranlib/snorm.f,
cruft/ranlib/tstbot.for, cruft/ranlib/tstgmn.for, cruft/ranlib/tstmid.for,
cruft/ranlib/wrap.f, cruft/slatec-err/fdump.f, cruft/slatec-err/ixsav.f,
cruft/slatec-err/j4save.f, cruft/slatec-err/module.mk,
cruft/slatec-err/xerclr.f, cruft/slatec-err/xercnt.f,
cruft/slatec-err/xerhlt.f, cruft/slatec-err/xermsg.f,
cruft/slatec-err/xerprn.f, cruft/slatec-err/xerrwd.f,
cruft/slatec-err/xersve.f, cruft/slatec-err/xgetf.f, cruft/slatec-err/xgetua.f,
cruft/slatec-err/xsetf.f, cruft/slatec-err/xsetua.f, cruft/slatec-fn/acosh.f,
cruft/slatec-fn/albeta.f, cruft/slatec-fn/algams.f, cruft/slatec-fn/alngam.f,
cruft/slatec-fn/alnrel.f, cruft/slatec-fn/asinh.f, cruft/slatec-fn/atanh.f,
cruft/slatec-fn/betai.f, cruft/slatec-fn/csevl.f, cruft/slatec-fn/d9gmit.f,
cruft/slatec-fn/d9lgic.f, cruft/slatec-fn/d9lgit.f, cruft/slatec-fn/d9lgmc.f,
cruft/slatec-fn/dacosh.f, cruft/slatec-fn/dasinh.f, cruft/slatec-fn/datanh.f,
cruft/slatec-fn/dbetai.f, cruft/slatec-fn/dcsevl.f, cruft/slatec-fn/derf.f,
cruft/slatec-fn/derfc.in.f, cruft/slatec-fn/dgami.f, cruft/slatec-fn/dgamit.f,
cruft/slatec-fn/dgamlm.f, cruft/slatec-fn/dgamma.f, cruft/slatec-fn/dgamr.f,
cruft/slatec-fn/dlbeta.f, cruft/slatec-fn/dlgams.f, cruft/slatec-fn/dlngam.f,
cruft/slatec-fn/dlnrel.f, cruft/slatec-fn/dpchim.f, cruft/slatec-fn/dpchst.f,
cruft/slatec-fn/erf.f, cruft/slatec-fn/erfc.in.f, cruft/slatec-fn/gami.f,
cruft/slatec-fn/gamit.f, cruft/slatec-fn/gamlim.f, cruft/slatec-fn/gamma.f,
cruft/slatec-fn/gamr.f, cruft/slatec-fn/initds.f, cruft/slatec-fn/inits.f,
cruft/slatec-fn/module.mk, cruft/slatec-fn/pchim.f, cruft/slatec-fn/pchst.f,
cruft/slatec-fn/r9gmit.f, cruft/slatec-fn/r9lgic.f, cruft/slatec-fn/r9lgit.f,
cruft/slatec-fn/r9lgmc.f, cruft/slatec-fn/xacosh.f, cruft/slatec-fn/xasinh.f,
cruft/slatec-fn/xatanh.f, cruft/slatec-fn/xbetai.f, cruft/slatec-fn/xdacosh.f,
cruft/slatec-fn/xdasinh.f, cruft/slatec-fn/xdatanh.f,
cruft/slatec-fn/xdbetai.f, cruft/slatec-fn/xderf.f, cruft/slatec-fn/xderfc.f,
cruft/slatec-fn/xdgami.f, cruft/slatec-fn/xdgamit.f, cruft/slatec-fn/xdgamma.f,
cruft/slatec-fn/xerf.f, cruft/slatec-fn/xerfc.f, cruft/slatec-fn/xgamma.f,
cruft/slatec-fn/xgmainc.f, cruft/slatec-fn/xsgmainc.f:
Moved from top-level libcruft to cruft directory below liboctave.
* numeric/CmplxAEPBAL.cc, numeric/CmplxAEPBAL.h, numeric/CmplxCHOL.cc,
numeric/CmplxCHOL.h, numeric/CmplxGEPBAL.cc, numeric/CmplxGEPBAL.h,
numeric/CmplxHESS.cc, numeric/CmplxHESS.h, numeric/CmplxLU.cc,
numeric/CmplxLU.h, numeric/CmplxQR.cc, numeric/CmplxQR.h, numeric/CmplxQRP.cc,
numeric/CmplxQRP.h, numeric/CmplxSCHUR.cc, numeric/CmplxSCHUR.h,
numeric/CmplxSVD.cc, numeric/CmplxSVD.h, numeric/CollocWt.cc,
numeric/CollocWt.h, numeric/DAE.h, numeric/DAEFunc.h, numeric/DAERT.h,
numeric/DAERTFunc.h, numeric/DASPK-opts.in, numeric/DASPK.cc, numeric/DASPK.h,
numeric/DASRT-opts.in, numeric/DASRT.cc, numeric/DASRT.h,
numeric/DASSL-opts.in, numeric/DASSL.cc, numeric/DASSL.h, numeric/DET.h,
numeric/EIG.cc, numeric/EIG.h, numeric/LSODE-opts.in, numeric/LSODE.cc,
numeric/LSODE.h, numeric/ODE.h, numeric/ODEFunc.h, numeric/ODES.cc,
numeric/ODES.h, numeric/ODESFunc.h, numeric/Quad-opts.in, numeric/Quad.cc,
numeric/Quad.h, numeric/SparseCmplxCHOL.cc, numeric/SparseCmplxCHOL.h,
numeric/SparseCmplxLU.cc, numeric/SparseCmplxLU.h, numeric/SparseCmplxQR.cc,
numeric/SparseCmplxQR.h, numeric/SparseQR.cc, numeric/SparseQR.h,
numeric/SparsedbleCHOL.cc, numeric/SparsedbleCHOL.h, numeric/SparsedbleLU.cc,
numeric/SparsedbleLU.h, numeric/base-aepbal.h, numeric/base-dae.h,
numeric/base-de.h, numeric/base-lu.cc, numeric/base-lu.h, numeric/base-min.h,
numeric/base-qr.cc, numeric/base-qr.h, numeric/bsxfun-decl.h,
numeric/bsxfun-defs.cc, numeric/bsxfun.h, numeric/dbleAEPBAL.cc,
numeric/dbleAEPBAL.h, numeric/dbleCHOL.cc, numeric/dbleCHOL.h,
numeric/dbleGEPBAL.cc, numeric/dbleGEPBAL.h, numeric/dbleHESS.cc,
numeric/dbleHESS.h, numeric/dbleLU.cc, numeric/dbleLU.h, numeric/dbleQR.cc,
numeric/dbleQR.h, numeric/dbleQRP.cc, numeric/dbleQRP.h, numeric/dbleSCHUR.cc,
numeric/dbleSCHUR.h, numeric/dbleSVD.cc, numeric/dbleSVD.h,
numeric/eigs-base.cc, numeric/fCmplxAEPBAL.cc, numeric/fCmplxAEPBAL.h,
numeric/fCmplxCHOL.cc, numeric/fCmplxCHOL.h, numeric/fCmplxGEPBAL.cc,
numeric/fCmplxGEPBAL.h, numeric/fCmplxHESS.cc, numeric/fCmplxHESS.h,
numeric/fCmplxLU.cc, numeric/fCmplxLU.h, numeric/fCmplxQR.cc,
numeric/fCmplxQR.h, numeric/fCmplxQRP.cc, numeric/fCmplxQRP.h,
numeric/fCmplxSCHUR.cc, numeric/fCmplxSCHUR.h, numeric/fCmplxSVD.cc,
numeric/fCmplxSVD.h, numeric/fEIG.cc, numeric/fEIG.h, numeric/floatAEPBAL.cc,
numeric/floatAEPBAL.h, numeric/floatCHOL.cc, numeric/floatCHOL.h,
numeric/floatGEPBAL.cc, numeric/floatGEPBAL.h, numeric/floatHESS.cc,
numeric/floatHESS.h, numeric/floatLU.cc, numeric/floatLU.h, numeric/floatQR.cc,
numeric/floatQR.h, numeric/floatQRP.cc, numeric/floatQRP.h,
numeric/floatSCHUR.cc, numeric/floatSCHUR.h, numeric/floatSVD.cc,
numeric/floatSVD.h, numeric/lo-mappers.cc, numeric/lo-mappers.h,
numeric/lo-specfun.cc, numeric/lo-specfun.h, numeric/module.mk,
numeric/oct-convn.cc, numeric/oct-convn.h, numeric/oct-fftw.cc,
numeric/oct-fftw.h, numeric/oct-norm.cc, numeric/oct-norm.h,
numeric/oct-rand.cc, numeric/oct-rand.h, numeric/oct-spparms.cc,
numeric/oct-spparms.h, numeric/randgamma.c, numeric/randgamma.h,
numeric/randmtzig.c, numeric/randmtzig.h, numeric/randpoisson.c,
numeric/randpoisson.h, numeric/sparse-base-chol.cc, numeric/sparse-base-chol.h,
numeric/sparse-base-lu.cc, numeric/sparse-base-lu.h, numeric/sparse-dmsolve.cc:
Moved from liboctave dir to numeric subdirectory.
* operators/Sparse-diag-op-defs.h, operators/Sparse-op-defs.h,
operators/Sparse-perm-op-defs.h, operators/config-ops.sh, operators/mk-ops.awk,
operators/module.mk, operators/mx-base.h, operators/mx-defs.h,
operators/mx-ext.h, operators/mx-inlines.cc, operators/mx-op-decl.h,
operators/mx-op-defs.h, operators/mx-ops, operators/sparse-mk-ops.awk,
operators/sparse-mx-ops, operators/vx-ops:
Moved from liboctave dir to operators subdirectory.
* system/dir-ops.cc, system/dir-ops.h, system/file-ops.cc, system/file-ops.h,
system/file-stat.cc, system/file-stat.h, system/lo-sysdep.cc,
system/lo-sysdep.h, system/mach-info.cc, system/mach-info.h, system/module.mk,
system/oct-env.cc, system/oct-env.h, system/oct-group.cc, system/oct-group.h,
system/oct-openmp.h, system/oct-passwd.cc, system/oct-passwd.h,
system/oct-syscalls.cc, system/oct-syscalls.h, system/oct-time.cc,
system/oct-time.h, system/oct-uname.cc, system/oct-uname.h, system/pathlen.h,
system/sysdir.h, system/syswait.h, system/tempnam.c, system/tempname.c:
Moved from liboctave dir to system subdirectory.
* util/base-list.h, util/byte-swap.h, util/caseless-str.h, util/cmd-edit.cc,
util/cmd-edit.h, util/cmd-hist.cc, util/cmd-hist.h, util/data-conv.cc,
util/data-conv.h, util/f2c-main.c, util/functor.h, util/glob-match.cc,
util/glob-match.h, util/kpse.cc, util/lo-array-gripes.cc,
util/lo-array-gripes.h, util/lo-cieee.c, util/lo-cutils.c, util/lo-cutils.h,
util/lo-ieee.cc, util/lo-ieee.h, util/lo-macros.h, util/lo-math.h,
util/lo-traits.h, util/lo-utils.cc, util/lo-utils.h, util/module.mk,
util/oct-alloc.cc, util/oct-alloc.h, util/oct-base64.cc, util/oct-base64.h,
util/oct-binmap.h, util/oct-cmplx.h, util/oct-glob.cc, util/oct-glob.h,
util/oct-inttypes.cc, util/oct-inttypes.h, util/oct-locbuf.cc,
util/oct-locbuf.h, util/oct-md5.cc, util/oct-md5.h, util/oct-mem.h,
util/oct-mutex.cc, util/oct-mutex.h, util/oct-refcount.h, util/oct-rl-edit.c,
util/oct-rl-edit.h, util/oct-rl-hist.c, util/oct-rl-hist.h, util/oct-shlib.cc,
util/oct-shlib.h, util/oct-sort.cc, util/oct-sort.h, util/oct-sparse.h,
util/pathsearch.cc, util/pathsearch.h, util/regexp.cc, util/regexp.h,
util/singleton-cleanup.cc, util/singleton-cleanup.h, util/sparse-sort.cc,
util/sparse-sort.h, util/sparse-util.cc, util/sparse-util.h, util/statdefs.h,
util/str-vec.cc, util/str-vec.h, util/sun-utils.h:
Moved from liboctave dir to util subdirectory.
* Makefile.am: Eliminate reference to top-level liboctave directory.
* autogen.sh: cd to new liboctave/operators directory to run config-ops.sh.
* build-aux/common.mk: Eliminate LIBCRUFT references.
* configure.ac: Eliminate libcruft top-level references. Switch test
programs to find files in liboctave/cruft subdirectory.
* OctaveFAQ.texi, install.txi, mkoctfile.1: Eliminate references to libcruft in
docs.
* libgui/src/Makefile.am, libinterp/Makefile.am, src/Makefile.am: Update
include file locations. Stop linking against libcruft.
* libinterp/corefcn/module.mk: Update location of OPT_INC files which are
now in numeric/ subdirectory.
* libinterp/dldfcn/config-module.awk: Stop linking against libcruft.
* libinterp/interpfcn/toplev.cc: Remove reference to LIBCRUFT.
* libinterp/link-deps.mk, liboctave/link-deps.mk:
Add GNULIB_LINK_DEPS to link dependencies.
* libinterp/oct-conf.in.h: Remove reference to OCTAVE_CONF_LIBCRUFT.
* liboctave/Makefile.am: Overhaul to use convenience libraries in
subdirectories.
* scripts/miscellaneous/mkoctfile.m: Eliminate reference to LIBCRUFT.
* src/mkoctfile.in.cc, src/mkoctfile.in.sh: Stop linking againt libcruft.
Eliminate references to LIBCRUFT.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 31 Aug 2012 20:00:20 -0700 |
parents | liboctave/lo-specfun.cc@d2220c3def3f |
children | 2fac72a256ce |
line wrap: on
line source
/* Copyright (C) 1996-2012 John W. Eaton Copyright (C) 2010 Jaroslav Hajek Copyright (C) 2010 VZLU Prague This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "Range.h" #include "CColVector.h" #include "CMatrix.h" #include "dRowVector.h" #include "dMatrix.h" #include "dNDArray.h" #include "CNDArray.h" #include "fCColVector.h" #include "fCMatrix.h" #include "fRowVector.h" #include "fMatrix.h" #include "fNDArray.h" #include "fCNDArray.h" #include "f77-fcn.h" #include "lo-error.h" #include "lo-ieee.h" #include "lo-specfun.h" #include "mx-inlines.cc" #include "lo-mappers.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif extern "C" { F77_RET_T F77_FUNC (zbesj, ZBESJ) (const double&, const double&, const double&, const octave_idx_type&, const octave_idx_type&, double*, double*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (zbesy, ZBESY) (const double&, const double&, const double&, const octave_idx_type&, const octave_idx_type&, double*, double*, octave_idx_type&, double*, double*, octave_idx_type&); F77_RET_T F77_FUNC (zbesi, ZBESI) (const double&, const double&, const double&, const octave_idx_type&, const octave_idx_type&, double*, double*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (zbesk, ZBESK) (const double&, const double&, const double&, const octave_idx_type&, const octave_idx_type&, double*, double*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (zbesh, ZBESH) (const double&, const double&, const double&, const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, double*, double*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (cbesj, cBESJ) (const FloatComplex&, const float&, const octave_idx_type&, const octave_idx_type&, FloatComplex*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (cbesy, CBESY) (const FloatComplex&, const float&, const octave_idx_type&, const octave_idx_type&, FloatComplex*, octave_idx_type&, FloatComplex*, octave_idx_type&); F77_RET_T F77_FUNC (cbesi, CBESI) (const FloatComplex&, const float&, const octave_idx_type&, const octave_idx_type&, FloatComplex*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (cbesk, CBESK) (const FloatComplex&, const float&, const octave_idx_type&, const octave_idx_type&, FloatComplex*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (cbesh, CBESH) (const FloatComplex&, const float&, const octave_idx_type&, const octave_idx_type&, const octave_idx_type&, FloatComplex*, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (zairy, ZAIRY) (const double&, const double&, const octave_idx_type&, const octave_idx_type&, double&, double&, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (cairy, CAIRY) (const float&, const float&, const octave_idx_type&, const octave_idx_type&, float&, float&, octave_idx_type&, octave_idx_type&); F77_RET_T F77_FUNC (zbiry, ZBIRY) (const double&, const double&, const octave_idx_type&, const octave_idx_type&, double&, double&, octave_idx_type&); F77_RET_T F77_FUNC (cbiry, CBIRY) (const float&, const float&, const octave_idx_type&, const octave_idx_type&, float&, float&, octave_idx_type&); F77_RET_T F77_FUNC (xdacosh, XDACOSH) (const double&, double&); F77_RET_T F77_FUNC (xacosh, XACOSH) (const float&, float&); F77_RET_T F77_FUNC (xdasinh, XDASINH) (const double&, double&); F77_RET_T F77_FUNC (xasinh, XASINH) (const float&, float&); F77_RET_T F77_FUNC (xdatanh, XDATANH) (const double&, double&); F77_RET_T F77_FUNC (xatanh, XATANH) (const float&, float&); F77_RET_T F77_FUNC (xderf, XDERF) (const double&, double&); F77_RET_T F77_FUNC (xerf, XERF) (const float&, float&); F77_RET_T F77_FUNC (xderfc, XDERFC) (const double&, double&); F77_RET_T F77_FUNC (xerfc, XERFC) (const float&, float&); F77_RET_T F77_FUNC (xdbetai, XDBETAI) (const double&, const double&, const double&, double&); F77_RET_T F77_FUNC (xbetai, XBETAI) (const float&, const float&, const float&, float&); F77_RET_T F77_FUNC (xdgamma, XDGAMMA) (const double&, double&); F77_RET_T F77_FUNC (xgamma, XGAMMA) (const float&, float&); F77_RET_T F77_FUNC (xgammainc, XGAMMAINC) (const double&, const double&, double&); F77_RET_T F77_FUNC (xsgammainc, XSGAMMAINC) (const float&, const float&, float&); F77_RET_T F77_FUNC (dlgams, DLGAMS) (const double&, double&, double&); F77_RET_T F77_FUNC (algams, ALGAMS) (const float&, float&, float&); } #if !defined (HAVE_ACOSH) double acosh (double x) { double retval; F77_XFCN (xdacosh, XDACOSH, (x, retval)); return retval; } #endif #if !defined (HAVE_ACOSHF) float acoshf (float x) { float retval; F77_XFCN (xacosh, XACOSH, (x, retval)); return retval; } #endif #if !defined (HAVE_ASINH) double asinh (double x) { double retval; F77_XFCN (xdasinh, XDASINH, (x, retval)); return retval; } #endif #if !defined (HAVE_ASINHF) float asinhf (float x) { float retval; F77_XFCN (xasinh, XASINH, (x, retval)); return retval; } #endif #if !defined (HAVE_ATANH) double atanh (double x) { double retval; F77_XFCN (xdatanh, XDATANH, (x, retval)); return retval; } #endif #if !defined (HAVE_ATANHF) float atanhf (float x) { float retval; F77_XFCN (xatanh, XATANH, (x, retval)); return retval; } #endif #if !defined (HAVE_ERF) double erf (double x) { double retval; F77_XFCN (xderf, XDERF, (x, retval)); return retval; } #endif #if !defined (HAVE_ERFF) float erff (float x) { float retval; F77_XFCN (xerf, XERF, (x, retval)); return retval; } #endif #if !defined (HAVE_ERFC) double erfc (double x) { double retval; F77_XFCN (xderfc, XDERFC, (x, retval)); return retval; } #endif #if !defined (HAVE_ERFCF) float erfcf (float x) { float retval; F77_XFCN (xerfc, XERFC, (x, retval)); return retval; } #endif double xgamma (double x) { double result; if (xisnan (x)) result = x; else if ((x <= 0 && D_NINT (x) == x) || xisinf (x)) result = octave_Inf; else #if defined (HAVE_TGAMMA) result = tgamma (x); #else F77_XFCN (xdgamma, XDGAMMA, (x, result)); #endif return result; } double xlgamma (double x) { #if defined (HAVE_LGAMMA) return lgamma (x); #else double result; double sgngam; if (xisnan (x)) result = x; else if ((x <= 0 && D_NINT (x) == x) || xisinf (x)) result = octave_Inf; else F77_XFCN (dlgams, DLGAMS, (x, result, sgngam)); return result; #endif } Complex rc_lgamma (double x) { double result; #if defined (HAVE_LGAMMA_R) int sgngam; result = lgamma_r (x, &sgngam); #else double sgngam; if (xisnan (x)) result = x; else if ((x <= 0 && D_NINT (x) == x) || xisinf (x)) result = octave_Inf; else F77_XFCN (dlgams, DLGAMS, (x, result, sgngam)); #endif if (sgngam < 0) return result + Complex (0., M_PI); else return result; } float xgamma (float x) { float result; if (xisnan (x)) result = x; else if ((x <= 0 && D_NINT (x) == x) || xisinf (x)) result = octave_Float_Inf; else #if defined (HAVE_TGAMMAF) result = tgammaf (x); #else F77_XFCN (xgamma, XGAMMA, (x, result)); #endif return result; } float xlgamma (float x) { #if defined (HAVE_LGAMMAF) return lgammaf (x); #else float result; float sgngam; if (xisnan (x)) result = x; else if ((x <= 0 && D_NINT (x) == x) || xisinf (x)) result = octave_Float_Inf; else F77_XFCN (algams, ALGAMS, (x, result, sgngam)); return result; #endif } FloatComplex rc_lgamma (float x) { float result; #if defined (HAVE_LGAMMAF_R) int sgngam; result = lgammaf_r (x, &sgngam); #else float sgngam; if (xisnan (x)) result = x; else if ((x <= 0 && D_NINT (x) == x) || xisinf (x)) result = octave_Float_Inf; else F77_XFCN (algams, ALGAMS, (x, result, sgngam)); #endif if (sgngam < 0) return result + FloatComplex (0., M_PI); else return result; } #if !defined (HAVE_EXPM1) double expm1 (double x) { double retval; double ax = fabs (x); if (ax < 0.1) { ax /= 16; // use Taylor series to calculate exp(x)-1. double t = ax; double s = 0; for (int i = 2; i < 7; i++) s += (t *= ax/i); s += ax; // use the identity (a+1)^2-1 = a*(a+2) double e = s; for (int i = 0; i < 4; i++) { s *= e + 2; e *= e + 2; } retval = (x > 0) ? s : -s / (1+s); } else retval = exp (x) - 1; return retval; } #endif Complex expm1 (const Complex& x) { Complex retval; if (std:: abs (x) < 1) { double im = x.imag (); double u = expm1 (x.real ()); double v = sin (im/2); v = -2*v*v; retval = Complex (u*v + u + v, (u+1) * sin (im)); } else retval = std::exp (x) - Complex (1); return retval; } #if !defined (HAVE_EXPM1F) float expm1f (float x) { float retval; float ax = fabs (x); if (ax < 0.1) { ax /= 16; // use Taylor series to calculate exp(x)-1. float t = ax; float s = 0; for (int i = 2; i < 7; i++) s += (t *= ax/i); s += ax; // use the identity (a+1)^2-1 = a*(a+2) float e = s; for (int i = 0; i < 4; i++) { s *= e + 2; e *= e + 2; } retval = (x > 0) ? s : -s / (1+s); } else retval = exp (x) - 1; return retval; } #endif FloatComplex expm1 (const FloatComplex& x) { FloatComplex retval; if (std:: abs (x) < 1) { float im = x.imag (); float u = expm1 (x.real ()); float v = sin (im/2); v = -2*v*v; retval = FloatComplex (u*v + u + v, (u+1) * sin (im)); } else retval = std::exp (x) - FloatComplex (1); return retval; } #if !defined (HAVE_LOG1P) double log1p (double x) { double retval; double ax = fabs (x); if (ax < 0.2) { // use approximation log (1+x) ~ 2*sum ((x/(2+x)).^ii ./ ii), ii = 1:2:2n+1 double u = x / (2 + x), t = 1, s = 0; for (int i = 2; i < 12; i += 2) s += (t *= u*u) / (i+1); retval = 2 * (s + 1) * u; } else retval = log (1 + x); return retval; } #endif Complex log1p (const Complex& x) { Complex retval; double r = x.real (), i = x.imag (); if (fabs (r) < 0.5 && fabs (i) < 0.5) { double u = 2*r + r*r + i*i; retval = Complex (log1p (u / (1+sqrt (u+1))), atan2 (1 + r, i)); } else retval = std::log (Complex (1) + x); return retval; } #if !defined (HAVE_CBRT) double cbrt (double x) { static const double one_third = 0.3333333333333333333; if (xfinite (x)) { // Use pow. double y = std::pow (std::abs (x), one_third) * signum (x); // Correct for better accuracy. return (x / (y*y) + y + y) / 3; } else return x; } #endif #if !defined (HAVE_LOG1PF) float log1pf (float x) { float retval; float ax = fabs (x); if (ax < 0.2) { // use approximation log (1+x) ~ 2*sum ((x/(2+x)).^ii ./ ii), ii = 1:2:2n+1 float u = x / (2 + x), t = 1, s = 0; for (int i = 2; i < 12; i += 2) s += (t *= u*u) / (i+1); retval = 2 * (s + 1) * u; } else retval = log (1 + x); return retval; } #endif FloatComplex log1p (const FloatComplex& x) { FloatComplex retval; float r = x.real (), i = x.imag (); if (fabs (r) < 0.5 && fabs (i) < 0.5) { float u = 2*r + r*r + i*i; retval = FloatComplex (log1p (u / (1+sqrt (u+1))), atan2 (1 + r, i)); } else retval = std::log (FloatComplex (1) + x); return retval; } #if !defined (HAVE_CBRTF) float cbrtf (float x) { static const float one_third = 0.3333333333333333333f; if (xfinite (x)) { // Use pow. float y = std::pow (std::abs (x), one_third) * signum (x); // Correct for better accuracy. return (x / (y*y) + y + y) / 3; } else return x; } #endif static inline Complex zbesj (const Complex& z, double alpha, int kode, octave_idx_type& ierr); static inline Complex zbesy (const Complex& z, double alpha, int kode, octave_idx_type& ierr); static inline Complex zbesi (const Complex& z, double alpha, int kode, octave_idx_type& ierr); static inline Complex zbesk (const Complex& z, double alpha, int kode, octave_idx_type& ierr); static inline Complex zbesh1 (const Complex& z, double alpha, int kode, octave_idx_type& ierr); static inline Complex zbesh2 (const Complex& z, double alpha, int kode, octave_idx_type& ierr); static inline Complex bessel_return_value (const Complex& val, octave_idx_type ierr) { static const Complex inf_val = Complex (octave_Inf, octave_Inf); static const Complex nan_val = Complex (octave_NaN, octave_NaN); Complex retval; switch (ierr) { case 0: case 3: retval = val; break; case 2: retval = inf_val; break; default: retval = nan_val; break; } return retval; } static inline bool is_integer_value (double x) { return x == static_cast<double> (static_cast<long> (x)); } static inline Complex zbesj (const Complex& z, double alpha, int kode, octave_idx_type& ierr) { Complex retval; if (alpha >= 0.0) { double yr = 0.0; double yi = 0.0; octave_idx_type nz; double zr = z.real (); double zi = z.imag (); F77_FUNC (zbesj, ZBESJ) (zr, zi, alpha, 2, 1, &yr, &yi, nz, ierr); if (kode != 2) { double expz = exp (std::abs (zi)); yr *= expz; yi *= expz; } if (zi == 0.0 && zr >= 0.0) yi = 0.0; retval = bessel_return_value (Complex (yr, yi), ierr); } else if (is_integer_value (alpha)) { // zbesy can overflow as z->0, and cause troubles for generic case below alpha = -alpha; Complex tmp = zbesj (z, alpha, kode, ierr); if ((static_cast <long> (alpha)) & 1) tmp = - tmp; retval = bessel_return_value (tmp, ierr); } else { alpha = -alpha; Complex tmp = cos (M_PI * alpha) * zbesj (z, alpha, kode, ierr); if (ierr == 0 || ierr == 3) { tmp -= sin (M_PI * alpha) * zbesy (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } else retval = Complex (octave_NaN, octave_NaN); } return retval; } static inline Complex zbesy (const Complex& z, double alpha, int kode, octave_idx_type& ierr) { Complex retval; if (alpha >= 0.0) { double yr = 0.0; double yi = 0.0; octave_idx_type nz; double wr, wi; double zr = z.real (); double zi = z.imag (); ierr = 0; if (zr == 0.0 && zi == 0.0) { yr = -octave_Inf; yi = 0.0; } else { F77_FUNC (zbesy, ZBESY) (zr, zi, alpha, 2, 1, &yr, &yi, nz, &wr, &wi, ierr); if (kode != 2) { double expz = exp (std::abs (zi)); yr *= expz; yi *= expz; } if (zi == 0.0 && zr >= 0.0) yi = 0.0; } return bessel_return_value (Complex (yr, yi), ierr); } else if (is_integer_value (alpha - 0.5)) { // zbesy can overflow as z->0, and cause troubles for generic case below alpha = -alpha; Complex tmp = zbesj (z, alpha, kode, ierr); if ((static_cast <long> (alpha - 0.5)) & 1) tmp = - tmp; retval = bessel_return_value (tmp, ierr); } else { alpha = -alpha; Complex tmp = cos (M_PI * alpha) * zbesy (z, alpha, kode, ierr); if (ierr == 0 || ierr == 3) { tmp += sin (M_PI * alpha) * zbesj (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } else retval = Complex (octave_NaN, octave_NaN); } return retval; } static inline Complex zbesi (const Complex& z, double alpha, int kode, octave_idx_type& ierr) { Complex retval; if (alpha >= 0.0) { double yr = 0.0; double yi = 0.0; octave_idx_type nz; double zr = z.real (); double zi = z.imag (); F77_FUNC (zbesi, ZBESI) (zr, zi, alpha, 2, 1, &yr, &yi, nz, ierr); if (kode != 2) { double expz = exp (std::abs (zr)); yr *= expz; yi *= expz; } if (zi == 0.0 && zr >= 0.0) yi = 0.0; retval = bessel_return_value (Complex (yr, yi), ierr); } else if (is_integer_value (alpha)) { // zbesi can overflow as z->0, and cause troubles for generic case below alpha = -alpha; Complex tmp = zbesi (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } else { alpha = -alpha; Complex tmp = zbesi (z, alpha, kode, ierr); if (ierr == 0 || ierr == 3) { Complex tmp2 = (2.0 / M_PI) * sin (M_PI * alpha) * zbesk (z, alpha, kode, ierr); if (kode == 2) { // Compensate for different scaling factor of besk. tmp2 *= exp (-z - std::abs (z.real ())); } tmp += tmp2; retval = bessel_return_value (tmp, ierr); } else retval = Complex (octave_NaN, octave_NaN); } return retval; } static inline Complex zbesk (const Complex& z, double alpha, int kode, octave_idx_type& ierr) { Complex retval; if (alpha >= 0.0) { double yr = 0.0; double yi = 0.0; octave_idx_type nz; double zr = z.real (); double zi = z.imag (); ierr = 0; if (zr == 0.0 && zi == 0.0) { yr = octave_Inf; yi = 0.0; } else { F77_FUNC (zbesk, ZBESK) (zr, zi, alpha, 2, 1, &yr, &yi, nz, ierr); if (kode != 2) { Complex expz = exp (-z); double rexpz = real (expz); double iexpz = imag (expz); double tmp = yr*rexpz - yi*iexpz; yi = yr*iexpz + yi*rexpz; yr = tmp; } if (zi == 0.0 && zr >= 0.0) yi = 0.0; } retval = bessel_return_value (Complex (yr, yi), ierr); } else { Complex tmp = zbesk (z, -alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } return retval; } static inline Complex zbesh1 (const Complex& z, double alpha, int kode, octave_idx_type& ierr) { Complex retval; if (alpha >= 0.0) { double yr = 0.0; double yi = 0.0; octave_idx_type nz; double zr = z.real (); double zi = z.imag (); F77_FUNC (zbesh, ZBESH) (zr, zi, alpha, 2, 1, 1, &yr, &yi, nz, ierr); if (kode != 2) { Complex expz = exp (Complex (0.0, 1.0) * z); double rexpz = real (expz); double iexpz = imag (expz); double tmp = yr*rexpz - yi*iexpz; yi = yr*iexpz + yi*rexpz; yr = tmp; } retval = bessel_return_value (Complex (yr, yi), ierr); } else { alpha = -alpha; static const Complex eye = Complex (0.0, 1.0); Complex tmp = exp (M_PI * alpha * eye) * zbesh1 (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } return retval; } static inline Complex zbesh2 (const Complex& z, double alpha, int kode, octave_idx_type& ierr) { Complex retval; if (alpha >= 0.0) { double yr = 0.0; double yi = 0.0; octave_idx_type nz; double zr = z.real (); double zi = z.imag (); F77_FUNC (zbesh, ZBESH) (zr, zi, alpha, 2, 2, 1, &yr, &yi, nz, ierr); if (kode != 2) { Complex expz = exp (-Complex (0.0, 1.0) * z); double rexpz = real (expz); double iexpz = imag (expz); double tmp = yr*rexpz - yi*iexpz; yi = yr*iexpz + yi*rexpz; yr = tmp; } retval = bessel_return_value (Complex (yr, yi), ierr); } else { alpha = -alpha; static const Complex eye = Complex (0.0, 1.0); Complex tmp = exp (-M_PI * alpha * eye) * zbesh2 (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } return retval; } typedef Complex (*dptr) (const Complex&, double, int, octave_idx_type&); static inline Complex do_bessel (dptr f, const char *, double alpha, const Complex& x, bool scaled, octave_idx_type& ierr) { Complex retval; retval = f (x, alpha, (scaled ? 2 : 1), ierr); return retval; } static inline ComplexMatrix do_bessel (dptr f, const char *, double alpha, const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = x.rows (); octave_idx_type nc = x.cols (); ComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x(i,j), alpha, (scaled ? 2 : 1), ierr(i,j)); return retval; } static inline ComplexMatrix do_bessel (dptr f, const char *, const Matrix& alpha, const Complex& x, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = alpha.rows (); octave_idx_type nc = alpha.cols (); ComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x, alpha(i,j), (scaled ? 2 : 1), ierr(i,j)); return retval; } static inline ComplexMatrix do_bessel (dptr f, const char *fn, const Matrix& alpha, const ComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr) { ComplexMatrix retval; octave_idx_type x_nr = x.rows (); octave_idx_type x_nc = x.cols (); octave_idx_type alpha_nr = alpha.rows (); octave_idx_type alpha_nc = alpha.cols (); if (x_nr == alpha_nr && x_nc == alpha_nc) { octave_idx_type nr = x_nr; octave_idx_type nc = x_nc; retval.resize (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x(i,j), alpha(i,j), (scaled ? 2 : 1), ierr(i,j)); } else (*current_liboctave_error_handler) ("%s: the sizes of alpha and x must conform", fn); return retval; } static inline ComplexNDArray do_bessel (dptr f, const char *, double alpha, const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); ComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = f (x(i), alpha, (scaled ? 2 : 1), ierr(i)); return retval; } static inline ComplexNDArray do_bessel (dptr f, const char *, const NDArray& alpha, const Complex& x, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = alpha.dims (); octave_idx_type nel = dv.numel (); ComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = f (x, alpha(i), (scaled ? 2 : 1), ierr(i)); return retval; } static inline ComplexNDArray do_bessel (dptr f, const char *fn, const NDArray& alpha, const ComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = x.dims (); ComplexNDArray retval; if (dv == alpha.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = f (x(i), alpha(i), (scaled ? 2 : 1), ierr(i)); } else (*current_liboctave_error_handler) ("%s: the sizes of alpha and x must conform", fn); return retval; } static inline ComplexMatrix do_bessel (dptr f, const char *, const RowVector& alpha, const ComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = x.length (); octave_idx_type nc = alpha.length (); ComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x(i), alpha(j), (scaled ? 2 : 1), ierr(i,j)); return retval; } #define SS_BESSEL(name, fcn) \ Complex \ name (double alpha, const Complex& x, bool scaled, octave_idx_type& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define SM_BESSEL(name, fcn) \ ComplexMatrix \ name (double alpha, const ComplexMatrix& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define MS_BESSEL(name, fcn) \ ComplexMatrix \ name (const Matrix& alpha, const Complex& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define MM_BESSEL(name, fcn) \ ComplexMatrix \ name (const Matrix& alpha, const ComplexMatrix& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define SN_BESSEL(name, fcn) \ ComplexNDArray \ name (double alpha, const ComplexNDArray& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define NS_BESSEL(name, fcn) \ ComplexNDArray \ name (const NDArray& alpha, const Complex& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define NN_BESSEL(name, fcn) \ ComplexNDArray \ name (const NDArray& alpha, const ComplexNDArray& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define RC_BESSEL(name, fcn) \ ComplexMatrix \ name (const RowVector& alpha, const ComplexColumnVector& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define ALL_BESSEL(name, fcn) \ SS_BESSEL (name, fcn) \ SM_BESSEL (name, fcn) \ MS_BESSEL (name, fcn) \ MM_BESSEL (name, fcn) \ SN_BESSEL (name, fcn) \ NS_BESSEL (name, fcn) \ NN_BESSEL (name, fcn) \ RC_BESSEL (name, fcn) ALL_BESSEL (besselj, zbesj) ALL_BESSEL (bessely, zbesy) ALL_BESSEL (besseli, zbesi) ALL_BESSEL (besselk, zbesk) ALL_BESSEL (besselh1, zbesh1) ALL_BESSEL (besselh2, zbesh2) #undef ALL_BESSEL #undef SS_BESSEL #undef SM_BESSEL #undef MS_BESSEL #undef MM_BESSEL #undef SN_BESSEL #undef NS_BESSEL #undef NN_BESSEL #undef RC_BESSEL static inline FloatComplex cbesj (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr); static inline FloatComplex cbesy (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr); static inline FloatComplex cbesi (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr); static inline FloatComplex cbesk (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr); static inline FloatComplex cbesh1 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr); static inline FloatComplex cbesh2 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr); static inline FloatComplex bessel_return_value (const FloatComplex& val, octave_idx_type ierr) { static const FloatComplex inf_val = FloatComplex (octave_Float_Inf, octave_Float_Inf); static const FloatComplex nan_val = FloatComplex (octave_Float_NaN, octave_Float_NaN); FloatComplex retval; switch (ierr) { case 0: case 3: retval = val; break; case 2: retval = inf_val; break; default: retval = nan_val; break; } return retval; } static inline bool is_integer_value (float x) { return x == static_cast<float> (static_cast<long> (x)); } static inline FloatComplex cbesj (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr) { FloatComplex retval; if (alpha >= 0.0) { FloatComplex y = 0.0; octave_idx_type nz; F77_FUNC (cbesj, CBESJ) (z, alpha, 2, 1, &y, nz, ierr); if (kode != 2) { float expz = exp (std::abs (imag (z))); y *= expz; } if (imag (z) == 0.0 && real (z) >= 0.0) y = FloatComplex (y.real (), 0.0); retval = bessel_return_value (y, ierr); } else if (is_integer_value (alpha)) { // zbesy can overflow as z->0, and cause troubles for generic case below alpha = -alpha; FloatComplex tmp = cbesj (z, alpha, kode, ierr); if ((static_cast <long> (alpha)) & 1) tmp = - tmp; retval = bessel_return_value (tmp, ierr); } else { alpha = -alpha; FloatComplex tmp = cosf (static_cast<float> (M_PI) * alpha) * cbesj (z, alpha, kode, ierr); if (ierr == 0 || ierr == 3) { tmp -= sinf (static_cast<float> (M_PI) * alpha) * cbesy (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } else retval = FloatComplex (octave_Float_NaN, octave_Float_NaN); } return retval; } static inline FloatComplex cbesy (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr) { FloatComplex retval; if (alpha >= 0.0) { FloatComplex y = 0.0; octave_idx_type nz; FloatComplex w; ierr = 0; if (real (z) == 0.0 && imag (z) == 0.0) { y = FloatComplex (-octave_Float_Inf, 0.0); } else { F77_FUNC (cbesy, CBESY) (z, alpha, 2, 1, &y, nz, &w, ierr); if (kode != 2) { float expz = exp (std::abs (imag (z))); y *= expz; } if (imag (z) == 0.0 && real (z) >= 0.0) y = FloatComplex (y.real (), 0.0); } return bessel_return_value (y, ierr); } else if (is_integer_value (alpha - 0.5)) { // zbesy can overflow as z->0, and cause troubles for generic case below alpha = -alpha; FloatComplex tmp = cbesj (z, alpha, kode, ierr); if ((static_cast <long> (alpha - 0.5)) & 1) tmp = - tmp; retval = bessel_return_value (tmp, ierr); } else { alpha = -alpha; FloatComplex tmp = cosf (static_cast<float> (M_PI) * alpha) * cbesy (z, alpha, kode, ierr); if (ierr == 0 || ierr == 3) { tmp += sinf (static_cast<float> (M_PI) * alpha) * cbesj (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } else retval = FloatComplex (octave_Float_NaN, octave_Float_NaN); } return retval; } static inline FloatComplex cbesi (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr) { FloatComplex retval; if (alpha >= 0.0) { FloatComplex y = 0.0; octave_idx_type nz; F77_FUNC (cbesi, CBESI) (z, alpha, 2, 1, &y, nz, ierr); if (kode != 2) { float expz = exp (std::abs (real (z))); y *= expz; } if (imag (z) == 0.0 && real (z) >= 0.0) y = FloatComplex (y.real (), 0.0); retval = bessel_return_value (y, ierr); } else { alpha = -alpha; FloatComplex tmp = cbesi (z, alpha, kode, ierr); if (ierr == 0 || ierr == 3) { FloatComplex tmp2 = static_cast<float> (2.0 / M_PI) * sinf (static_cast<float> (M_PI) * alpha) * cbesk (z, alpha, kode, ierr); if (kode == 2) { // Compensate for different scaling factor of besk. tmp2 *= exp (-z - std::abs (z.real ())); } tmp += tmp2; retval = bessel_return_value (tmp, ierr); } else retval = FloatComplex (octave_Float_NaN, octave_Float_NaN); } return retval; } static inline FloatComplex cbesk (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr) { FloatComplex retval; if (alpha >= 0.0) { FloatComplex y = 0.0; octave_idx_type nz; ierr = 0; if (real (z) == 0.0 && imag (z) == 0.0) { y = FloatComplex (octave_Float_Inf, 0.0); } else { F77_FUNC (cbesk, CBESK) (z, alpha, 2, 1, &y, nz, ierr); if (kode != 2) { FloatComplex expz = exp (-z); float rexpz = real (expz); float iexpz = imag (expz); float tmp_r = real (y) * rexpz - imag (y) * iexpz; float tmp_i = real (y) * iexpz + imag (y) * rexpz; y = FloatComplex (tmp_r, tmp_i); } if (imag (z) == 0.0 && real (z) >= 0.0) y = FloatComplex (y.real (), 0.0); } retval = bessel_return_value (y, ierr); } else { FloatComplex tmp = cbesk (z, -alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } return retval; } static inline FloatComplex cbesh1 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr) { FloatComplex retval; if (alpha >= 0.0) { FloatComplex y = 0.0; octave_idx_type nz; F77_FUNC (cbesh, CBESH) (z, alpha, 2, 1, 1, &y, nz, ierr); if (kode != 2) { FloatComplex expz = exp (FloatComplex (0.0, 1.0) * z); float rexpz = real (expz); float iexpz = imag (expz); float tmp_r = real (y) * rexpz - imag (y) * iexpz; float tmp_i = real (y) * iexpz + imag (y) * rexpz; y = FloatComplex (tmp_r, tmp_i); } retval = bessel_return_value (y, ierr); } else { alpha = -alpha; static const FloatComplex eye = FloatComplex (0.0, 1.0); FloatComplex tmp = exp (static_cast<float> (M_PI) * alpha * eye) * cbesh1 (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } return retval; } static inline FloatComplex cbesh2 (const FloatComplex& z, float alpha, int kode, octave_idx_type& ierr) { FloatComplex retval; if (alpha >= 0.0) { FloatComplex y = 0.0; octave_idx_type nz; F77_FUNC (cbesh, CBESH) (z, alpha, 2, 2, 1, &y, nz, ierr); if (kode != 2) { FloatComplex expz = exp (-FloatComplex (0.0, 1.0) * z); float rexpz = real (expz); float iexpz = imag (expz); float tmp_r = real (y) * rexpz - imag (y) * iexpz; float tmp_i = real (y) * iexpz + imag (y) * rexpz; y = FloatComplex (tmp_r, tmp_i); } retval = bessel_return_value (y, ierr); } else { alpha = -alpha; static const FloatComplex eye = FloatComplex (0.0, 1.0); FloatComplex tmp = exp (-static_cast<float> (M_PI) * alpha * eye) * cbesh2 (z, alpha, kode, ierr); retval = bessel_return_value (tmp, ierr); } return retval; } typedef FloatComplex (*fptr) (const FloatComplex&, float, int, octave_idx_type&); static inline FloatComplex do_bessel (fptr f, const char *, float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr) { FloatComplex retval; retval = f (x, alpha, (scaled ? 2 : 1), ierr); return retval; } static inline FloatComplexMatrix do_bessel (fptr f, const char *, float alpha, const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = x.rows (); octave_idx_type nc = x.cols (); FloatComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x(i,j), alpha, (scaled ? 2 : 1), ierr(i,j)); return retval; } static inline FloatComplexMatrix do_bessel (fptr f, const char *, const FloatMatrix& alpha, const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = alpha.rows (); octave_idx_type nc = alpha.cols (); FloatComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x, alpha(i,j), (scaled ? 2 : 1), ierr(i,j)); return retval; } static inline FloatComplexMatrix do_bessel (fptr f, const char *fn, const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled, Array<octave_idx_type>& ierr) { FloatComplexMatrix retval; octave_idx_type x_nr = x.rows (); octave_idx_type x_nc = x.cols (); octave_idx_type alpha_nr = alpha.rows (); octave_idx_type alpha_nc = alpha.cols (); if (x_nr == alpha_nr && x_nc == alpha_nc) { octave_idx_type nr = x_nr; octave_idx_type nc = x_nc; retval.resize (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x(i,j), alpha(i,j), (scaled ? 2 : 1), ierr(i,j)); } else (*current_liboctave_error_handler) ("%s: the sizes of alpha and x must conform", fn); return retval; } static inline FloatComplexNDArray do_bessel (fptr f, const char *, float alpha, const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); FloatComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = f (x(i), alpha, (scaled ? 2 : 1), ierr(i)); return retval; } static inline FloatComplexNDArray do_bessel (fptr f, const char *, const FloatNDArray& alpha, const FloatComplex& x, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = alpha.dims (); octave_idx_type nel = dv.numel (); FloatComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = f (x, alpha(i), (scaled ? 2 : 1), ierr(i)); return retval; } static inline FloatComplexNDArray do_bessel (fptr f, const char *fn, const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = x.dims (); FloatComplexNDArray retval; if (dv == alpha.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = f (x(i), alpha(i), (scaled ? 2 : 1), ierr(i)); } else (*current_liboctave_error_handler) ("%s: the sizes of alpha and x must conform", fn); return retval; } static inline FloatComplexMatrix do_bessel (fptr f, const char *, const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = x.length (); octave_idx_type nc = alpha.length (); FloatComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = f (x(i), alpha(j), (scaled ? 2 : 1), ierr(i,j)); return retval; } #define SS_BESSEL(name, fcn) \ FloatComplex \ name (float alpha, const FloatComplex& x, bool scaled, octave_idx_type& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define SM_BESSEL(name, fcn) \ FloatComplexMatrix \ name (float alpha, const FloatComplexMatrix& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define MS_BESSEL(name, fcn) \ FloatComplexMatrix \ name (const FloatMatrix& alpha, const FloatComplex& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define MM_BESSEL(name, fcn) \ FloatComplexMatrix \ name (const FloatMatrix& alpha, const FloatComplexMatrix& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define SN_BESSEL(name, fcn) \ FloatComplexNDArray \ name (float alpha, const FloatComplexNDArray& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define NS_BESSEL(name, fcn) \ FloatComplexNDArray \ name (const FloatNDArray& alpha, const FloatComplex& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define NN_BESSEL(name, fcn) \ FloatComplexNDArray \ name (const FloatNDArray& alpha, const FloatComplexNDArray& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define RC_BESSEL(name, fcn) \ FloatComplexMatrix \ name (const FloatRowVector& alpha, const FloatComplexColumnVector& x, bool scaled, \ Array<octave_idx_type>& ierr) \ { \ return do_bessel (fcn, #name, alpha, x, scaled, ierr); \ } #define ALL_BESSEL(name, fcn) \ SS_BESSEL (name, fcn) \ SM_BESSEL (name, fcn) \ MS_BESSEL (name, fcn) \ MM_BESSEL (name, fcn) \ SN_BESSEL (name, fcn) \ NS_BESSEL (name, fcn) \ NN_BESSEL (name, fcn) \ RC_BESSEL (name, fcn) ALL_BESSEL (besselj, cbesj) ALL_BESSEL (bessely, cbesy) ALL_BESSEL (besseli, cbesi) ALL_BESSEL (besselk, cbesk) ALL_BESSEL (besselh1, cbesh1) ALL_BESSEL (besselh2, cbesh2) #undef ALL_BESSEL #undef SS_BESSEL #undef SM_BESSEL #undef MS_BESSEL #undef MM_BESSEL #undef SN_BESSEL #undef NS_BESSEL #undef NN_BESSEL #undef RC_BESSEL Complex airy (const Complex& z, bool deriv, bool scaled, octave_idx_type& ierr) { double ar = 0.0; double ai = 0.0; octave_idx_type nz; double zr = z.real (); double zi = z.imag (); octave_idx_type id = deriv ? 1 : 0; F77_FUNC (zairy, ZAIRY) (zr, zi, id, 2, ar, ai, nz, ierr); if (! scaled) { Complex expz = exp (- 2.0 / 3.0 * z * sqrt (z)); double rexpz = real (expz); double iexpz = imag (expz); double tmp = ar*rexpz - ai*iexpz; ai = ar*iexpz + ai*rexpz; ar = tmp; } if (zi == 0.0 && (! scaled || zr >= 0.0)) ai = 0.0; return bessel_return_value (Complex (ar, ai), ierr); } Complex biry (const Complex& z, bool deriv, bool scaled, octave_idx_type& ierr) { double ar = 0.0; double ai = 0.0; double zr = z.real (); double zi = z.imag (); octave_idx_type id = deriv ? 1 : 0; F77_FUNC (zbiry, ZBIRY) (zr, zi, id, 2, ar, ai, ierr); if (! scaled) { Complex expz = exp (std::abs (real (2.0 / 3.0 * z * sqrt (z)))); double rexpz = real (expz); double iexpz = imag (expz); double tmp = ar*rexpz - ai*iexpz; ai = ar*iexpz + ai*rexpz; ar = tmp; } if (zi == 0.0 && (! scaled || zr >= 0.0)) ai = 0.0; return bessel_return_value (Complex (ar, ai), ierr); } ComplexMatrix airy (const ComplexMatrix& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = z.rows (); octave_idx_type nc = z.cols (); ComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = airy (z(i,j), deriv, scaled, ierr(i,j)); return retval; } ComplexMatrix biry (const ComplexMatrix& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = z.rows (); octave_idx_type nc = z.cols (); ComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = biry (z(i,j), deriv, scaled, ierr(i,j)); return retval; } ComplexNDArray airy (const ComplexNDArray& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = z.dims (); octave_idx_type nel = dv.numel (); ComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = airy (z(i), deriv, scaled, ierr(i)); return retval; } ComplexNDArray biry (const ComplexNDArray& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = z.dims (); octave_idx_type nel = dv.numel (); ComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = biry (z(i), deriv, scaled, ierr(i)); return retval; } FloatComplex airy (const FloatComplex& z, bool deriv, bool scaled, octave_idx_type& ierr) { float ar = 0.0; float ai = 0.0; octave_idx_type nz; float zr = z.real (); float zi = z.imag (); octave_idx_type id = deriv ? 1 : 0; F77_FUNC (cairy, CAIRY) (zr, zi, id, 2, ar, ai, nz, ierr); if (! scaled) { FloatComplex expz = exp (- static_cast<float> (2.0 / 3.0) * z * sqrt (z)); float rexpz = real (expz); float iexpz = imag (expz); float tmp = ar*rexpz - ai*iexpz; ai = ar*iexpz + ai*rexpz; ar = tmp; } if (zi == 0.0 && (! scaled || zr >= 0.0)) ai = 0.0; return bessel_return_value (FloatComplex (ar, ai), ierr); } FloatComplex biry (const FloatComplex& z, bool deriv, bool scaled, octave_idx_type& ierr) { float ar = 0.0; float ai = 0.0; float zr = z.real (); float zi = z.imag (); octave_idx_type id = deriv ? 1 : 0; F77_FUNC (cbiry, CBIRY) (zr, zi, id, 2, ar, ai, ierr); if (! scaled) { FloatComplex expz = exp (std::abs (real (static_cast<float> (2.0 / 3.0) * z * sqrt (z)))); float rexpz = real (expz); float iexpz = imag (expz); float tmp = ar*rexpz - ai*iexpz; ai = ar*iexpz + ai*rexpz; ar = tmp; } if (zi == 0.0 && (! scaled || zr >= 0.0)) ai = 0.0; return bessel_return_value (FloatComplex (ar, ai), ierr); } FloatComplexMatrix airy (const FloatComplexMatrix& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = z.rows (); octave_idx_type nc = z.cols (); FloatComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = airy (z(i,j), deriv, scaled, ierr(i,j)); return retval; } FloatComplexMatrix biry (const FloatComplexMatrix& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { octave_idx_type nr = z.rows (); octave_idx_type nc = z.cols (); FloatComplexMatrix retval (nr, nc); ierr.resize (dim_vector (nr, nc)); for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) retval(i,j) = biry (z(i,j), deriv, scaled, ierr(i,j)); return retval; } FloatComplexNDArray airy (const FloatComplexNDArray& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = z.dims (); octave_idx_type nel = dv.numel (); FloatComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = airy (z(i), deriv, scaled, ierr(i)); return retval; } FloatComplexNDArray biry (const FloatComplexNDArray& z, bool deriv, bool scaled, Array<octave_idx_type>& ierr) { dim_vector dv = z.dims (); octave_idx_type nel = dv.numel (); FloatComplexNDArray retval (dv); ierr.resize (dv); for (octave_idx_type i = 0; i < nel; i++) retval(i) = biry (z(i), deriv, scaled, ierr(i)); return retval; } static void gripe_betainc_nonconformant (const dim_vector& d1, const dim_vector& d2, const dim_vector& d3) { std::string d1_str = d1.str (); std::string d2_str = d2.str (); std::string d3_str = d3.str (); (*current_liboctave_error_handler) ("betainc: nonconformant arguments (x is %s, a is %s, b is %s)", d1_str.c_str (), d2_str.c_str (), d3_str.c_str ()); } static void gripe_betaincinv_nonconformant (const dim_vector& d1, const dim_vector& d2, const dim_vector& d3) { std::string d1_str = d1.str (); std::string d2_str = d2.str (); std::string d3_str = d3.str (); (*current_liboctave_error_handler) ("betaincinv: nonconformant arguments (x is %s, a is %s, b is %s)", d1_str.c_str (), d2_str.c_str (), d3_str.c_str ()); } double betainc (double x, double a, double b) { double retval; F77_XFCN (xdbetai, XDBETAI, (x, a, b, retval)); return retval; } Array<double> betainc (double x, double a, const Array<double>& b) { dim_vector dv = b.dims (); octave_idx_type nel = dv.numel (); Array<double> retval (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x, a, b(i)); return retval; } Array<double> betainc (double x, const Array<double>& a, double b) { dim_vector dv = a.dims (); octave_idx_type nel = dv.numel (); Array<double> retval (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x, a(i), b); return retval; } Array<double> betainc (double x, const Array<double>& a, const Array<double>& b) { Array<double> retval; dim_vector dv = a.dims (); if (dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x, a(i), b(i)); } else gripe_betainc_nonconformant (dim_vector (0, 0), dv, b.dims ()); return retval; } Array<double> betainc (const Array<double>& x, double a, double b) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); Array<double> retval (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a, b); return retval; } Array<double> betainc (const Array<double>& x, double a, const Array<double>& b) { Array<double> retval; dim_vector dv = x.dims (); if (dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a, b(i)); } else gripe_betainc_nonconformant (dv, dim_vector (0, 0), b.dims ()); return retval; } Array<double> betainc (const Array<double>& x, const Array<double>& a, double b) { Array<double> retval; dim_vector dv = x.dims (); if (dv == a.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a(i), b); } else gripe_betainc_nonconformant (dv, a.dims (), dim_vector (0, 0)); return retval; } Array<double> betainc (const Array<double>& x, const Array<double>& a, const Array<double>& b) { Array<double> retval; dim_vector dv = x.dims (); if (dv == a.dims () && dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a(i), b(i)); } else gripe_betainc_nonconformant (dv, a.dims (), b.dims ()); return retval; } float betainc (float x, float a, float b) { float retval; F77_XFCN (xbetai, XBETAI, (x, a, b, retval)); return retval; } Array<float> betainc (float x, float a, const Array<float>& b) { dim_vector dv = b.dims (); octave_idx_type nel = dv.numel (); Array<float> retval (dv); float *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x, a, b(i)); return retval; } Array<float> betainc (float x, const Array<float>& a, float b) { dim_vector dv = a.dims (); octave_idx_type nel = dv.numel (); Array<float> retval (dv); float *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x, a(i), b); return retval; } Array<float> betainc (float x, const Array<float>& a, const Array<float>& b) { Array<float> retval; dim_vector dv = a.dims (); if (dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); float *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x, a(i), b(i)); } else gripe_betainc_nonconformant (dim_vector (0, 0), dv, b.dims ()); return retval; } Array<float> betainc (const Array<float>& x, float a, float b) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); Array<float> retval (dv); float *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a, b); return retval; } Array<float> betainc (const Array<float>& x, float a, const Array<float>& b) { Array<float> retval; dim_vector dv = x.dims (); if (dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); float *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a, b(i)); } else gripe_betainc_nonconformant (dv, dim_vector (0, 0), b.dims ()); return retval; } Array<float> betainc (const Array<float>& x, const Array<float>& a, float b) { Array<float> retval; dim_vector dv = x.dims (); if (dv == a.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); float *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a(i), b); } else gripe_betainc_nonconformant (dv, a.dims (), dim_vector (0, 0)); return retval; } Array<float> betainc (const Array<float>& x, const Array<float>& a, const Array<float>& b) { Array<float> retval; dim_vector dv = x.dims (); if (dv == a.dims () && dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); float *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betainc (x(i), a(i), b(i)); } else gripe_betainc_nonconformant (dv, a.dims (), b.dims ()); return retval; } // FIXME -- there is still room for improvement here... double gammainc (double x, double a, bool& err) { double retval; err = false; if (a < 0.0 || x < 0.0) { (*current_liboctave_error_handler) ("gammainc: A and X must be non-negative"); err = true; } else F77_XFCN (xgammainc, XGAMMAINC, (a, x, retval)); return retval; } Matrix gammainc (double x, const Matrix& a) { octave_idx_type nr = a.rows (); octave_idx_type nc = a.cols (); Matrix result (nr, nc); Matrix retval; bool err; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { result(i,j) = gammainc (x, a(i,j), err); if (err) goto done; } retval = result; done: return retval; } Matrix gammainc (const Matrix& x, double a) { octave_idx_type nr = x.rows (); octave_idx_type nc = x.cols (); Matrix result (nr, nc); Matrix retval; bool err; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { result(i,j) = gammainc (x(i,j), a, err); if (err) goto done; } retval = result; done: return retval; } Matrix gammainc (const Matrix& x, const Matrix& a) { Matrix result; Matrix retval; octave_idx_type nr = x.rows (); octave_idx_type nc = x.cols (); octave_idx_type a_nr = a.rows (); octave_idx_type a_nc = a.cols (); if (nr == a_nr && nc == a_nc) { result.resize (nr, nc); bool err; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { result(i,j) = gammainc (x(i,j), a(i,j), err); if (err) goto done; } retval = result; } else (*current_liboctave_error_handler) ("gammainc: nonconformant arguments (arg 1 is %dx%d, arg 2 is %dx%d)", nr, nc, a_nr, a_nc); done: return retval; } NDArray gammainc (double x, const NDArray& a) { dim_vector dv = a.dims (); octave_idx_type nel = dv.numel (); NDArray retval; NDArray result (dv); bool err; for (octave_idx_type i = 0; i < nel; i++) { result (i) = gammainc (x, a(i), err); if (err) goto done; } retval = result; done: return retval; } NDArray gammainc (const NDArray& x, double a) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); NDArray retval; NDArray result (dv); bool err; for (octave_idx_type i = 0; i < nel; i++) { result (i) = gammainc (x(i), a, err); if (err) goto done; } retval = result; done: return retval; } NDArray gammainc (const NDArray& x, const NDArray& a) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); NDArray retval; NDArray result; if (dv == a.dims ()) { result.resize (dv); bool err; for (octave_idx_type i = 0; i < nel; i++) { result (i) = gammainc (x(i), a(i), err); if (err) goto done; } retval = result; } else { std::string x_str = dv.str (); std::string a_str = a.dims ().str (); (*current_liboctave_error_handler) ("gammainc: nonconformant arguments (arg 1 is %s, arg 2 is %s)", x_str.c_str (), a_str. c_str ()); } done: return retval; } float gammainc (float x, float a, bool& err) { float retval; err = false; if (a < 0.0 || x < 0.0) { (*current_liboctave_error_handler) ("gammainc: A and X must be non-negative"); err = true; } else F77_XFCN (xsgammainc, XSGAMMAINC, (a, x, retval)); return retval; } FloatMatrix gammainc (float x, const FloatMatrix& a) { octave_idx_type nr = a.rows (); octave_idx_type nc = a.cols (); FloatMatrix result (nr, nc); FloatMatrix retval; bool err; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { result(i,j) = gammainc (x, a(i,j), err); if (err) goto done; } retval = result; done: return retval; } FloatMatrix gammainc (const FloatMatrix& x, float a) { octave_idx_type nr = x.rows (); octave_idx_type nc = x.cols (); FloatMatrix result (nr, nc); FloatMatrix retval; bool err; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { result(i,j) = gammainc (x(i,j), a, err); if (err) goto done; } retval = result; done: return retval; } FloatMatrix gammainc (const FloatMatrix& x, const FloatMatrix& a) { FloatMatrix result; FloatMatrix retval; octave_idx_type nr = x.rows (); octave_idx_type nc = x.cols (); octave_idx_type a_nr = a.rows (); octave_idx_type a_nc = a.cols (); if (nr == a_nr && nc == a_nc) { result.resize (nr, nc); bool err; for (octave_idx_type j = 0; j < nc; j++) for (octave_idx_type i = 0; i < nr; i++) { result(i,j) = gammainc (x(i,j), a(i,j), err); if (err) goto done; } retval = result; } else (*current_liboctave_error_handler) ("gammainc: nonconformant arguments (arg 1 is %dx%d, arg 2 is %dx%d)", nr, nc, a_nr, a_nc); done: return retval; } FloatNDArray gammainc (float x, const FloatNDArray& a) { dim_vector dv = a.dims (); octave_idx_type nel = dv.numel (); FloatNDArray retval; FloatNDArray result (dv); bool err; for (octave_idx_type i = 0; i < nel; i++) { result (i) = gammainc (x, a(i), err); if (err) goto done; } retval = result; done: return retval; } FloatNDArray gammainc (const FloatNDArray& x, float a) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); FloatNDArray retval; FloatNDArray result (dv); bool err; for (octave_idx_type i = 0; i < nel; i++) { result (i) = gammainc (x(i), a, err); if (err) goto done; } retval = result; done: return retval; } FloatNDArray gammainc (const FloatNDArray& x, const FloatNDArray& a) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); FloatNDArray retval; FloatNDArray result; if (dv == a.dims ()) { result.resize (dv); bool err; for (octave_idx_type i = 0; i < nel; i++) { result (i) = gammainc (x(i), a(i), err); if (err) goto done; } retval = result; } else { std::string x_str = dv.str (); std::string a_str = a.dims ().str (); (*current_liboctave_error_handler) ("gammainc: nonconformant arguments (arg 1 is %s, arg 2 is %s)", x_str.c_str (), a_str.c_str ()); } done: return retval; } Complex rc_log1p (double x) { const double pi = 3.14159265358979323846; return x < -1.0 ? Complex (log (-(1.0 + x)), pi) : Complex (log1p (x)); } FloatComplex rc_log1p (float x) { const float pi = 3.14159265358979323846f; return x < -1.0f ? FloatComplex (logf (-(1.0f + x)), pi) : FloatComplex (log1pf (x)); } // This algorithm is due to P. J. Acklam. // See http://home.online.no/~pjacklam/notes/invnorm/ // The rational approximation has relative accuracy 1.15e-9 in the whole region. // For doubles, it is refined by a single step of Halley's 3rd order method. // For single precision, the accuracy is already OK, so we skip it to get // faster evaluation. static double do_erfinv (double x, bool refine) { // Coefficients of rational approximation. static const double a[] = { -2.806989788730439e+01, 1.562324844726888e+02, -1.951109208597547e+02, 9.783370457507161e+01, -2.168328665628878e+01, 1.772453852905383e+00 }; static const double b[] = { -5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01 }; static const double c[] = { -5.504751339936943e-03, -2.279687217114118e-01, -1.697592457770869e+00, -1.802933168781950e+00, 3.093354679843505e+00, 2.077595676404383e+00 }; static const double d[] = { 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00 }; static const double spi2 = 8.862269254527579e-01; // sqrt(pi)/2. static const double pbreak = 0.95150; double ax = fabs (x), y; // Select case. if (ax <= pbreak) { // Middle region. const double q = 0.5 * x, r = q*q; const double yn = (((((a[0]*r + a[1])*r + a[2])*r + a[3])*r + a[4])*r + a[5])*q; const double yd = ((((b[0]*r + b[1])*r + b[2])*r + b[3])*r + b[4])*r + 1.0; y = yn / yd; } else if (ax < 1.0) { // Tail region. const double q = sqrt (-2*log (0.5*(1-ax))); const double yn = ((((c[0]*q + c[1])*q + c[2])*q + c[3])*q + c[4])*q + c[5]; const double yd = (((d[0]*q + d[1])*q + d[2])*q + d[3])*q + 1.0; y = yn / yd * signum (-x); } else if (ax == 1.0) return octave_Inf * signum (x); else return octave_NaN; if (refine) { // One iteration of Halley's method gives full precision. double u = (erf (y) - x) * spi2 * exp (y*y); y -= u / (1 + y*u); } return y; } double erfinv (double x) { return do_erfinv (x, true); } float erfinv (float x) { return do_erfinv (x, false); } // The algorthim for erfcinv is an adaptation of the erfinv algorithm above // from P. J. Acklam. It has been modified to run over the different input // domain of erfcinv. See the notes for erfinv for an explanation. static double do_erfcinv (double x, bool refine) { // Coefficients of rational approximation. static const double a[] = { -2.806989788730439e+01, 1.562324844726888e+02, -1.951109208597547e+02, 9.783370457507161e+01, -2.168328665628878e+01, 1.772453852905383e+00 }; static const double b[] = { -5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01 }; static const double c[] = { -5.504751339936943e-03, -2.279687217114118e-01, -1.697592457770869e+00, -1.802933168781950e+00, 3.093354679843505e+00, 2.077595676404383e+00 }; static const double d[] = { 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00 }; static const double spi2 = 8.862269254527579e-01; // sqrt(pi)/2. static const double pbreak_lo = 0.04850; // 1-pbreak static const double pbreak_hi = 1.95150; // 1+pbreak double y; // Select case. if (x >= pbreak_lo && x <= pbreak_hi) { // Middle region. const double q = 0.5*(1-x), r = q*q; const double yn = (((((a[0]*r + a[1])*r + a[2])*r + a[3])*r + a[4])*r + a[5])*q; const double yd = ((((b[0]*r + b[1])*r + b[2])*r + b[3])*r + b[4])*r + 1.0; y = yn / yd; } else if (x > 0.0 && x < 2.0) { // Tail region. const double q = x < 1 ? sqrt (-2*log (0.5*x)) : sqrt (-2*log (0.5*(2-x))); const double yn = ((((c[0]*q + c[1])*q + c[2])*q + c[3])*q + c[4])*q + c[5]; const double yd = (((d[0]*q + d[1])*q + d[2])*q + d[3])*q + 1.0; y = yn / yd; if (x < pbreak_lo) y = -y; } else if (x == 0.0) return octave_Inf; else if (x == 2.0) return -octave_Inf; else return octave_NaN; if (refine) { // One iteration of Halley's method gives full precision. double u = (erf (y) - (1-x)) * spi2 * exp (y*y); y -= u / (1 + y*u); } return y; } double erfcinv (double x) { return do_erfcinv (x, true); } float erfcinv (float x) { return do_erfcinv (x, false); } // Implementation based on the Fortran code by W.J.Cody // see http://www.netlib.org/specfun/erf. // Templatized and simplified workflow. // FIXME: Maybe this should be globally visible. static inline float erfc (float x) { return erfcf (x); } template <class T> static T erfcx_impl (T x) { static const T c[] = { 5.64188496988670089e-1,8.88314979438837594, 6.61191906371416295e+1,2.98635138197400131e+2, 8.81952221241769090e+2,1.71204761263407058e+3, 2.05107837782607147e+3,1.23033935479799725e+3, 2.15311535474403846e-8 }; static const T d[] = { 1.57449261107098347e+1,1.17693950891312499e+2, 5.37181101862009858e+2,1.62138957456669019e+3, 3.29079923573345963e+3,4.36261909014324716e+3, 3.43936767414372164e+3,1.23033935480374942e+3 }; static const T p[] = { 3.05326634961232344e-1,3.60344899949804439e-1, 1.25781726111229246e-1,1.60837851487422766e-2, 6.58749161529837803e-4,1.63153871373020978e-2 }; static const T q[] = { 2.56852019228982242,1.87295284992346047, 5.27905102951428412e-1,6.05183413124413191e-2, 2.33520497626869185e-3 }; static const T sqrpi = 5.6418958354775628695e-1; static const T xhuge = sqrt (1.0 / std::numeric_limits<T>::epsilon ()); static const T xneg = -sqrt (log (std::numeric_limits<T>::max ()/2.0)); double y = fabs (x), result; if (x < xneg) result = octave_Inf; else if (y <= 0.46875) result = std::exp (x*x) * erfc (x); else { if (y <= 4.0) { double xnum = c[8]*y, xden = y; for (int i = 0; i < 7; i++) { xnum = (xnum + c[i]) * y; xden = (xden + d[i]) * y; } result = (xnum + c[7]) / (xden + d[7]); } else if (y <= xhuge) { double y2 = 1/(y*y), xnum = p[5]*y2, xden = y2; for (int i = 0; i < 4; i++) { xnum = (xnum + p[i]) * y2; xden = (xden + q[i]) * y2; } result = y2 * (xnum + p[4]) / (xden + q[4]); result = (sqrpi - result) / y; } else result = sqrpi / y; // Fix up negative argument. if (x < 0) { double y2 = ceil (x / 16.0) * 16.0, del = (x-y2)*(x+y2); result = 2*(std::exp (y2*y2) * std::exp (del)) - result; } } return result; } double erfcx (double x) { return erfcx_impl (x); } float erfcx (float x) { return erfcx_impl (x); } // // Incomplete Beta function ratio // // Algorithm based on the one by John Burkardt. // See http://people.sc.fsu.edu/~jburkardt/cpp_src/asa109/asa109.html // // The original code is distributed under the GNU LGPL v3 license. // // Reference: // // KL Majumder, GP Bhattacharjee, // Algorithm AS 63: // The incomplete Beta Integral, // Applied Statistics, // Volume 22, Number 3, 1973, pages 409-411. // double betain (double x, double p, double q, double beta, bool& err) { double acu = 0.1E-14, ai, cx; bool indx; int ns; double pp, psq, qq, rx, temp, term, value, xx; value = x; err = false; // Check the input arguments. if ((p <= 0.0 || q <= 0.0) || (x < 0.0 || 1.0 < x)) { err = true; return value; } // Special cases. if (x == 0.0 || x == 1.0) { return value; } // Change tail if necessary and determine S. psq = p + q; cx = 1.0 - x; if (p < psq * x) { xx = cx; cx = x; pp = q; qq = p; indx = true; } else { xx = x; pp = p; qq = q; indx = false; } term = 1.0; ai = 1.0; value = 1.0; ns = static_cast<int> (qq + cx * psq); // Use the Soper reduction formula. rx = xx / cx; temp = qq - ai; if (ns == 0) { rx = xx; } for ( ; ; ) { term = term * temp * rx / (pp + ai); value = value + term; temp = fabs (term); if (temp <= acu && temp <= acu * value) { value = value * exp (pp * log (xx) + (qq - 1.0) * log (cx) - beta) / pp; if (indx) { value = 1.0 - value; } break; } ai = ai + 1.0; ns = ns - 1; if (0 <= ns) { temp = qq - ai; if (ns == 0) { rx = xx; } } else { temp = psq; psq = psq + 1.0; } } return value; } // // Inverse of the incomplete Beta function // // Algorithm based on the one by John Burkardt. // See http://people.sc.fsu.edu/~jburkardt/cpp_src/asa109/asa109.html // // The original code is distributed under the GNU LGPL v3 license. // // Reference: // // GW Cran, KJ Martin, GE Thomas, // Remark AS R19 and Algorithm AS 109: // A Remark on Algorithms AS 63: The Incomplete Beta Integral // and AS 64: Inverse of the Incomplete Beta Integeral, // Applied Statistics, // Volume 26, Number 1, 1977, pages 111-114. // double betaincinv (double y, double p, double q) { double a, acu, adj, fpu, g, h; int iex; bool indx; double pp, prev, qq, r, s, sae = -37.0, sq, t, tx, value, w, xin, ycur, yprev; double beta = xlgamma (p) + xlgamma (q) - xlgamma (p + q); bool err = false; fpu = pow (10.0, sae); value = y; // Test for admissibility of parameters. if (p <= 0.0 || q <= 0.0) { (*current_liboctave_error_handler) ("betaincinv: wrong parameters"); } if (y < 0.0 || 1.0 < y) { (*current_liboctave_error_handler) ("betaincinv: wrong parameter Y"); } if (y == 0.0 || y == 1.0) { return value; } // Change tail if necessary. if (0.5 < y) { a = 1.0 - y; pp = q; qq = p; indx = true; } else { a = y; pp = p; qq = q; indx = false; } // Calculate the initial approximation. r = sqrt (- log (a * a)); ycur = r - (2.30753 + 0.27061 * r) / (1.0 + (0.99229 + 0.04481 * r) * r); if (1.0 < pp && 1.0 < qq) { r = (ycur * ycur - 3.0) / 6.0; s = 1.0 / (pp + pp - 1.0); t = 1.0 / (qq + qq - 1.0); h = 2.0 / (s + t); w = ycur * sqrt (h + r) / h - (t - s) * (r + 5.0 / 6.0 - 2.0 / (3.0 * h)); value = pp / (pp + qq * exp (w + w)); } else { r = qq + qq; t = 1.0 / (9.0 * qq); t = r * pow (1.0 - t + ycur * sqrt (t), 3); if (t <= 0.0) { value = 1.0 - exp ((log ((1.0 - a) * qq) + beta) / qq); } else { t = (4.0 * pp + r - 2.0) / t; if (t <= 1.0) { value = exp ((log (a * pp) + beta) / pp); } else { value = 1.0 - 2.0 / (t + 1.0); } } } // Solve for X by a modified Newton-Raphson method, // using the function BETAIN. r = 1.0 - pp; t = 1.0 - qq; yprev = 0.0; sq = 1.0; prev = 1.0; if (value < 0.0001) { value = 0.0001; } if (0.9999 < value) { value = 0.9999; } iex = std::max (- 5.0 / pp / pp - 1.0 / pow (a, 0.2) - 13.0, sae); acu = pow (10.0, iex); for ( ; ; ) { ycur = betain (value, pp, qq, beta, err); if (err) { return value; } xin = value; ycur = (ycur - a) * exp (beta + r * log (xin) + t * log (1.0 - xin)); if (ycur * yprev <= 0.0) { prev = std::max (sq, fpu); } g = 1.0; for ( ; ; ) { for ( ; ; ) { adj = g * ycur; sq = adj * adj; if (sq < prev) { tx = value - adj; if (0.0 <= tx && tx <= 1.0) { break; } } g = g / 3.0; } if (prev <= acu) { if (indx) { value = 1.0 - value; } return value; } if (ycur * ycur <= acu) { if (indx) { value = 1.0 - value; } return value; } if (tx != 0.0 && tx != 1.0) { break; } g = g / 3.0; } if (tx == value) { break; } value = tx; yprev = ycur; } if (indx) { value = 1.0 - value; } return value; } Array<double> betaincinv (double x, double a, const Array<double>& b) { dim_vector dv = b.dims (); octave_idx_type nel = dv.numel (); Array<double> retval (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betaincinv (x, a, b(i)); return retval; } Array<double> betaincinv (double x, const Array<double>& a, double b) { dim_vector dv = a.dims (); octave_idx_type nel = dv.numel (); Array<double> retval (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betaincinv (x, a(i), b); return retval; } Array<double> betaincinv (double x, const Array<double>& a, const Array<double>& b) { Array<double> retval; dim_vector dv = a.dims (); if (dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betaincinv (x, a(i), b(i)); } else gripe_betaincinv_nonconformant (dim_vector (0, 0), dv, b.dims ()); return retval; } Array<double> betaincinv (const Array<double>& x, double a, double b) { dim_vector dv = x.dims (); octave_idx_type nel = dv.numel (); Array<double> retval (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betaincinv (x(i), a, b); return retval; } Array<double> betaincinv (const Array<double>& x, double a, const Array<double>& b) { Array<double> retval; dim_vector dv = x.dims (); if (dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betaincinv (x(i), a, b(i)); } else gripe_betaincinv_nonconformant (dv, dim_vector (0, 0), b.dims ()); return retval; } Array<double> betaincinv (const Array<double>& x, const Array<double>& a, double b) { Array<double> retval; dim_vector dv = x.dims (); if (dv == a.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betaincinv (x(i), a(i), b); } else gripe_betaincinv_nonconformant (dv, a.dims (), dim_vector (0, 0)); return retval; } Array<double> betaincinv (const Array<double>& x, const Array<double>& a, const Array<double>& b) { Array<double> retval; dim_vector dv = x.dims (); if (dv == a.dims () && dv == b.dims ()) { octave_idx_type nel = dv.numel (); retval.resize (dv); double *pretval = retval.fortran_vec (); for (octave_idx_type i = 0; i < nel; i++) *pretval++ = betaincinv (x(i), a(i), b(i)); } else gripe_betaincinv_nonconformant (dv, a.dims (), b.dims ()); return retval; }