Logo Search packages:      
Sourcecode: adapt version File versions  Download package

symrl.f

      subroutine symrl(s, center, hwidth, minord, maxord, intvls,
     *     intcls, numsms, weghts, fulsms, fail)
c  multidimensional fully symmetric rule integration subroutine
c
c   this subroutine computes a sequence of fully symmetric rule
c   approximations to a fully symmetric multiple integral.
c   written by a. genz, mathematical institute, university of kent,
c   canterbury, kent ct2 7nf, england
c
c**************    parameters for symrl  ********************************
c*****input parameters
c  s     integer number of variables, must exceed 0 but not exceed 20
c  f     externally declared user defined real function integrand.
c        it must have parameters (s,x), where x is a real array
c        with dimension s.
c  minord  integer minimum order parameter.  on entry minord specifies
c        the current highest order approximation to the integral,
c        available in the array intvls.  for the first call of symrl
c        minord should be set to 0.  otherwise a previous call is
c        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 minord
c        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 of
c        the number of distinct partitions of length at most s
c        of the integers 0,1,...,maxord-1.  an upper bound for numsms
c        when s+maxord is less than 19 is 200
c******output parameters
c  intvls  real array of dimension(maxord).  upon successful exit
c        intvls(1), intvls(2),..., intvls(maxord) are approximations
c        to the integral.  intvls(d+1) will be an approximation of
c        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 exit
c        weghts(j) contains the weight for fulsms(j).
c  fulsms  real working storage array with dimension (numsms). on exit
c        fulsms(j) contains the fully symmetric basic rule sum
c        indexed by the jth s-partition of the integers
c        0,1,...,maxord-1.
c  fail        integer failure output parameter
c        fail=0 for successful termination of the subroutine
c        fail=1 when numsms is too small for the subroutine to
c              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 of
c              maxord compatible with the given value of numsms.
c        fail=2 when parameters s,minord, maxord or g are out of
c              range
c***********************************************************************
cmmm    external f
ctsl  real f
ctsl       double precision f
c***  for double precision change real to double precision
c      in the next statement
      integer d, i, fail, k(20), intcls, prtcnt, l, m(20), maxord,
     * minord, modofm, numsms, s, sumcls
      double 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, wht
c     patterson generators
      data 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/
c
c***  parameter checking and initialisation
      fail = 2
      maxrdm = 20
      maxs = 20
      if (s.gt.maxs .or. s.lt.1) return
      if (minord.lt.0 .or. minord.ge.maxord) return
      if (maxord.gt.maxrdm) return
      zero = 0
      one = 1
      two = 2
      momtol = one
   10 momtol = momtol/two
      if (momtol+one.gt.one) go to 10
      hundrd = 100
      momtol = hundrd*two*momtol
      d = minord
      if (d.eq.0) intcls = 0
c***  calculate moments and modified moments
      do 20 l=1,maxord
      floatl = l + l - 1
      moment(l) = two/floatl
   20 continue
      if (maxord.ne.1) then
         do 40 l=2,maxord
            intmpa = moment(l-1)
            glsqrd = g(l-1)**2
            do 30 i=l,maxord
               intmpb = moment(i)
               moment(i) = moment(i) - glsqrd*intmpa
               intmpa = intmpb
 30         continue
            if (moment(l)**2.lt.(momtol*moment(1))**2) moment(l) = zero
 40      continue
      endif
      do 70 l=1,maxord
      if (g(l).lt.zero) return
      momnkn = one
      momprd(l,1) = moment(1)
      if (maxord.eq.1) go to 70
      glsqrd = g(l)**2
      do 60 i=2,maxord
        if (i.le.l) gisqrd = g(i-1)**2
        if (i.gt.l) gisqrd = g(i)**2
        if (glsqrd.eq.gisqrd) return
        momnkn = momnkn/(glsqrd-gisqrd)
        momprd(l,i) = momnkn*moment(i)
   60 continue
   70 continue
      fail = 1
c
c***  begin LOOP
c      for each d find all distinct partitions m with mod(m))=d
c
   80 prtcnt = 0
      intval = zero
      modofm = 0
      call nxprt(prtcnt, s, m)
   90 if (prtcnt.gt.numsms) return
c
c***  calculate weight for partition m and fully symmetric sums
c***   when necessary
c
      if (d.eq.modofm) weghts(prtcnt) = zero
      if (d.eq.modofm) fulsms(prtcnt) = zero
      fulwgt = wht(s,moment,m,k,modofm,d,maxrdm,momprd)
      sumcls = 0
      if (weghts(prtcnt).eq.zero .and. fulwgt.ne.zero) fulsms(prtcnt) =
     * flsm(s, center, hwidth, moment, m, k, maxord, g, sumcls)
      intcls = intcls + sumcls
      intval = intval + fulwgt*fulsms(prtcnt)
      weghts(prtcnt) = weghts(prtcnt) + fulwgt
      call nxprt(prtcnt, s, m)
      if (m(1).gt.modofm) modofm = modofm + 1
      if (modofm.le.d) go to 90
c
c***  end loop for each d
      if (d.gt.0) intval = intvls(d) + intval
      intvls(d+1) = intval
      d = d + 1
      if (d.lt.maxord) go to 80
c
c***  set failure parameter and return
      fail = 0
      minord = maxord
      return
      end

Generated by  Doxygen 1.6.0   Back to index