You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4158 lines
167 KiB
Fortran

!****************************************************************************
! if compilation complains about too many continuation lines extend it.
!
!
! modules: GLOBALDATA, QUAD, RIND71MOD Version 1.0
!
! Programs available in module RIND71MOD :
! (NB! the GLOBALDATA and QUAD module is also used to transport the inputs)
!
!
! SETDATA initializes global constants explicitly:
!
! CALL SETDATA(EPSS,REPS,EPS2,NIT,xCutOff,NINT,XSPLT)
!
! GLOBALDATA module :
! EPSS,CEPSS = 1.d0 - EPSS , controlling the accuracy of indicator function
! EPS2 = if conditional variance is less it is considered as zero
! i.e., the variable is considered deterministic
! xCutOff = 5 (standard deviations by default)
!
! QUAD module:
! Nint1(i) = quadrature formulae used in integration of Xd(i)
! implicitly determining # nodes
!
! INITDATA initializes global constants implicitly:
!
! CALL INITDATA (speed)
!
! speed = 1,2,...,9 (1=slowest and most accurate,9=fastest,
! but less accurate)
!
! see the GLOBALDATA and QUAD module for other constants and default values
!
!
!RIND71 computes E[Jacobian*Indicator|Condition]*f_{Xc}(xc(:,ix))
!
! where
! "Indicator" = I{ H_lo(i) < X(i) < H_up(i), i=1:Nt+Nd }
! "Jacobian" = J(X(Nt+1),...,X(Nt+Nd+Nc)), special case is
! "Jacobian" = |X(Nt+1)*...*X(Nt+Nd)|=|Xd(1)*Xd(2)..Xd(Nd)|
! "condition" = Xc=xc(:,ix), ix=1,...,Nx.
! X = [Xt; Xd ;Xc], a stochastic vector of Multivariate Gaussian
! variables where Xt,Xd and Xc have the length Nt, Nd and Nc,
! respectively.
! (Recommended limitations Nx, Nt<101, Nd<7 and NIT,Nc<11)
! (RIND = Random Integration N Dimensions)
!
!CALL RIND71(E,S,m,xc,indI,Blo,Bup,xcScale);
!
! E = expectation/density as explained above size 1 x Nx (out)
! S = Covariance matrix of X=[Xt;Xd;Xc] size N x N (N=Nt+Nd+Nc) (inout)
! NB!: out=conditional sorted Covariance matrix
! m = the expectation of X=[Xt;Xd;Xc] size N x 1 (in)
! xc = values to condition on size Nc x Nx (in)
! indI = vector of indices to the different barriers in the (in)
! indicator function, length NI, where NI = Nb+1
! (NB! restriction indI(1)=0, indI(NI)=Nt+Nd )
!Blo,Bup = Lower and upper barrier coefficients used to compute the (in)
! integration limits Hlo and Hup, respectively.
! size Mb x Nb. If Mb<Nc+1 then
! Blo(Mb+1:Nc+1,:) is assumed to be zero. The relation
! to the integration limits Hlo and Hup are as follows
!
! Hlo(i)=Blo(1,j)+Blo(2:Mb,j).'*xc(1:Mb-1,ix),
! Hup(i)=Bup(1,j)+Bup(2:Mb,j).'*xc(1:Mb-1,ix),
!
! where i=indI(j-1)+1:indI(j), j=2:NI, ix=1:Nx
! Thus the integration limits may change with the conditional
! variables See example below.
! xcScale = REAL to scale the conditinal probability density, i.e.,
! f_{Xc} = exp(-0.5*Xc*inv(Sxc)*Xc + XcScale) (Optional, default XcScale =0)
!
!Example:
! The indices, indI=[0 3 5], and coefficients Blo=[-inf 0], Bup=[0 inf]
! gives Hlo = [-inf -inf -inf 0 0] Hup = [0 0 0 inf inf]
!
! The GLOBALDATA and QUAD modules are used to transport the inputs:
! SCIS = 0 Integrate by Gauss-Legendre quadrature (default) (Podgorski et al. 1999)
! 1 Integrate by SADAPT for Ndim<9 and by KRBVRC otherwise
! 2 Integrate by SADAPT for Ndim<19 and by KRBVRC otherwise
! 3 Integrate by KRBVRC by Genz (1993) (Fast Ndim<101)
! 4 Integrate by KROBOV by Genz (1992) (Fast Ndim<101)
! 5 Integrate by RCRUDE by Genz (1992) (Slow Ndim<1001)
! 6 Integrate by SOBNIED (Fast Ndim<1041)
! 7 Integrate by DKBVRC by Genz (2003) (Fast Ndim<1001)
! NIT = 0,1,2..., maximum # of iterations/integrations done by quadrature
! to calculate the indicator function (default NIT=2)
! NB! the size information below must be set before calling RINDD
! Nx = # different xc
! Nt = length of Xt
! Nd = length of Xd
! Nc = length of Xc
! Ntd = Nt+Nd
! Ntdc = Nt+Nd+Nc
! Mb
! NI
! Nj = # of variables in indicator integrated directly like the
! variables in the jacobian (default 0)
! The order of integration between Xd and Nj of Xt is done in
! decreasing order of conditional variance.
! Njj = # of variables in indicator integrated directly like the
! variables in the jacobian (default 0)
! The Njj variables of Xt is integrated after Xd and Nj of Xt
! also in decreasing order of conditional variance. (Not implemented yet)
!
! (Recommended limitations Nx,Nt<101, Nd<7 and NIT,Nc<11)
!
! if SCIS > 0 then you must initialize the random generator before you
! call rindd by the following lines:
!
! call random_seed(SIZE=seed_size)
! allocate(seed(seed_size))
! call random_seed(GET=seed(1:seed_size)) ! get current seed
! seed(1)=seed1 ! change seed
! call random_seed(PUT=seed(1:seed_size))
! deallocate(seed)
!
! For further description see the modules
!
!
! References
! Podgorski et. al. (1999)
! "Exact distributions for apparent waves in irregular seas"
! Ocean Engineering (RINDXXX)
!
! R. Ambartzumian, A. Der Kiureghian, V. Ohanian and H.
! Sukiasian (1998)
! "Multinormal probabilities by sequential conditioned
! importance sampling: theory and application" (RINDSCIS, MNORMPRB,MVNFUN,MVNFUN2)
! Probabilistic Engineering Mechanics, Vol. 13, No 4. pp 299-308
!
! Alan Genz (1992)
! 'Numerical Computation of Multivariate Normal Probabilites'
! J. computational Graphical Statistics, Vol.1, pp 141--149
!
! William H. Press, Saul Teukolsky,
! William T. Wetterling and Brian P. Flannery (1997)
! "Numerical recipes in Fortran 77", Vol. 1, pp 55-63, 299--305 (SVDCMP,SOBSEQ)
!
! Igor Rychlik and Georg Lindgren (1993)
! "Crossreg - A technique for first passage and wave density analysis" (RINDXXX)
! Probability in the Engineering and informational Sciences,
! Vol 7, pp 125--148
!
! Igor Rychlik (1992)
! "Confidence bands for linear regressions" (RIND2,RINDNIT)
! Commun. Statist. -simula., Vol 21,No 2, pp 333--352
!
!
! Donald E. Knuth (1973) "The art of computer programming,",
! Vol. 3, pp 84- (sorting and searching) (SORTRE)
! Tested on: DIGITAL UNIX Fortran90 compiler
! PC pentium II with Lahey Fortran90 compiler
! Solaris with SunSoft F90 compiler Version 1.0.1.0 (21229283)
! History:
! revised pab aug 2009
! -moved c1c2 to c1c2mod
! -removed rateLHD, useMIDP, FxCutOff, CFxCutOff from globaldata module
! revised pab July 2007
! -reordered integration methods (SCIS)
! revised pab 9 may 2004
! removed xcutoff2
! introduced XcScale to rindd
! revised pab 17.02.2003
! -new name rind71
! commented out all print statements
! revised pab 08.02.2001
! - New name rind70.f
! - moved the jacob function to a separate module.
! - jacobdef in module GLOBALDATA is now obsolete.
! revised pab 19.01.2001
! - added a NEW BVU function
! revised pab 06.11.2000
! - added checks in condsort2, condsort3, condsort4 telling if the matrix is
! negative definit
! - changed the order of SCIS integration again.
! revised pab 07.09.2000
! - To many continuation lines in QUAD module =>
! broke them up and changed PARAMETER statements into DATA
! statements instead.
! revised pab 22.05.2000
! - changed order of SCIS integration: moved the less important SCIS
! revised pab 19.04.2000
! - found a bug in THL when L<-1, now fixed
! revised pab 18.04.2000
! new name rind60
! New assumption of BIG for the conditional sorted variables:
! BIG(I,I)=sqrt(Var(X(I)|X(I+1)...X(N))=SQI
! BIG(1:I-1,I)=COV(X(1:I-1),X(I)|X(I+1)...X(N))/SQI
! Otherwise
! BIG(I,I) = Var(X(I)|X(I+1)...X(N)
! BIG(1:I-1,I)=COV(X(1:I-1),X(I)|X(I+1)...X(N))
! This also affects C1C2: SQ0=sqrt(Var(X(I)|X(I+1)...X(N)) is removed from input
! => A lot of wasteful divisions are avoided
! revised pab 23.03.2000
! - done some optimization in initdata
! - added some things in THL + optimized THL
! - fixed a bug in condsort and condsort0 when Nd+Nj=0
! revised pab 20.03.2000
! - new name rind57
! - added condsort0 and condsort4 which sort the covariance matrix using the shortest
! expected integration interval => integration time is much shorter for all methods.
! condsort and condsort3 sort by decreasing conditional variance
! revised pab 17.03.2000
! - changed argp0 so that I0 and I1 really are the indices to the minimum and the second minimum
! - changed rindnit so that norm2dprb is called whenever NITL<1 and Nsnew>=2
! - changed default parameters for initdata for speed=7,8 and 9 to increase accuracy.
! - Changed so that xCutOff varies with speed => program is much faster without loosing any accuracy it seems
! revised pab 15.03.2000
! - changed rindscis and mnormprb: moved the actual multidimensional integration
! into separate module, rcrudemod.f (as a consequence SVDCMP,PYTHAG and SORTRE
! are also moved into this module) => made the structure of the program simpler
! - added the possibility to use adapt, krbvrc, krobov and ranmc to integrate
! - Set NUGGET to 0 when Nc=0, since it is no longer needed
! - added the module MVNFUNDATA
! revised pab 03.03.2000
! - BIG are no longer changed when called by RINDD instead it is copied into a new variable
! - new name rind55.f
! - fixed the bug in THL, i.e. THL forgot to return a value in some cases giving floating invalid
!revised by I.R. 27.01.2000, Removed bugs in RINDNIT (There where some returns
! without deallocating some variables. A misco error in THL, leading
! to floating invalid on alpha has been repaired by seting value=zero.
! Probably there is an error somehere making variable "value" to behave badly.
!Revised by IR. 03.01.2000 Bug in C1C2 fixed and deallocation of ind in RINDNIT.
!revised by I.R. 27.12.1999, New name RIND51.f
! I have changed assumption about deterministic variables. Those have now
! variances equal EPS2 not zero and have consequences for C1C2 and on some
! places in RINDND. The effect is that barriers becomes fuzzy (not sharp)
! and prevents for discountinuities due to numerical errors of order 1E-16.
! The program RIND0 is removed making the structure of program simpler.
! We have still a problem when variables in indicator become
! deterministic before conditioning on derivatives in Xd - it needs to be solved.
!revised by Igor Rychlik 01.12.1999 New name RIND49.f
! - changed RINDNIT and ARGP0 in order to exclude
! irrelevant variables (such that probability of beeing
! between barriers is 1.) All computations related to NIT
! are moved to RINDNIT (removing RIND2,RIND3). This caused some changes
! in RIND0,RINDDND. Furthermore RINDD1 is removed and moved
! some parts of it to RINDDND. This made program few seconds slower. The lower
! bound in older ARGP0 programs contained logical error - corrected.
!revised by Per A. Brodtkorb 08.11.1999
! - fixed a bug in rinddnd
! new line: CmNew(Nst+1:Nsd-1)= Cm(Nst+1:Nsd-1)
!revised by Per A. Brodtkorb 28.10.1999
! - fixed a bug in rinddnd
! - changed rindscis, mnormprb
! - added MVNFUN, MVNFUN2
! - replaced CVaccept with RelEps
!revised by Per A. Brodtkorb 27.10.1999
! - changed NINT to NINT1 due to naming conflict with an intrinsic of the same name
!revised by Per A. Brodtkorb 25.10.1999
! - added an alternative FIINV for use in rindscis and mnormprb
!revised by Per A. Brodtkorb 13.10.1999
! - added useMIDP for use in rindscis and mnormprb
!
!revised by Per A. Brodtkorb 22.09.1999
! - removed all underscore letters due to
! problems with SunSoft F90 compiler
! (i.e. changed GLOBAL_DATA to GLOBALDATA etc.)
!revised by Per A. Brodtkorb 09.09.1999
! - added sobseq: Sobol sequence (quasi random numbers)
! an alternative to random_number in RINDSCIS and mnormprb
!revised by Per A. Brodtkorb 07.09.1999
! - added pythag,svdcmp,sortre
! - added RINDSCIS: evaluating multinormal integrals by SCIS
! condsort3: prepares BIG for use with RINDSCIS and mnormprb
!revised by Per A. Brodtkorb 03.09.1999
! - added mnormprb: evaluating multinormal probabilities by SCIS
! See globaldata for SCIS
! revised by Per A. Brodtkorb 01.09.1999
! - increased the default NUGGET from 1.d-12 to 1.d-8
! - also set NUGGET depending on speed in INITDATA
! revised by Per A. Brodtkorb 27.08.1999
! - changed rindnit,rind2:
! enabled option to do the integration faster/(smarter?).
! See GLOBALDATA for XSPLT
! revised by Per A. Brodtkorb 17.08.1999
! - added THL, norm2dprb not taken in to use
! due to some mysterious floating invalid
! occuring from time to time in norm2dprb (on DIGITAL unix)
! revised by Per A. Brodtkorb 02.08.1999
! - updated condsort
! - enabled the use of C1C2 in rinddnd
! revised by Per A. Brodtkorb 14.05.1999
! - updated to fortran90
! - enabled recursive calls
! - No limitations on size of the inputs
! - fixed some bugs
! - added some additonal checks
! - added Hermite, Laguerre quadratures for alternative integration
! - rewritten CONDSORT, conditional covariance matrix in upper
! triangular.
! - RINDXXX routines only work on the upper triangular
! of the covariance matrix
! - Added a Nugget effect to the covariance matrix in order
! to ensure the conditioning is not corrupted by numerical errors
! - added the option to condsort Nj variables of Xt, i.e.,
! enabling direct integration like the integration of Xd
! by Igor Rychlik 29.10.1998 (PROGRAM RIND11 --- Version 1.0)
! which was a revision of program RIND from 3.9.1993 - the program that
! is used in wave_t and wave_t2 programs.
!*********************************************************************
MODULE GLOBALDATA
IMPLICIT NONE
! Constants determining accuracy of integration
!-----------------------------------------------
!if the conditional variance are less than:
DOUBLE PRECISION :: EPS2=1.d-4 !- EPS2, the variable is
! considered deterministic
DOUBLE PRECISION :: EPS = 1.d-2 ! SQRT(EPS2)
DOUBLE PRECISION :: XCEPS2=1.d-16 ! if Var(Xc) is less return NaN
DOUBLE PRECISION :: EPSS = 5.d-5 ! accuracy of Indicator
DOUBLE PRECISION :: CEPSS=0.99995 ! accuracy of Indicator
DOUBLE PRECISION :: EPS0 = 5.d-5 ! used in GAUSSLE1 to implicitly
! determ. # nodes
DOUBLE PRECISION :: xcScale=0.d0
DOUBLE PRECISION :: fxcEpss=1.d-20 ! if less do not compute E(...|Xc)
DOUBLE PRECISION :: xCutOff=5.d0 ! upper/lower truncation limit of the
! normal CDF
! Nugget>0: Adds a small value to diagonal
! elements of the covariance matrix to ensure
! that the inversion is not corrupted by
! round off errors.
! Good choice might be 1e-8
DOUBLE PRECISION :: NUGGET=1.d-8 ! Obs NUGGET must be smaller then EPS2
!parameters controlling the performance of RINDSCIS and MNORMPRB:
INTEGER :: SCIS=0 !=0 integr. all by quadrature
!=1 Integrate all by SADAPT for Ndim<9 and by KRBVRC otherwise
!=2 Integrate all by SADAPT for Ndim<9 and by KROBOV otherwise
!=3 Integrate all by KRBVRC (Fast and reliable)
!=4 Integrate all by KROBOV (Fast and reliable)
!=5 Integrate all by RCRUDE (Reliable)
!=6 Integrate all by SOBNIED (NDIM<1041)
!=7 Integrate all by DKBVRC (Ndim<1001)
INTEGER :: NSIMmax = 1000 ! maximum number of simulations per stochastic dimension
INTEGER :: NSIMmin = 10 ! minimum number of simulations per stochastic dimension
INTEGER :: Ntscis = 0 ! Ntscis=Nt-Nj-Njj when SCIS>0 otherwise Ntscis=0
DOUBLE PRECISION :: RelEps = 0.001 ! Relative error, i.e. if
! 3.0*STD(XIND)/XIND is less we accept the estimate
! The following may be allocated outside RINDD
! if one wants the coefficient of variation, i.e.
! STDEV(XIND)/XIND when SCIS=2. (NB: size Nx)
DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: COV
integer :: COVix ! counting variable for COV
LOGICAL,PARAMETER :: useC1C2=.true. ! use C1C2 in rindscis,mnormprb
LOGICAL,PARAMETER :: C1C2det=.true. ! use C1C2 only on the variables that becomes
! deterministic after conditioning on X(N)
! used in rinddnd rindd1 and rindscis mnormprb
!parameters controlling performance of quadrature integration:
! if Hup>=xCutOff AND Hlo<-XSPLT OR
! Hup>=XSPLT AND Hl0<=-xCutOff then
! do a different integration to increase speed
! in rind2 and rindnit. This give slightly different
! results
! DEFAULT 5 =xCutOff => do the same integration allways
! However, a resonable value is XSPLT=1.5
DOUBLE PRECISION :: XSPLT = 5.d0 ! DEFAULT XSPLT= 5 =xCutOff
! weight between upper&lower limit returned by ARGP0
DOUBLE PRECISION, PARAMETER :: Plowgth=0.d0 ! 0 => no weight to
! lower limit
INTEGER :: NIT=2 ! NIT=maximum # of iterations/integrations by
! quadrature used to calculate the indicator function
! size information of the covariance matrix BIG
! Nt,Nd,....Ntd,Nx must be set before calling
! RINDD. NsXtmj, NsXdj is set in RINDD
INTEGER :: Nt,Nd,Nc,Ntdc,Ntd,Nx
! Constants determines how integration is done
INTEGER :: Nj=0,Njj=0 ! Njj is not implemented yet
! size information of indI, Blo,Bup
! Blo/Bup size Mb x NI-1
! indI vector of length NI
INTEGER :: NI,Mb ! must be set before calling RINDD
! The following is allocated in RINDD
DOUBLE PRECISION, DIMENSION(:,:), ALLOCATABLE :: SQ
DOUBLE PRECISION, DIMENSION(:), ALLOCATABLE :: Hlo,Hup
INTEGER, DIMENSION(:), ALLOCATABLE :: index1,xedni,indXtd
INTEGER, DIMENSION(:), ALLOCATABLE :: NsXtmj, NsXdj
! global constants
DOUBLE PRECISION, PARAMETER :: SQTWOPI1=3.9894228040143d-1 !=1/sqrt(2*pi)
DOUBLE PRECISION, PARAMETER :: SQPI1=5.6418958354776d-1 !=1/sqrt(pi)
DOUBLE PRECISION, PARAMETER :: SQPI= 1.77245385090552d0 !=sqrt(pi)
DOUBLE PRECISION, PARAMETER :: SQTWO=1.41421356237310d0 !=sqrt(2)
DOUBLE PRECISION, PARAMETER :: SQTWO1=0.70710678118655d0 !=1/sqrt(2)
DOUBLE PRECISION, PARAMETER :: PI1=0.31830988618379d0 !=1/pi
DOUBLE PRECISION, PARAMETER :: PI= 3.14159265358979D0 !=pi
DOUBLE PRECISION, PARAMETER :: TWOPI=6.28318530717958D0 !=2*pi
END MODULE GLOBALDATA
MODULE C1C2MOD
IMPLICIT NONE
INTERFACE C1C2
MODULE PROCEDURE C1C2
END INTERFACE
CONTAINS
SUBROUTINE C1C2(C1, C2, Cm, B1, SQ, ind)
! The regression equation for the conditional distr. of Y given X=x
! is equal to the conditional expectation of Y given X=x, i.e.,
!
! E(Y|X=x)=E(Y)+Cov(Y,X)/Var(X)[x-E(X)]
!
! Let x1=(x-E(X))/SQRT(Var(X)) be zero mean, C1<x1<C2, B1(I)=COV(Y(I),X)/SQRT(Var(X)).
! Then the process Y(I) with mean Cm(I) can be written as
!
! y(I)=Cm(I)+x1*B1(I)+Delta(I) for I=1,...,N.
!
! where SQ(I)=sqrt(Var(Y|X)) is the standard deviation of Delta(I).
!
! Since we are truncating all Gaussian variables to
! the interval [-C,C], then if for any I
!
! a) Cm(I)+x1*B1(I)-C*SQ(I)>Hup(I) or
!
! b) Cm(I)+x1*B1(I)+C*SQ(I)<Hlo(I) then
!
! (XIND|X1=x1) = 0 !!!!!!!!!
!
! Consequently, for increasing the accuracy (by excluding possible
! discontinuouities) we shall exclude such values for which (XIND|X1=x1) = 0.
! Hence we assume that if C1<x<C2 any of the previous conditions are
! satisfied
!
! OBSERVE!!, C1, C2 has to be set to (the normalized) lower and upper bounds
! of possible values for x1,respectively, i.e.,
! C1=max((Hlo-E(X))/SQRT(Var(X)),-C), C2=min((Hup-E(X))/SQRT(Var(X)),C)
! before calling C1C2 subroutine.
!
USE GLOBALDATA, ONLY : Hup,Hlo,xCutOff,EPS2,EPS
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:), INTENT(in) :: Cm, B1, SQ
INTEGER, DIMENSION(:), INTENT(in) :: ind
DOUBLE PRECISION, INTENT(inout) :: C1,C2
! local variables
DOUBLE PRECISION :: CC1, CC2,CSQ,HHup,HHlo,BdSQ0
INTEGER :: N,I,I0 !,changedLimits=0
!ind contains indices to the varibles
!location in Hlo and Hup
IF (C1.GE.C2) GO TO 112
N = SIZE(ind)
IF (N.LT.1) RETURN !Not able to change integration limits
DO I = N,1,-1 ! C=xCutOff
CSQ = xCutOff*SQ(I)
I0 = ind(I)
HHup = Hup (I0) - Cm (I)
HHlo = Hlo (I0) - Cm (I)
! If ABS(B1(I)) < EPS2 overflow may occur
! and hence if
! 1) Cm(I) is so large or small so we can
! surely assume that the probability
! of staying between the barriers is 0,
! consequently C1=C2=0
BdSQ0 = B1 (I)
!print *,'C1C1',C1,C2
!print *,'I,HHup,HHlo,Bdsq0',I,HHup,HHlo,BdsQ0,CSQ
IF (ABS (BdSQ0 ) .LT.EPS2 ) THEN
IF (SQ(I).LT.EPS2) CSQ= xCutOff*EPS
IF (HHlo.GT.CSQ.OR.HHup.LT. - CSQ) THEN
! print *,'C1C2:', I,BdSQ0,CSQ,HHlo,HHup, xCutOff*SQ(I) !changedLimits=1
GOTO 112
ENDIF
ELSE ! In other cases this part follows
! from the description of the problem.
! IF (CSQ.GT.0) PRINT *,'c1c2:', I,BdSQ0,CSQ,HHlo,HHup, SQ(I)
IF (BdSQ0.LT.0.d0) THEN
CC2 = (HHlo - CSQ) / BdSQ0
CC1 = (HHup + CSQ) / BdSQ0
ELSE ! BdSQ0>0
CC1 = (HHlo - CSQ) / BdSQ0
CC2 = (HHup + CSQ) / BdSQ0
ENDIF
IF (C1.LT.CC1) THEN
C1 = CC1 !changedLimits=1
IF (C2.GT.CC2) C2 = CC2
IF (C1.GE.C2) GO TO 112
ELSEIF (C2.GT.CC2) THEN
C2 = CC2 !changedLimits=1
IF (C1.GE.C2) GO TO 112
END IF
ENDIF
END DO
!IF (changedLimits.EQ.1) THEN
! PRINT *,'C1C2=',C1,C2
!END IF
RETURN
112 continue
C1 = -2D0*xCutOff
C2 = -2D0*xCutOff
RETURN
END SUBROUTINE C1C2
END MODULE C1C2MOD
!**************************************
MODULE FUNCMOD
! FUNCTION module containing constants transfeered to mvnfun and mvnfun2
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), ALLOCATABLE :: BIG
DOUBLE PRECISION, DIMENSION(: ), ALLOCATABLE :: Cm,CmN,xd,xc
DOUBLE PRECISION :: Pl1,Pu1
INTERFACE MVNFUN
MODULE PROCEDURE MVNFUN
END INTERFACE
INTERFACE MVNFUN2
MODULE PROCEDURE MVNFUN2
END INTERFACE
CONTAINS
function MVNFUN(Ndim,W) RESULT (XIND)
USE FIMOD
USE C1C2MOD
USE JACOBMOD
USE GLOBALDATA, ONLY : Hlo,Hup,xCutOff,Nt,Nd,Nj,Ntd,SQ,
& NsXtmj, NsXdj,indXtd,index1,useC1C2,C1C2det,EPS2
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: W
INTEGER, INTENT(in) :: Ndim
DOUBLE PRECISION :: XIND
!local variables
DOUBLE PRECISION :: Pl,Pu
DOUBLE PRECISION :: X,Y,XMI,XMA,SQ0
INTEGER :: Nst,NstN,NsdN,Nst0,Nsd,Nsd0,K
INTEGER :: Ndleft,Ndjleft,Ntmj
!MVNFUN Multivariate Normal integrand function
! where the integrand is transformed from an integral
! having integration limits Hl0 and Hup to an
! integral having constant integration limits i.e.
! Hup 1
! int jacob(xd,xc)*f(xd,xt)dxt dxd = int F2(W) dW
!Hlo 0
!
! W - new transformed integration variables, valid range 0..1
! The vector must have the length Ndim=Nst0+Ntd-Nsd0
! BIG - conditional sorted covariance matrix (IN)
! Cm = conditional mean of Xd and Xt given Xc, E(Xd,Xt|Xc)
! CmN - local conditional mean
! xd - variables to the jacobian variable, need no initialization
! xc - conditional variables (IN)
! Pl1 = FI(XMI) for the first integration variable (IN)
! Pu1 = FI(XMA) ------||-------------------------------
! print *,'MVNFUN, ndim', ndim, shape(W)
CmN(1:Ntd) = Cm(1:Ntd) ! initialize conditional mean
Nst = NsXtmj(Ntd+1) ! index to last stoch variable of Xt before conditioning on X(Ntd)
Ntmj=Nt-Nj
Nsd0=NsXdj(1)
if (Nt.gt.Nj) then
Nst0=NsXtmj(Ntmj)
else
Nst0=0
endif
Pl=Pl1
Pu=Pu1
! IF (NDIM.LT.Nst0+Ntd-Nsd0+1) PRINT *, 'MVNFUN NDIM,',NDIM
Y=Pu-Pl
if (Nd+Nj.EQ.0) then
SQ0=SQ(1,1)
goto 200
endif
Ndjleft=Nd+Nj
Nsd = NsXdj(Ndjleft+1) ! index to last stoch variable of Xd and Nj of Xt before conditioning on X(Ntd)
Ndleft=Nd
SQ0=SQ(Ntd,Ntd)
!print *,'mvnfun,nst,nsd,nd,nj',nst,nsd,Nd,Nj
!print *,'mvn start K loop'
DO K=Ntd-1,Nsd0,-1
X=FIINV(Pl+W(Ntd-K)*(Pu-Pl))
IF (index1(K+1).GT.Nt) THEN ! isXd
xd (Ndleft) = CmN(K+1)+X*SQ0
Ndleft=Ndleft-1
END IF
Nst = NsXtmj(K+1) ! # stoch. var. of Xt before conditioning on X(K)
if (Nst.GT.0) CmN(1:Nst) =CmN(1:Nst)+X*BIG(1:Nst,K+1) !/SQ0
CmN(Nsd:K) =CmN(Nsd:K)+X*BIG(Nsd:K,K+1) !/SQ0
Ndjleft = Ndjleft-1
Nsd = NsXdj(Ndjleft+1)
SQ0 = SQ(K,K)
XMA = (Hup (K)-CmN(K))/SQ0
XMI = (Hlo (K)-CmN(K))/SQ0
if (useC1C2) then ! see if we can narrow down sampling range
XMI=max(XMI,-xCutOff)
XMA=min(XMA,xCutOff)
if (C1C2det) then
NsdN = NsXdj(Ndjleft)
NstN = NsXtmj(K)
CALL C1C2(XMI,XMA,CmN(Nsd:NsdN-1),
& BIG(Nsd:NsdN-1,K),SQ(Nsd:NsdN-1,K),
& indXtd(Nsd:NsdN-1))
CALL C1C2(XMI,XMA,CmN(NstN+1:Nst),
& BIG(NstN+1:Nst,K),SQ(NstN+1:Nst,K),
& indXtd(NstN+1:Nst))
else
CALL C1C2(XMI,XMA,CmN(Nsd:K-1),BIG(Nsd:K-1,K),
& SQ(Nsd:K-1,Ntmj+Ndjleft),indXtd(Nsd:K-1))
CALL C1C2(XMI,XMA,CmN(1:Nst),BIG(1:Nst,K)
& ,SQ(1:Nst,Ntmj+Ndjleft),indXtd(1:Nst))
endif
IF (XMA.LE.XMI) goto 260
endif
Pl = FI(XMI)
Pu = FI(XMA)
Y=Y*(Pu-Pl)
ENDDO ! K LOOP
X = FIINV(Pl+W(Ntd-Nsd0+1)*(Pu-Pl))
Nst = NsXtmj(Nsd0) ! # stoch. var. of Xt after conditioning on X(Nsd0)
! and before conditioning on X(1)
! CmN(1:Nst)=CmN(1:Nst)+X*BIG(1:Nst,Nsd0) !/SQ0)
if (Nd.gt.0) then
CmN(Nsd:Nsd0-1) = CmN(Nsd:Nsd0-1)+X*BIG(Nsd:Nsd0-1,Nsd0) !/SQ0
if (Ndleft.gt.0) then
if (index1(Nsd0).GT.Nt) then
xd (Ndleft) = CmN(Nsd0)+X*SQ0
Ndleft=Ndleft-1
endif
K=Nsd0-1
do while (Ndleft.gt.0)
if ((index1(K).GT.Nt)) THEN ! isXd
xd (Ndleft) = CmN(K)
Ndleft=Ndleft-1
END IF
K=K-1
ENDDO
endif ! Ndleft
Y = Y*jacob ( xd,xc) ! jacobian of xd,xc
endif ! Nd>0
if (Nst0.gt.0) then
CmN(1:Nst)=CmN(1:Nst)+X*BIG(1:Nst,Nsd0) !/SQ0)
SQ0 = SQ(1,1)
XMA = MIN((Hup (1)-CmN(1))/SQ0,xCutOff)
XMI = MAX((Hlo (1)-CmN(1))/SQ0,-xCutOff)
if (C1C2det) then
NstN = NsXtmj(1) ! # stoch. var. after conditioning
CALL C1C2(XMI,XMA,CmN(NstN+1:Nst),
& BIG(1,NstN+1:Nst),SQ(NstN+1:Nst,1),
& indXtd(NstN+1:Nst))
else
CALL C1C2(XMI,XMA,CmN(2:Nst),BIG(1,2:Nst),
& SQ(2:Nst,1),indXtd(2:Nst))
endif
IF (XMA.LE.XMI) GO TO 260
Pl = FI(XMI)
Pu = FI(XMA)
Y = Y*(Pu-Pl)
endif
!if (COVix.gt.2) then
!print *,' mvnfun start K2 loop'
!endif
200 do K = 2,Nst0
X = FIINV(Pl+W(Ntd-Nsd0+K)*(Pu-Pl))
Nst = NsXtmj(K-1) ! index to last stoch. var. before conditioning on X(K)
CmN(K:Nst)=CmN(K:Nst)+X*BIG(K-1,K:Nst) !/SQ0
SQ0 = SQ(K,K)
XMA = MIN((Hup (K)-CmN(K))/SQ0,xCutOff)
XMI = MAX((Hlo (K)-CmN(K))/SQ0,-xCutOff)
if (C1C2det) then
NstN = NsXtmj(K) ! index to last stoch. var. after conditioning X(K)
CALL C1C2(XMI,XMA,CmN(NstN+1:Nst),
& BIG(K,NstN+1:Nst),SQ(NstN+1:Nst,K),
& indXtd(NstN+1:Nst))
else
CALL C1C2(XMI,XMA,CmN(K+1:Nst),BIG(K,K+1:Nst),
& SQ(K+1:Nst,K),indXtd(K+1:Nst))
endif
IF (XMA.LE.XMI) GO TO 260
Pl = FI(XMI)
Pu = FI(XMA)
Y=Y*(Pu-Pl)
enddo ! K loop
XIND = Y
RETURN
260 XIND = 0.D0
!if (Y.LT.0.d0) PRINT *,'MVNFUN NEGATIVE INTEGRAND'
!print *,' mvnfun leaving'
return
END FUNCTION MVNFUN
function MVNFUN2(Ndim,W) RESULT (XIND)
USE FIMOD
USE C1C2MOD
USE GLOBALDATA, ONLY : Hlo,Hup,xCutOff,Njj,Nj,Ntscis,Ntd,SQ,
& NsXtmj, NsXdj,indXtd,index1,useC1C2,C1C2det,Nt,EPS2
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: W
INTEGER, INTENT(in) :: Ndim
DOUBLE PRECISION :: XIND
!local variables
DOUBLE PRECISION :: Pl,Pu
DOUBLE PRECISION :: X,Y,XMI,XMA,SQ0
INTEGER :: Nst,NstN,Nst0,K
!MVNFUN2 Multivariate Normal integrand function
! where the integrand is transformed from an integral
! having integration limits Hl0 and Hup to an
! integral having constant integration limits i.e.
! Hup 1
! int f(xt)dxt = int F2(W) dW
!Hlo 0
!
! W - new transformed integration variables, valid range 0..1
! The vector must have the size Nst0
! BIG - conditional sorted covariance matrix (IN)
! CmN - Local conditional mean
! Cm = Conditional mean E(Xt,Xd|Xc)
! Pl1 = FI(XMI) for the first integration variable
! Pu1 = FI(XMA) ------||-------------------------
!print *,'MVNFUN2, ndim', ndim, shape(W)
Nst0 = NsXtmj(Njj+Ntscis)
if (Njj.GT.0) then
Nst = NsXtmj(Njj)
else
Nst = NsXtmj(Ntscis+1)
endif
! IF (NDIM.LT.Nst0+Njj) PRINT *, 'MVNFUN2 NDIM,',NDIM
! initialize conditional mean
CmN(1:Nst)=Cm(1:Nst)
Pl = Pl1
Pu = Pu1
Y = Pu-Pl
SQ0 = SQ(1,1)
do K = 2,Nst0
X = FIINV(Pl+W(K-1)*(Pu-Pl))
Nst = NsXtmj(K-1) ! index to last stoch. var. before conditioning on X(K)
CmN(K:Nst)=CmN(K:Nst)+X*BIG(K-1,K:Nst) !/SQ0
SQ0 = SQ(K,K)
XMA = MIN((Hup (K)-CmN(K))/SQ0,xCutOff)
XMI = MAX((Hlo (K)-CmN(K))/SQ0,-xCutOff)
if (C1C2det) then
NstN=NsXtmj(K) ! index to last stoch. var. after conditioning on X(K)
CALL C1C2(XMI,XMA,CmN(NstN+1:Nst),
& BIG(K,NstN+1:Nst),SQ(NstN+1:Nst,K),
& indXtd(NstN+1:Nst))
else
CALL C1C2(XMI,XMA,CmN(K+1:Nst),BIG(K,K+1:Nst),
& SQ(K+1:Nst,K),indXtd(K+1:Nst))
endif
IF (XMA.LE.XMI) GO TO 260
Pl = FI(XMI)
Pu = FI(XMA)
Y = Y*(Pu-Pl)
enddo ! K loop
XIND = Y
RETURN
260 XIND = 0.d0
return
END FUNCTION MVNFUN2
END MODULE FUNCMOD
MODULE QUAD
IMPLICIT NONE ! Quadratures available: Legendre,Hermite,Laguerre
INTEGER :: I
INTEGER, PARAMETER :: PMAX=24 ! maximum # nodes
INTEGER, PARAMETER :: sizNint=13 ! size of Nint1
INTEGER :: minQNr=1 ! minimum quadrature number
! used in GaussLe1, Gaussle2
INTEGER :: Le2QNr=8 ! quadr. number used in rind2,rindnit
INTEGER, DIMENSION(sizNint) :: Nint1 ! use quadr. No. Nint1(i) in
! integration of Xd(i)
! # different quadratures stored for :
!-------------------------------------
INTEGER,PARAMETER :: NLeW=13 ! Legendre
INTEGER,PARAMETER :: NHeW=13 ! Hermite
INTEGER,PARAMETER :: NLaW=13 ! Laguerre
! Quadrature Number stored for :
!-------------------------------------
INTEGER, DIMENSION(NLeW) :: LeQNr ! Legendre
INTEGER, DIMENSION(NHeW) :: HeQNr ! Hermite
INTEGER, DIMENSION(NLaW) :: LaQNr ! Laguerre
PARAMETER (LeQNr=(/ 2,3,4,5,6,7, 8, 9, 10, 12, 16, 20, 24 /))
PARAMETER (HeQNr=(/ 2,3,4,5,6,7, 8, 9, 10, 12, 16, 20, 24 /))
PARAMETER (LaQNr=(/ 2,3,4,5,6,7, 8, 9, 10, 12, 16, 20, 24 /))
! The indices to the weights & nodes stored for:
!------------------------------------------------
INTEGER, DIMENSION(NLeW+1) :: LeIND !Legendre
INTEGER, DIMENSION(NHeW+1) :: HeIND !Hermite
INTEGER, DIMENSION(NLaW+1) :: LaIND !Laguerre
PARAMETER (LeIND=(/0,2,5,9,14,20,27,35,44,54,66,82,102,126/)) !Legendre
PARAMETER (HeIND=(/0,2,5,9,14,20,27,35,44,54,66,82,102,126/)) !Hermite
PARAMETER (LaIND=(/0,2,5,9,14,20,27,35,44,54,66,82,102,126/)) !Laguerre
!------------------------------------------------
DOUBLE PRECISION, DIMENSION(126) :: LeBP,LeWF,HeBP,HeWF
DOUBLE PRECISION, DIMENSION(126) :: LaBP0,LaWF0,LaBP5,LaWF5
!The Hermite Quadrature integrates an integral of the form
! inf n
! Int (exp(-x^2) F(x)) dx = Sum wf(j)*F( bp(j) )
! -Inf j=1
!The Laguerre Quadrature integrates an integral of the form
! inf n
! Int (x^alpha exp(-x) F(x)) dx = Sum wf(j)*F( bp(j) )
! 0 j=1
! weights stored here are for alpha=0 and alpha=-0.5
! initialize Legendre weights, wf, and nodes, bp
!PARAMETER ( LeWF = (
DATA ( LeWF(I), I = 1, 78 )
* / 1.d0, 1.d0, 0.555555555555556d0,
* 0.888888888888889d0, 0.555555555555556d0,
* 0.347854845137454d0, 0.652145154862546d0,
* 0.652145154862546d0, 0.347854845137454d0,
* 0.236926885056189d0, 0.478628670499366d0,
* 0.568888888888889d0, 0.478628670499366d0,
* 0.236926885056189d0, 0.171324492379170d0,
* 0.360761573048139d0, 0.467913934572691d0,
* 0.467913934572691d0, 0.360761573048139d0,
* 0.171324492379170d0, 0.129484966168870d0,
* 0.279705391489277d0, 0.381830050505119d0,
* 0.417959183673469d0, 0.381830050505119d0,
* 0.279705391489277d0, 0.129484966168870d0,
* 0.101228536290376d0, 0.222381034453374d0,
* 0.313706645877887d0, 0.362683783378362d0,
* 0.362683783378362d0, 0.313706645877887d0,
* 0.222381034453374d0, 0.101228536290376d0,
* 0.081274388361574d0, 0.180648160694857d0,
* 0.260610696402935d0, 0.312347077040003d0,
* 0.330239355001260d0, 0.312347077040003d0,
* 0.260610696402935d0, 0.180648160694857d0,
* 0.081274388361574d0, 0.066671344308688d0,
* 0.149451349150581d0, 0.219086362515982d0,
* 0.269266719309996d0, 0.295524224714753d0,
* 0.295524224714753d0, 0.269266719309996d0,
* 0.219086362515982d0, 0.149451349150581d0,
* 0.066671344308688d0, 0.047175336386512d0,
* 0.106939325995318d0, 0.160078328543346d0,
* 0.203167426723066d0, 0.233492536538355d0,
* 0.249147048513403d0, 0.249147048513403d0,
* 0.233492536538355d0,
* 0.203167426723066d0, 0.160078328543346d0,
* 0.106939325995318d0, 0.047175336386512d0,
* 0.027152459411754094852d0, 0.062253523938647892863d0,
* 0.095158511682492784810d0, 0.124628971255533872052d0,
* 0.149595988816576732081d0, 0.169156519395002538189d0,
* 0.182603415044923588867d0, 0.189450610455068496285d0,
* 0.189450610455068496285d0, 0.182603415044923588867d0,
* 0.169156519395002538189d0, 0.149595988816576732081d0/
DATA ( LeWF(I), I = 79, 126 )
* / 0.124628971255533872052d0, 0.095158511682492784810d0,
* 0.062253523938647892863d0, 0.027152459411754094852d0,
* 0.017614007139152118312d0, 0.040601429800386941331d0,
* 0.062672048334109063570d0, 0.083276741576704748725d0,
* 0.101930119817240435037d0, 0.118194531961518417312d0,
* 0.131688638449176626898d0, 0.142096109318382051329d0,
* 0.149172986472603746788d0, 0.152753387130725850698d0,
* 0.152753387130725850698d0, 0.149172986472603746788d0,
* 0.142096109318382051329d0, 0.131688638449176626898d0,
* 0.118194531961518417312d0, 0.101930119817240435037d0,
* 0.083276741576704748725d0, 0.062672048334109063570d0,
* 0.040601429800386941331d0, 0.017614007139152118312d0,
* 0.012341229799987199547d0, 0.028531388628933663181d0,
* 0.044277438817419806169d0, 0.059298584915436780746d0,
* 0.073346481411080305734d0, 0.086190161531953275917d0,
* 0.097618652104113888270d0, 0.107444270115965634783d0,
* 0.115505668053725601353d0, 0.121670472927803391204d0,
* 0.125837456346828296121d0, 0.127938195346752156974d0,
* 0.127938195346752156974d0, 0.125837456346828296121d0,
* 0.121670472927803391204d0, 0.115505668053725601353d0,
* 0.107444270115965634783d0, 0.097618652104113888270d0,
* 0.086190161531953275917d0, 0.073346481411080305734d0,
* 0.059298584915436780746d0, 0.044277438817419806169d0,
* 0.028531388628933663181d0, 0.012341229799987199547d0 /
! PARAMETER
DATA ( LeBP(I), I=1,77)
* / -0.577350269189626d0,0.577350269189626d0,
* -0.774596669241483d0, 0.d0,
* 0.774596669241483d0, -0.861136311594053d0,
* -0.339981043584856d0, 0.339981043584856d0,
* 0.861136311594053d0, -0.906179845938664d0,
* -0.538469310105683d0, 0.d0,
* 0.538469310105683d0, 0.906179845938664d0,
* -0.932469514203152d0, -0.661209386466265d0,
* -0.238619186083197d0, 0.238619186083197d0,
* 0.661209386466265d0, 0.932469514203152d0,
* -0.949107912342759d0, -0.741531185599394d0,
* -0.405845151377397d0, 0.d0,
* 0.405845151377397d0, 0.741531185599394d0,
* 0.949107912342759d0, -0.960289856497536d0,
* -0.796666477413627d0, -0.525532409916329d0,
* -0.183434642495650d0, 0.183434642495650d0,
* 0.525532409916329d0, 0.796666477413627d0,
* 0.960289856497536d0, -0.968160239507626d0,
* -0.836031107326636d0, -0.613371432700590d0,
* -0.324253423403809d0, 0.d0,
* 0.324253423403809d0, 0.613371432700590d0,
* 0.836031107326636d0, 0.968160239507626d0,
* -0.973906528517172d0, -0.865063366688985d0,
* -0.679409568299024d0, -0.433395394129247d0,
* -0.148874338981631d0, 0.148874338981631d0,
* 0.433395394129247d0, 0.679409568299024d0,
* 0.865063366688985d0, 0.973906528517172d0,
* -0.981560634246719d0, -0.904117256370475d0,
* -0.769902674194305d0, -0.587317954286617d0,
* -0.367831498198180d0, -0.125233408511469d0,
* 0.125233408511469d0, 0.367831498198180d0,
* 0.587317954286617d0, 0.769902674194305d0,
* 0.904117256370475d0, 0.981560634246719d0,
* -0.989400934991649932596d0,
* -0.944575023073232576078d0, -0.865631202387831743880d0,
* -0.755404408355003033895d0, -0.617876244402643748447d0,
* -0.458016777657227386342d0, -0.281603550779258913230d0,
* -0.095012509837637440185d0, 0.095012509837637440185d0,
* 0.281603550779258913230d0, 0.458016777657227386342d0/
DATA ( LeBP(I), I=78,126)
* / 0.617876244402643748447d0, 0.755404408355003033895d0,
* 0.865631202387831743880d0, 0.944575023073232576078d0,
* 0.989400934991649932596d0, -0.993128599185094924786d0,
* -0.963971927277913791268d0, -0.912234428251325905868d0,
* -0.839116971822218823395d0, -0.746331906460150792614d0,
* -0.636053680726515025453d0, -0.510867001950827098004d0,
* -0.373706088715419560673d0, -0.227785851141645078080d0,
* -0.076526521133497333755d0, 0.076526521133497333755d0,
* 0.227785851141645078080d0, 0.373706088715419560673d0,
* 0.510867001950827098004d0, 0.636053680726515025453d0,
* 0.746331906460150792614d0, 0.839116971822218823395d0,
* 0.912234428251325905868d0,
* 0.963971927277913791268d0, 0.993128599185094924786d0,
* -0.995187219997021360180d0, -0.974728555971309498198d0,
* -0.938274552002732758524d0, -0.886415527004401034213d0,
* -0.820001985973902921954d0, -0.740124191578554364244d0,
* -0.648093651936975569252d0, -0.545421471388839535658d0,
* -0.433793507626045138487d0, -0.315042679696163374387d0,
* -0.191118867473616309159d0, -0.064056892862605626085d0,
* 0.064056892862605626085d0, 0.191118867473616309159d0,
* 0.315042679696163374387d0, 0.433793507626045138487d0,
* 0.545421471388839535658d0, 0.648093651936975569252d0,
* 0.740124191578554364244d0, 0.820001985973902921954d0,
* 0.886415527004401034213d0, 0.938274552002732758524d0,
* 0.974728555971309498198d0, 0.995187219997021360180d0 /
! initialize Hermite weights in HeWF and
! nodes in HeBP
! NB! the relative error of these numbers
! are less than 10^-15
! PARAMETER
DATA (HeWF(I),I=1,78) / 8.8622692545275816d-1,
* 8.8622692545275816d-1,
* 2.9540897515091930d-1, 1.1816359006036770d0,
* 2.9540897515091930d-1, 8.1312835447245310d-2,
* 8.0491409000551251d-1, 8.0491409000551295d-1,
* 8.1312835447245213d-2, 1.9953242059045910d-2,
* 3.9361932315224146d-1, 9.4530872048294134d-1,
* 3.9361932315224102d-1, 1.9953242059045962d-2,
* 4.5300099055088378d-3, 1.5706732032285636d-1,
* 7.2462959522439319d-1, 7.2462959522439241d-1,
* 1.5706732032285681d-1, 4.5300099055088534d-3,
* 9.7178124509952175d-4, 5.4515582819126975d-2,
* 4.2560725261012805d-1, 8.1026461755680768d-1,
* 4.2560725261012783d-1, 5.4515582819126975d-2,
* 9.7178124509951828d-4, 1.9960407221136729d-4,
* 1.7077983007413571d-2, 2.0780232581489183d-1,
* 6.6114701255824082d-1, 6.6114701255824138d-1,
* 2.0780232581489202d-1, 1.7077983007413498d-2,
* 1.9960407221136775d-4, 3.9606977263264446d-5,
* 4.9436242755369411d-3, 8.8474527394376654d-2,
* 4.3265155900255586d-1, 7.2023521560605108d-1,
* 4.3265155900255559d-1, 8.8474527394376543d-2,
* 4.9436242755369350d-3, 3.9606977263264324d-5,
* 7.6404328552326139d-6, 1.3436457467812229d-3,
* 3.3874394455481210d-2, 2.4013861108231502d-1,
* 6.1086263373532623d-1, 6.1086263373532546d-1,
* 2.4013861108231468d-1, 3.3874394455480884d-2,
* 1.3436457467812298d-3, 7.6404328552325919d-6,
* 2.6585516843562997d-7, 8.5736870435879089d-5,
* 3.9053905846291028d-3, 5.1607985615883860d-2,
* 2.6049231026416092d-1, 5.7013523626247820d-1,
* 5.7013523626248030d-1, 2.6049231026416109d-1,
* 5.1607985615883846d-2, 3.9053905846290530d-3,
* 8.5736870435878506d-5, 2.6585516843562880d-7,
* 2.6548074740111735d-10, 2.3209808448651987d-7,
* 2.7118600925379007d-5, 9.3228400862418819d-4,
* 1.2880311535509989d-2, 8.3810041398985652d-2,
* 2.8064745852853318d-1, 5.0792947901661278d-1,
* 5.0792947901661356d-1, 2.8064745852853334d-1,
* 8.3810041398985735d-2, 1.2880311535510015d-2/
DATA (HeWF(I),I=79,126) /
* 9.3228400862418407d-4, 2.7118600925378956d-5,
* 2.3209808448651966d-7, 2.6548074740111787d-10,
* 2.2293936455342015d-13, 4.3993409922730765d-10,
* 1.0860693707692910d-7, 7.8025564785320463d-6,
* 2.2833863601635403d-4, 3.2437733422378719d-3,
* 2.4810520887463536d-2, 1.0901720602002360d-1,
* 2.8667550536283382d-1, 4.6224366960061047d-1,
* 4.6224366960061070d-1, 2.8667550536283398d-1,
* 1.0901720602002325d-1, 2.4810520887463588d-2,
* 3.2437733422378649d-3, 2.2833863601635316d-4,
* 7.8025564785321005d-6, 1.0860693707692749d-7,
* 4.3993409922731370d-10, 2.2293936455342167d-13,
* 1.6643684964891124d-16, 6.5846202430781508d-13,
* 3.0462542699875022d-10, 4.0189711749413878d-8,
* 2.1582457049023452d-6, 5.6886916364043773d-5,
* 8.2369248268841073d-4, 7.0483558100726748d-3,
* 3.7445470503230736d-2, 1.2773962178455966d-1,
* 2.8617953534644325d-1, 4.2693116386869828d-1,
* 4.2693116386869912d-1, 2.8617953534644286d-1,
* 1.2773962178455908d-1, 3.7445470503230875d-2,
* 7.0483558100726844d-3, 8.2369248268842027d-4,
* 5.6886916364044037d-5, 2.1582457049023460d-6,
* 4.0189711749414963d-8, 3.0462542699876118d-10,
* 6.5846202430782225d-13, 1.6643684964889408d-16 /
!hermite nodes
! PARAMETER (HeBP = (
DATA (HeBP(I),I=1,79) / -7.07106781186547572d-1,
* 7.0710678118654752d-1, -1.2247448713915894d0,
* 0.d0, 1.2247448713915894d0,
* -1.6506801238857845d0, -5.2464762327529035d-1,
* 5.2464762327529035d-1, 1.6506801238857845d0,
* -2.0201828704560869d0, -9.5857246461381806d-1,
* 0.d0, 9.5857246461381851d-1,
* 2.0201828704560860d0, -2.3506049736744918d0,
* -1.3358490740136963d0, -4.3607741192761629d-1,
* 4.3607741192761657d-1, 1.3358490740136963d0,
* 2.3506049736744927d0, -2.6519613568352334d0,
* -1.6735516287674728d0, -8.1628788285896470d-1,
* 0.d0, 8.1628788285896470d-1,
* 1.6735516287674705d0, 2.6519613568352325d0,
* -2.9306374202572423d0, -1.9816567566958434d0,
* -1.1571937124467806d0, -3.8118699020732233d-1,
* 3.8118699020732211d-1, 1.1571937124467804d0,
* 1.9816567566958441d0, 2.9306374202572423d0,
* -3.1909932017815290d0, -2.2665805845318436d0,
* -1.4685532892166682d0, -7.2355101875283812d-1,
* 0.d0, 7.2355101875283756d-1,
* 1.4685532892166657d0, 2.2665805845318405d0,
* 3.1909932017815281d0, -3.4361591188377387d0,
* -2.5327316742327906d0, -1.7566836492998805d0,
* -1.0366108297895140d0, -3.4290132722370548d-1,
* 3.4290132722370464d-1, 1.0366108297895136d0,
* 1.7566836492998834d0, 2.5327316742327857d0,
* 3.4361591188377396d0, -3.8897248978697796d0,
* -3.0206370251208856d0, -2.2795070805010567d0,
* -1.5976826351526050d0, -9.4778839124016290d-1,
* -3.1424037625435908d-1, 3.1424037625435935d-1,
* 9.4778839124016356d-1, 1.5976826351526054d0,
* 2.2795070805010602d0, 3.0206370251208905d0,
* 3.8897248978697831d0, -4.6887389393058214d0,
* -3.8694479048601251d0, -3.1769991619799582d0,
* -2.5462021578474765d0, -1.9517879909162541d0,
* -1.3802585391988809d0, -8.2295144914465523d-1,
* -2.7348104613815177d-1, 2.7348104613815244d-1,
* 8.2295144914465579d-1, 1.3802585391988802d0,
* 1.9517879909162534d0, 2.5462021578474801d0/
DATA (HeBP(I),I=80,126) /
* 3.1769991619799565d0, 3.8694479048601265d0,
* 4.6887389393058196d0, -5.3874808900112274d0,
* -4.6036824495507513d0, -3.9447640401156296d0,
* -3.3478545673832154d0, -2.7888060584281300d0,
* -2.2549740020892721d0, -1.7385377121165839d0,
* -1.2340762153953209d0, -7.3747372854539361d-1,
* -2.4534070830090124d-1, 2.4534070830090149d-1,
* 7.3747372854539439d-1, 1.2340762153953226d0,
* 1.7385377121165866d0, 2.2549740020892770d0,
* 2.7888060584281282d0, 3.3478545673832105d0,
* 3.9447640401156230d0, 4.6036824495507398d0,
* 5.3874808900112274d0, -6.0159255614257390d0,
* -5.2593829276680442d0, -4.6256627564237904d0,
* -4.0536644024481472d0, -3.5200068130345219d0,
* -3.0125461375655647d0, -2.5238810170114276d0,
* -2.0490035736616989d0, -1.5842500109616944d0,
* -1.1267608176112460d0, -6.7417110703721150d-1,
* -2.2441454747251538d-1, 2.2441454747251532d-1,
* 6.7417110703721206d-1, 1.1267608176112454d0,
* 1.5842500109616939d0, 2.0490035736616958d0,
* 2.5238810170114281d0, 3.0125461375655687d0,
* 3.5200068130345232d0, 4.0536644024481499d0,
* 4.6256627564237816d0, 5.2593829276680353d0,
* 6.0159255614257550d0 /
!initialize Laguerre weights and nodes (basepoints)
! for alpha=0
! NB! the relative error of these numbers
! are less than 10^-15
! PARAMETER
DATA (LaWF0(I),I=1,75) / 8.5355339059327351d-1,
* 1.4644660940672624d-1, 7.1109300992917313d-1,
* 2.7851773356924092d-1, 1.0389256501586137d-2,
* 6.0315410434163386d-1,
* 3.5741869243779956d-1, 3.8887908515005364d-2,
* 5.3929470556132730d-4, 5.2175561058280850d-1,
* 3.9866681108317570d-1, 7.5942449681707588d-2,
* 3.6117586799220489d-3, 2.3369972385776180d-5,
* 4.5896467394996360d-1, 4.1700083077212080d-1,
* 1.1337338207404497d-1, 1.0399197453149061d-2,
* 2.6101720281493249d-4, 8.9854790642961944d-7,
* 4.0931895170127397d-1, 4.2183127786171964d-1,
* 1.4712634865750537d-1,
* 2.0633514468716974d-2, 1.0740101432807480d-3,
* 1.5865464348564158d-5, 3.1703154789955724d-8,
* 3.6918858934163773d-1, 4.1878678081434328d-1,
* 1.7579498663717152d-1, 3.3343492261215649d-2,
* 2.7945362352256712d-3, 9.0765087733581999d-5,
* 8.4857467162725493d-7, 1.0480011748715038d-9,
* 3.3612642179796304d-1, 4.1121398042398466d-1,
* 1.9928752537088576d0, 4.7460562765651609d-2,
* 5.5996266107945772d-3, 3.0524976709321133d-4,
* 6.5921230260753743d-6, 4.1107693303495271d-8,
* 3.2908740303506941d-11,
* 3.0844111576502009d-1, 4.0111992915527328d-1,
* 2.1806828761180935d-1, 6.2087456098677683d-2,
* 9.5015169751810902d-3, 7.5300838858753855d-4,
* 2.8259233495995652d-5, 4.2493139849626742d-7,
* 1.8395648239796174d-9, 9.9118272196090085d-13,
& 2.6473137105544342d-01,
& 3.7775927587313773d-01, 2.4408201131987739d-01,
& 9.0449222211681030d-02, 2.0102381154634138d-02,
& 2.6639735418653122d-03, 2.0323159266299895d-04,
& 8.3650558568197802d-06, 1.6684938765409045d-07,
& 1.3423910305150080d-09, 3.0616016350350437d-12,
& 8.1480774674261369d-16, 2.0615171495780091d-01,
& 3.3105785495088480d-01, 2.6579577764421392d-01,
& 1.3629693429637740d-01, 4.7328928694125222d-02,
& 1.1299900080339390d-02, 1.8490709435263156d-03,
& 2.0427191530827761d-04, 1.4844586873981184d-05/
DATA (LaWF0(I),I=76,126) /
& 6.8283193308711422d-07, 1.8810248410796518d-08,
& 2.8623502429738514d-10, 2.1270790332241105d-12,
& 6.2979670025179594d-15, 5.0504737000353956d-18,
& 4.1614623703728548d-22, 1.6874680185111446d-01,
& 2.9125436200606764d-01, 2.6668610286700062d-01,
& 1.6600245326950708d-01, 7.4826064668792408d-02,
& 2.4964417309283247d-02, 6.2025508445722223d-03,
& 1.1449623864769028d-03, 1.5574177302781227d-04,
& 1.5401440865224898d-05, 1.0864863665179799d-06,
& 5.3301209095567054d-08, 1.7579811790505857d-09,
& 3.7255024025122967d-11, 4.7675292515782048d-13,
& 3.3728442433624315d-15, 1.1550143395004071d-17,
& 1.5395221405823110d-20, 5.2864427255691140d-24,
& 1.6564566124989991d-28, 1.4281197333478154d-01,
& 2.5877410751742391d-01, 2.5880670727286992d-01,
& 1.8332268897777793d-01, 9.8166272629918963d-02,
& 4.0732478151408603d-02, 1.3226019405120104d-02,
& 3.3693490584783083d-03, 6.7216256409355021d-04,
& 1.0446121465927488d-04, 1.2544721977993268d-05,
& 1.1513158127372857d-06, 7.9608129591336357d-08,
& 4.0728589875500037d-09, 1.5070082262925912d-10,
& 3.9177365150584634d-12, 6.8941810529581520d-14,
& 7.8198003824593093d-16, 5.3501888130099474d-18,
& 2.0105174645555229d-20, 3.6057658645531092d-23,
& 2.4518188458785009d-26, 4.0883015936805334d-30,
& 5.5753457883284229d-35 /
! PARAMETER (LaBP0=(/
DATA (LaBP0(I),I=1,78) /5.8578643762690485d-1,
* 3.4142135623730949d+00, 4.1577455678347897d-1,
* 2.2942803602790409d0, 6.2899450829374803d0,
* 3.2254768961939217d-1, 1.7457611011583465d0,
* 4.5366202969211287d0, 9.3950709123011364d0,
* 2.6356031971814076d-1, 1.4134030591065161d0,
* 3.5964257710407206d0, 7.0858100058588356d0,
* 1.2640800844275784d+01, 2.2284660417926061d-1,
* 1.1889321016726229d0, 2.9927363260593141d+00,
* 5.7751435691045128d0, 9.8374674183825839d0,
* 1.5982873980601699d+01, 1.9304367656036231d-1,
* 1.0266648953391919d0, 2.5678767449507460d0,
* 4.9003530845264844d0, 8.1821534445628572d0,
* 1.2734180291797809d+01, 1.9395727862262543d+01,
* 1.7027963230510107d-1, 9.0370177679938035d-1,
* 2.2510866298661316d0, 4.2667001702876597d0,
* 7.0459054023934673d0, 1.0758516010180994d+01,
* 1.5740678641278004d+01, 2.2863131736889272d+01,
* 1.5232222773180798d-1, 8.0722002274225590d-1,
* 2.0051351556193473d0, 3.7834739733312328d0,
* 6.2049567778766175d0, 9.3729852516875773d0,
* 1.3466236911092089d+01, 1.8833597788991703d+01,
* 2.6374071890927389d+01, 1.3779347054049221d-1,
* 7.2945454950317090d-1, 1.8083429017403163d0,
* 3.4014336978548996d0,
* 5.5524961400638029d0, 8.3301527467644991d0,
* 1.1843785837900066d+01, 1.6279257831378107d+01,
* 2.1996585811980765d+01, 2.9920697012273894d+01 ,
& 1.1572211735802050d-01, 6.1175748451513112d-01,
& 1.5126102697764183d+00, 2.8337513377435077d+00,
& 4.5992276394183476d+00, 6.8445254531151809d+00,
& 9.6213168424568707d+00, 1.3006054993306348d+01,
& 1.7116855187462260d+01, 2.2151090379397019d+01,
& 2.8487967250983996d+01, 3.7099121044466933d+01,
& 8.7649410478926978d-02, 4.6269632891508106d-01,
& 1.1410577748312269d+00, 2.1292836450983796d+00,
& 3.4370866338932058d+00, 5.0780186145497677d+00,
& 7.0703385350482320d+00, 9.4383143363919331d+00,
& 1.2214223368866158d+01, 1.5441527368781616d+01,
& 1.9180156856753147d+01, 2.3515905693991915d+01/
DATA (LaBP0(I),I=79,126) /
& 2.8578729742882153d+01,
& 3.4583398702286622d+01, 4.1940452647688396d+01,
& 5.1701160339543350d+01, 7.0539889691989419d-02,
& 3.7212681800161185d-01, 9.1658210248327376d-01,
& 1.7073065310283420d+00, 2.7491992553094309d+00,
& 4.0489253138508827d+00, 5.6151749708616148d+00,
& 7.4590174536710663d+00, 9.5943928695810943d+00,
& 1.2038802546964314d+01, 1.4814293442630738d+01,
& 1.7948895520519383d+01, 2.1478788240285009d+01,
& 2.5451702793186907d+01, 2.9932554631700611d+01,
& 3.5013434240478986d+01, 4.0833057056728535d+01,
& 4.7619994047346523d+01, 5.5810795750063903d+01,
& 6.6524416525615763d+01, 5.9019852181507730d-02,
& 3.1123914619848325d-01, 7.6609690554593646d-01,
& 1.4255975908036129d+00, 2.2925620586321909d+00,
& 3.3707742642089964d+00, 4.6650837034671726d+00,
& 6.1815351187367655d+00, 7.9275392471721489d+00,
& 9.9120980150777047d+00, 1.2146102711729766d+01,
& 1.4642732289596671d+01, 1.7417992646508978d+01,
& 2.0491460082616424d+01, 2.3887329848169724d+01,
& 2.7635937174332710d+01, 3.1776041352374712d+01,
& 3.6358405801651635d+01, 4.1451720484870783d+01,
& 4.7153106445156347d+01, 5.3608574544695017d+01,
& 6.1058531447218698d+01, 6.9962240035105026d+01,
& 8.1498279233948850d+01/
!Laguerre nodes for alpha=-0.5
! PARAMETER (LaBP5 = (/
DATA (LaBP5(I),I=1,79) /2.7525512860841095e-01,
& 2.7247448713915889e+00, 1.9016350919348812e-01,
& 1.7844927485432514e+00, 5.5253437422632619e+00,
& 1.4530352150331699e-01, 1.3390972881263605e+00,
& 3.9269635013582880e+00, 8.5886356890120332e+00,
& 1.1758132021177792e-01, 1.0745620124369035e+00,
& 3.0859374437175511e+00, 6.4147297336620337e+00,
& 1.1807189489971735e+01, 9.8747014068480951e-02,
& 8.9830283456961701e-01, 2.5525898026681721e+00,
& 5.1961525300544675e+00, 9.1242480375311814e+00,
& 1.5129959781108084e+01, 8.5115442997593743e-02,
& 7.7213792004277715e-01, 2.1805918884504596e+00,
& 4.3897928867310174e+00, 7.5540913261017897e+00,
& 1.1989993039823887e+01, 1.8528277495852500e+01,
& 7.4791882596818141e-02, 6.7724908764928937e-01,
& 1.9051136350314275e+00, 3.8094763614849056e+00,
& 6.4831454286271679e+00, 1.0093323675221344e+01,
& 1.4972627088426393e+01, 2.1984272840962646e+01,
& 6.6702230958194261e-02, 6.0323635708174905e-01,
& 1.6923950797931777e+00, 3.3691762702432655e+00,
& 5.6944233429577471e+00, 8.7697567302685968e+00,
& 1.2771825354869195e+01, 1.8046505467728977e+01,
& 2.5485979166099078e+01, 6.0192063149587700e-02,
& 5.4386750029464592e-01, 1.5229441054044432e+00,
& 3.0225133764515753e+00, 5.0849077500985240e+00,
& 7.7774392315254426e+00, 1.1208130204348663e+01,
& 1.5561163332189356e+01, 2.1193892096301536e+01,
& 2.9024950340236231e+01, 5.0361889117293709e-02,
& 4.5450668156378027e-01, 1.2695899401039612e+00,
& 2.5098480972321284e+00, 4.1984156448784127e+00,
& 6.3699753880306362e+00, 9.0754342309612088e+00,
& 1.2390447963809477e+01, 1.6432195087675318e+01,
& 2.1396755936166095e+01, 2.7661108779846099e+01,
& 3.6191360360615583e+01, 3.7962914575312985e-02,
& 3.4220015601094805e-01, 9.5355315539086472e-01,
& 1.8779315076960728e+00, 3.1246010507021431e+00,
& 4.7067267076675874e+00, 6.6422151797414388e+00,
& 8.9550013377233881e+00, 1.1677033673975952e+01,
& 1.4851431341801243e+01, 1.8537743178606682e+01,
& 2.2821300693525199e+01, 2.7831438211328681e+01/
DATA (LaBP5(I),I=80,126) /
& 3.3781970488226136e+01, 4.1081666525491165e+01,
& 5.0777223877537075e+01, 3.0463239279482423e-02,
& 2.7444471579285024e-01, 7.6388755844391365e-01,
& 1.5018014976681033e+00, 2.4928301451213657e+00,
& 3.7434180412162927e+00, 5.2620558537883513e+00,
& 7.0596277357415627e+00, 9.1498983120306470e+00,
& 1.1550198286442805e+01, 1.4282403685210406e+01,
& 1.7374366975199074e+01, 2.0862075185437845e+01,
& 2.4793039892463458e+01, 2.9231910157093431e+01,
& 3.4270428925039589e+01, 4.0046815790245596e+01,
& 4.6788846392124952e+01, 5.4931555621020564e+01,
& 6.5589931990639684e+01, 2.5437996585689085e-02,
& 2.2910231649262403e-01, 6.3729027873266897e-01,
& 1.2517406323627462e+00, 2.0751129098523808e+00,
& 3.1110524551477146e+00, 4.3642830769353065e+00,
& 5.8407332713236055e+00, 7.5477046800234531e+00,
& 9.4940953300264859e+00, 1.1690695926056069e+01,
& 1.4150586187285759e+01, 1.6889671928527100e+01,
& 1.9927425875242456e+01, 2.3287932824879903e+01,
& 2.7001406056472355e+01, 3.1106464709046559e+01,
& 3.5653703516328221e+01, 4.0711598185543110e+01,
& 4.6376979557540103e+01, 5.2795432527283602e+01,
& 6.0206666963057259e+01, 6.9068601975304347e+01,
& 8.0556280819950416e+01/
! PARAMETER (LaWF5 = (/
DATA (LaWF5(I),I=1,79) / 1.6098281800110255e+00,
& 1.6262567089449037e-01, 1.4492591904487846e+00,
& 3.1413464064571323e-01, 9.0600198110176913e-03,
& 1.3222940251164819e+00, 4.1560465162978422e-01,
& 3.4155966014826969e-02, 3.9920814442273529e-04,
& 1.2217252674706509e+00, 4.8027722216462992e-01,
& 6.7748788910962143e-02, 2.6872914935624635e-03,
& 1.5280865710465251e-05, 1.1402704725249586e+00,
& 5.2098462052832328e-01, 1.0321597123176789e-01,
& 7.8107811692581406e-03, 1.7147374087175731e-04,
& 5.3171033687126004e-07, 1.0728118194241802e+00,
& 5.4621121812849427e-01, 1.3701106844693015e-01,
& 1.5700109452915889e-02, 7.1018522710384658e-04,
& 9.4329687100378043e-06, 1.7257182336250307e-08,
& 1.0158589580332265e+00, 5.6129491705706813e-01,
& 1.6762008279797133e-01, 2.5760623071019968e-02,
& 1.8645680172483614e-03, 5.4237201850757696e-05,
& 4.6419616897304271e-07, 5.3096149480223697e-10,
& 9.6699138945091101e-01, 5.6961457133995952e-01,
& 1.9460349528263074e-01, 3.7280084775089407e-02,
& 3.7770452605368474e-03, 1.8362253735858719e-04,
& 3.6213089621868382e-06, 2.0934411591584102e-08,
& 1.5656399544231742e-11, 9.2448733920121973e-01,
& 5.7335101072566907e-01, 2.1803441204004675e-01,
& 4.9621041774927162e-02, 6.4875466844757246e-03,
& 4.5667727203270848e-04, 1.5605112957064066e-05,
& 2.1721387415385585e-07, 8.7986819845463701e-10,
& 4.4587872910682818e-13, 8.5386232773739834e-01,
& 5.7235907069288550e-01, 2.5547924356911883e-01,
& 7.4890941006461639e-02, 1.4096711620145414e-02,
& 1.6473849653768340e-03, 1.1377383272808749e-04,
& 4.3164914098046565e-06, 8.0379423498828602e-08,
& 6.0925085399751771e-10, 1.3169240486156312e-12,
& 3.3287369929782692e-16, 7.5047670518560539e-01,
& 5.5491628460505815e-01, 3.0253946815328553e-01,
& 1.2091626191182542e-01, 3.5106857663146820e-02,
& 7.3097806533088429e-03, 1.0725367310559510e-03,
& 1.0833168123639965e-04, 7.3011702591247581e-06,
& 3.1483355850911864e-07, 8.1976643295418016e-09,
& 1.1866582926793190e-10, 8.4300204226528705e-13/
DATA (LaWF5(I),I=80,126) /
& 2.3946880341857530e-15, 1.8463473073036743e-18,
& 1.4621352854768128e-22, 6.7728655485117817e-01,
& 5.3145650375475362e-01, 3.2675746542654360e-01,
& 1.5694921173080897e-01, 5.8625131072344717e-02,
& 1.6921776016516312e-02, 3.7429936591959084e-03,
& 6.2770718908266166e-04, 7.8738679621849850e-05,
& 7.2631523013860402e-06, 4.8222883273410492e-07,
& 2.2424721664551585e-08, 7.0512415827308280e-10,
& 1.4313056105380569e-11, 1.7611415290432366e-13,
& 1.2016717578981511e-15, 3.9783620242330409e-18,
& 5.1351867308233644e-21, 1.7088113927550770e-24,
& 5.1820874276942667e-29, 6.2200206075592535e-01,
& 5.0792308532951769e-01, 3.3840894389128295e-01,
& 1.8364459415856996e-01, 8.0959353969207851e-02,
& 2.8889923149962169e-02, 8.3060098239550965e-03,
& 1.9127846396388331e-03, 3.5030086360234562e-04,
& 5.0571980554969836e-05, 5.6945173834697106e-06,
& 4.9373179873395243e-07, 3.2450282717915824e-08,
& 1.5860934990330932e-09, 5.6305930756763865e-11,
& 1.4093865163091798e-12, 2.3951797309583852e-14,
& 2.6303192453168292e-16, 1.7460319202373756e-18,
& 6.3767746470103704e-21, 1.1129154937804721e-23,
& 7.3700721603011131e-27, 1.1969225386627985e-30,
& 1.5871102921547987e-35 /
INTERFACE GAUSSLA0
MODULE PROCEDURE GAUSSLA0
END INTERFACE
INTERFACE GAUSSLE0
MODULE PROCEDURE GAUSSLE0
END INTERFACE
INTERFACE GAUSSHE0
MODULE PROCEDURE GAUSSHE0
END INTERFACE
INTERFACE GAUSSLE1
MODULE PROCEDURE GAUSSLE1
END INTERFACE
INTERFACE GAUSSLE2
MODULE PROCEDURE GAUSSLE2
END INTERFACE
INTERFACE GAUSSQ
MODULE PROCEDURE GAUSSQ
END INTERFACE
CONTAINS
SUBROUTINE GAUSSLE1 (N,WFout,BPOUT,XMI,XMA)
USE GLOBALDATA,ONLY : EPS0
USE FIMOD
! USE QUAD , ONLY: LeBP,LeWF,LeIND,NLeW,minQnr
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:),INTENT(out) :: BPOUT, WFout
DOUBLE PRECISION, INTENT(in) :: XMI,XMA
INTEGER, INTENT(inout) :: N
! local variables
DOUBLE PRECISION :: Z1,SDOT, SDOT1, DIFF1
DOUBLE PRECISION,PARAMETER :: SQTWOPI1 = 0.39894228040143D0 !=1/sqrt(2*pi)
INTEGER :: NN,I,J,k
! The subroutine picks the lowest Gauss-Legendre
! quadrature needed to integrate the test function
! gaussint to the specified accuracy, EPS0.
! The nodes and weights between the integration
! limits XMI and XMA (all normalized) are returned.
! Note that the weights are multiplied with
! 1/sqrt(2*pi)*exp(.5*bpout^2)
IF (XMA.LE.XMI) THEN
! PRINT * , 'Warning XMIN>=XMAX in GAUSSLE1 !',XMI,XMA
RETURN
ENDIF
DO I = minQnr, NLeW
NN = N !initialize
DO J = LeIND(I)+1, LeIND(I+1)
BPOUT (NN+1) = 0.5d0*(LeBP(J)*(XMA-XMI)+XMA+XMI)
Z1 = BPOUT (NN+1) * BPOUT (NN+1)
!IF (Z1.LE.xCutOff2) THEN
NN=NN+1
WFout (NN) = 0.5d0 * SQTWOPI1 * (XMA - XMI) *
& LeWF(J) *EXP ( - 0.5d0* Z1 )
!ENDIF
ENDDO
SDOT = GAUSINT (XMI, XMA, - 2.5d0, 2.d0, 2.5d0, 2.d0)
SDOT1 = 0.d0
DO k = N+1, NN
SDOT1 = SDOT1+WFout(k)*(-2.5d0+2.d0*BPOUT(k) )*
& (2.5d0 + 2.d0 * BPOUT (k) )
ENDDO
DIFF1 = ABS (SDOT - SDOT1)
IF (EPS0.GT.DIFF1) THEN
N=NN
! PRINT * ,'gaussle1, XMI,XMA,NN',XMI,XMA,NN
RETURN
END IF
END DO
RETURN
END SUBROUTINE GAUSSLE1
SUBROUTINE GAUSSLE0 (N, wfout, bpout, XMI, XMA, N0)
USE GLOBALDATA, ONLY : EPSS
! USE QUAD, ONLY : LeBP,LeWF,NLeW,LeIND
IMPLICIT NONE
INTEGER, INTENT(in) :: N0
INTEGER, INTENT(inout) :: N
DOUBLE PRECISION, DIMENSION(:), INTENT(out) :: wfout,bpout
DOUBLE PRECISION, INTENT(in) :: XMI,XMA
! Local variables
DOUBLE PRECISION,PARAMETER :: SQTWOPI1 = 0.39894228040143D0 !=1/sqrt(2*pi)
DOUBLE PRECISION :: Z1
INTEGER :: J
! The subroutine computes Gauss-Legendre
! nodes and weights between
! the (normalized) integration limits XMI and XMA
! Note that the weights are multiplied with
! 1/sqrt(2*pi)*exp(.5*bpout^2) so that
! b
! int f(x)*exp(-x^2/2)/sqrt(2*pi)dx=sum f(bp(j))*wf(j)
! a j
IF (XMA.LE.XMI) THEN
!PRINT * , 'Warning XMIN>=XMAX in GAUSSLE0 !',XMI,XMA
RETURN ! no more nodes added
ENDIF
IF ((XMA-XMI).LT.EPSS) THEN
N=N+1
BPout (N) = 0.5d0 * (XMA + XMI)
Z1 = BPOUT (N) * BPOUT (N)
WFout (N) = SQTWOPI1 * (XMA - XMI) *EXP ( - 0.5d0* Z1 )
RETURN
ENDIF
IF (N0.GT.NLeW) THEN
!PRINT * , 'error in GAUSSLE0, quadrature not available'
STOP
ENDIF
!print *, 'GAUSSLE0',N0
!print *, N
DO J = LeIND(N0)+1, LeIND(N0+1)
BPout (N+1) = 0.5d0 * (LeBP(J) * (XMA - XMI) + XMA + XMI)
Z1 = BPOUT (N+1) * BPOUT (N+1)
! IF (Z1.LE.xCutOff2) THEN
N=N+1 ! add a new node and weight
WFout (N) = 0.5d0 * SQTWOPI1 * (XMA - XMI) *
& LeWF(J) *EXP ( - 0.5d0* Z1 )
! ENDIF
ENDDO
!print *,BPout
RETURN
END SUBROUTINE GAUSSLE0
SUBROUTINE GAUSSLE2 (N, wfout, bpout, XMI, XMA, N0)
USE GLOBALDATA, ONLY : xCutOff,EPSS
! USE QUAD, ONLY : LeBP,LeWF,NLeW,LeIND,minQNr
IMPLICIT NONE
INTEGER, INTENT(in) :: N0
INTEGER, INTENT(inout) :: N
DOUBLE PRECISION, DIMENSION(:), INTENT(out) :: wfout,bpout
DOUBLE PRECISION, INTENT(in) :: XMI,XMA
! Local variables
DOUBLE PRECISION :: Z1
INTEGER :: J,N1
DOUBLE PRECISION,PARAMETER :: SQTWOPI1 = 0.39894228040143D0 !=1/sqrt(2*pi)
! The subroutine computes Gauss-Legendre
! nodes and weights between
! the (normalized) integration limits XMI and XMA
! This procedure select number of nodes
! depending on the length of the integration interval.
! Note that the weights are multiplied with
! 1/sqrt(2*pi)*exp(.5*bpout^2) so that
! b
! int f(x)*exp(-x^2/2)/sqrt(2*pi)dx=sum f(bp(j))*wf(j)
! a j
IF (XMA.LE.XMI) THEN
!PRINT * , 'Warning XMIN>=XMAX in GAUSSLE2 !',XMI,XMA
RETURN ! no more nodes added
ENDIF
! IF (XMA.LT.XMI+EPSS) THEN
! N=N+1
! BPout (N) = 0.65d0 * (XMA + XMI)
! Z1 = BPOUT (N) * BPOUT (N)
! WFout (N) = SQTWOPI1 * (XMA - XMI) *EXP ( - 0.5d0* Z1 )
! RETURN
! ENDIF
IF (N0.GT.NLeW) THEN
!PRINT * , 'Warning in GAUSSLE2, quadrature not available'
ENDIF
!print *, 'GAUSSLE2',N0
!print *, N
N1=CEILING(0.5d0*(XMA-XMI)*DBLE(N0)/xCutOff) !0.65d0
N1=MAX(MIN(N1,NLew),minQNr)
DO J = LeIND(N1)+1, LeIND(N1+1)
BPout (N+1) = 0.5d0 * (LeBP(J) * (XMA - XMI) + XMA + XMI)
Z1 = BPOUT (N+1) * BPOUT (N+1)
! IF (Z1.LE.xCutOff2) THEN
N=N+1 ! add a new node and weight
WFout (N) = 0.5d0 * SQTWOPI1 * (XMA - XMI) *
& LeWF(J) *EXP ( - 0.5d0* Z1 )
! ENDIF
ENDDO
!PRINT * ,'gaussle2, XMI,XMA,N',XMI,XMA,N
!print *,BPout
RETURN
END SUBROUTINE GAUSSLE2
SUBROUTINE GAUSSHE0 (N, WFout, BPout, XMI, XMA, N0)
! USE QUAD, ONLY : HeBP,HeWF,HeIND,NHeW
IMPLICIT NONE
INTEGER, INTENT(in) :: N0
INTEGER, INTENT(inout) :: N
DOUBLE PRECISION, DIMENSION(:), INTENT(out) :: wfout,bpout
DOUBLE PRECISION, INTENT(in) :: XMI,XMA
! Local variables
DOUBLE PRECISION, PARAMETER :: SQPI1= 5.6418958354776D-1 !=1/sqrt(pi)
DOUBLE PRECISION, PARAMETER :: SQTWO= 1.41421356237310D0 !=sqrt(2)
INTEGER :: J
! The subroutine returns modified Gauss-Hermite
! nodes and weights between
! the integration limits XMI and XMA
! for the chosen number of nodes
! implicitly assuming that the integrand
! goes smoothly towards zero as its approach XMI or XMA
! Note that the nodes and weights are modified
! according to
! Inf
! int f(x)*exp(-x^2/2)/sqrt(2*pi)dx=sum f(bp(j))*wf(j)
! -Inf j
IF (XMA.LE.XMI) THEN
!PRINT * , 'Warning XMIN>=XMAX in GAUSSHE0 !',XMI,XMA
RETURN ! no more nodes added
ENDIF
IF (N0.GT.NHeW) THEN
!PRINT * , 'error in GAUSSHE0, quadrature not available'
STOP
ENDIF
DO J = HeIND(N0)+1, HeIND(N0+1)
BPout (N+1) = HeBP (J) * SQTWO
IF (BPout (N+1).GT.XMA) THEN
RETURN
END IF
IF (BPout (N+1).GE.XMI) THEN
N=N+1 ! add the node
WFout (N) = HeWF (J) * SQPI1
END IF
ENDDO
RETURN
END SUBROUTINE GAUSSHE0
SUBROUTINE GAUSSLA0 (N, WFout, BPout, XMI, XMA, N0)
USE GLOBALDATA, ONLY : SQPI1
! USE QUAD, ONLY : LaBP5,LaWF5,LaIND,NLaW
IMPLICIT NONE
INTEGER, INTENT(in) :: N0
INTEGER, INTENT(inout) :: N
DOUBLE PRECISION, DIMENSION(:), INTENT(out) :: wfout,bpout
DOUBLE PRECISION, INTENT(in) :: XMI, XMA
INTEGER :: J
! The subroutine returns modified Gauss-Laguerre
! nodes and weights for alpha=-0.5 between
! the integration limits XMI and XMA
! for the chosen number of nodes
! implicitly assuming the integrand
! goes smoothly towards zero as its approach XMI or XMA
! Note that the nodes and weights are modified
! according to
! Inf
! int f(x)*exp(-x^2/2)/sqrt(2*pi)dx=sum f(bp(j))*wf(j)
! 0 j
IF (XMA.LE.XMI) THEN
!PRINT * , 'Warning XMIN>=XMAX in GAUSSLA0 !',XMI,XMA
RETURN !no more nodes added
ENDIF
IF (N0.GT.NLaW) THEN
!PRINT * , 'error in GAUSSLA0, quadrature not available'
STOP
ENDIF
DO J = LaIND(N0)+1, LaIND(N0+1)
IF (XMA.LE.0.d0) THEN
BPout (N+1) = -SQRT(2.d0*LaBP5(J))
ELSE
BPout (N+1) = SQRT(2.d0*LaBP5(J))
END IF
IF (BPout (N+1).GT.XMA) THEN
RETURN
END IF
IF (BPout (N+1).GE.XMI) THEN
N=N+1 ! add the node
WFout (N) = LaWF5 (J)*0.5d0*SQPI1
END IF
ENDDO
!PRINT *,'gaussla0, bp',LaBP5(LaIND(N0)+1:LaIND(N0+1))
!PRINT *,'gaussla0, wf',LaWF5(LaIND(N0)+1:LaIND(N0+1))
RETURN
END SUBROUTINE GAUSSLA0
SUBROUTINE GAUSSQ(N, WF, BP, XMI, XMA, N0)
USE GLOBALDATA, ONLY : xCutOff
! USE QUAD , ONLY : minQNr
IMPLICIT NONE
INTEGER, INTENT(in) :: N0
INTEGER, INTENT(inout) :: N
DOUBLE PRECISION, DIMENSION(:), INTENT(out) :: wf,bp
DOUBLE PRECISION, INTENT(in) :: XMI,XMA
INTEGER :: N1
! The subroutine returns
! nodes and weights between
! the integration limits XMI and XMA
! for the chosen number of nodes
! Note that the nodes and weights are modified
! according to
! Inf
! int f(x)*exp(-x^2/2)/sqrt(2*pi)dx=sum f(bp(j))*wf(j)
! 0 j
!IF (XMA.LE.XMI) THEN
! PRINT * , 'Warning XMIN>=XMAX in GAUSSQ !',XMI,XMA
! RETURN !no more nodes added
!ENDIF
CALL GAUSSLE0(N,WF,BP,XMI,XMA,N0)
RETURN
IF ((XMA.GE.xCutOff).AND.(XMI.LE.-xCutOff)) THEN
CALL GAUSSHE0(N,WF,BP,XMI,XMA,N0)
ELSE
CALL GAUSSLE2(N,WF,BP,XMI,XMA,N0)
RETURN
IF (((XMA.LT.xCutOff).AND.(XMI.GT.-xCutOff)).OR.(.TRUE.)
& .OR.(XMI.GT.0.d0).OR.(XMA.LT.0.d0)) THEN
! Grid by Gauss-LegENDre quadrature
CALL GAUSSLE2(N,WF,BP,XMI,XMA,N0)
ELSE
! this does not work well
!PRINT *,'N0',N0,N
N1=CEILING(DBLE(N0)/2.d0)
IF (XMA.GE.xCutOff) THEN
IF (XMI.LT.0.d0) THEN
CALL GAUSSLE2 (N, WF, BP,XMI ,0.d0,N0)
ENDIF
CALL GAUSSLA0 (N, WF, BP,0.d0, XMA, N1)
ELSE
IF (XMA.GT.0.d0) THEN
CALL GAUSSLE2 (N, WF,BP,0.d0,XMA,N0)
ENDIF
CALL GAUSSLA0 (N, WF,BP,XMI,0.d0, N1)
END IF
END IF
ENDIF
!PRINT *,'gaussq, wf',wf(1:N)
!PRINT *,'gaussq, bp',bp(1:N)
RETURN
END SUBROUTINE GAUSSQ
END MODULE QUAD
MODULE RIND71MOD
IMPLICIT NONE
PRIVATE
PUBLIC :: RIND71, INITDATA, SETDATA,ECHO
INTERFACE
FUNCTION MVNFUN(N,Z) result (VAL)
DOUBLE PRECISION,DIMENSION(:), INTENT(IN) :: Z
INTEGER, INTENT(IN) :: N
DOUBLE PRECISION :: VAL
END FUNCTION MVNFUN
END INTERFACE
INTERFACE
FUNCTION MVNFUN2(N,Z) result (VAL)
DOUBLE PRECISION,DIMENSION(:), INTENT(IN) :: Z
INTEGER, INTENT(IN) :: N
DOUBLE PRECISION :: VAL
END FUNCTION MVNFUN2
END INTERFACE
INTERFACE
FUNCTION FI( Z ) RESULT (VALUE)
DOUBLE PRECISION, INTENT(in) :: Z
DOUBLE PRECISION :: VALUE
END FUNCTION FI
END INTERFACE
INTERFACE
FUNCTION FIINV( Z ) RESULT (VALUE)
DOUBLE PRECISION, INTENT(in) :: Z
DOUBLE PRECISION :: VALUE
END FUNCTION FIINV
END INTERFACE
INTERFACE
FUNCTION JACOB(XD,XC) RESULT (VALUE)
DOUBLE PRECISION, DIMENSION(:), INTENT(in) :: XD,XC
DOUBLE PRECISION :: VALUE
END FUNCTION JACOB
END INTERFACE
INTERFACE RIND71
MODULE PROCEDURE RIND71
END INTERFACE
INTERFACE SETDATA
MODULE PROCEDURE SETDATA
END INTERFACE
INTERFACE INITDATA
MODULE PROCEDURE INITDATA
END INTERFACE
INTERFACE ARGP0
MODULE PROCEDURE ARGP0
END INTERFACE
INTERFACE RINDDND
MODULE PROCEDURE RINDDND
END INTERFACE
INTERFACE RINDSCIS
MODULE PROCEDURE RINDSCIS
END INTERFACE
INTERFACE RINDNIT
MODULE PROCEDURE RINDNIT
END INTERFACE
INTERFACE BARRIER
MODULE PROCEDURE BARRIER
END INTERFACE
INTERFACE echo
MODULE PROCEDURE echo
END INTERFACE
INTERFACE swapRe
MODULE PROCEDURE swapRe
END INTERFACE
INTERFACE swapint
MODULE PROCEDURE swapint
END INTERFACE
INTERFACE getdiag
MODULE PROCEDURE getdiag
END INTERFACE
INTERFACE CONDSORT0
MODULE PROCEDURE CONDSORT0
END INTERFACE
INTERFACE CONDSORT
MODULE PROCEDURE CONDSORT
END INTERFACE
INTERFACE CONDSORT2
MODULE PROCEDURE CONDSORT2
END INTERFACE
INTERFACE CONDSORT3
MODULE PROCEDURE CONDSORT3
END INTERFACE
INTERFACE CONDSORT4
MODULE PROCEDURE CONDSORT4
END INTERFACE
CONTAINS
SUBROUTINE SETDATA(method,scale, dEPSS,dREPS,dEPS2,
& dNIT,dXc, dNINT,dXSPLT)
USE GLOBALDATA
USE FIMOD
USE QUAD, ONLY: sizNint,Nint1,minQnr,Le2Qnr
IMPLICIT NONE
DOUBLE PRECISION , INTENT(in) :: scale, dEPSS,dREPS
DOUBLE PRECISION , INTENT(in) :: dEPS2,dXc, dXSPLT
!INTEGER, DIMENSION(:), INTENT(in) :: dNINT
INTEGER, INTENT(in) :: method,dNINT,dNIT
INTEGER :: N=1
!N=SIZE(dNINT)
IF (sizNint.LT.N) THEN
!PRINT *,'Error in setdata, Nint too large'
N=sizNint
ENDIF
NINT1(1:N)=dNINT !(1:N) ! quadrature formulae for the Xd variables
IF (N.LT.sizNint) THEN
NINT1(N:sizNint)=NINT1(N)
END IF
minQnr = 1
Le2Qnr = NINT1(1)
SCIS = method
XcScale = scale
RelEps = dREPS
EPSS = dEPSS ! accuracy of integration
CEPSS = 1.d0 - EPSS
EPS2 = dEPS2 ! Constants controlling
EPS = SQRT(EPS2)
xCutOff = dXc
XSPLT = dXSPLT
NIT = dNIT
IF (Nc.LT.1) NUGGET=0.d0 ! Nugget is not needed when Nc=0
IF (EPSS.LE.1e-4) NsimMax=2000
IF (EPSS.LE.1e-5) NsimMax=4000
IF (EPSS.LE.1e-6) NsimMax=8000
RETURN
IF (.FALSE.) THEN
print *,'Requested parameters :'
SELECT CASE (SCIS)
CASE (:0)
PRINT *,'NIT = ',NIT,' integration by quadrature'
CASE (1)
PRINT *,'SCIS = 1 SADAPT if NDIM<9 otherwise by KRBVRC'
CASE (2)
PRINT *,'SCIS = 2 SADAPT if NDIM<20 otherwise by KRBVRC'
CASE (3)
PRINT *,'SCIS = 3 KRBVRC (Ndim<101)'
CASE (4)
PRINT *,'SCIS = 4 KROBOV (Ndim<101)'
CASE (5)
PRINT *,'SCIS = 5 RCRUDE (Ndim<1001)'
CASE (6)
PRINT *,'SCIS = 6 SOBNIED (Ndim<1041)'
CASE (7:)
PRINT *,'SCIS = 7 DKBVRC (Ndim<1001)'
END SELECT
PRINT *,'EPSS = ', EPSS, ' RELEPS = ' ,RELEPS
PRINT *,'EPS2 = ',EPS2, ' xCutOff = ',xCutOff
PRINT *,'NsimMax = ',NsimMax !,FIINV(EPSS)
ENDIF
RETURN
END SUBROUTINE SETDATA
SUBROUTINE INITDATA (speed)
USE GLOBALDATA
USE FIMOD
USE QUAD, ONLY: sizNint,Nint1,minQnr,Le2Qnr
IMPLICIT NONE
INTEGER , INTENT(in) :: speed
SELECT CASE (speed)
CASE (9:)
NINT1 (1) = 2
NINT1 (2) = 3
NINT1 (3) = 4
CASE (8)
NINT1 (1) = 3
NINT1 (2) = 4
NINT1 (3) = 5
CASE (7)
NINT1 (1) = 4
NINT1 (2) = 5
NINT1 (3) = 6
CASE (6)
NINT1 (1) = 5
NINT1 (2) = 6
NINT1 (3) = 7
CASE (5)
NINT1 (1) = 6
NINT1 (2) = 7
NINT1 (3) = 8
CASE (4) ! quadrature formulae for the Xd variables
NINT1 (1) = 7 ! use quadr. form. No. 6 in integration of Xd(1)
NINT1 (2) = 8 ! use quadr. form. No. 7 in integration of Xd(2)
NINT1 (3) = 9 ! use quadr. form. No. 8 in integration of Xd(3)
CASE (3)
NINT1 (1) = 8
NINT1 (2) = 9
NINT1 (3) = 10
CASE (2)
NINT1 (1) = 9
NINT1 (2) = 10
NINT1 (3) = 11
CASE (:1)
NINT1 (1) = 11
NINT1 (2) = 12
NINT1 (3) = 13
END SELECT
NsimMax=1000*abs(10-min(speed,9))
NsimMin=0
SELECT case (speed)
CASE (11:)
EPSS = 1d-1
CASE (10)
EPSS = 1d-2
CASE (7:9)
EPSS = 1d-3
CASE (4:6)
EPSS = 1d-4
CASE (:3)
EPSS = 1d-5
END SELECT
EPSS=EPSS*1d-1
RELEPS = MIN(EPSS ,1.d-2)
EPS2=EPSS*1.d1
!EPS2*1.d+1
!EPS2=1.d-10
!xCutOff=MIN(MAX(ABS(FIINV(EPSS)),3.5d0),5.d0)
!xCutOff=ABS(FIINV(EPSS*1.d-1)) ! this is good
xCutOff=ABS(FIINV(EPSS))
!xCutOff=ABS(FIINV(EPSS*5.d-1))
if (SCIS.gt.0) then
xCutOff= MIN(MAX(xCutOff+0.5d0,4.d0),5.d0)
! This gives approximately the same accuracy as when using RINDDND and RINDNIT
EPSS=EPSS*1.d+2
!EPS2=1.d-10
endif
NINT1(1:sizNint)=NINT1(3)
Le2Qnr=NINT1(1)
minQnr=1 ! minimum quadrature No. used in GaussLe1,Gaussle2
NUGGET = EPS2*1.d-1
IF (Nc.LT.1) NUGGET=0.d0 ! Nugget is not needed when Nc=0
EPS = SQRT(EPS2)
CEPSS = 1.d0 - EPSS
! If SCIS=0 then the absolute error is usually less than EPSS*100
! otherwise absolute error is less than EPSS
return
IF (.FALSE.) THEN
print *,'Requested parameters :'
SELECT CASE (SCIS)
CASE (:0)
PRINT *,'NIT = ',NIT,' integration by quadrature'
CASE (1)
PRINT *,'SCIS = 1 SADAPT if NDIM<9 otherwise by KRBVRC'
CASE (2)
PRINT *,'SCIS = 2 SADAPT if NDIM<19 otherwise by KRBVRC'
CASE (3)
PRINT *,'SCIS = 3 KRBVRC (Ndim<101)'
CASE (4)
PRINT *,'SCIS = 4 KROBOV (Ndim<101)'
CASE (5)
PRINT *,'SCIS = 5 RCRUDE (Ndim<1001)'
CASE (6)
PRINT *,'SCIS = 6 SOBNIED (Ndim<1041)'
CASE (7:)
PRINT *,'SCIS = 7 DKBVRC (Ndim<1001)'
END SELECT
PRINT *,'EPSS = ', EPSS, ' RELEPS = ' ,RELEPS
PRINT *,'EPS2 = ',EPS2, ' xCutOff = ',xCutOff
PRINT *,'NsimMax = ',NsimMax !,FIINV(EPSS)
ENDIF
RETURN
END SUBROUTINE INITDATA
SUBROUTINE ECHO(array)
INTEGER ::j
DOUBLE PRECISION,DIMENSION(:,:)::array
DO j=1,size(array,1)
PRINT 111,j,array(j,:)
111 FORMAT (i2,':',10F10.5)
END DO
END SUBROUTINE ECHO
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!******************* RIND71 - the main program *********************!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE RIND71(fxind,BIG1,Ex,xc1,Nt1,indI,Blo,Bup)
USE FUNCMOD, ONLY : BIG, Cm,CmN,xd,xc
USE GLOBALDATA, ONLY :Nt,Nj,Njj,Nd,Nc,Nx,Ntd,Ntdc,NsXtmj,NsXdj,
& indXtd,index1,xedni,SQ,Hlo,Hup,fxcepss,EPS2,XCEPS2,NIT,
& SQTWOPI1,xCutOff,SCIS,Ntscis,COVix,EPS, xcScale
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), INTENT(in) :: BIG1
DOUBLE PRECISION, DIMENSION(:,:), INTENT(in) :: xc1
DOUBLE PRECISION, DIMENSION(:), INTENT(in) :: Ex
DOUBLE PRECISION, DIMENSION(:), INTENT(out):: fxind
DOUBLE PRECISION, DIMENSION(:,:), INTENT(in) :: Blo, Bup
INTEGER, DIMENSION(:), INTENT(in) :: indI
INTEGER, INTENT(IN) :: Nt1
! local variables
INTEGER :: J,ix,Ntdcmj,Nst,Nsd,INFORM
DOUBLE PRECISION :: xind,SQ0,xx,fxc,quant
! IF (.NOT.PRESENT(xcScale)) THEN
! xcScale = 0.0d0
! ENDIF
Nt =Nt1
!print *,'rindd SCIS',SCIS
Nc = size(xc1,dim=1)
Nx = MAX(size(xc1,dim=2),1)
Ntdc = size(BIG1,dim=1)
IF (Nt+Nc.GT.Ntdc) Nt=Ntdc-Nc ! make sure it does not exceed Ntdc-Nc
Nd = Ntdc - Nt - Nc
Ntd = Nt + Nd
!Initialization
!Call Initdata(speed)
Nj = MIN(Nj,MAX(Nt,0)) ! make sure Nj<=Nt
Njj = MIN(Njj,MAX(Nt-Nj,0)) ! make sure Njj<=Nt-Nj
ALLOCATE(xc(1:Nc))
IF (Nd.GT.0) THEN
ALLOCATE(xd(1:Nd))
xd = 0.d0
END IF
If (SCIS.GT.0) then
Ntscis=Nt-Nj-Njj
ALLOCATE(SQ(1:Ntd,1:Ntd)) ! Cond. stdev's
ALLOCATE(NsXtmj(1:Ntd+1)) ! indices to stoch. var. See condsort
else
Ntscis=0
ALLOCATE(SQ(1:Ntd,1:max(Njj+Nj+Nd,1)) ) ! Cond. stdev's
ALLOCATE(NsXtmj(1:Nd+Nj+Njj+1)) ! indices to stoch. var. See condsort
endif
ALLOCATE(BIG(Ntdc,Ntdc))
ALLOCATE(Cm(Ntdc),CmN(Ntd)) !Cond. mean which has the same order as local
Cm = 0.d0 !covariance matrices (after sorting) or excluding
!irrelevant variables.
ALLOCATE(index1(Ntdc)) ! indices to the var. original place in BIG
index1=(/(J,J=1,Ntdc)/) ! (before sort.)
ALLOCATE(xedni(Ntdc)) ! indices to var. new place (after sorting),
xedni=index1 ! eg. the point xedni(1) is the original position
! of variable with conditional mean CM(1).
ALLOCATE(Hlo(Ntd)) ! lower and upper integration limits are computed
! in the new order that is the same as CM.
! This convention is expressed in the vector indXTD.
Hlo = 0.d0 ! However later on some variables will be exluded
! since those are irrelevant and hence CMnew(1)
! does not to be conditional mean of the same variable
! as CM(1) is from the beginning. Consequently
ALLOCATE(Hup(Ntd)) ! the order of Hup, Hlo will be unchanged. So we need
Hup=0.d0 ! to know where the relevant variables bounds are
! This will be given in the subroutines by a vector indS.
ALLOCATE(NsXdj(Nd+Nj+1)) ! indices to stoch. var. See condsort
NsXdj=0
ALLOCATE(indXtd(Ntd)) ! indices to Xt and Xd as they are
indXtd=(/(J,J=1,Ntd)/) ! sorted in Hlo and Hup
BIG = BIG1(1:Ntdc,1:Ntdc) !conditional covariance matrix BIG
IF (.TRUE.) THEN ! sort by shortest expected int. interval
Cm = Ex (1:Ntdc)
!xc = SUM(xc1(1:Nc,1:Nx),DIM=2)/DBLE(Nx) ! average of all xc's
xc = xc1(1:Nc,max(Nx/2,1)) ! Or select the one in the middle
CALL BARRIER(xc,indI,Blo,Bup) ! compute average integrationlimits
! print *,'rindd,xcmean:',xc
! print *,'rindd,Hup:',Hup
! print *,'rindd,Hlo:',Hlo
CALL CONDSORT0(BIG,Cm,xc,SQ,index1,xedni,NsXtmj,NsXdj,INFORM)
ELSE ! sort by decreasing cond. variance
CALL CONDSORT (BIG,SQ,index1,xedni,NsXtmj,NsXdj,INFORM)
ENDIF
IF (INFORM.GT.0) GOTO 110 !Degenerated case the density can not computed
! PRINT *, 'index=', index1
! PRINT *,(sqrt(BIG(J,J)),J=1,Ntdc)
! PRINT *, 'BIG'
! CALL ECHO(BIG(1:Ntdc,1:MIN(Ntdc,10)))
!PRINT *, 'xedni=', xedni
!print *,'NsXtmj=',NsXtmj
!print *,'NsXdj=',NsXdj
fxind = 0.d0 ! initialize
! Now the loop over all different values of
! variables Xc (the one one is conditioning on)
DO ix = 1, Nx ! is started. The density f_{Xc}(xc(:,ix))
COVix = ix ! will be computed and denoted by fxc.
xind = 0.d0
fxc = 1.d0
! Cm = Ex (1:Ntdc)
! index1=(/(J,J=1,Ntdc)/)
! xedni=index1
! BIG = BIG1(1:Ntdc,1:Ntdc)
! CALL BARRIER(xc1(1:Nc,ix),indI,Blo,Bup) ! integrationlimits
! CALL CONDSORT0 (BIG,Cm,xc1(:,ix),SQ, index1,
! & xedni, NsXtmj,NsXdj)
! Set the original means of the variables
Cm =Ex (index1(1:Ntdc)) ! Cm(1:Ntdc) =Ex (index1(1:Ntdc))
quant = 0.0d0
DO J = 1, Nc !Recursive conditioning on the last Nc variables
Ntdcmj=Ntdc-J
SQ0 = BIG(Ntdcmj+1,Ntdcmj+1) ! SQRT(var(X(i)|X(i+1),X(i+2),...,X(Ntdc)))
! i=Ntdc-J+1 (J=1 var(X(Ntdc))
xx = (xc1(index1(Ntdcmj+1)-Ntd,ix)-Cm(Ntdcmj+1))/SQ0
!Trick to calculate
!fxc = fxc*SQTWPI1*EXP(-0.5*(XX**2))/SQ0
quant = quant - 0.5d0 * xx * xx + LOG(SQTWOPI1) - LOG(SQ0)
! conditional mean (expectation)
! E(X(1:i-1)|X(i),X(i+1),...,X(Ntdc))
Cm(1:Ntdcmj) = Cm(1:Ntdcmj)+xx*BIG (1:Ntdcmj,Ntdcmj+1)
ENDDO
! fxc probability density for i=Ntdc-J+1,
! fXc=f(X(i)|X(i+1),X(i+2)...X(Ntdc))*
! f(X(i+1)|X(i+2)...X(Ntdc))*..*f(X(Ntdc))
fxc = EXP(QUANT+XcScale)
!print *,'density',fxc ! J
!PRINT *, 'Rindd, Cm=',Cm(xedni(max(1,Nt-5):Ntdc))
!PRINT *, 'Rindd, Cm=',Cm(xedni(1:Ntdc))
!IF (fxc .LT.fxcEpss) print *,'small, fxc=',fxc
IF (fxc .LT.fxcEpss) GOTO 100 ! Small probability don't bother calculating it
!set the global integration limits Hlo,Hup
CALL BARRIER(xc1(1:Nc,ix),indI,Blo,Bup)
Nst = NsXtmj(Ntscis+Njj+Nd+Nj+1)
Nsd = NsXdj(Nd+Nj+1)
IF (any((Cm(Nst+1:Nsd-1) .GT.Hup(Nst+1:Nsd-1)+EPS ).OR.
* (Cm (Nst+1:Nsd-1)+EPS .LT.Hlo (Nst+1:Nsd-1)))) GO TO 100 !degenerate case
!mean of deterministic variable(s) is
! outside the barriers
!PRINT *,'RINDD SCIS',SCIS
IF (SCIS.GE.1.AND.SCIS.LE.9) then ! integrate all by SCIS
XIND=RINDSCIS(xc1(:,ix))
GO TO 100
endif
SELECT CASE (Nd+Nj)
CASE (:0)
IF (SCIS.NE.0) then ! integrate all by SCIS
XIND=MNORMPRB(Cm(1:Nst))
ELSE
XIND=RINDNIT(BIG,SQ(1:Nst,1),Cm,indXtd(1:Nst),NIT)
END IF
CASE (1:)
xind=RINDDND(BIG,Cm,xd,xc1(:,ix),Nd,Nj)
END SELECT
100 fxind(ix)=xind*fxc
!IF (fxc .LT.fxcEpss) print *,'small, fxc, xind',fxc,xind
!PRINT *, 'Rindd, Cm=',Cm(xedni(1:Ntdc))
ENDDO !ix
! PRINT *, 'Rindd, Cm=',Cm(xedni(1:Ntdc))
110 CONTINUE
IF (ALLOCATED(xc)) DEALLOCATE(xc)
IF (ALLOCATED(xd)) DEALLOCATE(xd)
IF (ALLOCATED(SQ)) DEALLOCATE(SQ)
IF (ALLOCATED(NsXtmj)) DEALLOCATE(NsXtmj)
IF (ALLOCATED(Cm)) DEALLOCATE(Cm)
IF (ALLOCATED(CmN)) DEALLOCATE(CmN)
IF (ALLOCATED(BIG)) DEALLOCATE(BIG)
IF (ALLOCATED(index1)) DEALLOCATE(index1)
IF (ALLOCATED(xedni)) DEALLOCATE(xedni)
! print *,'before dealocation',Ntd,size(Hup),size(Hlo)
IF (ALLOCATED(Hlo)) DEALLOCATE(Hlo)
IF (ALLOCATED(Hup)) DEALLOCATE(Hup)
IF (ALLOCATED(NsXdj)) DEALLOCATE(NsXdj)
IF (ALLOCATED(indXtd)) DEALLOCATE(indXtd)
RETURN
END SUBROUTINE RIND71
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!*************************** ARGP0 *********************************!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE ARGP0 (I0,I1,P0,Plo,SQ,Cm,indS,ind,Nind)
USE FIMOD
USE GLOBALDATA, ONLY : Hlo,Hup,xCutOff,EPSS,EPS2,EPS
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:), INTENT(in) :: SQ , Cm !stdev./mean
INTEGER, DIMENSION(:), INTENT(in) :: indS
INTEGER, DIMENSION(:), INTENT(out) :: ind
DOUBLE PRECISION, INTENT(out) :: P0,Plo
INTEGER, INTENT(out) :: I0, I1
INTEGER, INTENT(out) :: Nind
DOUBLE PRECISION :: P1,Prb
DOUBLE PRECISION :: Xup, Xlo
INTEGER :: I, Nstoc
! indS contains the indices to the limits
Nstoc = SIZE(indS) ! in Hlo/Hup of variables in the indicator
! ind contains indices to the relevant
! variables which are Nind<=Nstoc.
! We wish to compute P(Hlo<X<Hup) but
! only have lower and upper bounds Plo,P0, resp.
! I0 is the position of the minimal
! probability in the vector ind, i.e.
! P0=P(Hlo<X(indS(ind(I0)))<Hup)
! I1 is the second minimum.
P0 = 2.d0
P1 = 2.d0
I0 = 1
I1 = 1
Plo = 0.d0
Nind = 0
DO I = 1,Nstoc,1
Xup = xCutOff
Xlo =-xCutOff
IF (SQ(I).GE.EPS2) THEN
Xup = MIN( (Hup (indS(I)) - Cm (I))/ SQ(I),Xup)
Xlo = MAX( (Hlo (indS(I)) - Cm (I))/ SQ(I),Xlo)
ELSE
IF (Hup(indS(I))+EPS.LT.Cm (I)) Xup = Xlo
IF (Hlo(indS(I)).GT.Cm (I)+EPS) Xlo = Xup
!PRINT *,'argpo',Xlo,Xup
END IF
IF (Xup.LE.Xlo+EPSS) THEN ! +EPSS
P0 = 0.d0
Plo = 0.d0
ind(1) = I
I0 = 1
Nind = 1
RETURN
ENDIF
IF ((Xup+EPSS.LT.xCutOff).or.(Xlo+xCutOff.GT.EPSS)) THEN
Nind = Nind+1
ind(Nind) = I
! this procedure calculates
Prb = FI(Xup)-FI(Xlo)
Plo = Plo+Prb
IF (Prb.LT.P0) THEN
I1 = I0
I0 = Nind
P1 = P0 ! Prob(I0)=Prob(XMA>X(i0)>XMI)=
P0 = Prb ! min Prob(Hup(i)> X(i)>Hlo(i))
IF (P0.LT.EPSS) THEN
Plo=0.d0
RETURN
ENDIF
ELSEIF (Prb.LT.P1) THEN
I1 = Nind
P1 = Prb
ENDIF
ENDIF
ENDDO
Plo = MAX(0.d0,1.d0-DBLE(Nind)+Plo)
P0 = MIN(1.d0,P0)
! print *,'ARGP0',Nstoc,Nind,P0,Plo,I0,I1,CM(ind(I0))
RETURN
END SUBROUTINE ARGP0
!Ntmj is the number of elements in indicator
!since Nj points of process valeus (Nt) have
!been moved to the jacobian.
!index1 contains the original
!positions of variables in the
!covaraince matrix before condsort
!and that why if index(Ntmj+1)>Nt
!it means the variable to conditon on
!is a derivative isXd=1
!= # stochastic variables before
!conditioning on X(Ntmj+1). This
!I still not checked why.
! ******************* RINDDND ****************************************
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RECURSIVE FUNCTION RINDDND (BIG,Cm,xd,xc,Ndleft,Njleft)
& RESULT (xind)
USE JACOBMOD
USE GLOBALDATA, ONLY :SQPI1, SQTWOPI1,Hup,Hlo,Nt,Nj,Njj,Nd,
& NsXtmj,NsXdj,EPS2,NIT,xCutOff,EPSS,CEPSS,index1,
& indXtd,SQ,SQTWO,SQTWO1,SCIS,Ntscis,C1C2det,EPS
USE FIMOD
USE C1C2MOD
USE QUAD
IMPLICIT NONE
INTEGER,INTENT(in) :: Ndleft,Njleft ! # DIMENSIONs to integrate
DOUBLE PRECISION, DIMENSION(:,:), INTENT(inout) :: BIG
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: Cm ! conditional mean
DOUBLE PRECISION, DIMENSION(: ), INTENT(inout) :: xd ! integr. variables
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: xc ! conditional values
!local variables
DOUBLE PRECISION :: xind
DOUBLE PRECISION :: xind1
DOUBLE PRECISION, DIMENSION(PMAX) :: WXdi, Xdi !weights/nodes
DOUBLE PRECISION, DIMENSION(: ), ALLOCATABLE :: CmNEW
INTEGER :: Nrr, Nr, J, N,Ndleft1,Ndjleft,Ntmj,isXd
INTEGER :: Nst,Nstn,Nsd,NsdN
DOUBLE PRECISION :: SQ0,fxd,XMA,XMI
Ntmj=Nt-Nj
Ndjleft= Ndleft+Njleft
N=Ntmj+Ndjleft
IF (index1(N).GT.Nt) THEN
isXd=1
ELSE
isXd=0
END IF
XIND = 0.d0
SQ0 = BIG (N, N)
! index to last stoch. variable of Xt before conditioning on X(N)
Nst = NsXtmj(Ntscis+Njj+Ndjleft+1)
!********************************************************************************
!** Here Starts the degenerated case the remaining variables are deterministic **
!********************************************************************************
IF (SQ0.LT.EPS2) THEN
!Next is the check for the special situation
!that after conditioning on Xc all derivatives are
!singular and not satisfying the limitations
!(so something is generally wrong)
IF (any((Cm(Nst+1:N).GT.Hup(Nst+1:N)+EPS ).OR.
& (Cm(Nst+1:N)+EPS.LT.Hlo(Nst+1:N)))) THEN
RETURN !the mean of Xd or Xt is too extreme
ENDIF
!Here we are putting in all conditional expectations
!for the values of the "deterministic" derivatives.
IF (Nd.GT.0) THEN
Ndleft1=Ndleft
DO WHILE (Ndleft1.GT.0)
IF (index1(N).GT.Nt) THEN ! isXd
xd (Ndleft1) = Cm (N)
Ndleft1=Ndleft1-1
END IF
N=N-1
ENDDO
fxd = jacob (xd,xc) ! jacobian of xd,xc
ELSE
fxd = 1.d0 ! XIND = FxCutOff???
END IF
XIND=fxd
IF (Nst.le.0) RETURN
IF (SCIS.ne.0) then
XIND=fxd*MNORMPRB(Cm(1:Nst))
ELSE
XIND=fxd*RINDNIT(BIG,SQ(:,Ntscis+Njj+1),
& Cm,indXtd(1:Nst),NIT)
END IF
RETURN
ENDIF
!***** Here Starts the conditioning on the last variable (nondeterministic) *
!****************************************************************************
! SQ0 = SQ(N,Ntscis+Njj+Ndjleft) !SQRT (SS0)
!print *,'RINDD SQO', SQ0,SQ(N,Ntscis+Njj+Ndjleft) !SQ(1:N,Ndjleft)
XMA=MIN((Hup (indXtd(N))-Cm (N))/SQ0, xCutOff)
XMI=MAX((Hlo (indXtd(N))-Cm (N))/SQ0,-xCutOff)
! See if we can narrow down integration range
! index to first stoch. variable of Xd before conditioning on X(N)
Nsd = NsXdj(Ndjleft+1)
! index to last stoch. variable of Xt after cond. on X(N)
NstN = NsXtmj(Ntscis+Njj+Ndjleft)
!PRINT *,xmi,xma
! print *,Ntscis+Njj+Ndjleft
! print *,'CM=',Cm(1:N-1)
! print *,'SQ=', SQ(1:N-1,Ntscis+Njj+Ndjleft)
if (C1C2det) then ! checking only on the variables that becomes deterministic
! index to first stoch. variable of Xd after conditioning on X(N)
NsdN = NsXdj(Ndjleft)
CALL C1C2(XMI,XMA,Cm(Nsd:NsdN-1),BIG(Nsd:NsdN-1,N),
& SQ(Nsd:NsdN-1,Ntscis+Njj+Ndjleft),indXtd(Nsd:NsdN-1))
CALL C1C2(XMI,XMA,Cm(NstN+1:Nst),BIG(NstN+1:Nst,N),
& SQ(NstN+1:Nst,Ntscis+Njj+Ndjleft),indXtd(NstN+1:Nst))
else ! check on all variables
CALL C1C2(XMI,XMA,Cm(Nsd:N-1),BIG(Nsd:N-1,N),
& SQ(Nsd:N-1,Ntscis+Njj+Ndjleft),indXtd(Nsd:N-1))
CALL C1C2(XMI,XMA,Cm(1:Nst),BIG(1:Nst,N),
& SQ(1:Nst,Ntscis+Njj+Ndjleft),indXtd(1:Nst))
endif
! CALL C1C2(XMI,XMA,Cm(1:N-1),BIG(1:N-1,N),
! & SQ(1:N-1,Ntscis+Njj+Ndjleft),SQ0,indXtd(1:N-1))
!PRINT *,xmi,xma
! if (Ndleft<2) stop
IF (XMA.LE.XMI) THEN
XIND=0.d0
RETURN
ENDIF
Nrr = NINT1 (MIN(Ndjleft,sizNint))
Nr=0 ! initialize # of nodes
!print *, 'rinddnd Nrr',Nrr
!Grid the interval [XMI,XMA] by GAUSS quadr.
CALL GAUSSLE2(Nr, WXdi, Xdi,XMI,XMA, Nrr)
!print *, 'Xdi',Xdi
ALLOCATE(CmNEW(1:N-1))
! The following variables are independent of X(N)
! because BIG(Nst+1:Nsd-1,N) is set to 0 in condsrort.
! Thus the mean is not changed for these variables
! in order to avoid numerical problems
! The following if test is necessary on Solaris F90 compiler.
if (Nst+1.LT.Nsd) CmNEW(Nst+1:Nsd-1)=Cm(Nst+1:Nsd-1)
! print *,Ndjleft,N,NstN+1,Nsd-1
! print *,BIG(Nst+1:Nsd-1,N)
! print *,'Cm=',Cm(NstN+1:Nsd-1)
DO J = 1, Nr
! IF (Wxdi(J).GT.(CFxCutOff)) GO TO 100 !THEN ! EPSS???
IF (isXd.EQ.1) xd (Ndleft) = Xdi (J)*SQ0 + Cm (N)
! Here we start with the case when there
! some derivatives left to integrate.
! The following if test is necessary on Solaris F90 compiler.
if (1.LE.Nst) CmNEW(1:Nst) = Cm(1:Nst)+Xdi(J)*BIG(1:Nst,N)
if (Nsd.LT.N) CmNEW(Nsd:(N-1)) = Cm(Nsd:(N-1))+
& Xdi(J)*BIG(Nsd:(N-1),N)
!print *,'CmNew=',N-1,Ndjleft,CmNew(1:N-1)
fxd = Wxdi(J)
IF (Ndjleft.GT.1) THEN
XIND1=RINDDND(BIG,CmNEW,xd,xc,Ndleft-isXd,Njleft-1+isXd)
ELSE ! Here all is conditioned on
! and we wish to compute the
! conditional probability that
! variables in indicator stays between barriers.
XIND1 = 1.d0
!if there are derivatives we need
!to compute the jacobian, jacob(xd,xc)
IF (Nd.GT.0) fxd = fxd *jacob(xd(1:Nd),xc)
!If there are no derivatives
!then we assume that jacob(xc)=1
IF (NstN.LT.1) GOTO 100 !Here there are no points in indicator
!left to integrate and hence XIND1=1.
!integrate by Monte Carlo - SCIS
IF (SCIS.NE.0) XIND1 = MNORMPRB(CmNEW)
!integrate by quadrature
IF (SCIS.EQ.0) XIND1 = RINDNIT(BIG,
& SQ(:,Ntscis+Njj+1),CmNEW,indXtd(1:NstN),NIT)
!print *,'jacobian',xind,xind1,xind+fxd*xind1
END IF
100 CONTINUE
XIND = XIND+XIND1 * fxd !END IF
ENDDO
DEALLOCATE(CmNEW)
RETURN
END FUNCTION RINDDND
! ******************* RINDNIT ****************************************
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! old procedure rind2-6
RECURSIVE FUNCTION RINDNIT(R,SQ,Cm,indS,NITL) RESULT (xind)
USE GLOBALDATA, ONLY : Hlo,Hup,EPS2, EPSS,CEPSS
& ,xCutOff,Plowgth,XSPLT
USE FIMOD
USE C1C2MOD
USE QUAD
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), INTENT(in) :: R
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: SQ
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: Cm
DOUBLE PRECISION :: xind
INTEGER, DIMENSION(: ), INTENT(in) :: indS
INTEGER, INTENT(in) :: NITL
! local variables
DOUBLE PRECISION, DIMENSION(:,:), ALLOCATABLE :: RNEW
DOUBLE PRECISION, DIMENSION(: ), ALLOCATABLE :: B,SQnew
DOUBLE PRECISION, DIMENSION(: ), ALLOCATABLE :: CmNEW
INTEGER, DIMENSION(: ), ALLOCATABLE :: indSNEW,ind
INTEGER :: I0,I1
DOUBLE PRECISION, DIMENSION(PMAX) :: H1, XX1
DOUBLE PRECISION :: XIND1,XIND2,SQ0,SQ1,SS0,SS1,SS
DOUBLE PRECISION, DIMENSION(2) :: XMI, XMA
INTEGER, DIMENSION(2) :: INFIN
DOUBLE PRECISION :: SGN,P0,Plo,rho
INTEGER :: Ns,Nsnew,row,r1,r2,J,N1
! Assumption is that there is at least one variable X in the indicator,
! LNIT nonegative integer.
! If LNIT=0 or the number of relevant variables is less then 3, the recursion
! stops. It gives exact value if after removing irrelevant variables there
! are maximum 2 variables left in the indicator. The program is not using
! RIND2 function any more. IR. 28 XI 1999 - Indianapolis.
!
! explanation to variables (above):
! R = cov. matr.
! B = R(I,I0) I=1:Ns
! SQ = SQRT(R(I,I)) I=1:Ns
! Cm = cond. mean
! indS = indices to the stochastic variables as they are stored in
! the global variables Hlo and Hup
! Ns = size of indS =# of variables in indicator before conditioning
! Nsnew = # of relevant variables in indicator before conditioning
! I0,I1 = indicies to minimum prob. and next minimal, respectively
! ..NEW = the var. above after conditioning on X(I0) or used in recursion
! ind = temp. variable storing indices
Ns=SIZE(indS) !=# stochastic variables before conditioning
XIND=1.d0
if (Ns.lt.1) return
ALLOCATE(ind(1:Ns))
CALL ARGP0(I0,I1,P0,Plo,SQ,Cm,indS,ind,NSnew)
! print *,'NSnew,P0,Plo=',NSnew,P0,Plo
!The probability of being between barriers is one
!since there are no relevant variables.
! print *,'NIT',NITl,P0,Plo,Ns,Nsnew
IF (NSnew.lt.1) GOTO 300
XIND=(P0*DBLE(NSnew)+Plowgth*Plo)/(DBLE(NSnew)+Plowgth)
!Lower bound Plo and upper bound P0 are close
!or all variables are close to be irrelevant,
!e.g. Nsnew=1.
IF ((P0.LT.Plo+EPSS).OR.(P0.GT.CEPSS)) GOTO 300
! Now CEPSS>P0>EPSS+Plo and there are more than one relevant variable (NSnew>1)
! Those have indices ind(I0), ind(I1).
! Hence we have nondegenerated case.
SS0 = R (ind(I0) ,ind(I0))
SQ0 = SQRT(SS0)
r1=indS(ind(I0))
! print *,'P0-Plo,SS0,Sq0',P0-Plo,SS0,Sq0
XMA(1) = MIN((Hup (r1)-Cm (ind(I0)))/SQ0,xCutOff)
XMI(1) = MAX((Hlo (r1)-Cm (ind(I0)))/SQ0,-xCutOff)
!If NSnew = 2 then we can compute the probability exactly and recursion stops.
IF ((NSnew.EQ.2).OR.(NITL.LT.1)) THEN !.OR.(NITL.LT.1)
! Not necessary any longer:
! I1=2
! if (I0.eq.2) I1=1
! if (I0.eq.I1) print *,'rindnit, I1,I0:',I1,I0
SS1 = R (ind(I1) ,ind(I1))
SQ1 = SQRT(SS1)
IF (ind(I0).LT.ind(I1)) THEN
SS=R(ind(I0),ind(I1))
ELSE
SS=R(ind(I1),ind(I0))
ENDIF
rho= SS/(SQ0*SQ1)
r2=indS(ind(I1))
XMA(2) = MIN((Hup (r2)-Cm (ind(I1)))/SQ1,xCutOff)
XMI(2) = MAX((Hlo (r2)-Cm (ind(I1)))/SQ1,-xCutOff)
IF (ABS(rho).gt.1.d0+EPSS) THEN
!print *,'rindnit, Correlation > 1, rho=',rho
IF (ABS(rho).gt.1.d0+EPSS) GO TO 300
rho = sign(1.D0,rho)
! print *,'rindnit, P0,Plo',P0,Plo,XIND
! print *,'rindnit I0,I1:',I0,I1
! print *,'rindnit XMI,XMA,XMI1,XMA1:',XMI(1),XMA(1),
! & XMI(2),XMA(2)
! print *,'rindnit cov(I1,I0):',R(ind(I1),ind(I0))
! print *,'rindnit cov(I0,I1):',R(ind(I0),ind(I1))
! print *,'rindnit SS,SS1,SS0:',SS,SS1,SS0
! print *,'rindnit ind:',ind(1:NSnew)
ENDIF
! print *,XMA1,XMI1,XMA,XMI,rho
! XIND = NORM2DPRB(XMI(1),XMA(1),XMI(2),XMA(2),rho)
! GO TO 300
* if INFIN(I) = 0, Ith limits are (-infinity, UPPER(I)];
* if INFIN(I) = 1, Ith limits are [LOWER(I), infinity);
* if INFIN(I) = 2, Ith limits are [LOWER(I), UPPER(I)].
! INFIN = 2
IF (XMI(1).LE.-xCutOff) INFIN(1)=0
IF (XMI(2).LE.-xCutOff) INFIN(2)=0
IF (XMA(1).GE. xCutOff) INFIN(1)=1
IF (XMA(2).GE. xCutOff) INFIN(2)=1
!print *,'rindnit, xind,xind2=', XIND, BVNMVN(XMI,XMA,INFIN,rho)
XIND = BVNMVN(XMI,XMA,INFIN,rho)
! print *,xind
GOTO 300
END IF
!If NITL=0 which means computations without conditioning on X(ind(I0))
IF(NITL.lt.1) GOTO 300
!We have NITL>0 and at least 3 variables in the indicator, ie.
!we will condition on X(ind(I0)).
!First we check whether one can use XSPLIT variant of integration.
if ((XMA(1).GE.xCutOff).AND.(XMI(1).LT.-XSPLT)) THEN ! (.FALSE.).AND.
XMA(1)=XMI(1)
XMI(1)=-xCutOff
SGN=-1.d0
elseif ((XMA(1).GT.XSPLT).AND.(XMI(1).LE.-xCutOff)) THEN
XMI(1)=XMA(1)
XMA(1)=xCutOff
SGN=-1.d0
else
SGN=1.d0
XIND2=0.d0
endif
! Must allocate several variables to recursively
! transfer them to rindnit: Rnew, SQnew, CMnew, indSnew
! The variable B is used in computations of conditional mean and cov.
! The size is NSnew-1 (the relevant variables minus X(ind(I0)).
ALLOCATE(indSNEW(1:NSnew-1))
ALLOCATE(RNEW(NSnew-1,NSnew-1))
ALLOCATE(CMnew(1:NSnew-1))
ALLOCATE(SQnew(1:NSnew-1))
ALLOCATE(B(1:NSnew-1))
!This DO loop is divided in two parts in order
!to only work on the upper triangular of R
DO row=1,I0-1
r1=ind(row)
Rnew(row,row:I0-1)=R(r1,ind(row:I0-1))
! The if test below is required on Solaris F90 compiler
IF (I0.LT.Nsnew) Rnew(row,I0:NSnew-1)=R(r1,ind(I0+1:NSnew))
B(row)=R(r1,ind(I0))/SQ0
enddo
DO row=I0+1,NSnew
r1=ind(row)
Rnew(row-1,row-1:NSnew-1) = R(r1,ind(row:NSnew))
B(row-1)=R(ind(i0),r1)/SQ0
enddo
DO row=I0+1,NSnew
ind(row-1)=ind(row)
enddo
CMnew=CM(ind(1:NSnew-1))
SQnew=SQ(ind(1:NSnew-1))
indSnew=indS(ind(1:NSnew-1))
!USE the XSPLIT variant
IF (SGN.LT.0.d0) XIND2 = RINDNIT(Rnew,SQnew,CMnew,indSnew,NITL-1)
! Perform conditioning on X(I0)
NSnew=NSnew-1
N1=0
DO row = 1, NSnew
Rnew(row,row:NSnew) = Rnew(row,row:NSnew) -
& B(row)*B(row:NSnew) !/SS0)
SS = RNEW(row,row)
IF (SS.GE.EPS2) then
SQNEW (row) = SQRT (SS)
ELSE
SQNEW(row) = 0.d0
N1=N1+1 ! count number of deterministic variables
END IF
ENDDO
!See if we can Narrow down the limits
CALL C1C2(XMI(1),XMA(1),CmNew,B,SQNEW,indSnew)
XIND = (FI (XMA(1)) - FI (XMI(1)))
! if Nsnew<=N1 then PRB = XIND almost always
! if this check is not performed then
! the numerical integration may currupt the answer due
! to the limited number of nodes used in the integration
IF (XIND.LT.EPSS.OR.Nsnew.LT.N1+1) GOTO 200
! print *,'rindnit gaussle2'
N1=0 ! computing nodes for num. integration.
CALL GAUSSLE2 (N1, H1, XX1, XMI(1), XMA(1),LE2Qnr)
! new conditional covariance
XIND = 0.d0
! print *,'rindnit for loop',N1
DO J = 1, N1
!IF (H1(J).GT.CFxCutOff) THEN
CMnew=Cm(ind(1:NSnew)) + XX1(J)*B !/ SQ0)
XIND1=RINDNIT(Rnew,SQnew,CMnew,indSnew,NITL-1)
XIND = XIND+XIND1 * H1 (J)
!END IF
ENDDO
200 CONTINUE
XIND=XIND2+SGN*XIND
! Print *,'XIND, XIND2',XIND,XIND2
! Print *,'XMI',XMI
! Print *,'XMA',XMA
! Print *,'xind,nit', xind,nitl,shape(indsnew),shape(ind)
!fix up round off errors and make sure 0=<xind<=1
if (XIND.GT.1.d0) THEN
XIND=1.D0
elseif (XIND.LT.0.D0) THEN
XIND=0.d0
endif
300 continue
if (allocated(INDSNEW)) DEALLOCATE(INDSNEW)
if (allocated(RNEW)) DEALLOCATE(RNEW)
if (allocated(CmNEW)) DEALLOCATE(CmNEW)
if (allocated(SQNEW)) DEALLOCATE(SQNEW)
if (allocated(B)) DEALLOCATE(B)
if (allocated(ind)) DEALLOCATE(ind)
! print *,'rindnit leaving end'
RETURN
END FUNCTION RINDNIT
SUBROUTINE BARRIER(xc,indI,Blo,Bup)
USE GLOBALDATA, ONLY : Hup,Hlo,xedni,Ntd,index1
IMPLICIT NONE
INTEGER, DIMENSION(: ), INTENT(in) :: indI
DOUBLE PRECISION, DIMENSION(:,:), INTENT(in) :: Blo,Bup
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: xc
INTEGER :: I, J, K, L
INTEGER :: Mb, Nb, NI, Nc
!this procedure set Hlo,Hup according to Blo/Bup
Mb=size(Blo,DIM=1)
Nb=size(Blo,DIM=2)
NI=size(indI,DIM=1)
Nc=size(xc,DIM=1)
DO J = 2, NI
DO I =indI (J - 1) + 1 , indI (J)
L=xedni(I)
Hlo (L) = Blo (1, J - 1)
Hup (L) = Bup (1, J - 1)
DO K = 1, Mb-1
Hlo(L) = Hlo(L)+Blo(K+1,J-1)*xc(K)
Hup(L) = Hup(L)+Bup(K+1,J-1)*xc(K)
ENDDO ! K
ENDDO ! I
ENDDO ! J
!print * ,'barrier hup:'
!print * ,size(Hup),Hup(xedni(1:Ntd))
!print * ,'barrier hlo:'
!print * ,size(Hlo),Hlo(xedni(1:Ntd))
RETURN
END SUBROUTINE BARRIER
function MNORMPRB(Cm1) RESULT (VALUE)
USE ADAPTMOD
USE KRBVRCMOD
USE KROBOVMOD
USE RCRUDEMOD
USE DKBVRCMOD
USE SSOBOLMOD
USE FUNCMOD
USE FIMOD
USE C1C2MOD
USE GLOBALDATA, ONLY : Hlo,Hup,xCutOff,NUGGET,EPSS,EPS2,
& RelEps,NSIMmax,NSIMmin,Nt,Nd,Nj,Ntd,SQ,
& Njj,Ntscis,NsXtmj, indXtd,index1,
& useC1C2,C1C2det,COV,COVix
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: Cm1 ! conditional mean
DOUBLE PRECISION :: VALUE
DOUBLE PRECISION :: XMI,XMA,SQ0
INTEGER :: Nst,Nst0,Nlhd
INTEGER :: Ndim,DEF
INTEGER :: MINPTS,MAXPTS, INFORM
DOUBLE PRECISION :: ABSEPS, ERROR
!MNORMPRB Multivariate Normal integrals by SCIS or LHSCIS
! SCIS = Sequential conditioned importance sampling
! LHSCIS = Latin Hypercube Sequential Conditioned Importance Sampling
!
! ! NB!!: R must be conditional sorted by condsort3
! works on the upper triangular part of R
!
! References
! R. Ambartzumian, A. Der Kiureghian, V. Ohanian and H.
! Sukiasian (1998)
! Probabilistic Engineering Mechanics, Vol. 13, No 4. pp 299-308
!
! Alan Genz (1992)
! 'Numerical Computation of Multivariate Normal Probabilities'
! J. computational Graphical Statistics, Vol.1, pp 141--149
!print *,'enter mnormprb'
Nst0 = NsXtmj(Njj+Ntscis)
if (Njj.GT.0) then
Nst = NsXtmj(Njj)
else
Nst = NsXtmj(Ntscis+1)
endif
!Nst=size(Cm)
if (Nst.lt.Njj+1) then
VALUE=1.d0
if (allocated(COV)) then ! save the coefficient of variation in COV
COV(COVix)=0.d0
endif
return
endif
if (Nst.lt.Njj+1) then
if (allocated(COV)) then ! save the coefficient of variation in COV
COV(COVix)=0.d0
endif
VALUE=1.d0
return
endif
!print *,' mnormprb start calculat'
VALUE=0.d0
Cm(1:Nst-Njj)=Cm1(Njj+1:Nst) ! initialize conditional mean
SQ0 = SQ(Njj+1,Njj+1)
XMA = MIN((Hup (Njj+1)-Cm1(Njj+1))/SQ0,xCutOff)
XMI = MAX((Hlo (Njj+1)-Cm1(Njj+1))/SQ0,-xCutOff)
if (useC1C2) then ! see if we can narrow down sampling range
CALL C1C2(XMI,XMA,Cm1(Njj+2:Nst),BIG(1,2:Nst),
& SQ(2:Nst,1),indXtd(2:Nst))
endif
IF (XMA.LE.XMI) RETURN
Pl1 = FI(XMI)
Pu1 = FI(XMA)
Ndim = Nst0-Njj
MAXPTS = NSIMmax*Ndim
MINPTS = NSIMmin*Ndim
ABSEPS = EPSS
DEF = 1 ! krbvrc is fastest
SELECT CASE (DEF)
CASE (:1)
!print * ,'RINDSCIS: Ndim',Ndim
IF (NDIM.lt.9) THEN
CALL SADAPT(Ndim,MAXPTS,MVNFUN2,ABSEPS,
& RELEPS,ERROR,VALUE,INFORM)
ELSE
CALL KRBVRC( NDIM, MINPTS, MAXPTS, MVNFUN2, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
ENDIF
CASE (2)
!print * ,'RINDSCIS: Ndim',Ndim
IF (NDIM.lt.19) THEN
! Call the subregion adaptive integration subroutine
CALL SADAPT(Ndim,MAXPTS,MVNFUN2,ABSEPS,
& RELEPS,ERROR,VALUE,INFORM)
ELSE
CALL KRBVRC( NDIM, MINPTS, MAXPTS, MVNFUN2, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
ENDIF
CASE (3)
CALL KRBVRC( NDIM, MINPTS, MAXPTS, MVNFUN2, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
CASE (4)
CALL KROBOV( NDIM, MINPTS, MAXPTS, MVNFUN2, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
CASE (5) ! Call Crude Monte Carlo integration procedure
CALL RANMC( NDIM, MAXPTS, MVNFUN2, ABSEPS,
& RELEPS, ERROR, VALUE, INFORM )
CASE (6) ! Call the scrambled Sobol sequence rule integration procedure
CALL SOBNIED( NDIM, MINPTS, MAXPTS, MVNFUN2, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
CASE (7:)
CALL DKBVRC( NDIM, MINPTS, MAXPTS, MVNFUN2, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
END SELECT
if (allocated(COV)) then ! save the coefficient of variation in COV
if ((VALUE.gt.0.d0)) COV(COVix)=ERROR/VALUE/3.0d0
endif
!print *,'mnormprb, error, inform,',error,inform
!print *,'leaving mnormprb'
return
END FUNCTION MNORMPRB
FUNCTION RINDSCIS(xc1) result(VALUE)
!RINDSCIS Multivariate Normal integrals by SCIS
! SCIS = Sequential conditioned importance sampling
! The points can be sampled using Lattice rules, Latin Hypercube samples,
! uniformly distributed, or using an adaptive algorithm
!
! References
! R. Ambartzumian, A. Der Kiureghian, V. Ohanian and H.
! Sukiasian (1998)
! Probabilistic Engineering Mechanics, Vol. 13, No 4. pp 299-308
!
! Alan Genz (1992)
! 'Numerical Computation of Multivariate Normal Probabilities'
! J. computational Graphical Statistics, Vol.1, pp 141--149
USE ADAPTMOD
USE KRBVRCMOD
USE KROBOVMOD
USE RCRUDEMOD
USE DKBVRCMOD
USE SSOBOLMOD
USE FUNCMOD
USE FIMOD
USE C1C2MOD
USE JACOBMOD
USE GLOBALDATA, ONLY : Hlo,Hup,xCutOff,NUGGET,EPSS,EPS2,
& RelEps,NSIMmax,NSIMmin,Nt,Nd,Nj,Ntd,SQ,Nc,
& NsXtmj, NsXdj,indXtd,index1,
& useC1C2,C1C2det,COV,COVix,SCIS
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: xc1 ! conditional values
DOUBLE PRECISION :: VALUE
DOUBLE PRECISION :: XMI,XMA,SQ0
INTEGER :: Nst,Nst0,Nsd,Nsd0,K
INTEGER :: Ndim,Ndleft,Ntmj,NLHD
INTEGER :: MINPTS,MAXPTS, INFORM
DOUBLE PRECISION :: ABSEPS, ERROR
VALUE = 0.d0
! print *,'enter rindscis'
Nst = NsXtmj(Ntd+1)
Ntmj=Nt-Nj
if (Ntmj.GT.0) then
Nst0 = NsXtmj(Ntmj)
else
Nst0 = 0
endif
Nsd = NsXdj(Nd+Nj+1)
Nsd0 = NsXdj(1)
Ndim = Nst0+Ntd-Nsd0+1 ! # dim. we treat stochastically
MAXPTS = NSIMmax*Ndim
MINPTS = NSIMmin*Ndim
ABSEPS = EPSS
IF (Nc.GT.0) xc=xc1
if (Nd+Nj.gt.0) then
IF ( BIG(Ntd,Ntd).LT.EPS2) THEN !degenerate case
IF (Nd.GT.0) THEN
Ndleft=Nd;K=Ntd
DO WHILE (Ndleft.GT.0)
IF (index1(K).GT.Nt) THEN ! isXd
xd (Ndleft) = Cm (K)
Ndleft=Ndleft-1
END IF
K=K-1
ENDDO
VALUE = jacob (xd,xc) ! jacobian of xd,xc
ELSE
VALUE = 1.d0 ! VALUE = FxCutOff???
END IF
!print *,'jacob,xd',VALUE,xd
IF (Nst.LT.1) then
if (allocated(COV)) then ! save the coefficient of variation in COV
COV(COVix)=0.d0
endif
RETURN
endif
!print *,'RINDSCIS calling MNORMPRB '
VALUE=VALUE*MNORMPRB(Cm(1:Nst))
!print *,'leaving rindscis'
RETURN
ENDIF
elseif (Nst.lt.1) then
if (allocated(COV)) then ! save the coefficient of variation in COV
COV(COVix)=0.d0
endif
VALUE=1.d0
return
endif
if (Nd+Nj.gt.0) then
SQ0=SQ(Ntd,Ntd)
XMA = MIN((Hup (Ntd)-Cm(Ntd))/SQ0,xCutOff)
XMI = MAX((Hlo (Ntd)-Cm(Ntd))/SQ0,-xCutOff)
if (useC1C2) then ! see if we can narrow down sampling range
CALL C1C2(XMI,XMA,Cm(1:Ntd-1),BIG(1:Ntd-1,Ntd),
& SQ(1:Ntd-1,Ntd),indXtd(1:Ntd-1))
endif
else
SQ0=SQ(1,1)
XMA = MIN((Hup (1)-Cm(1))/SQ0,xCutOff)
XMI = MAX((Hlo (1)-Cm(1))/SQ0,-xCutOff)
if (useC1C2) then ! see if we can narrow down sampling range
CALL C1C2(XMI,XMA,Cm(2:Nst),BIG(1,2:Nst),
& SQ(2:Nst,1),indXtd(2:Nst))
endif
endif
IF (XMA.LE.XMI) return !PQ= Y=0 for all return
Pl1 = FI(XMI)
Pu1 = FI(XMA)
IF ( Ndim .GT. 20. AND. SCIS.EQ.3) THEN
!print *, 'Ndim to large for SADMVN. Calling KRBVRC instead'
SCIS=4
ENDIF
!print * ,'RINDSCIS: Ndim',Ndim
SELECT CASE (SCIS)
CASE (:1)
!print * ,'RINDSCIS: Ndim',Ndim
IF (NDIM.lt.9) THEN
CALL SADAPT(Ndim,MAXPTS,MVNFUN,ABSEPS,
& RELEPS,ERROR,VALUE,INFORM)
ELSE
CALL KRBVRC( NDIM, MINPTS, MAXPTS, MVNFUN, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
ENDIF
CASE (2)
!print * ,'RINDSCIS: Ndim',Ndim
IF (NDIM.lt.19) THEN
! Call the subregion adaptive integration subroutine
CALL SADAPT(Ndim,MAXPTS,MVNFUN,ABSEPS,
& RELEPS,ERROR,VALUE,INFORM)
ELSE
CALL KRBVRC( NDIM, MINPTS, MAXPTS, MVNFUN, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
ENDIF
CASE (3)
CALL KRBVRC( NDIM, MINPTS, MAXPTS, MVNFUN, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
CASE (4)
CALL KROBOV( NDIM, MINPTS, MAXPTS, MVNFUN, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
CASE (5) ! Call Crude Monte Carlo integration procedure
CALL RANMC( NDIM, MAXPTS, MVNFUN, ABSEPS,
& RELEPS, ERROR, VALUE, INFORM )
CASE (6) ! Call the scrambled Sobol sequence rule integration procedure
CALL SOBNIED( NDIM, MINPTS, MAXPTS, MVNFUN, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
CASE (7:)
CALL DKBVRC( NDIM, MINPTS, MAXPTS, MVNFUN, ABSEPS, RELEPS,
& ERROR, VALUE, INFORM )
END SELECT
if (allocated(COV)) then ! save the coefficient of variation in COV
if ((VALUE.gt.0.d0)) COV(COVix)=ERROR/VALUE/3.0d0
endif
IF (inform.gt.0.and.error.gt.10.*epss) then
!print *,'rindscis, error', error,'inform,',inform
endif
!print *,'rindscis, Ndim,MINPTS, error',Ndim,MINPTS,error
END FUNCTION RINDSCIS
!********************************************************************
SUBROUTINE CONDSORT0 (R,Cm,xcmean,CSTD,index1,xedni,NsXtmj,NsXdj
& ,INFORM)
USE GLOBALDATA, ONLY : Nt,Nj,Njj,Nd,Nc,Ntdc,Ntd,EPS2,Nugget,
& XCEPS2,SCIS,Ntscis,SQTWOPI1,Hlo,Hup,xCutOff,EPSS
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), INTENT(inout) :: R
DOUBLE PRECISION, DIMENSION(: ), INTENT(inout) :: Cm
DOUBLE PRECISION, DIMENSION(: ), INTENT(in) :: xcmean
DOUBLE PRECISION, DIMENSION(:,:), INTENT(out) :: CSTD
INTEGER, DIMENSION(: ), INTENT(inout) :: index1
INTEGER, DIMENSION(: ), INTENT(inout) :: xedni
INTEGER, DIMENSION(: ), INTENT(out) :: NsXtmj
INTEGER, DIMENSION(: ), INTENT(out) :: NsXdj
INTEGER, INTENT(out) :: INFORM
! local variables
DOUBLE PRECISION, DIMENSION(: ), allocatable :: SQ
DOUBLE PRECISION, DIMENSION(:,:), allocatable :: CSTD2
INTEGER, DIMENSION(1 ) :: m
INTEGER, DIMENSION(: ), allocatable :: ind
DOUBLE PRECISION :: P0,P1,XMI,XMA,SQ0,XX
INTEGER :: I0,I1
INTEGER :: Nstoc,Ntmp,NstoXd !,degenerate
INTEGER :: changed,m1,r1,c1,r2,c2,ix,iy,Njleft,Ntmj
! R = Input: Cov(X) where X=[Xt Xd Xc] is stochastic vector
! Output: sorted Conditional Covar. matrix Shape N X N (N=Nt+Nd+Nc)
! CSTD = SQRT(Var(X(1:I-1)|X(I:N)))
! conditional standard deviation. Shape Ntd X max(Nd+Nj,1)
! index1 = indices to the variables original place. Size Ntdc
! xedni = indices to the variables new place. Size Ntdc
! NsXtmj(I) = indices to the last stochastic variable
! among Nt-Nj first of Xt after conditioning on
! X(Nt-Nj+I). Size Nd+Nj+Njj+Ntscis+1
! NsXdj(I) = indices to the first stochastic variable
! among Xd+Nj of Xt after conditioning on
! X(Nt-Nj+I). Size Nd+Nj+1
!
! R=Cov([Xt,Xd,Xc]) is a covariance matrix of the stochastic vector X=[Xt Xd Xc]
! where the variables Xt, Xd and Xc have the size Nt, Nd and Nc, respectively.
! Xc is (are) the conditional variable(s).
! Xd and Xt are the variables to integrate.
! Xd + Nj variables of Xt are integrated directly by the RindDXX
! subroutines in the order of shortest expected integration interval.
! The remaining Nt-Nj variables of Xt are integrated in
! increasing order of the marginal probabilities by the RindXX subroutines.
! CONDSORT prepare and rearrange the covariance matrix
! in a special way to accomodate this strategy:
!
! After conditioning and sorting, the first Nt-Nj x Nt-Nj block of R
! will contain the conditional covariance matrix
! of Xt(1:Nt-Nj) given Xt(Nt-Nj+1:Nt) Xd and Xc, i.e.,
! Cov(Xt(1:Nt-Nj),Xt(1:Nt-Nj)|Xt(Nt-Nj+1:Nt), Xd,Xc)
! NB! for Nj>0 the order of Xd and Xt(Nt-Nj+1:Nt) may be mixed.
! The covariances, Cov(X(1:I-1),X(I)|X(I+1:N)), needed for computation of the
! conditional expectation, E(X(1:I-1)|X(I:N), are saved in column I of R
! for I=Nt-Nj+1:Ntdc.
!
! IF any of the variables have variance less than EPS2. They will be
! be treated as deterministic and not stochastic variables by the
! RindXXX subroutines. The deterministic variables are moved to
! middle in the order they became deterministic in order to
! keep track of them. Their variance and covariance with
! the remaining stochastic variables are set to zero in
! order to avoid numerical difficulties.
!
! NsXtmj(I) is the number of variables among the Nt-Nj
! first we treat stochastically after conditioning on X(Nt-Nj+I).
! The covariance matrix is sorted so that all variables with indices
! from 1 to NsXtmj(I) are stochastic after conditioning
! on X(Nt-Nj+I). Thus NsXtmj(I) may also be considered
! as the index to the last stochastic variable after conditioning
! on X(Nt-Nj+I). In other words NsXtmj keeps track of the deterministic
! and stochastic variables among the Nt-Nj first variables in each
! conditioning step.
!
! Similarly NsXdj(I) keeps track of the deterministic and stochastic
! variables among the Nd+Nj following variables in each conditioning step.
! NsXdj(I) is the index to the first stochastic variable
! among the Nd+Nj following variables after conditioning on X(Nt-Nj+I).
! The covariance matrix is sorted so that all variables with indices
! from NsXdj(I+1) to NsXdj(I)-1 are deterministic conditioned on
! X(Nt-Nj+I).
!
! Var(Xc(1))>Var(Xc(2)|Xc(1))>...>Var(Xc(Nc)|Xc(1),Xc(2),...,Xc(Nc)).
! If Nj=0 then
! Var(Xd(1)|Xc)>Var(Xd(2)|Xd(1),Xc)>...>Var(Xd(Nd)|Xd(1),Xd(2),...,Xd(Nd),Xc).
!
! NB!! Since R is symmetric, only the upper triangular contains the
! sorted conditional covariance. The whole matrix
! is easily obtained by copying elements of the upper triangle to
! the lower or by uncommenting some lines in the end of this subroutine
!
! revised pab 18.04.2000
! new name rind60
! New assumption of BIG for the conditional sorted variables:
! BIG(I,I)=sqrt(Var(X(I)|X(I+1)...X(N))=SQI
! BIG(1:I-1,I)=COV(X(1:I-1),X(I)|X(I+1)...X(N))/SQI
! Otherwise
! BIG(I,I) = Var(X(I)|X(I+1)...X(N)
! BIG(1:I-1,I)=COV(X(1:I-1),X(I)|X(I+1)...X(N))
! This also affects C1C2: SQ0=sqrt(Var(X(I)|X(I+1)...X(N)) is removed from input
! => A lot of wasteful divisions are avoided
! Using SQ to temporarily store the diagonal of R
! Adding a nugget effect to ensure the the inversion is
! not corrupted by round off errors
! good choice for nugget might be 1e-8
!call getdiag(SQ,R)
INFORM = 0
ALLOCATE(SQ(1:Ntdc))
ALLOCATE(ind(1:Ntdc))
IF (Nd+Nj+Njj+Ntscis.GT.0) THEN
ALLOCATE(CSTD2(1:Ntd,1:Nd+Nj+Njj+Ntscis))
CSTD2=0.d0 ! initialize CSTD
ENDIF
!CALL ECHO(R,Ntdc)
DO ix = 1, Ntdc
R(ix,ix) = R(ix,ix)+Nugget
SQ(ix) = R(ix,ix)
index1 (ix) = ix ! initialize index1
ENDDO
Ntmj = Nt-Nj
Njleft = Nj
NstoXd = Ntmj+1
Nstoc = Ntmj
DO ix = 1, Nc ! Condsort Xc
r1=Ntdc-ix
m=r1+2-MAXLOC(SQ(r1+1:Ntd+1:-1))
IF (SQ(m(1)).LT.XCEPS2) THEN
INFORM = 1
!PRINT *,'Condsort0, degenerate Xc'
!degenerate=1
GOTO 200 ! RETURN !degenerate case
ENDIF
m1 = index1(m(1))
CALL swapint(index1(m(1)),index1(r1+1))
CALL swapre(Cm(m(1)),Cm(r1+1))
SQ(r1+1) = SQRT(SQ(m(1)))
R(index1(1:r1+1),m1) = R(index1(1:r1+1),m1)/SQ(r1+1)
R(m1,index1(1:r1)) = R(index1(1:r1),m1)
! Calculate the conditional mean
Cm(1:r1)=Cm(1:r1)+(xcmean(index1(r1+1)-Ntd)-Cm(r1+1))*
& R(index1(1:r1),m1) !/SQ(r1+1)
! sort and calculate conditional covariances
CALL CONDSORT2(R,SQ,index1,Nstoc,NstoXd,Njleft,m1,r1)
ENDDO ! ix
! index to first stochastic variable of Xd and Nj of Xt
NsXdj(Nd+Nj+1) = NstoXd
! index to last stochastic variable of Nt-Nj of Xt
NsXtmj(Nd+Nj+Njj+Ntscis+1) = Nstoc
!print *, 'condsort index1', index1
!print *, 'condsort Xd'
!call echo(R,Ntdc)
DO ix = 1, Nd+Nj ! Condsort Xd + Nj of Xt
CALL ARGP0(I1,r2,P1,XX,SQRT(SQ(NstoXd:Ntd-ix+1)),
& Cm(NstoXd:Ntd-ix+1),index1(NstoXd:Ntd-ix+1),ind,r1)
IF (r1.NE.0) I1=ind(I1)
m = MIN(NstoXd+I1-1,Ntd-ix+1)
IF (Njleft.GT.0) THEN
CALL ARGP0(I0,r2,P0,XX,SQRT(SQ(1:Nstoc)),
& Cm(1:Nstoc),index1(1:Nstoc),ind,r1)
IF (r1.NE.0) I0=ind(I0)
! m=Ntd-ix+2-MAXLOC(SQ(Ntd-ix+1:1:-1))
IF (P0.LT.P1.AND.r1.GT.0) THEN
m = I0
P1 = P0
END IF
Ntmp = NstoXd+Njleft-1
IF (((NstoXd.LE.m(1)).AND.(m(1).LE.Ntmp))
& .OR.(m(1).LE.Nstoc)) THEN
CALL swapint(index1(m(1)),index1(Ntmp))
CALL swapRe(SQ(m(1)),SQ(Ntmp))
CALL swapre(Cm(m(1)),Cm(Ntmp))
m(1)=Ntmp
Njleft=Njleft-1
END IF
END IF ! Njleft
IF (SQ(m(1)).LT.EPS2) THEN
!PRINT *,'Condsort, degenerate Xd'
Ntmp = Nd+Nj+1-ix
NsXtmj(Ntscis+Njj+1:Ntmp+Ntscis+Njj+1) = Nstoc
NsXdj(1:Ntmp+1) = NstoXd
IF (ix.EQ.1) THEN
DO iy = 1,Ntd !sqrt(VAR(X(I)|X(Ntd-ix+1:Ntdc))
r1 = index1(iy)
CSTD2(r1,Ntscis+Njj+1:Ntmp+Ntscis+Njj)=SQRT(SQ(iy))
ENDDO
ELSE
DO iy=ix,Nd+Nj
CSTD2(:,Nd+Nj+Ntscis+Njj+1-iy)=
& CSTD2(:,Ntmp+Ntscis+Njj+1)
ENDDO
ENDIF
GOTO 200 ! degenerate case
END IF
r1 = Ntd-ix
m1 = index1(m(1));
CALL swapint(index1(m(1)),index1(r1+1))
CALL swapre(Cm(m(1)),Cm(r1+1))
! CALL swapre(SQ(r1+1),SQ(m(1)))
SQ0 = SQRT(SQ(m(1)))
SQ(r1+1) = SQ0
CSTD2(m1,Nd+Nj+Ntscis+Njj+1-ix)=SQ0
R(index1(1:r1+1),m1) = R(index1(1:r1+1),m1)/SQ0
R(m1,index1(1:r1)) = R(index1(1:r1),m1)
XMA = MIN( (Hup (index1(r1+1)) - Cm (r1+1))/ SQ0,xCutOff)
XMA = MAX(XMA,-xCutOff)
XMI = MAX( (Hlo (index1(r1+1)) - Cm (r1+1))/ SQ0,-xCutOff)
XMI = MIN(XMI,xCutOff)
! There is something wrong with XX
IF (P1.GT. EPSS ) THEN
! Calculate the normalized expected mean without the jacobian
XX = SQTWOPI1*(EXP(-0.5d0*XMI*XMI)-EXP(-0.5d0*XMA*XMA))/P1
ELSE
IF ( XMI .LE. -xCutOff ) XX = XMA
IF ( XMA .GE. xCutOff ) XX = XMI
IF (XMI.GT.-xCutOff.AND.XMA.LT.xCutOff) XX=(XMI+XMA)*0.5d0
END IF
! Calculate the conditional expected mean
Cm(1:r1) = Cm(1:r1)+XX*R(index1(1:r1),m1)
! Calculating conditional variances
CALL CONDSORT2(R,SQ,index1,Nstoc,NstoXd,Njleft,m1,Ntd-ix)
! saving indices
NsXtmj(Nd+Nj+Njj+Ntscis+1-ix)=Nstoc
NsXdj(Nd+Nj+1-ix)=NstoXd
! Calculating standard deviations non-deterministic variables
DO r2=1,Nstoc
r1=index1(r2)
CSTD2(r1,Nd+Nj+Njj+Ntscis+1-ix)=SQRT(SQ(r2)) !sqrt(VAR(X(I)|X(Ntd-ix+1:Ntdc))
ENDDO
DO r2=NstoXd,Ntd-ix
r1=index1(r2)
CSTD2(r1,Nd+Nj+Ntscis+Njj+1-ix)=SQRT(SQ(r2)) !sqrt(VAR(X(I)|X(Ntd-ix+1:Ntdc))
ENDDO
ENDDO ! ix
200 IF ((SCIS.GT.0).OR. (Njj.gt.0)) THEN ! check on Njj instead
! Calculating conditional variances and sort for Nstoc of Xt
CALL CONDSORT4(R,Cm,CSTD2,SQ,index1,NsXtmj,Nstoc)
!Nst0=Nstoc
ENDIF
IF (Nd+Nj+Njj+Ntscis.GT.0) THEN
DO r2=1,Ntd ! sorting CSTD according to index1
r1=index1(r2)
CSTD(r2,:)= CSTD2(r1,:)
END DO
DEALLOCATE(CSTD2)
ELSE
IF (Nc.EQ.0) THEN
ix=1; Nstoc=Ntmj
DO WHILE (ix.LE.Nstoc)
IF (SQ(ix).LT.EPS2) THEN
DO WHILE ((SQ(Nstoc).LT.EPS2).AND.(ix.LT.Nstoc))
SQ(Nstoc)=0.d0 !MAX(0.d0,SQ(Nstoc))
Nstoc=Nstoc-1
END DO
CALL swapint(index1(ix),index1(Nstoc)) ! swap indices
!CALL swapre(SQ(ix),SQ(Nstoc))
SQ(ix)=SQ(Nstoc);SQ(Nstoc)=0.d0
Nstoc=Nstoc-1
ENDIF
ix=ix+1
END DO
ENDIF
CSTD(1:Nt,1)=SQRT(SQ(1:Nt))
NsXtmj(1)=Nstoc
ENDIF
changed=0
DO r2=Ntdc,1,-1 ! sorting the upper triangular of the
r1=index1(r2) ! covariance matrix according to index1
xedni(r1)=r2
!PRINT *,'condsort,xedni',xedni
!PRINT *,'condsort,r1,r2',r1,r2
IF ((r1.NE.r2).OR.(changed.EQ.1)) THEN
changed=1
R(r2,r2) = SQ(r2)
DO c2=r2+1,Ntdc
c1=index1(c2)
IF (c1.GT.r1) THEN
R(r2,c2)=R(c1,r1)
ELSE
R(r2,c2)=R(r1,c1)
END IF
END DO
END IF
END DO
! you may sort the lower triangular according
! to index1 also, but it is not needed
! since R is symmetric. Uncomment the
! following if the whole matrix is needed
DO c2=1,Ntdc
DO r2=c2+1,Ntdc
R(r2,c2)=R(c2,r2) ! R symmetric
END DO
END DO
! IF (degenerate.EQ.1) THEN
! PRINT *,'condsort,R='
! call echo(R,Ntdc)
! PRINT *,'condsort,SQ='
! call echo(CSTD,Ntd)
! PRINT *,'index=',index1
! PRINT *,'xedni=',xedni
! ENDIF
! PRINT * , 'big'
!600 FORMAT(4F8.4)
! PRINT 600, R
! PRINT 600, SQ
DEALLOCATE(SQ)
IF (ALLOCATED(ind)) DEALLOCATE(ind)
RETURN
END SUBROUTINE CONDSORT0
SUBROUTINE CONDSORT4(R,Cm,CSTD2,SQ,index1,NsXtmj,Nstoc)
USE GLOBALDATA, ONLY : EPS2,Njj,Ntscis,SQTWOPI1,Hlo,Hup,
& xCutOff,EPSS
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), INTENT(inout) :: R,CSTD2
DOUBLE PRECISION, DIMENSION(: ), INTENT(inout) :: Cm
DOUBLE PRECISION, DIMENSION(:), INTENT(inout) :: SQ ! diag. of R
INTEGER, DIMENSION(: ), INTENT(inout) :: index1,NsXtmj
INTEGER, INTENT(inout) :: Nstoc
! local variables
DOUBLE PRECISION :: P0,Plo,XMI,XMA,SQ0,XX
INTEGER :: I0
INTEGER, DIMENSION(1) :: m
INTEGER, DIMENSION(:), ALLOCATABLE :: ind
INTEGER :: m1
INTEGER :: Nsold
INTEGER :: r1,c1,row,col,iy,ix
! This function condsort all the Xt variables for use with RINDSCIS and
! MNORMPRB
!Nsoold=Nstoc
ix=1
ALLOCATE(ind(1:Nstoc))
DO WHILE ((ix.LE.Nstoc).and.(ix.LE.(Ntscis+Njj)))
CALL ARGP0(I0,c1,P0,Plo,SQRT(SQ(ix:Nstoc)),
& Cm(ix:Nstoc),index1(ix:Nstoc),ind,r1)
IF (r1.NE.0) I0=ind(I0)
m = ix-1+max(I0-1,1)
! m=ix-1+MAXLOC(SQ(ix:Nstoc))
IF (SQ(m(1)).LT.EPS2) THEN
!PRINT *,'Condsort3, error degenerate X'
NsXtmj(1:Njj+Ntscis)=0
Nstoc=0 !degenerate=1
RETURN !degenerate case
ENDIF
m1=index1(m(1));
CALL swapint(index1(m(1)),index1(ix))
CALL swapre(SQ(ix),SQ(m(1)))
SQ0=SQRT(SQ(ix))
CSTD2(m1,ix)=SQ0
R(index1(ix:Nstoc),m1) = R(index1(ix:Nstoc),m1)/SQ0
R(m1,index1(ix+1:Nstoc)) = R(index1(ix+1:Nstoc),m1)
CALL swapre(Cm(m(1)),Cm(ix))
XMA = MIN( (Hup (index1(ix)) - Cm (ix))/ SQ0,xCutOff)
XMI = MAX( (Hlo (index1(ix)) - Cm (ix))/ SQ0,-xCutOff)
XMA = MAX(XMA,-xCutOff)
XMI = MIN(XMI,xCutOff)
IF (P0.GT. EPSS ) THEN
! Calculate the expected mean
XX= SQTWOPI1*(EXP(-0.5d0*XMI*XMI)-EXP(-0.5d0*XMA*XMA))/P0
ELSE
IF ( XMI .LE. -xCutOff ) XX = XMA
IF ( XMA .GE. xCutOff ) XX = XMI
IF (XMI.GT.-xCutOff.AND.XMA.LT.xCutOff) XX=(XMI+XMA)*0.5d0
END IF
! Calculate the conditional expected mean
Cm(ix+1:Nstoc)=Cm(ix+1:Nstoc)+XX*
& R(m1,index1(ix+1:Nstoc))
! Calculating conditional variances for the
! first Nstoc variables.
! variables with variance less than EPS2
! will be treated as deterministic and not
! stochastic variables and are therefore moved
! to the end among these variables.
! Nstoc is the # of variables we treat
! stochastically
iy=ix+1;Nsold=Nstoc
DO WHILE (iy.LE.Nstoc)
r1=index1(iy)
SQ(iy)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
IF (SQ(iy).LT.EPS2) THEN
! IF (SQ(iy).LT.-EPS2) THEN
! PRINT *,'Cndsrt4,Error Covariance negative definit'
! ENDIF
IF (iy.LT.Nstoc) THEN
r1=index1(Nstoc)
SQ(Nstoc)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
DO WHILE ((SQ(Nstoc).LT.EPS2).AND.(iy.LT.Nstoc))
! IF (SQ(Nstoc).LT.-EPS2) THEN
! PRINT *,'Cndsrt4,Error Covariance negative definit'
! ENDIF
SQ(Nstoc)=0.d0 !MAX(0.d0,SQ(Nstoc))
Nstoc=Nstoc-1
r1=index1(Nstoc)
SQ(Nstoc)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
END DO
CALL swapint(index1(iy),index1(Nstoc)) ! swap indices
!CALL swapre(SQ(iy),SQ(Nstoc)) ! swap values
SQ(iy)=SQ(Nstoc);
ENDIF
SQ(Nstoc)=0.d0
Nstoc=Nstoc-1
ENDIF
iy=iy+1
END DO
NsXtmj(ix)=Nstoc ! saving index to last stoch. var. after conditioning
! Calculating Covariances for non-deterministic variables
DO row=ix+1,Nstoc
r1=index1(row)
R(r1,r1)=SQ(row)
CSTD2(r1,ix)=SQRT(SQ(row)) ! saving stdev after conditioning on ix
DO col=row+1,Nstoc
c1=index1(col)
R(c1,r1)=R(r1,c1)-R(r1,m1)*R(m1,c1) !/R(m1,m1)
R(r1,c1)=R(c1,r1)
ENDDO
ENDDO
! similarly for deterministic values
DO row=Nstoc+1,Nsold
r1=index1(row)
SQ(row) = 0.d0 !MAX(0.d0,SQ(row))
CSTD2(r1,ix)=0.d0 !SQRT(SQ(row)) ! saving stdev after conditioning on ix
R(r1,r1) = SQ(row)
DO col=ix+1,Nsold !row-1
c1=index1(col)
R(c1,r1)=0.d0
R(r1,c1)=0.d0
ENDDO
ENDDO
ix=ix+1
ENDDO
if (Nstoc.LT.Njj+Ntscis) THEN
! This test is necessary on Solaris F90 compiler.
NsXtmj(Nstoc+1:Njj+Ntscis) = Nstoc
! else
! PRINT *,'Condsort4'
! PRINT *,'Nstoc,Njj, Ntscis',Nstoc,Njj,Ntscis
endif
IF (ALLOCATED(ind)) DEALLOCATE(ind)
RETURN
END SUBROUTINE CONDSORT4
SUBROUTINE CONDSORT (R,CSTD,index1,xedni,NsXtmj,NsXdj,INFORM)
USE GLOBALDATA, ONLY : Nt,Nj,Njj,Nd,Nc,Ntdc,Ntd,EPS2,Nugget,
& XCEPS2,SCIS,Ntscis
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), INTENT(inout) :: R
DOUBLE PRECISION, DIMENSION(:,:), INTENT(out) :: CSTD
INTEGER, DIMENSION(: ), INTENT(out) :: index1
INTEGER, DIMENSION(: ), INTENT(out) :: xedni
INTEGER, DIMENSION(: ), INTENT(out) :: NsXtmj
INTEGER, DIMENSION(: ), INTENT(out) :: NsXdj
INTEGER, INTENT(out) :: INFORM
! local variables
DOUBLE PRECISION, DIMENSION(: ), allocatable :: SQ
DOUBLE PRECISION, DIMENSION(:,:), allocatable :: CSTD2
INTEGER, DIMENSION(1 ) :: m
INTEGER :: Nstoc,Ntmp,NstoXd !,degenerate
INTEGER :: changed,m1,r1,c1,row,col,ix,iy,Njleft,Ntmj
! R = Input: Cov(X) where X=[Xt Xd Xc] is stochastic vector
! Output: sorted Conditional Covar. matrix Shape N X N (N=Nt+Nd+Nc)
! CSTD = SQRT(Var(X(1:I-1)|X(I:N)))
! conditional standard deviation. Shape Ntd X max(Nd+Nj,1)
! index1 = indices to the variables original place. Size Ntdc
! xedni = indices to the variables new place. Size Ntdc
! NsXtmj(I) = indices to the last stochastic variable
! among Nt-Nj first of Xt after conditioning on
! X(Nt-Nj+I). Size Nd+Nj+Njj+Ntscis+1
! NsXdj(I) = indices to the first stochastic variable
! among Xd+Nj of Xt after conditioning on
! X(Nt-Nj+I). Size Nd+Nj+1
!
! R=Cov([Xt,Xd,Xc]) is a covariance matrix of the stochastic vector X=[Xt Xd Xc]
! where the variables Xt, Xd and Xc have the size Nt, Nd and Nc, respectively.
! Xc is (are) the conditional variable(s).
! Xd and Xt are the variables to integrate.
! Xd + Nj variables of Xt are integrated directly by the RindDXX
! subroutines in the order of decreasing conditional variance.
! The remaining Nt-Nj variables of Xt are integrated in
! increasing order of the marginal probabilities by the RindXX subroutines.
! CONDSORT prepare and rearrange the covariance matrix
! by decreasing order of conditional variances in a special way
! to accomodate this strategy:
!
! After conditioning and sorting, the first Nt-Nj x Nt-Nj block of R
! will contain the conditional covariance matrix
! of Xt(1:Nt-Nj) given Xt(Nt-Nj+1:Nt) Xd and Xc, i.e.,
! Cov(Xt(1:Nt-Nj),Xt(1:Nt-Nj)|Xt(Nt-Nj+1:Nt), Xd,Xc)
! NB! for Nj>0 the order of Xd and Xt(Nt-Nj+1:Nt) may be mixed.
! The covariances, Cov(X(1:I-1),X(I)|X(I+1:N)), needed for computation of the
! conditional expectation, E(X(1:I-1)|X(I:N), are saved in column I of R
! for I=Nt-Nj+1:Ntdc.
!
! IF any of the variables have variance less than EPS2. They will be
! be treated as deterministic and not stochastic variables by the
! RindXXX subroutines. The deterministic variables are moved to
! middle in the order they became deterministic in order to
! keep track of them. Their variance and covariance with
! the remaining stochastic variables are set to zero in
! order to avoid numerical difficulties.
!
! NsXtmj(I) is the number of variables among the Nt-Nj
! first we treat stochastically after conditioning on X(Nt-Nj+I).
! The covariance matrix is sorted so that all variables with indices
! from 1 to NsXtmj(I) are stochastic after conditioning
! on X(Nt-Nj+I). Thus NsXtmj(I) may also be considered
! as the index to the last stochastic variable after conditioning
! on X(Nt-Nj+I). In other words NsXtmj keeps track of the deterministic
! and stochastic variables among the Nt-Nj first variables in each
! conditioning step.
!
! Similarly NsXdj(I) keeps track of the deterministic and stochastic
! variables among the Nd+Nj following variables in each conditioning step.
! NsXdj(I) is the index to the first stochastic variable
! among the Nd+Nj following variables after conditioning on X(Nt-Nj+I).
! The covariance matrix is sorted so that all variables with indices
! from NsXdj(I+1) to NsXdj(I)-1 are deterministic conditioned on
! X(Nt-Nj+I).
!
! Var(Xc(1))>Var(Xc(2)|Xc(1))>...>Var(Xc(Nc)|Xc(1),Xc(2),...,Xc(Nc)).
! If Nj=0 then
! Var(Xd(1)|Xc)>Var(Xd(2)|Xd(1),Xc)>...>Var(Xd(Nd)|Xd(1),Xd(2),...,Xd(Nd),Xc).
!
! NB!! Since R is symmetric, only the upper triangular contains the
! sorted conditional covariance. The whole matrix
! is easily obtained by copying elements of the upper triangle to
! the lower or by uncommenting some lines in the end of this subroutine
! revised pab 18.04.2000
! new name rind60
! New assumption of BIG for the conditional sorted variables:
! BIG(I,I)=sqrt(Var(X(I)|X(I+1)...X(N))=SQI
! BIG(1:I-1,I)=COV(X(1:I-1),X(I)|X(I+1)...X(N))/SQI
! Otherwise
! BIG(I,I) = Var(X(I)|X(I+1)...X(N)
! BIG(1:I-1,I)=COV(X(1:I-1),X(I)|X(I+1)...X(N))
! This also affects C1C2: SQ0=sqrt(Var(X(I)|X(I+1)...X(N)) is removed from input
! => A lot of wasteful divisions are avoided
! Using SQ to temporarily store the diagonal of R
! Adding a nugget effect to ensure the the inversion is
! not corrupted by round off errors
! good choice for nugget might be 1e-8
!call getdiag(SQ,R)
INFORM = 0
ALLOCATE(SQ(1:Ntdc))
IF (Nd+Nj+Njj+Ntscis.GT.0) THEN
ALLOCATE(CSTD2(1:Ntd,1:Nd+Nj+Njj+Ntscis))
CSTD2=0.d0 ! initialize CSTD
ENDIF
!CALL ECHO(R,Ntdc)
DO ix = 1, Ntdc
R(ix,ix)=R(ix,ix)+Nugget
SQ(ix)=R(ix,ix)
index1 (ix) = ix ! initialize index1
ENDDO
Ntmj=Nt-Nj
!NsXtmj(Njj+Nd+Nj+1)=Ntmj ! index to last stochastic variable of Nt-Nj of Xt
!NsXdj(Nd+Nj+1)=Ntmj+1 ! index to first stochastic variable of Xd and Nj of Xt
!degenerate=0
Njleft=Nj
NstoXd=Ntmj+1;Nstoc=Ntmj
DO ix = 1, Nc ! Condsort Xc
r1 = Ntdc-ix
m=r1+2-MAXLOC(SQ(r1+1:Ntd+1:-1))
IF (SQ(m(1)).LT.XCEPS2) THEN
INFORM = 1
!PRINT *,'Condsort, degenerate Xc'
IF (SQ(m(1)).LT.-XCEPS2) THEN
!print *, 'Condsort, Not semi-positive definit'
ENDIF
!degenerate=1
GOTO 200 ! RETURN !degenerate case
ENDIF
m1=index1(m(1));
CALL swapint(index1(m(1)),index1(Ntdc-ix+1))
!CALL swapRe(SQ(r1+1),SQ(m(1)))
SQ(r1+1) = SQRT(SQ(m(1)))
R(index1(1:r1+1),m1) = R(index1(1:r1+1),m1)/SQ(r1+1)
R(m1,index1(1:r1)) = R(index1(1:r1),m1)
! sort and calculate conditional covariances
CALL CONDSORT2(R,SQ,index1,Nstoc,NstoXd,Njleft,m1,Ntdc-ix)
ENDDO ! ix
NsXdj(Nd+Nj+1) = NstoXd ! index to first stochastic variable of Xd and Nj of Xt
NsXtmj(Nd+Nj+Njj+Ntscis+1) = Nstoc ! index to last stochastic variable of Nt-Nj of Xt
!print *, 'condsort index1', index1
!print *, 'condsort Xd'
!call echo(R,Ntdc)
DO ix = 1, Nd+Nj ! Condsort Xd + Nj of Xt
r1 = Ntd-ix
IF (Njleft.GT.0) THEN
m=r1+2-MAXLOC(SQ(r1+1:1:-1))
Ntmp=NstoXd+Njleft-1
IF (((NstoXd.LE.m(1)).AND.(m(1).LE.Ntmp))
& .OR.(m(1).LE.Nstoc)) THEN
CALL swapint(index1(m(1)),index1(Ntmp))
CALL swapRe(SQ(m(1)),SQ(Ntmp))
m(1)=Ntmp
Njleft=Njleft-1
END IF
ELSE
m=r1+2-MAXLOC(SQ(r1+1:Ntmj+1:-1))
END IF
IF (SQ(m(1)).LT.EPS2) THEN
!PRINT *,'Condsort, degenerate Xd'
!degenerate=1
Ntmp=Nd+Nj+1-ix
NsXtmj(Ntscis+Njj+1:Ntmp+Ntscis+Njj+1)=Nstoc
NsXdj(1:Ntmp+1)=NstoXd
IF (ix.EQ.1) THEN
DO iy=1,Ntd !sqrt(VAR(X(I)|X(Ntd-ix+1:Ntdc))
r1=index1(iy)
CSTD2(r1,Ntscis+Njj+1:Ntmp+Ntscis+Njj)=SQRT(SQ(iy))
ENDDO
ELSE
DO iy=ix,Nd+Nj
CSTD2(:,Nd+Nj+Ntscis+Njj+1-iy)=
& CSTD2(:,Ntmp+Ntscis+Njj+1)
ENDDO
ENDIF
GOTO 200 ! degenerate case
END IF
m1=index1(m(1));
CALL swapint(index1(m(1)),index1(r1+1))
!CSTD2(m1,Nd+Nj+Ntscis+Njj+1-ix)=SQRT(SQ(m(1)))
!CALL swapRe(SQ(Ntd-ix+1),SQ(m(1)))
SQ(r1+1) = SQRT(SQ(m(1)))
CSTD2(m1,Nd+Nj+Ntscis+Njj+1-ix) = SQ(r1+1)
R(index1(1:r1+1),m1) = R(index1(1:r1+1),m1)/SQ(r1+1)
R(m1,index1(1:r1)) = R(index1(1:r1),m1)
! Calculating conditional variances
CALL CONDSORT2(R,SQ,index1,Nstoc,NstoXd,Njleft,m1,Ntd-ix)
! saving indices
NsXtmj(Nd+Nj+Njj+Ntscis+1-ix)=Nstoc
NsXdj(Nd+Nj+1-ix)=NstoXd
! Calculating standard deviations non-deterministic variables
DO row=1,NsXtmj(Nd+Nj+Njj+Ntscis+2-ix) !Nstoc
r1=index1(row)
CSTD2(r1,Nd+Nj+Njj+Ntscis+1-ix)=SQRT(SQ(row)) !sqrt(VAR(X(I)|X(Ntd-ix+1:Ntdc))
ENDDO
DO row=NsXdj(Nd+Nj+2-ix),Ntd-ix !NstoXd,Ntd-ix
r1=index1(row)
CSTD2(r1,Nd+Nj+Ntscis+Njj+1-ix)=SQRT(SQ(row)) !sqrt(VAR(X(I)|X(Ntd-ix+1:Ntdc))
ENDDO
ENDDO ! ix
200 IF ((SCIS.GT.0).OR. (Njj.gt.0)) THEN ! check on Njj instead
! Calculating conditional variances and sort for Nstoc of Xt
CALL CONDSORT3(R,CSTD2,SQ,index1,NsXtmj,Nstoc)
!Nst0=Nstoc
ENDIF
IF ((Nd+Nj+Njj+Ntscis.GT.0)) THEN
DO row=1,Ntd ! sorting CSTD according to index1
r1=index1(row)
CSTD(row,:)= CSTD2(r1,:)
END DO
DEALLOCATE(CSTD2)
ELSE
IF (Nc.EQ.0) THEN
ix=1; Nstoc=Ntmj
DO WHILE (ix.LE.Nstoc)
IF (SQ(ix).LT.EPS2) THEN
DO WHILE ((SQ(Nstoc).LT.EPS2).AND.(ix.LT.Nstoc))
SQ(Nstoc)=0.d0 !max(0.d0,SQ(Nstoc))
Nstoc=Nstoc-1
END DO
CALL swapint(index1(ix),index1(Nstoc)) ! swap indices
!CALL swapRe(SQ(ix),SQ(Nstoc))
SQ(ix)=SQ(Nstoc);SQ(Nstoc)=0.d0
Nstoc=Nstoc-1
ENDIF
ix=ix+1
END DO
ENDIF
CSTD(1:Nt,1)=SQRT(SQ(1:Nt))
NsXtmj(1)=Nstoc
ENDIF
changed=0
DO row=Ntdc,1,-1 ! sorting the upper triangular of the
r1=index1(row) ! covariance matrix according to index1
xedni(r1)=row
!PRINT *,'condsort,xedni',xedni
!PRINT *,'condsort,r1,row',r1,row
IF ((r1.NE.row).OR.(changed.EQ.1)) THEN
changed=1
R(row,row)=SQ(row)
DO col=row+1,Ntdc
c1=index1(col)
IF (c1.GT.r1) THEN
R(row,col)=R(c1,r1)
ELSE
R(row,col)=R(r1,c1)
END IF
END DO
END IF
END DO
! you may sort the lower triangular according
! to index1 also, but it is not needed
! since R is symmetric. Uncomment the
! following if the whole matrix is needed
! DO col=1,Ntdc
! DO row=col+1,Ntdc
! R(row,col)=R(col,row) ! R symmetric
! END DO
! END DO
! IF (degenerate.EQ.1) THEN
! PRINT *,'condsort,R='
! call echo(R,Ntdc)
! PRINT *,'condsort,SQ='
! call echo(CSTD,Ntd)
! PRINT *,'index=',index1
! PRINT *,'xedni=',xedni
! ENDIF
! PRINT * , 'big'
!600 FORMAT(4F8.4)
! PRINT 600, R
! PRINT 600, SQ
DEALLOCATE(SQ)
RETURN
END SUBROUTINE CONDSORT
SUBROUTINE CONDSORT2(R,SQ,index1,Nstoc,NstoXd,Njleft,m1,N)
USE GLOBALDATA, ONLY : Ntd,EPS2,XCEPS2
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), INTENT(inout) :: R
DOUBLE PRECISION, DIMENSION(:), INTENT(inout) :: SQ
INTEGER, DIMENSION(: ), INTENT(inout) :: index1
INTEGER, INTENT(inout) :: Nstoc,NstoXd,Njleft
INTEGER, INTENT(in) :: m1,N
! local variables
INTEGER :: Nsold,Ndold, Ntmp
INTEGER :: r1,c1,row,col,iy
! save their old values
Nsold=Nstoc;Ndold=NstoXd
! Calculating conditional variances for the
! Xc variables.
DO row=Ntd+1,N
r1 = index1(row)
SQ(row) = R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
IF (SQ(row).LT.XCEPS2) THEN
IF (SQ(row).LT.-XCEPS2) THEN
!print *, 'Condsort2,Error: Covariance negative definit'
ENDIF
R(r1,r1) = 0.d0
SQ(row) = 0.d0
!PRINT *,'condsort2, degenerate xc'
RETURN ! degenerate case XIND should return NaN
ELSE
R(r1,r1)=SQ(row)
DO col=row+1,N
c1 = index1(col)
R(c1,r1) = R(r1,c1)-R(r1,m1)*R(m1,c1) !/R(m1,m1)
R(r1,c1) = R(c1,r1)
ENDDO
ENDIF
ENDDO ! Calculating conditional variances for the
! first Nstoc variables.
! variables with variance less than EPS2
! will be treated as deterministic and not
! stochastic variables and are therefore moved
! to the end among these Nt-Nj first variables.
! Nstoc is the # of variables we treat
! stochastically
iy=1
DO WHILE (iy.LE.Nstoc)
r1=index1(iy)
SQ(iy)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
IF (SQ(iy).LT.EPS2) THEN
IF (SQ(iy).LT.-EPS2) THEN
!print *, 'Condsort2,Error: Covariance negative definit'
ENDIF
r1=index1(Nstoc)
SQ(Nstoc)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
DO WHILE ((SQ(Nstoc).LT.EPS2).AND.(iy.LT.Nstoc))
IF (SQ(Nstoc).LT.-EPS2) THEN
!print *, 'Condsort2,Error: Covariance negative definit'
ENDIF
SQ(Nstoc)=0.d0 !MAX(0.d0,SQ(Nstoc))
Nstoc=Nstoc-1
r1=index1(Nstoc)
SQ(Nstoc)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
END DO
CALL swapint(index1(iy),index1(Nstoc)) ! swap indices
!CALL swapre(SQ(iy),SQ(Nstoc)) ! swap values
SQ(iy)=SQ(Nstoc);SQ(Nstoc)=0.d0
Nstoc=Nstoc-1
ENDIF
iy=iy+1
END DO
! Calculating conditional variances for the
! stochastic variables Xd and Njleft of Xt.
! Variables with conditional variance less than
! EPS2 are moved to the beginning among these
! with only One exception: if it is one of the
! Xt variables and Nstoc>0 then it switch place
! with Xt(Nstoc)
DO iy=Ndold,MIN(Ntd,N)
r1=index1(iy)
SQ(iy)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
IF (SQ(iy).LT.EPS2) THEN
IF (Njleft.GT.0) THEN
Ntmp=NstoXd+Njleft
IF (iy.LT.Ntmp) THEN
IF (Nstoc.GT.0) THEN !switch place with Xt(Nstoc)
CALL swapint(index1(iy),index1(Nstoc))
!CALL swapre(SQ(iy),SQ(Nstoc))
SQ(iy)=SQ(Nstoc);SQ(Nstoc)=0.d0
Nstoc=Nstoc-1
ELSE
CALL swapint(index1(iy),index1(NstoXd))
!CALL swapre(SQ(iy),SQ(NstoXd))
SQ(iy)=SQ(NstoXd);SQ(NstoXd)=0.d0
Njleft=Njleft-1
NstoXd=NstoXd+1
ENDIF
ELSE
CALL swapint(index1(iy),index1(Ntmp))
CALL swapint(index1(Ntmp),index1(NstoXd))
!CALL swapre(SQ(iy),SQ(Ntmp))
!CALL swapre(SQ(Ntmp),SQ(NstoXd))
SQ(iy)=SQ(Ntmp);SQ(Ntmp)=SQ(NstoXd)
SQ(NstoXd)=0.d0
NstoXd=NstoXd+1
ENDIF
ELSE
CALL swapint(index1(iy),index1(NstoXd))
!CALL swapre(SQ(iy),SQ(NstoXd)) !
SQ(iy)=SQ(NstoXd);SQ(NstoXd)=0.d0
NstoXd=NstoXd+1
ENDIF
ENDIF ! SQ < EPS2
ENDDO
! Calculating Covariances for non-deterministic variables
DO row=1,Nstoc
r1=index1(row)
R(r1,r1)=SQ(row)
DO col=row+1,Nstoc
c1=index1(col)
R(c1,r1)=R(r1,c1)-R(r1,m1)*R(m1,c1) !/R(m1,m1)
R(r1,c1)=R(c1,r1)
ENDDO
DO col=NstoXd,N
c1=index1(col)
R(c1,r1)=R(r1,c1)-R(r1,m1)*R(m1,c1) !/R(m1,m1)
R(r1,c1)=R(c1,r1)
ENDDO
ENDDO
DO row=NstoXd,MIN(Ntd,N)
r1=index1(row)
R(r1,r1)=SQ(row)
DO col=row+1,N
c1=index1(col)
R(c1,r1)=R(r1,c1)-R(r1,m1)*R(m1,c1) !/R(m1,m1)
R(r1,c1)=R(c1,r1)
ENDDO
ENDDO
! Set covariances for Deterministic variables to zero
! in order to avoid numerical problems
DO row=Ndold,NStoXd-1
r1=index1(row)
SQ(row) = 0.d0 !MAX(SQ(row),0.d0)
R(r1,r1) = SQ(row)
DO col=row+1,N
c1=index1(col)
R(c1,r1)=0.d0
R(r1,c1)=0.d0
ENDDO
DO col=1,Nsold
c1=index1(col)
R(c1,r1)=0.d0
R(r1,c1)=0.d0
ENDDO
ENDDO
DO row=Nstoc+1,Nsold
r1=index1(row)
SQ(row) = 0.d0 !MAX(SQ(row),0.d0)
R(r1,r1)=SQ(row)
DO col=1,row-1
c1=index1(col)
R(c1,r1)=0.d0
R(r1,c1)=0.d0
ENDDO
DO col=NstoXd,N
c1=index1(col)
R(c1,r1)=0.d0
R(r1,c1)=0.d0
ENDDO
ENDDO
RETURN
END SUBROUTINE CONDSORT2
SUBROUTINE CONDSORT3(R,CSTD2,SQ,index1,NsXtmj,Nstoc)
USE GLOBALDATA, ONLY : EPS2,Njj,Ntscis
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(:,:), INTENT(inout) :: R,CSTD2
DOUBLE PRECISION, DIMENSION(:), INTENT(inout) :: SQ ! diag. of R
INTEGER, DIMENSION(: ), INTENT(inout) :: index1,NsXtmj
INTEGER, DIMENSION(1) :: m
INTEGER, INTENT(inout) :: Nstoc
! local variables
INTEGER :: m1
INTEGER :: Nsold
INTEGER :: r1,c1,row,col,iy,ix
! This function condsort all the Xt variables for use with RINDSCIS and
! MNORMPRB
!Nsoold=Nstoc
ix=1
DO WHILE ((ix.LE.Nstoc).and.(ix.LE.(Ntscis+Njj)))
m=ix-1+MAXLOC(SQ(ix:Nstoc))
IF (SQ(m(1)).LT.EPS2) THEN
!PRINT *,'Condsort3, error degenerate X'
NsXtmj(1:Njj+Ntscis)=0
Nstoc=0 !degenerate=1
RETURN !degenerate case
ENDIF
m1=index1(m(1));
CALL swapint(index1(m(1)),index1(ix))
SQ(ix) = SQRT(SQ(m(1)))
CSTD2(m1,ix) = SQ(ix)
R(index1(ix:Nstoc),m1) = R(index1(ix:Nstoc),m1)/SQ(ix)
R(m1,index1(ix+1:Nstoc)) = R(index1(ix+1:Nstoc),m1)
! Calculating conditional variances for the
! first Nstoc variables.
! variables with variance less than EPS2
! will be treated as deterministic and not
! stochastic variables and are therefore moved
! to the end among these variables.
! Nstoc is the # of variables we treat
! stochastically
iy=ix+1;Nsold=Nstoc
DO WHILE (iy.LE.Nstoc)
r1=index1(iy)
SQ(iy)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
IF (SQ(iy).LT.EPS2) THEN
IF (SQ(iy).LT.-EPS2) THEN
!print *,'Cndsrt3,Error:Covariance negative definit'
ENDIF
r1=index1(Nstoc)
SQ(Nstoc)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
DO WHILE ((SQ(Nstoc).LT.EPS2).AND.(iy.LT.Nstoc))
IF (SQ(Nstoc).LT.-EPS2) THEN
!print *,'Cndsrt3,Error:Covariance negative definit'
ENDIF
SQ(Nstoc)=0.d0 !MAX(0.d0,SQ(Nstoc))
Nstoc=Nstoc-1
r1=index1(Nstoc)
SQ(Nstoc)=R(r1,r1)-R(r1,m1)*R(m1,r1) !/R(m1,m1)
END DO
CALL swapint(index1(iy),index1(Nstoc)) ! swap indices
!CALL swapre(SQ(iy),SQ(Nstoc)) !
SQ(iy)=SQ(Nstoc); SQ(Nstoc)=0.d0 ! swap values
Nstoc=Nstoc-1
ENDIF
iy=iy+1
END DO
NsXtmj(ix)=Nstoc ! saving index to last stoch. var. after conditioning
! Calculating Covariances for non-deterministic variables
DO row=ix+1,Nstoc
r1=index1(row)
R(r1,r1)=SQ(row)
CSTD2(r1,ix)=SQRT(SQ(row)) ! saving stdev after conditioning on ix
DO col=row+1,Nstoc
c1=index1(col)
R(c1,r1)=R(r1,c1)-R(r1,m1)*R(m1,c1) !/R(m1,m1)
R(r1,c1)=R(c1,r1)
ENDDO
ENDDO
! similarly for deterministic values
DO row=Nstoc+1,Nsold
r1=index1(row)
SQ(row)=0.d0 !MAX(SQ(row),0.d0)
R(r1,r1)=SQ(row)
DO col=ix+1,Nsold !row-1
c1=index1(col)
R(c1,r1)=0.d0
R(r1,c1)=0.d0
ENDDO
ENDDO
ix=ix+1
ENDDO
NsXtmj(Nstoc+1:Njj+Ntscis)=Nstoc
RETURN
END SUBROUTINE CONDSORT3
SUBROUTINE swapRe(m,n)
IMPLICIT NONE
DOUBLE PRECISION, INTENT(inout) :: m,n
DOUBLE PRECISION :: tmp
tmp=m
m=n
n=tmp
END SUBROUTINE swapRe
SUBROUTINE swapint(m,n)
IMPLICIT NONE
INTEGER, INTENT(inout) :: m,n
INTEGER :: tmp
tmp=m
m=n
n=tmp
END SUBROUTINE swapint
SUBROUTINE getdiag(diag,matrix)
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(: ), INTENT(out) :: diag
DOUBLE PRECISION, DIMENSION(:,:), INTENT(in) :: matrix
DOUBLE PRECISION, DIMENSION(: ), ALLOCATABLE :: vector
ALLOCATE(vector(SIZE(matrix)))
vector=PACK(matrix,.TRUE.)
diag=vector(1:SIZE(matrix):SIZE(matrix,dim=1)+1)
DEALLOCATE(vector)
END SUBROUTINE getdiag
END MODULE RIND71MOD