Merge remote-tracking branch 'origin/release-v4.6.1'
[WRF.git] / external / fftpack / fftpack5 / dcosq1b.F
blobf110987a6819335c4f1621e3e2f39531b0876dc3
1 subroutine dcosq1b ( n, inc, x, lenx, wsave, lensav, work, lenwrk, ier )
3 !*****************************************************************************80
5 !! DCOSQ1B: real double precision backward cosine quarter wave transform, 1D.
7 !  Discussion:
9 !    DCOSQ1B computes the one-dimensional Fourier transform of a sequence
10 !    which is a cosine series with odd wave numbers.  This transform is
11 !    referred to as the backward transform or Fourier synthesis, transforming
12 !    the sequence from spectral to physical space.
14 !    This transform is normalized since a call to DCOSQ1B followed
15 !    by a call to DCOSQ1F (or vice-versa) reproduces the original
16 !    array  within roundoff error.
20 !  Modified:
22 !    17 November 2007
24 !  Author:
26 !    Original real single precision by Paul Swarztrauber, Richard Valent.
27 !    Real double precision version by John Burkardt.
29 !  Reference:
31 !    Paul Swarztrauber,
32 !    Vectorizing the Fast Fourier Transforms,
33 !    in Parallel Computations,
34 !    edited by G. Rodrigue,
35 !    Academic Press, 1982.
37 !    Paul Swarztrauber,
38 !    Fast Fourier Transform Algorithms for Vector Computers,
39 !    Parallel Computing, pages 45-63, 1984.
41 !  Parameters:
43 !    Input, integer ( kind = 4 ) N, the number of elements to be transformed
44 !    in the sequence.  The transform is most efficient when N is a
45 !    product of small primes.
47 !    Input, integer ( kind = 4 ) INC, the increment between the locations, in
48 !    array R, of two consecutive elements within the sequence.
50 !    Input/output, real ( kind = 8 ) R(LENR); on input, containing the sequence
51 !    to be transformed, and on output, containing the transformed sequence.
53 !    Input, integer ( kind = 4 ) LENR, the dimension of the R array.
54 !    LENR must be at least INC*(N-1)+ 1.
56 !    Input, real ( kind = 8 ) WSAVE(LENSAV).  WSAVE's contents must be
57 !    initialized with a call to DCOSQ1I before the first call to routine
58 !    DCOSQ1F or DCOSQ1B for a given transform length N.  WSAVE's contents may
59 !    be re-used for subsequent calls to DCOSQ1F and DCOSQ1B with the same N.
61 !    Input, integer ( kind = 4 ) LENSAV, the dimension of the WSAVE array.
62 !    LENSAV must be at least 2*N + INT(LOG(REAL(N))) + 4.
64 !    Workspace, real ( kind = 8 ) WORK(LENWRK).
66 !    Input, integer ( kind = 4 ) LENWRK, the dimension of the WORK array.
67 !    LENWRK must be at least N.
69 !    Output, integer ( kind = 4 ) IER, error flag.
70 !    0, successful exit;
71 !    1, input parameter LENR   not big enough;
72 !    2, input parameter LENSAV not big enough;
73 !    3, input parameter LENWRK not big enough;
74 !    20, input error returned by lower level routine.
76   implicit none
78   integer ( kind = 4 ) inc
79   integer ( kind = 4 ) lensav
80   integer ( kind = 4 ) lenwrk
82   integer ( kind = 4 ) ier
83   integer ( kind = 4 ) ier1
84   integer ( kind = 4 ) lenx
85   integer ( kind = 4 ) n
86   real ( kind = 8 ) ssqrt2
87   real ( kind = 8 ) work(lenwrk)
88   real ( kind = 8 ) wsave(lensav)
89   real ( kind = 8 ) x(inc,*)
90   real ( kind = 8 ) x1
92   ier = 0
94   if ( lenx < inc * ( n - 1 ) + 1 ) then
95     ier = 1
96     call xerfft ( 'DCOSQ1B', 6 )
97     return
98   end if
100   if ( lensav < 2 * n + int ( log ( real ( n, kind = 8 ) ) ) + 4 ) then
101     ier = 2
102     call xerfft ( 'DCOSQ1B', 8 )
103     return
104   end if
106   if ( lenwrk < n ) then
107     ier = 3
108     call xerfft ( 'DCOSQ1B', 10 )
109     return
110   end if
112   if ( n < 2 ) then
113     return
114   end if
116   if ( n == 2 ) then
117     ssqrt2 = 1.0D+00 / sqrt ( 2.0D+00 )
118     x1 = x(1,1) + x(1,2)
119     x(1,2) = ssqrt2 * ( x(1,1) - x(1,2) )
120     x(1,1) = x1
121     return
122   end if
124   call dcosqb1 ( n, inc, x, wsave, work, ier1 )
126   if ( ier1 /= 0 ) then
127     ier = 20
128     call xerfft ( 'DCOSQ1B', -5 )
129     return
130   end if
132   return