Blame | Last modification | View Log | Download | RSS feed
subroutine symrl(s, center, hwidth, minord, maxord, intvls,* intcls, numsms, weghts, fulsms, fail)c multidimensional fully symmetric rule integration subroutinecc this subroutine computes a sequence of fully symmetric rulec approximations to a fully symmetric multiple integral.c written by a. genz, mathematical institute, university of kent,c canterbury, kent ct2 7nf, englandcc************** parameters for symrl ********************************c*****input parametersc s integer number of variables, must exceed 0 but not exceed 20c f externally declared user defined real function integrand.c it must have parameters (s,x), where x is a real arrayc with dimension s.c minord integer minimum order parameter. on entry minord specifiesc the current highest order approximation to the integral,c available in the array intvls. for the first call of symrlc minord should be set to 0. otherwise a previous call isc assumed that computed intvls(1), ... , intvls(minord).c on exit minord is set to maxord.c maxord integer maximum order parameter, must be greater than minordc and not exceed 20. the subroutine computes intvls(minord+1),c intvls(minord+2),..., intvls(maxord).c g real array of dimension(maxord) of generators.c all generators must be distinct and nonnegative.c numsms integer length of array fulsms, must be at least the sum ofc the number of distinct partitions of length at most sc of the integers 0,1,...,maxord-1. an upper bound for numsmsc when s+maxord is less than 19 is 200c******output parametersc intvls real array of dimension(maxord). upon successful exitc intvls(1), intvls(2),..., intvls(maxord) are approximationsc to the integral. intvls(d+1) will be an approximation ofc polynomial degree 2d+1.c intcls integer total number of f values needed for intvls(maxord)c weghts real working storage array with dimension (numsms). on exitc weghts(j) contains the weight for fulsms(j).c fulsms real working storage array with dimension (numsms). on exitc fulsms(j) contains the fully symmetric basic rule sumc indexed by the jth s-partition of the integersc 0,1,...,maxord-1.c fail integer failure output parameterc fail=0 for successful termination of the subroutinec fail=1 when numsms is too small for the subroutine toc continue. in this case weghts(1), weghts(2), ...,c weghts(numsms), fulsms(1), fulsms(2), ...,c fulsms(numsms) and intvls(1), intvls(2),...,c intvls(j) are returned, where j is maximum value ofc maxord compatible with the given value of numsms.c fail=2 when parameters s,minord, maxord or g are out ofc rangec***********************************************************************cmmm external fctsl real fctsl double precision fc*** for double precision change real to double precisionc in the next statementinteger d, i, fail, k(20), intcls, prtcnt, l, m(20), maxord,* minord, modofm, numsms, s, sumclsdouble precision intvls(maxord), center(s), hwidth(s), gisqrd,* glsqrd,* intmpa, intmpb, intval, one, fulsms(numsms), weghts(numsms),* two, momtol, momnkn, momprd(20,20), moment(20), zero, g(20)double precision flsm, whtc patterson generatorsdata g(1), g(2) /0.0000000000000000,0.7745966692414833/data g(3), g(4) /0.9604912687080202,0.4342437493468025/data g(5), g(6) /0.9938319632127549,0.8884592328722569/data g(7), g(8) /0.6211029467372263,0.2233866864289668/data g(9), g(10), g(11), g(12) /0.1, 0.2, 0.3, 0.4/cc*** parameter checking and initialisationfail = 2maxrdm = 20maxs = 20if (s.gt.maxs .or. s.lt.1) returnif (minord.lt.0 .or. minord.ge.maxord) returnif (maxord.gt.maxrdm) returnzero = 0one = 1two = 2momtol = one10 momtol = momtol/twoif (momtol+one.gt.one) go to 10hundrd = 100momtol = hundrd*two*momtold = minordif (d.eq.0) intcls = 0c*** calculate moments and modified momentsdo 20 l=1,maxordfloatl = l + l - 1moment(l) = two/floatl20 continueif (maxord.ne.1) thendo 40 l=2,maxordintmpa = moment(l-1)glsqrd = g(l-1)**2do 30 i=l,maxordintmpb = moment(i)moment(i) = moment(i) - glsqrd*intmpaintmpa = intmpb30 continueif (moment(l)**2.lt.(momtol*moment(1))**2) moment(l) = zero40 continueendifdo 70 l=1,maxordif (g(l).lt.zero) returnmomnkn = onemomprd(l,1) = moment(1)if (maxord.eq.1) go to 70glsqrd = g(l)**2do 60 i=2,maxordif (i.le.l) gisqrd = g(i-1)**2if (i.gt.l) gisqrd = g(i)**2if (glsqrd.eq.gisqrd) returnmomnkn = momnkn/(glsqrd-gisqrd)momprd(l,i) = momnkn*moment(i)60 continue70 continuefail = 1cc*** begin LOOPc for each d find all distinct partitions m with mod(m))=dc80 prtcnt = 0intval = zeromodofm = 0call nxprt(prtcnt, s, m)90 if (prtcnt.gt.numsms) returncc*** calculate weight for partition m and fully symmetric sumsc*** when necessarycif (d.eq.modofm) weghts(prtcnt) = zeroif (d.eq.modofm) fulsms(prtcnt) = zerofulwgt = wht(s,moment,m,k,modofm,d,maxrdm,momprd)sumcls = 0if (weghts(prtcnt).eq.zero .and. fulwgt.ne.zero) fulsms(prtcnt) =* flsm(s, center, hwidth, moment, m, k, maxord, g, sumcls)intcls = intcls + sumclsintval = intval + fulwgt*fulsms(prtcnt)weghts(prtcnt) = weghts(prtcnt) + fulwgtcall nxprt(prtcnt, s, m)if (m(1).gt.modofm) modofm = modofm + 1if (modofm.le.d) go to 90cc*** end loop for each dif (d.gt.0) intval = intvls(d) + intvalintvls(d+1) = intvald = d + 1if (d.lt.maxord) go to 80cc*** set failure parameter and returnfail = 0minord = maxordreturnend