
     C06(3NAG)         Foundation Library (12/10/92)         C06(3NAG)



          C06 -- Summation of Series                    Introduction -- C06
                                    Chapter C06
                                Summation of Series

          1. Scope of the Chapter

          This chapter is concerned with calculating the discrete Fourier
          transform of a sequence of real or complex data values, and
          applying it to calculate convolutions and correlations.

          2. Background to the Problems

          2.1. Discrete Fourier Transforms

          2.1.1.  Complex transforms

          Most of the routines in this chapter calculate the finite
          discrete Fourier transform  (DFT) of a sequence of n complex
          numbers z , for j=0,1,...,n-1. The transform is defined by:
                   j

                                  n-1
                          ^    1  --      (   2(pi)jk)
                          z = --- >  z exp(-i -------)                  (1)
                           k      --  j   (      n   )
                              \/n j=0

          for k=0,1,...,n-1. Note that equation (1) makes sense for all
                                             ^
          integral k and with this extension z  is periodic with period n,
                                              k
               ^  ^                        ^   ^
          i.e. z =z    , and in particular z  =z   .
                k  k+-n                     -k  n-k

                                    ^                                 ^
          If we write z =x +iy  and z =a +ib , then the definition of z
                       j  j   j      k  k   k                          k
          may be written in terms of sines and cosines as:

                            n-1
                         1  -- (     ( 2(pi)jk)      ( 2(pi)jk))
                    a = --- >  (x cos( -------)+y sin( -------))
                     k      -- ( j   (    n   )  j   (    n   ))
                        \/n j=0

                            n-1
                         1  -- (     ( 2(pi)jk)      ( 2(pi)jk))
                    b = --- >  (y cos( -------)-x sin( -------)).
                     k      -- ( j   (    n   )  j   (    n   ))
                        \/n j=0

          The original data values z  may conversely be recovered from the
                                    j
                    ^
          transform z  by an  inverse discrete Fourier transform:
                     k


                                  n-1
                               1  -- ^    (   2(pi)jk)
                          z = --- >  z exp(+i -------)                  (2)
                           j      --  k   (      n   )
                              \/n k=0

          for j=0,1,...,n-1. If we take the complex conjugate of (2), we
                                                               

                                                               ^
          find that the sequence z  is the DFT of the sequence z . Hence
                                  j                             k
                                          ^
          the inverse DFT of the sequence z  may be obtained by: taking the
                                           k
                                    ^
          complex conjugates of the z ; performing a DFT; and taking the
                                     k
          complex conjugates of the result.

          Notes: definitions of the discrete Fourier transform vary.
          Sometimes (2) is used as the definition of the DFT, and (1) as
                                                                      

          the definition of the inverse. Also the scale-factor of 1/\/n may
          be omitted in the definition of the DFT, and replaced by 1/n in
          the definition of the inverse.

          2.1.2. Real transforms

          If the original sequence is purely real valued, i.e. z =x , then
                                                                j  j

                                        n-1
                         ^           1  --      (   2(pi)jk)
                         z =a +ib = --- >  x exp(-i -------)
                          k  k   k      --  j   (      n   )
                                    \/n j=0

              ^                                ^
          and z    is the complex conjugate of z . Thus the DFT of a real
               n-k                              k
          sequence is a particular type of complex sequence, called a
          Hermitian sequence, or  half-complex or  conjugate symmetric with
          the properties:
                         a   =a  b   =-b  b =0 and, if n is even, b   =0.
                          n-k  k  n-k   k  0                       n/2

          Thus a Hermitian sequence of n complex data values can be
          represented by only n, rather than 2n, independent real values.
          This can obviously lead to economies in storage, the following
          scheme being used in this chapter: the real parts a  for
                                                             k
          0<=k<=n/2 are stored in normal order in the first n/2+1 locations
          of an array X of length n; the corresponding non-zero imaginary
          parts are stored in reverse order in the remaining locations of
          X. In other words, if X is declared with bounds (0:n-1) in the
                                                               ^
          user's (sub)program, the real and imaginary parts of z  are
                                                                k
          stored as follows:

                         if n=2s    if n=2s-1

              X(0)       a          a
                          0          0

              X(1)       a          a
                          1          1

              X(2)       a          a
                          2          2

              .          .          .

              .          .          .

              .          .          .

              X(s-1)     a          a
                          s-1        s-1

              X(s)       a          b
                          s          s-1

              X(s+1)     b          b
                          s-1        s-2

              .          .          .

              .          .          .

              .          .          .

              X(n-2)     b          b
                          2          2

              X(n-1)     b          b
                          1          1


                         (     n/2-1                                      )
                       1 (     --   (     ( 2(pi)jk)      ( 2(pi)jk))     )
          Hence   x = ---(a +2 >    (a cos( -------)-b sin( -------))+a   )
                   j     ( 0   --   ( k   (    n   )  k   (    n   ))  n/2)
                      \/n(     k=0                                        )

          where a    = 0 if n is odd.
                 n/2

          2.1.3.  Fourier integral transforms

          The usual application of the discrete Fourier transform is that
          of obtaining an approximation of the  Fourier integral transform


                                +infty
                                /
                          F(s)= |     f(t)exp(-i2(pi)st)dt
                                /
                                -infty

          when f(t) is negligible outside some region (0,c). Dividing the
          region into n equal intervals we have

                                    n-1
                                  c --
                           F(s)~= - >  f exp(-i2(pi)sjc/n)
                                  n --  j
                                    j=0

          and so

                                   n-1
                                 c --
                            F ~= - >  f exp(-i2(pi)jk/n)
                             k   n --  j
                                   j=0

          for k=0,1,...,n-1, where f =f(jc/n) and F =F(k/c).
                                    j              k

          Hence the discrete Fourier transform gives an approximation to
          the Fourier integral transform in the region s=0 to s=n/c.

          If the function f(t) is defined over some more general interval
          (a,b), then the integral transform can still be approximated by
          the discrete transform provided a shift is applied to move the
          point a to the origin.

          2.1.4.  Convolutions and correlations

          One of the most important applications of the discrete Fourier
          transform is to the computation of the discrete convolution or
          correlation of two vectors x and y defined (as in Brigham [1])
          by:

                                n-1
                                --
               convolution: z = >  x y
                             k  --  j k-j
                                j=0

                                n-1
                                -- 
               correlation: w = >  x y
                             k  --  j k+j
                                j=0

          (Here x and y are assumed to be periodic with period n.)

          Under certain circumstances (see Brigham [1]) these can be used
          as approximations to the convolution or correlation integrals
          defined by:

                                    +infty
                                    /
                              z(s)= |     x(t)y(s-t)dt
                                    /
                                    -infty

          and

                          +infty
                          /     
                    w(s)= |     x(t)y(s+t)dt,   -infty<s<+infty.
                          /
                          -infty

          For more general advice on the use of Fourier transforms, see
          Hamming [2]; more detailed information on the fast Fourier
          transform algorithm can be found in Van Loan [3] and Brigham [1].

          2.2. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          [2]   Hamming R W (1962) Numerical Methods for Scientists and
                Engineers. McGraw-Hill.

          [3]   Van Loan C (1992) Computational Frameworks for the Fast
                Fourier Transform. SIAM Philadelphia.

          3. Recommendations on Choice and Use of Routines

          3.1. One-dimensional Fourier Transforms

          The choice of routine is determined first of all by whether the
          data values constitute a real, Hermitian or general complex
          sequence. It is wasteful of time and storage to use an
          inappropriate routine.

          Two groups, each of three routines, are provided

                                   Group 1      Group 2

              Real sequences       C06EAF       C06FPF

              Hermitian sequences  C06EBF       C06FQF

              General complex      C06ECF       C06FRF
              sequences

          Group 1 routines each compute a single transform of length n,
          without requiring any extra working storage. The Group 1 routines
          impose some restrictions on the value of n, namely that no prime
          factor of n may exceed 19 and the total number of prime factors
          (including repetitions) may not exceed 20 (though the latter
                                                     6
          restriction only becomes relevant when n>10 ).

          Group 2 routines are designed to perform several transforms in a
          single call, all with the same value of n. They do however
          require more working storage. Even on scalar processors, they may
          be somewhat faster than repeated calls to Group 1 routines
          because of reduced overheads and because they pre-compute and
          store the required values of trigonometric functions. Group 2
          routines impose no practical restrictions on the value of n;
          however the fast Fourier transform algorithm ceases to be 'fast'
          if applied to values of n which cannot be expressed as a product
          of small prime factors. All the above routines are particularly
          efficient if the only prime factors of n are 2, 3 or 5.

          If extensive use is to be made of these routines, users who are
          concerned about efficiency are advised to conduct their own
          timing tests.

          To compute inverse discrete Fourier transforms the above routines
          should be used in conjunction with the utility routines C06GBF,
          C06GCF and C06GQF which form the complex conjugate of a Hermitian
          or general sequence of complex data values.

          3.2. Multi-dimensional Fourier Transforms

          C06FUF computes a 2-dimensional discrete Fourier transform of a
          2-dimensional sequence of complex data values. This is defined by

                         n -1 n -1
                          1    2          (   2(pi)j k )   (   2(pi)j k )
          ^         1    --   --          (         1 1)   (         2 2)
          z    = ------- >    >   z    exp(-i ---------)exp(-i ---------).
                         --   --          (      n     )   (      n     )
           k k     /n n  j =0 j =0 j j    (       1    )   (       2    )
            1 2  \/  1 2  1    2    1 2

          3.3. Convolution and Correlation

          C06EKF computes either the discrete convolution or the discrete
          correlation of two real vectors.

          3.4. Index

          Complex conjugate,
               complex sequence                                      C06GCF
               Hermitian sequence                                    C06GBF
               multiple Hermitian sequences                          C06GQF
          Complex sequence from Hermitian sequences                  C06GSF
          Convolution or Correlation
               real vectors                                          C06EKF
          Discrete Fourier Transform
               two-dimensional
                    complex sequence                                 C06FUF
               one-dimensional, multiple transforms
                    complex sequence                                 C06FRF
                    Hermitian sequence                               C06FQF
                    real sequence                                    C06FPF
               one-dimensional, single transforms
                    complex sequence                                 C06ECF
                    Hermitian sequence                               C06EBF
                    real sequence                                    C06EAF



          C06 -- Summation of Series                        Contents -- C06
          Chapter C06

          Summation of Series

          C06EAF  Single 1-D real discrete Fourier transform, no extra
                  workspace

          C06EBF  Single 1-D Hermitian discrete Fourier transform, no extra
                  workspace

          C06ECF  Single 1-D complex discrete Fourier transform, no extra
                  workspace

          C06EKF  Circular convolution or correlation of two real vectors,
                  no extra workspace

          C06FPF  Multiple 1-D real discrete Fourier transforms

          C06FQF  Multiple 1-D Hermitian discrete Fourier transforms

          C06FRF  Multiple 1-D complex discrete Fourier transforms

          C06FUF  2-D complex discrete Fourier transform

          C06GBF  Complex conjugate of Hermitian sequence

          C06GCF  Complex conjugate of complex sequence

          C06GQF  Complex conjugate of multiple Hermitian sequences

          C06GSF  Convert Hermitian sequences to general complex sequences

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06EAF(3NAG)      Foundation Library (12/10/92)      C06EAF(3NAG)

          C06 -- Summation of Series                                 C06EAF
                  C06EAF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06EAF calculates the discrete Fourier transform of a sequence of
          n real data values. (No extra workspace required.)

          2. Specification

                 SUBROUTINE C06EAF (X, N, IFAIL)
                 INTEGER          N, IFAIL
                 DOUBLE PRECISION X(N)

          3. Description

          Given a sequence of n real data values x , for j=0,1,...,n-1,
                                                  j
          this routine calculates their discrete Fourier transform defined
          by:

                            n-1
                    ^    1  --       (   2(pi)jk)
                    z = --- >  x *exp(-i -------), k=0,1,...,n-1.
                     k      --  j    (      n   )
                        \/n j=0

                                      1
          (Note the scale factor of  --- in this definition.) The
                                       

                                     \/n
                             ^
          transformed values z  are complex, but they form a Hermitian
                              k
                          ^                                ^
          sequence (i.e., z    is the complex conjugate of z ), so they are
                           n-k                              k
          completely determined by n real numbers (see also the Chapter
          Introduction).

          To compute the inverse discrete Fourier transform defined by:

                                   n-1
                           ^    1  --       (   2(pi)jk)
                           w = --- >  x *exp(+i -------),
                            k      --  j    (      n   )
                               \/n j=0

          this routine should be followed by a call of C06GBF to form the
                                    ^
          complex conjugates of the z .
                                     k

          The routine uses the fast Fourier transform (FFT) algorithm
          (Brigham [1]). There are some restrictions on the value of n (see
          Section 5).

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          5. Parameters

           1:  X(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: if X is declared with bounds (0:N-1) in the (sub)
               program from which C06EAF is called, then X(j) must contain
               x , for j=0,1,...,n-1. On exit: the discrete Fourier
                j
               transform stored in Hermitian form. If the components of the
                         ^
               transform z  are written as a +ib , and if X is declared
                          k                 k   k
               with bounds (0:N-1) in the (sub)program from which C06EAF is
               called, then for 0<=k<=n/2, a  is contained in X(k), and for
                                            k
               1<=k<=(n-1)/2, b  is contained in X(n-k). (See also Section
                               k
               2.1.2 of the Chapter Introduction, and the Example Program.)

           2:  N -- INTEGER                                           Input
               On entry: the number of data values, n. The largest prime
               factor of N must not exceed 19, and the total number of
               prime factors of N, counting repetitions, must not exceed
               20. Constraint: N > 1.

           3:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          IFAIL= 1
               At least one of the prime factors of N is greater than 19.

          IFAIL= 2
               N has more than 20 prime factors.

          IFAIL= 3
               N <= 1.

          7. Accuracy

          Some indication of accuracy can be obtained by performing a
          subsequent inverse transform and comparing the results with the
          original sequence (in exact arithmetic they would be identical).

          8. Further Comments

          The time taken by the routine is approximately proportional to
          n*logn, but also depends on the factorization of n. The routine
          is somewhat faster than average if the only prime factors of n
          are 2, 3 or 5; and fastest of all if n is a power of 2.

          On the other hand, the routine is particularly slow if n has
          several unpaired prime factors, i.e., if the 'square-free' part
          of n has several factors. For such values of n, routine C06FAF(*)
          (which requires an additional n elements of workspace) is
          considerably faster.

          9. Example

          This program reads in a sequence of real data values, and prints
          their discrete Fourier transform (as computed by C06EAF), after
          expanding it from Hermitian form into a full complex sequence.

          It then performs an inverse transform using C06GBF and C06EBF,
          and prints the sequence so obtained alongside the original data
          values.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06EBF(3NAG)      Foundation Library (12/10/92)      C06EBF(3NAG)

          C06 -- Summation of Series                                 C06EBF
                  C06EBF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06EBF calculates the discrete Fourier transform of a Hermitian
          sequence of n complex data values. (No extra workspace required.)

          2. Specification

                 SUBROUTINE C06EBF (X, N, IFAIL)
                 INTEGER          N, IFAIL
                 DOUBLE PRECISION X(N)

          3. Description

          Given a Hermitian sequence of n complex data values z  (i.e., a
                                                               j
          sequence such that z  is real and z    is the complex conjugate
                              0              n-j
          of z , for j=1,2,...,n-1) this routine calculates their discrete
              j
          Fourier transform defined by:

                            n-1
                    ^    1  --       (   2(pi)jk)
                    x = --- >  z *exp(-i -------), k=0,1,...,n-1.
                     k      --  j    (      n   )
                        \/n j=0

                                      1
          (Note the scale factor of  --- in this definition.) The
                                       

                                     \/n
                             ^
          transformed values x  are purely real (see also the the Chapter
                              k
          Introduction).

          To compute the inverse discrete Fourier transform defined by:

                                   n-1
                           ^    1  --       (   2(pi)jk)
                           y = --- >  z *exp(+i -------),
                            k      --  j    (      n   )
                               \/n j=0

          this routine should be preceded by a call of C06GBF to form the
          complex conjugates of the z .
                                     j

          The routine uses the fast Fourier transform (FFT) algorithm
          (Brigham [1]). There are some restrictions on the value of n (see
          Section 5).

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          5. Parameters

           1:  X(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: the sequence to be transformed stored in
               Hermitian form. If the data values z  are written as x +iy ,
                                                   j                 j   j
               and if X is declared with bounds (0:N-1) in the subroutine
               from which C06EBF is called, then for 0<=j<=n/2, x  is
                                                                 j
               contained in X(j), and for 1<=j<=(n-1)/2, y  is contained in
                                                          j
               X(n-j). (See also Section 2.1.2 of the Chapter Introduction
               and the Example Program.) On exit: the components of the
                                          ^
               discrete Fourier transform x . If X is declared with bounds
                                           k
               (0:N-1) in the (sub)program from which C06EBF is called,
                    ^
               then x  is stored in X(k), for k=0,1,...,n-1.
                     k

           2:  N -- INTEGER                                           Input
               On entry: the number of data values, n. The largest prime
               factor of N must not exceed 19, and the total number of
               prime factors of N, counting repetitions, must not exceed
               20. Constraint: N > 1.

           3:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          IFAIL= 1
               At least one of the prime factors of N is greater than 19.

          IFAIL= 2
               N has more than 20 prime factors.

          IFAIL= 3
               N <= 1.

          7. Accuracy

          Some indication of accuracy can be obtained by performing a
          subsequent inverse transform and comparing the results with the
          original sequence (in exact arithmetic they would be identical).

          8. Further Comments

          The time taken by the routine is approximately proportional to
          n*logn, but also depends on the factorization of n. The routine
          is somewhat faster than average if the only prime factors of n
          are 2, 3 or 5; and fastest of all if n is a power of 2.

          On the other hand, the routine is particularly slow if n has
          several unpaired prime factors, i.e., if the 'square-free' part
          of n has several factors. For such values of n, routine C06FBF(*)
          (which requires an additional n elements of workspace) is
          considerably faster.

          9. Example

          This program reads in a sequence of real data values which is
          assumed to be a Hermitian sequence of complex data values stored
          in Hermitian form. The input sequence is expanded into a full
          complex sequence and printed alongside the original sequence. The
          discrete Fourier transform (as computed by C06EBF) is printed
          out.

          The program then performs an inverse transform using C06EAF and
          C06GBF, and prints the sequence so obtained alongside the
          original data values.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06ECF(3NAG)      Foundation Library (12/10/92)      C06ECF(3NAG)

          C06 -- Summation of Series                                 C06ECF
                  C06ECF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06ECF calculates the discrete Fourier transform of a sequence of
          n complex data values. (No extra workspace required.)

          2. Specification

                 SUBROUTINE C06ECF (X, Y, N, IFAIL)
                 INTEGER          N, IFAIL
                 DOUBLE PRECISION X(N), Y(N)

          3. Description

          Given a sequence of n complex data values z , for j=0,1,...,n-1,
                                                     j
          this routine calculates their discrete Fourier transform defined
          by:

                            n-1
                    ^    1  --       (   2(pi)jk)
                    z = --- >  z *exp(-i -------), k=0,1,...,n-1.
                     k      --  j    (      n   )
                        \/n j=0

                                      1
          (Note the scale factor of  --- in this definition.)
                                       

                                     \/n

          To compute the inverse discrete Fourier transform defined by:

                                   n-1
                           ^    1  --       (   2(pi)jk)
                           w = --- >  z *exp(+i -------),
                            k      --  j    (      n   )
                               \/n j=0

          this routine should be preceded and followed by calls of C06GCF
                                                           ^
          to form the complex conjugates of the z  and the z .
                                                 j          k

          The routine uses the fast Fourier transform (FFT) algorithm
          (Brigham [1]). There are some restrictions on the value of n (see
          Section 5).

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          5. Parameters

           1:  X(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: if X is declared with bounds (0:N-1) in the (sub)
               program from which C06ECF is called, then X(j) must contain
               x , the real part of z , for j=0,1,...,n-1. On exit: the
                j                    j
               real parts a  of the components of the discrete Fourier
                           k
               transform. If X is declared with bounds (0:N-1) in the (sub)
               program from which C06ECF is called, then a  is contained in
                                                          k
               X(k), for k=0,1,...,n-1.

           2:  Y(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: if Y is declared with bounds (0:N-1) in the (sub)
               program from which C06ECF is called, then Y(j) must contain
               y , the imaginary part of z , for j=0,1,...,n-1. On exit:
                j                         j
               the imaginary parts b  of the components of the discrete
                                    k
               Fourier transform. If Y is declared with bounds (0:N-1) in
               the (sub)program from which C06ECF is called, then b  is
                                                                   k
               contained in Y(k), for k=0,1,...,n-1.

           3:  N -- INTEGER                                           Input
               On entry: the number of data values, n. The largest prime
               factor of N must not exceed 19, and the total number of
               prime factors of N, counting repetitions, must not exceed
               20. Constraint: N > 1.

           4:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          IFAIL= 1
               At least one of the prime factors of N is greater than 19.

          IFAIL= 2
               N has more than 20 prime factors.

          IFAIL= 3
               N <= 1.

          7. Accuracy

          Some indication of accuracy can be obtained by performing a
          subsequent inverse transform and comparing the results with the
          original sequence (in exact arithmetic they would be identical).

          8. Further Comments

          The time taken by the routine is approximately proportional to
          n*logn, but also depends on the factorization of n. The routine
          is somewhat faster than average if the only prime factors of n
          are 2, 3 or 5; and fastest of all if n is a power of 2.

          On the other hand, the routine is particularly slow if n has
          several unpaired prime factors, i.e., if the 'square-free' part
          of n has several factors. For such values of n, routine C06FCF(*)
          (which requires an additional n real elements of workspace) is
          considerably faster.

          9. Example

          This program reads in a sequence of complex data values and
          prints their discrete Fourier transform.

          It then performs an inverse transform using C06GCF and C06ECF,
          and prints the sequence so obtained alongside the original data
          values.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06EKF(3NAG)      Foundation Library (12/10/92)      C06EKF(3NAG)

          C06 -- Summation of Series                                 C06EKF
                  C06EKF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06EKF calculates the circular convolution or correlation of two
          real vectors of period n. No extra workspace is required.

          2. Specification

                 SUBROUTINE C06EKF (JOB, X, Y, N, IFAIL)
                 INTEGER          JOB, N, IFAIL
                 DOUBLE PRECISION X(N), Y(N)

          3. Description

          This routine computes:

          if JOB =1, the discrete convolution of x and y, defined by:

                                  n-1        n-1
                                  --         --
                              z = >  x y   = >  x   y ;
                               k  --  j k-j  --  k-j j
                                  j=0        j=0

          if JOB =2, the discrete correlation of x and y defined by:

                                       n-1
                                       --
                                   w = >  x y   .
                                    k  --  j k+j
                                       j=0

          Here x and y are real vectors, assumed to be periodic, with
          period n, i.e., x =x    =x     =...; z and w are then also
                           j  j+-n  j+-2n
          periodic with period n.

          Note: this usage of the terms 'convolution' and 'correlation' is
          taken from Brigham [1]. The term 'convolution' is sometimes used
          to denote both these computations.

             ^  ^  ^     ^
          If x, y, z and w are the discrete Fourier transforms of these
          sequences,

                        n-1
                ^    1  --       (   2(pi)jk)
          i.e., x = --- >  x *exp(-i -------), etc,
                 k      --  j    (      n   )
                    \/n j=0

                ^      ^ ^
          then  z =\/n.x y
                 k      k k

                       

                ^      ^ ^
          and   w =\/n.x y
                 k      k k

          (the bar denoting complex conjugate).

          This routine calls the same auxiliary routines as C06EAF and
          C06EBF to compute discrete Fourier transforms, and there are some
          restrictions on the value of n.

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          5. Parameters

           1:  JOB -- INTEGER                                         Input
               On entry: the computation to be performed:
                                    n-1
                                    --
                    if JOB = 1, z = >  x y    (convolution);
                                 k  --  j k-j
                                    j=0

                                    n-1
                                    --
                    if JOB = 2, w = >  x y    (correlation).
                                 k  --  j k+j
                                    j=0
               Constraint: JOB = 1 or 2.

           2:  X(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: the elements of one period of the vector x. If X
               is declared with bounds (0:N-1) in the (sub)program from
               which C06EKF is called, then X(j) must contain x , for
                                                               j
               j=0,1,...,n-1. On exit: the corresponding elements of the
               discrete convolution or correlation.

           3:  Y(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: the elements of one period of the vector y. If Y
               is declared with bounds (0:N-1) in the (sub)program from
               which C06EKF is called, then Y(j) must contain y , for
                                                               j
               j=0,1,...,n-1. On exit: the discrete Fourier transform of
               the convolution or correlation returned in the array X; the
               transform is stored in Hermitian form, exactly as described
               in the document  C06EAF.

           4:  N -- INTEGER                                           Input
               On entry: the number of values, n, in one period of the
               vectors X and Y. The largest prime factor of N must not
               exceed 19, and the total number of prime factors of N,
               counting repetitions, must not exceed 20. Constraint: N > 1.

           5:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          IFAIL= 1
               At least one of the prime factors of N is greater than 19.

          IFAIL= 2
               N has more than 20 prime factors.

          IFAIL= 3
               N <= 1.

          IFAIL= 4
               JOB /= 1 or 2.

          7. Accuracy

          The results should be accurate to within a small multiple of the
          machine precision.

          8. Further Comments

          The time taken by the routine is approximately proportional to
          n*logn, but also depends on the factorization of n. The routine
          is faster than average if the only prime factors are 2, 3 or 5;
          and fastest of all if n is a power of 2.

          The routine is particularly slow if n has several unpaired prime
          factors, i.e., if the 'square free' part of n has several
          factors. For such values of n, routine C06FKF(*) is considerably
          faster (but requires an additional workspace of n elements).

          9. Example

          This program reads in the elements of one period of two real
          vectors x and y and prints their discrete convolution and
          correlation (as computed by C06EKF). In realistic computations
          the number of data values would be much larger.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06FPF(3NAG)      Foundation Library (12/10/92)      C06FPF(3NAG)

          C06 -- Summation of Series                                 C06FPF
                  C06FPF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06FPF computes the discrete Fourier transforms of m sequences,
          each containing n real data values. This routine is designed to
          be particularly efficient on vector processors.

          2. Specification

                 SUBROUTINE C06FPF (M, N, X, INIT, TRIG, WORK, IFAIL)
                 INTEGER          M, N, IFAIL
                 DOUBLE PRECISION X(M*N), TRIG(2*N), WORK(M*N)
                 CHARACTER*1      INIT

          3. Description

                                                   p
          Given m sequences of n real data values x , for j=0,1,...,n-1;
                                                   j
          p=1,2,...,m, this routine simultaneously calculates the Fourier
          transforms of all the sequences defined by:

                     n-1
             ^p   1  --  p    (   2(pi)jk)
             z = --- >  x *exp(-i -------), k=0,1,...,n-1; p=1,2,...,m.
              k      --  j    (      n   )
                 \/n j=0

                                   1
          (Note the scale factor  --- in this definition.)
                                    

                                  \/n

                                 ^p
          The transformed values z  are complex, but for each value of p
                                  k
              ^p                                 ^p
          the z  form a Hermitian sequence (i.e.,z    is the complex
               k                                  n-k
                       ^p
          conjugate of z ), so they are completely determined by mn real
                        k
          numbers (see also the Chapter Introduction).

          The discrete Fourier transform is sometimes defined using a
          positive sign in the exponential term:

                                   n-1
                           ^p   1  --  p    (   2(pi)jk)
                           z = --- >  x *exp(+i -------).
                            k      --  j    (      n   )
                               \/n j=0

          To compute this form, this routine should be followed by a call
                                                          ^p
          to C06GQF to form the complex conjugates of the z .
                                                           k

          The routine uses a variant of the fast Fourier transform (FFT)
          algorithm (Brigham [1]) known as the Stockham self-sorting
          algorithm, which is described in Temperton [2]. Special coding is
          provided for the factors 2, 3, 4, 5 and 6. This routine is
          designed to be particularly efficient on vector processors, and
          it becomes especially fast as M, the number of transforms to be
          computed in parallel, increases.

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          [2]   Temperton C (1983) Fast Mixed-Radix Real Fourier Transforms.
                J. Comput. Phys. 52 340--350.

          5. Parameters

           1:  M -- INTEGER                                           Input
               On entry: the number of sequences to be transformed, m.
               Constraint: M >= 1.

           2:  N -- INTEGER                                           Input
               On entry: the number of real values in each sequence, n.
               Constraint: N >= 1.

           3:  X(M,N) -- DOUBLE PRECISION array                Input/Output
               On entry: the data must be stored in X as if in a two-
               dimensional array of dimension (1:M,0:N-1); each of the m
               sequences is stored in a row of the array. In other words,
               if the data values of the pth sequence to be transformed are
                           p
               denoted by x , for j=0,1,...,n-1, then the mn elements of
                           j
               the array X must contain the values
                    1  2      m   1  2       m      1    2        m
                   x ,x ,...,x , x ,x ,..., x ,...,x   ,x   ,...,x   .
                    0  0      0   1  1       1      n-1  n-1      n-1
               On exit: the m discrete Fourier transforms stored as if in
               a two-dimensional array of dimension (1:M,0:N-1). Each of
               the m transforms is stored in a row of the array in
               Hermitian form, overwriting the corresponding original
               sequence. If the n components of the discrete Fourier
                         ^p                 p   p                       p
               transform z  are written as a +ib , then for 0<=k<=n/2, a
                          k                 k   k                       k
                                                               p
               is contained in X(p,k), and for 1<=k<=(n-1)/2, b  is
                                                               k
               contained in X(p,n-k). (See also Section 2.1.2 of the
               Chapter Introduction.)

           4:  INIT -- CHARACTER*1                                    Input
               On entry: if the trigonometric coefficients required to
               compute the transforms are to be calculated by the routine
               and stored in the array TRIG, then INIT must be set equal to
               'I' (Initial call).

               If INIT contains 'S' (Subsequent call), then the routine
               assumes that trigonometric coefficients for the specified
               value of n are supplied in the array TRIG, having been
               calculated in a previous call to one of C06FPF, C06FQF or
               C06FRF.

               If INIT contains 'R' (Restart then the routine assumes that
               trigonometric coefficients for the particular value of n are
               supplied in the array TRIG, but does not check that C06FPF,
               C06FQF or C06FRF have previously been called. This option
               allows the TRIG array to be stored in an external file, read
               in and re-used without the need for a call with INIT equal
               to 'I'. The routine carries out a simple test to check that
               the current value of n is consistent with the array TRIG.
               Constraint: INIT = 'I', 'S' or 'R'.

           5:  TRIG(2*N) -- DOUBLE PRECISION array             Input/Output
               On entry: if INIT = 'S' or 'R', TRIG must contain the
               required coefficients calculated in a previous call of the
               routine. Otherwise TRIG need not be set. On exit: TRIG
               contains the required coefficients (computed by the routine
               if INIT = 'I').

           6:  WORK(M*N) -- DOUBLE PRECISION array                Workspace

           7:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).


          6. Error Indicators and Warnings

          Errors detected by the routine:

          If on entry IFAIL = 0 or -1, explanatory error messages are
          output on the current error message unit (as defined by X04AAF).

          IFAIL= 1
               On entry M < 1.

          IFAIL= 2
               N < 1.

          IFAIL= 3
               INIT is not one of 'I', 'S' or 'R'.

          IFAIL= 4
               INIT = 'S', but none of C06FPF, C06FQF or C06FRF has
               previously been called.

          IFAIL= 5
               INIT = 'S' or 'R', but the array TRIG and the current value
               of N are inconsistent.

          7. Accuracy

          Some indication of accuracy can be obtained by performing a
          subsequent inverse transform and comparing the results with the
          original sequence (in exact arithmetic they would be identical).

          8. Further Comments

          The time taken by the routine is approximately proportional to
          nm*logn, but also depends on the factors of n. The routine is
          fastest if the only prime factors of n are 2, 3 and 5, and is
          particularly slow if n is a large prime, or has large prime
          factors.

          9. Example

          This program reads in sequences of real data values and prints
          their discrete Fourier transforms (as computed by C06FPF). The
          Fourier transforms are expanded into full complex form using
          C06GSF and printed. Inverse transforms are then calculated by
          calling C06GQF followed by C06FQF showing that the original
          sequences are restored.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06FQF(3NAG)      Foundation Library (12/10/92)      C06FQF(3NAG)

          C06 -- Summation of Series                                 C06FQF
                  C06FQF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06FQF computes the discrete Fourier transforms of m Hermitian
          sequences, each containing n complex data values. This routine is
          designed to be particularly efficient on vector processors.

          2. Specification

                 SUBROUTINE C06FQF (M, N, X, INIT, TRIG, WORK, IFAIL)
                 INTEGER          M, N, IFAIL
                 DOUBLE PRECISION X(M*N), TRIG(2*N), WORK(M*N)
                 CHARACTER*1      INIT

          3. Description

                                                                p
          Given m Hermitian sequences of n complex data values z , for
                                                                j
          j=0,1,...,n-1; p=1,2,...,m, this routine simultaneously
          calculates the Fourier transforms of all the sequences defined
          by:

                     n-1
             ^p   1  --  p    (   2(pi)jk)
             x = --- >  z *exp(-i -------), k=0,1,...,n-1; p=1,2,...,m.
              k      --  j    (      n   )
                 \/n j=0

                                   1
          (Note the scale factor  --- in this definition.)
                                    

                                  \/n

          The transformed values are purely real (see also the Chapter
          Introduction).

          The discrete Fourier transform is sometimes defined using a
          positive sign in the exponential term

                                   n-1
                           ^p   1  --  p    (   2(pi)jk)
                           x = --- >  z *exp(+i -------).
                            k      --  j    (      n   )
                               \/n j=0

          To compute this form, this routine should be preceded by a call
                                                          ^p
          to C06GQF to form the complex conjugates of the z .
                                                           j

          The routine uses a variant of the fast Fourier transform (FFT)
          algorithm (Brigham [1]) known as the Stockham self-sorting
          algorithm, which is described in Temperton [2]. Special code is
          included for the factors 2, 3, 4, 5 and 6. This routine is
          designed to be particularly efficient on vector processors, and
          it becomes especially fast as m, the number of transforms to be
          computed in parallel, increases.

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          [2]   Temperton C (1983) Fast Mixed-Radix Real Fourier Transforms.
                J. Comput. Phys. 52 340--350.

          5. Parameters

           1:  M -- INTEGER                                           Input
               On entry: the number of sequences to be transformed, m.
               Constraint: M >= 1.

           2:  N -- INTEGER                                           Input
               On entry: the number of data values in each sequence, n.
               Constraint: N >= 1.

           3:  X(M,N) -- DOUBLE PRECISION array                Input/Output
               On entry: the data must be stored in X as if in a two-
               dimensional array of dimension (1:M,0:N-1); each of the m
               sequences is stored in a row of the array in Hermitian form.
                                     p                 p   p
               If the n data values z  are written as x +iy , then for
                                     j                 j   j
                           p
               0<=j<=n/2, x  is contained in X(p,j), and for 1<=j<=(n-1)/2,
                           j
                p
               y  is contained in X(p,n-j). (See also Section 2.1.2 of the
                j
               Chapter Introduction.) On exit: the components of the m
               discrete Fourier transforms, stored as if in a two-
               dimensional array of dimension (1:M,0:N-1). Each of the m
               transforms is stored as a row of the array, overwriting the
               corresponding original sequence. If the n components of the
                                                         ^p
               discrete Fourier transform are denoted by x , for
                                                          k
               k=0,1,...,n-1, then the mn elements of the array X contain
               the values
                   ^1 ^2     ^m  ^1 ^2      ^m     ^1   ^2       ^m
                   x ,x ,...,x , x ,x ,..., x ,...,x   ,x   ,...,x   .
                    0  0      0   1  1       1      n-1  n-1      n-1

           4:  INIT -- CHARACTER*1                                    Input
               On entry: if the trigonometric coefficients required to
               compute the transforms are to be calculated by the routine
               and stored in the array TRIG, then INIT must be set equal to
               'I' (Initial call).

               If INIT contains 'S' (Subsequent call), then the routine
               assumes that trigonometric coefficients for the specified
               value of n are supplied in the array TRIG, having been
               calculated in a previous call to one of C06FPF, C06FQF or
               C06FRF.

               If INIT contains 'R' (Restart), then the routine assumes
               that trigonometric coefficients for the particular value of
               N are supplied in the array TRIG, but does not check that
               C06FPF, C06FQF or C06FRF have previously been called. This
               option allows the TRIG array to be stored in an external
               file, read in and re-used without the need for a call with
               INIT equal to 'I'. The routine carries out a simple test to
               check that the current value of n is compatible with the
               array TRIG. Constraint: INIT = 'I', 'S' or 'R'.

           5:  TRIG(2*N) -- DOUBLE PRECISION array             Input/Output
               On entry: if INIT = 'S' or 'R', TRIG must contain the
               required coefficients calculated in a previous call of the
               routine. Otherwise TRIG need not be set. On exit: TRIG
               contains the required coefficients (computed by the routine
               if INIT = 'I').

           6:  WORK(M*N) -- DOUBLE PRECISION array                Workspace

           7:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          If on entry IFAIL = 0 or -1, explanatory error messages are
          output on the current error message unit (as defined by X04AAF).

          IFAIL= 1
               On entry M < 1.

          IFAIL= 2
               On entry N < 1.

          IFAIL= 3
               On entry INIT is not one of 'I', 'S' or 'R'.

          IFAIL= 4
               On entry INIT = 'S', but none of C06FPF, C06FQF and C06FRF
               has previously been called.

          IFAIL= 5
               On entry INIT = 'S' or 'R', but the array TRIG and the
               current value of n are inconsistent.

          7. Accuracy

          Some indication of accuracy can be obtained by performing a
          subsequent inverse transform and comparing the results with the
          original sequence (in exact arithmetic they would be identical).

          8. Further Comments

          The time taken by the routine is approximately proportional to
          nm*logn, but also depends on the factors of n. The routine is
          fastest if the only prime factors of n are 2, 3 and 5, and is
          particularly slow if n is a large prime, or has large prime
          factors.

          9. Example

          This program reads in sequences of real data values which are
          assumed to be Hermitian sequences of complex data stored in
          Hermitian form. The sequences are expanded into full complex form
          using C06GSF and printed. The discrete Fourier transforms are
          then computed (using C06FQF) and printed out. Inverse transforms
          are then calculated by calling C06FPF followed by C06GQF showing
          that the original sequences are restored.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06FRF(3NAG)      Foundation Library (12/10/92)      C06FRF(3NAG)

          C06 -- Summation of Series                                 C06FRF
                  C06FRF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06FRF computes the discrete Fourier transforms of m sequences,
          each containing n complex data values. This routine is designed
          to be particularly efficient on vector processors.

          2. Specification

                 SUBROUTINE C06FRF (M, N, X, Y, INIT, TRIG, WORK, IFAIL)
                 INTEGER          M, N, IFAIL
                 DOUBLE PRECISION X(M*N), Y(M*N), TRIG(2*N), WORK(2*M*N)
                 CHARACTER*1      INIT

          3. Description

                                                      p
          Given m sequences of n complex data values z , for j=0,1,...,n-1;
                                                      j
          p=1,2,...,m, this routine simultaneously calculates the Fourier
          transforms of all the sequences defined by:

                     n-1
             ^p   1  --  p    (   2(pi)jk)
             z = --- >  z *exp(-i -------), k=0,1,...,n-1; p=1,2,...,m.
              k      --  j    (      n   )
                 \/n j=0

                                   1
          (Note the scale factor  --- in this definition.)
                                    

                                  \/n

          The discrete Fourier transform is sometimes defined using a
          positive sign in the exponential term

                                   n-1
                           ^p   1  --  p    (   2(pi)jk)
                           z = --- >  z *exp(+i -------).
                            k      --  j    (      n   )
                               \/n j=0

          To compute this form, this routine should be preceded and
          followed by a call of C06GCF to form the complex conjugates of
               p         ^p
          the z  and the z .
               j          k

          The routine uses a variant of the fast Fourier transform (FFT)
          algorithm (Brigham [1]) known as the Stockham self-sorting
          algorithm, which is described in Temperton [2]. Special code is
          provided for the factors 2, 3, 4, 5 and 6. This routine is
          designed to be particularly efficient on vector processors, and
          it becomes especially fast as m, the number of transforms to be
          computed in parallel, increases.

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          [2]   Temperton C (1983) Self-sorting Mixed-radix Fast Fourier
                Transforms. J. Comput. Phys. 52 1--23.

          5. Parameters

           1:  M -- INTEGER                                           Input
               On entry: the number of sequences to be transformed, m.
               Constraint: M >= 1.

           2:  N -- INTEGER                                           Input
               On entry: the number of complex values in each sequence, n.
               Constraint: N >= 1.

           3:  X(M,N) -- DOUBLE PRECISION array                Input/Output

           4:  Y(M,N) -- DOUBLE PRECISION array                Input/Output
               On entry: the real and imaginary parts of the complex data
               must be stored in X and Y respectively as if in a two-
               dimensional array of dimension (1:M,0:N-1); each of the m
               sequences is stored in a row of each array. In other words,
               if the real parts of the pth sequence to be transformed are
                           p
               denoted by x , for j=0,1,...,n-1, then the mn elements of
                           j
               the array X must contain the values
                    1  2      m   1  2      m       1    2        m
                   x ,x ,...,x , x ,x ,...,x ,..., x   ,x   ,...,x   .
                    0  0      0   1  1      1       n-1  n-1      n-1
               On exit: X and Y are overwritten by the real and imaginary
               parts of the complex transforms.

           5:  INIT -- CHARACTER*1                                    Input
               On entry: if the trigonometric coefficients required to
               compute the transforms are to be calculated by the routine
               and stored in the array TRIG, then INIT must be set equal to
               'I' (Initial call).

               If INIT contains 'S' (Subsequent call), then the routine
               assumes that trigonometric coefficients for the specified
               value of n are supplied in the array TRIG, having been
               calculated in a previous call to one of C06FPF, C06FQF or
               C06FRF.

               If INIT contains 'R' (Restart) then the routine assumes that
               trigonometric coefficients for the particular value of n are
               supplied in the array TRIG, but does not check that C06FPF,
               C06FQF or C06FRF have previously been called. This option
               allows the TRIG array to be stored in an external file, read
               in and re-used without the need for a call with INIT equal
               to 'I'. The routine carries out a simple test to check that
               the current value of n is compatible with the array TRIG.
               Constraint: INIT = 'I', 'S' or 'R'.

           6:  TRIG(2*N) -- DOUBLE PRECISION array             Input/Output
               On entry: if INIT = 'S' or 'R', TRIG must contain the
               required coefficients calculated in a previous call of the
               routine. Otherwise TRIG need not be set. On exit: TRIG
               contains the required coefficients (computed by the routine
               if INIT = 'I').

           7:  WORK(2*M*N) -- DOUBLE PRECISION array              Workspace

           8:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          If on entry IFAIL = 0 or -1, explanatory error messages are
          output on the current error message unit (as defined by X04AAF).

          IFAIL= 1
               On entry M < 1.

          IFAIL= 2
               On entry N < 1.

          IFAIL= 3
               On entry INIT is not one of 'I', 'S' or 'R'.

          IFAIL= 4
               On entry INIT = 'S', but none of C06FPF, C06FQF and C06FRF
               has previously been called.

          IFAIL= 5
               On entry INIT = 'S' or 'R', but the array TRIG and the
               current value of n are inconsistent.

          7. Accuracy

          Some indication of accuracy can be obtained by performing a
          subsequent inverse transform and comparing the results with the
          original sequence (in exact arithmetic they would be identical).

          8. Further Comments

          The time taken by the routine is approximately proportional to
          nm*logn, but also depends on the factors of n. The routine is
          fastest if the only prime factors of n are 2, 3 and 5, and is
          particularly slow if n is a large prime, or has large prime
          factors.

          9. Example

          This program reads in sequences of complex data values and prints
          their discrete Fourier transforms (as computed by C06FRF).
          Inverse transforms are then calculated using C06GCF and C06FRF
          and printed out, showing that the original sequences are
          restored.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06FUF(3NAG)      Foundation Library (12/10/92)      C06FUF(3NAG)

          C06 -- Summation of Series                                 C06FUF
                  C06FUF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06FUF computes the two-dimensional discrete Fourier transform of
          a bivariate sequence of complex data values. This routine is
          designed to be particularly efficient on vector processors.

          2. Specification

                 SUBROUTINE C06FUF (M, N, X, Y, INIT, TRIGM, TRIGN, WORK,
                1                   IFAIL)
                 INTEGER          M, N, IFAIL
                 DOUBLE PRECISION X(M*N), Y(M*N), TRIGM(2*M), TRIGN(2*N),
                1                 WORK(2*M*N)
                 CHARACTER*1      INIT

          3. Description

          This routine computes the two-dimensional discrete Fourier
          transform of a bivariate sequence of complex data values z    ,
                                                                    j j
                                                                     1 2
          where j =0,1,...,m-1, j =0,1,...,n-1.
                 1               2

          The discrete Fourier transform is here defined by:

                            m-1  n-1          (       ( j k   j k ))
                ^       1   --   --           (       (  1 1   2 2))
                z    = ---- >    >   z    *exp(-2(pi)i( ----+ ----)),
                            --   --   j j     (       (  m     n  ))
                 k k   \/mn j =0 j =0  1 2
                  1 2        1    2

          where k =0,1,...,m-1, k =0,1,...,n-1.
                 1               2

                                      1
          (Note the scale factor of  ---- in this definition.)
                                       

                                     \/mn

          To compute the inverse discrete Fourier transform, defined with
          exp(+2(pi)i(...)) in the above formula instead of exp(-
          2(pi)i(...)), this routine should be preceded and followed by
          calls of C06GCF to form the complex conjugates of the data values
          and the transform.

          This routine calls C06FRF to perform multiple one-dimensional
          discrete Fourier transforms by the fast Fourier transform (FFT)
          algorithm in Brigham [1]. It is designed to be particularly
          efficient on vector processors.

          4. References

          [1]   Brigham E O (1973) The Fast Fourier Transform. Prentice-
                Hall.

          [2]   Temperton C (1983) Self-sorting Mixed-radix Fast Fourier
                Transforms. J. Comput. Phys. 52 1--23.

          5. Parameters

           1:  M -- INTEGER                                           Input
               On entry: the number of rows, m, of the arrays X and Y.
               Constraint: M >= 1.

           2:  N -- INTEGER                                           Input
               On entry: the number of columns, n, of the arrays X and Y.
               Constraint: N >= 1.

           3:  X(M,N) -- DOUBLE PRECISION array                Input/Output

           4:  Y(M,N) -- DOUBLE PRECISION array                Input/Output
               On entry: the real and imaginary parts of the complex data
               values must be stored in arrays X and Y respectively. If X
               and Y are regarded as two-dimensional arrays of dimension
               (0:M-1,0:N-1), then X(j ,j ) and Y(j ,j ) must contain the
                                      1  2         1  2
               real and imaginary parts of z    . On exit: the real and
                                            j j
                                             1 2
               imaginary parts respectively of the corresponding elements
               of the computed transform.

           5:  INIT -- CHARACTER*1                                    Input
               On entry: if the trigonometric coefficients required to
               compute the transforms are to be calculated by the routine
               and stored in the arrays TRIGM and TRIGN, then INIT must be
               set equal to 'I', (Initial call).

               If INIT contains 'S', (Subsequent call), then the routine
               assumes that trigonometric coefficients for the specified
               values of m and n are supplied in the arrays TRIGM and
               TRIGN, having been calculated in a previous call to the
               routine.

               If INIT contains 'R', (Restart), then the routine assumes
               that trigonometric coefficients for the particular values of
               m and n are supplied in the arrays TRIGM and TRIGN, but does
               not check that the routine has previously been called. This
               option allows the TRIGM and TRIGN arrays to be stored in an
               external file, read in and re-used without the need for a
               call with INIT equal to 'I'. The routine carries out a
               simple test to check that the current values of m and n are
               compatible with the arrays TRIGM and TRIGN. Constraint: INIT
               = 'I', 'S' or 'R'.

           6:  TRIGM(2*M) -- DOUBLE PRECISION array            Input/Output

           7:  TRIGN(2*N) -- DOUBLE PRECISION array            Input/Output
               On entry: if INIT = 'S' or 'R',TRIGM and TRIGN must contain
               the required coefficients calculated in a previous call of
               the routine. Otherwise TRIGM and TRIGN need not be set.

               If m=n the same array may be supplied for TRIGM and TRIGN.
               On exit: TRIGM and TRIGN contain the required coefficients
               (computed by the routine if INIT = 'I').

           8:  WORK(2*M*N) -- DOUBLE PRECISION array              Workspace

           9:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          If on entry IFAIL = 0 or -1, explanatory error messages are
          output on the current error message unit (as defined by X04AAF).

          IFAIL= 1
               On entry M < 1.

          IFAIL= 2
               On entry N < 1.

          IFAIL= 3
               On entry INIT is not one of 'I', 'S' or 'R'.

          IFAIL= 4
               On entry INIT = 'S', but C06FUF has not previously been
               called.

          IFAIL= 5
               On entry INIT = 'S' or 'R', but at least one of the arrays
               TRIGM and TRIGN is inconsistent with the current value of M
               or N.

          7. Accuracy

          Some indication of accuracy can be obtained by performing a
          subsequent inverse transform and comparing the results with the
          original sequence (in exact arithmetic they would be identical).

          8. Further Comments

          The time taken by the routine is approximately proportional to
          mn*log(mn), but also depends on the factorization of the
          individual dimensions m and n. The routine is somewhat faster
          than average if their only prime factors are 2, 3 or 5; and
          fastest of all if they are powers of 2.

          9. Example

          This program reads in a bivariate sequence of complex data values
          and prints the two-dimensional Fourier transform. It then
          performs an inverse transform and prints the sequence so
          obtained, which may be compared to the original data values.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06GBF(3NAG)      Foundation Library (12/10/92)      C06GBF(3NAG)

          C06 -- Summation of Series                                 C06GBF
                  C06GBF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06GBF forms the complex conjugate of a Hermitian sequence of n
          data values.

          2. Specification

                 SUBROUTINE C06GBF (X, N, IFAIL)
                 INTEGER          N, IFAIL
                 DOUBLE PRECISION X(N)

          3. Description

          This is a utility routine for use in conjunction with C06EAF,
          C06EBF, C06FAF(*) or C06FBF(*) to calculate inverse discrete
          Fourier transforms (see the Chapter Introduction).

          4. References

          None.

          5. Parameters

           1:  X(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: if the data values z  are written as x +iy  and
                                             j                 j   j
               if X is declared with bounds (0:N-1) in the (sub)program
               from which C06GBF is called, then for 0<=j<=n/2, X(j) must
               contain x (=x   ), while for n/2<j<=n-1, X(j) must contain
                        j   n-j
               -y (=y   ). In other words, X must contain the Hermitian
                 j   n-j
               sequence in Hermitian form. (See also Section 2.1.2 of the
               Chapter Introduction). On exit: the imaginary parts y  are
                                                                    j
               negated. The real parts x  are not referenced.
                                        j

           2:  N -- INTEGER                                           Input
               On entry: the number of data values, n. Constraint: N >= 1.

           3:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          IFAIL= 1
               N < 1.

          7. Accuracy

          Exact.

          8. Further Comments

          The time taken by the routine is negligible.

          9. Example

          This program reads in a sequence of real data values, calls
          C06EAF followed by C06GBF to compute their inverse discrete
          Fourier transform, and prints this after expanding it from
          Hermitian form into a full complex sequence.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06GCF(3NAG)      Foundation Library (12/10/92)      C06GCF(3NAG)

          C06 -- Summation of Series                                 C06GCF
                  C06GCF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06GCF forms the complex conjugate of a sequence of n data
          values.

          2. Specification

                 SUBROUTINE C06GCF (Y, N, IFAIL)
                 INTEGER          N, IFAIL
                 DOUBLE PRECISION Y(N)

          3. Description

          This is a utility routine for use in conjunction with C06ECF or
          C06FCF(*) to calculate inverse discrete Fourier transforms (see
          the Chapter Introduction).

          4. References

          None.

          5. Parameters

           1:  Y(N) -- DOUBLE PRECISION array                  Input/Output
               On entry: if Y is declared with bounds (0:N-1) in the (sub)
               program which C06GCF is called, then Y(j) must contain the
               imaginary part of the jth data value, for 0<=j<=n-1. On
               exit: these values are negated.

           2:  N -- INTEGER                                           Input
               On entry: the number of data values, n. Constraint: N >= 1.

           3:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          IFAIL= 1
               N < 1.

          7. Accuracy

          Exact.

          8. Further Comments

          The time taken by the routine is negligible.

          9. Example

          This program reads in a sequence of complex data values and
          prints their inverse discrete Fourier transform as computed by
          calling C06GCF, followed by C06ECF and C06GCF again.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06GQF(3NAG)      Foundation Library (12/10/92)      C06GQF(3NAG)

          C06 -- Summation of Series                                 C06GQF
                  C06GQF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06GQF forms the complex conjugates of m Hermitian sequences,
          each containing n data values.

          2. Specification

                 SUBROUTINE C06GQF (M, N, X, IFAIL)
                 INTEGER          M, N, IFAIL
                 DOUBLE PRECISION X(M*N)

          3. Description

          This is a utility routine for use in conjunction with C06FPF and
          C06FQF to calculate inverse discrete Fourier transforms (see the
          Chapter Introduction).

          4. References

          None.

          5. Parameters

           1:  M -- INTEGER                                           Input
               On entry: the number of Hermitian sequences to be
               conjugated, m. Constraint: M >= 1.

           2:  N -- INTEGER                                           Input
               On entry: the number of data values in each Hermitian
               sequence, n. Constraint: N >= 1.

           3:  X(M,N) -- DOUBLE PRECISION array                Input/Output
               On entry: the data must be stored in array X as if in a
               two-dimensional array of dimension (1:M,0:N-1); each of the
               m sequences is stored in a row of the array in Hermitian
                                           p                 p   p
               form. If the n data values z  are written as x +iy , then
                                           j                 j   j
                               p
               for 0<=j<=n/2, x  is contained in X(p,j), and for 1<=j<=(n-
                               j
                      p
               1)/2, y  is contained in X(p,n-j). (See also Section 2.1.2
                      j
               of the Chapter Introduction.) On exit: the imaginary parts
                p                              p
               y  are negated. The real parts x  are not referenced.
                j                              j

           4:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          If on entry IFAIL = 0 or -1, explanatory error messages are
          output on the current error message unit (as defined by X04AAF).

          IFAIL= 1
               On entry M < 1.

          IFAIL= 2
               On entry N < 1.

          7. Accuracy

          Exact.

          8. Further Comments

          None.

          9. Example

          This program reads in sequences of real data values which are
          assumed to be Hermitian sequences of complex data stored in
          Hermitian form. The sequences are expanded into full complex form
          using C06GSF and printed. The sequences are then conjugated
          (using C06GQF) and the conjugated sequences are expanded into
          complex form using C06GSF and printed out.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

     C06GSF(3NAG)      Foundation Library (12/10/92)      C06GSF(3NAG)

          C06 -- Summation of Series                                 C06GSF
                  C06GSF -- NAG Foundation Library Routine Document

          Note: Before using this routine, please read the Users' Note for
          your implementation to check implementation-dependent details.
          The symbol (*) after a NAG routine name denotes a routine that is
          not included in the Foundation Library.

          1. Purpose

          C06GSF takes m Hermitian sequences, each containing n data
          values, and forms the real and imaginary parts of the m
          corresponding complex sequences.

          2. Specification

                 SUBROUTINE C06GSF (M, N, X, U, V, IFAIL)
                 INTEGER          M, N, IFAIL
                 DOUBLE PRECISION X(M*N), U(M*N), V(M*N)

          3. Description

          This is a utility routine for use in conjunction with C06FPF and
          C06FQF (see the Chapter Introduction).

          4. References

          None.

          5. Parameters

           1:  M -- INTEGER                                           Input
               On entry: the number of Hermitian sequences, m, to be
               converted into complex form. Constraint: M >= 1.

           2:  N -- INTEGER                                           Input
               On entry: the number of data values, n, in each sequence.
               Constraint: N >= 1.

           3:  X(M,N) -- DOUBLE PRECISION array                       Input
               On entry: the data must be stored in X as if in a two-
               dimensional array of dimension (1:M,0:N-1); each of the m
               sequences is stored in a row of the array in Hermitian form.
                                     p                 p   p
               If the n data values z  are written as x +iy , then for
                                     j                 j   j
                           p
               0<=j<=n/2, x  is contained in X(p,j), and for 1<=j<=(n-1)/2,
                           j
                p
               y  is contained in X(p,n-j). (See also Section 2.1.2 of the
                j
               Chapter Introduction.)

           4:  U(M,N) -- DOUBLE PRECISION array                      Output

           5:  V(M,N) -- DOUBLE PRECISION array                      Output
               On exit: the real and imaginary parts of the m sequences of
               length n, are stored in U and V respectively, as if in two-
               dimensional arrays of dimension (1:M,0:N-1); each of the m
               sequences is stored as if in a row of each array. In other
               words, if the real parts of the pth sequence are denoted by
                p
               x , for j=0,1,...,n-1 then the mn elements of the array U
                j
               contain the values
                     1  2      m   1  2      m       1    2        m
                    x ,x ,...,x , x ,x ,...,x ,..., x   ,x   ,...,x
                     0  0      0   1  1      1       n-1  n-1      n-1

           6:  IFAIL -- INTEGER                                Input/Output
               On entry: IFAIL must be set to 0, -1 or 1. For users not
               familiar with this parameter (described in the Essential
               Introduction) the recommended value is 0.

               On exit: IFAIL = 0 unless the routine detects an error (see
               Section 6).

          6. Error Indicators and Warnings

          Errors detected by the routine:

          If on entry IFAIL = 0 or -1, explanatory error messages are
          output on the current error message unit (as defined by X04AAF).

          IFAIL= 1
               On entry M < 1.

          IFAIL= 2
               On entry N < 1.

          7. Accuracy

          Exact.

          8. Further Comments

          None.

          9. Example

          This program reads in sequences of real data values which are
          assumed to be Hermitian sequences of complex data stored in
          Hermitian form. The sequences are then expanded into full complex
          form using C06GSF and printed.

          The example program is not reproduced here. The source code for
          all example programs is distributed with the NAG Foundation
          Library software and should be available on-line.

