248 lines
8.4 KiB
Fortran
248 lines
8.4 KiB
Fortran
SUBROUTINE DG01ND( INDI, N, XR, XI, INFO )
|
|
C
|
|
C SLICOT RELEASE 5.0.
|
|
C
|
|
C Copyright (c) 2002-2009 NICONET e.V.
|
|
C
|
|
C This program is free software: you can redistribute it and/or
|
|
C modify it under the terms of the GNU General Public License as
|
|
C published by the Free Software Foundation, either version 2 of
|
|
C the License, or (at your option) any later version.
|
|
C
|
|
C This program is distributed in the hope that it will be useful,
|
|
C but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
C GNU General Public License for more details.
|
|
C
|
|
C You should have received a copy of the GNU General Public License
|
|
C along with this program. If not, see
|
|
C <http://www.gnu.org/licenses/>.
|
|
C
|
|
C PURPOSE
|
|
C
|
|
C To compute the discrete Fourier transform, or inverse Fourier
|
|
C transform, of a real signal.
|
|
C
|
|
C ARGUMENTS
|
|
C
|
|
C Mode Parameters
|
|
C
|
|
C INDI CHARACTER*1
|
|
C Indicates whether a Fourier transform or inverse Fourier
|
|
C transform is to be performed as follows:
|
|
C = 'D': (Direct) Fourier transform;
|
|
C = 'I': Inverse Fourier transform.
|
|
C
|
|
C Input/Output Parameters
|
|
C
|
|
C N (input) INTEGER
|
|
C Half the number of real samples. N must be a power of 2.
|
|
C N >= 2.
|
|
C
|
|
C XR (input/output) DOUBLE PRECISION array, dimension (N+1)
|
|
C On entry with INDI = 'D', the first N elements of this
|
|
C array must contain the odd part of the input signal; for
|
|
C example, XR(I) = A(2*I-1) for I = 1,2,...,N.
|
|
C On entry with INDI = 'I', the first N+1 elements of this
|
|
C array must contain the the real part of the input discrete
|
|
C Fourier transform (computed, for instance, by a previous
|
|
C call of the routine).
|
|
C On exit with INDI = 'D', the first N+1 elements of this
|
|
C array contain the real part of the output signal, that is
|
|
C of the computed discrete Fourier transform.
|
|
C On exit with INDI = 'I', the first N elements of this
|
|
C array contain the odd part of the output signal, that is
|
|
C of the computed inverse discrete Fourier transform.
|
|
C
|
|
C XI (input/output) DOUBLE PRECISION array, dimension (N+1)
|
|
C On entry with INDI = 'D', the first N elements of this
|
|
C array must contain the even part of the input signal; for
|
|
C example, XI(I) = A(2*I) for I = 1,2,...,N.
|
|
C On entry with INDI = 'I', the first N+1 elements of this
|
|
C array must contain the the imaginary part of the input
|
|
C discrete Fourier transform (computed, for instance, by a
|
|
C previous call of the routine).
|
|
C On exit with INDI = 'D', the first N+1 elements of this
|
|
C array contain the imaginary part of the output signal,
|
|
C that is of the computed discrete Fourier transform.
|
|
C On exit with INDI = 'I', the first N elements of this
|
|
C array contain the even part of the output signal, that is
|
|
C of the computed inverse discrete Fourier transform.
|
|
C
|
|
C Error Indicator
|
|
C
|
|
C INFO INTEGER
|
|
C = 0: successful exit;
|
|
C < 0: if INFO = -i, the i-th argument had an illegal
|
|
C value.
|
|
C
|
|
C METHOD
|
|
C
|
|
C Let A(1),....,A(2*N) be a real signal of 2*N samples. Then the
|
|
C first N+1 samples of the discrete Fourier transform of this signal
|
|
C are given by the formula:
|
|
C
|
|
C 2*N ((m-1)*(i-1))
|
|
C FA(m) = SUM ( A(i) * W ),
|
|
C i=1
|
|
C 2
|
|
C where m = 1,2,...,N+1, W = exp(-pi*j/N) and j = -1.
|
|
C
|
|
C This transform can be computed as follows. First, transform A(i),
|
|
C i = 1,2,...,2*N, into the complex signal Z(i) = (X(i),Y(i)),
|
|
C i = 1,2,...,N. That is, X(i) = A(2*i-1) and Y(i) = A(2*i). Next,
|
|
C perform a discrete Fourier transform on Z(i) by calling SLICOT
|
|
C Library routine DG01MD. This gives a new complex signal FZ(k),
|
|
C such that
|
|
C
|
|
C N ((k-1)*(i-1))
|
|
C FZ(k) = SUM ( Z(i) * V ),
|
|
C i=1
|
|
C
|
|
C where k = 1,2,...,N, V = exp(-2*pi*j/N). Using the values of
|
|
C FZ(k), the components of the discrete Fourier transform FA can be
|
|
C computed by simple linear relations, implemented in the DG01NY
|
|
C subroutine.
|
|
C
|
|
C Finally, let
|
|
C
|
|
C XR(k) = Re(FZ(k)), XI(k) = Im(FZ(k)), k = 1,2,...,N,
|
|
C
|
|
C be the contents of the arrays XR and XI on entry to DG01NY with
|
|
C INDI = 'D', then on exit XR and XI contain the real and imaginary
|
|
C parts of the Fourier transform of the original real signal A.
|
|
C That is,
|
|
C
|
|
C XR(m) = Re(FA(m)), XI(m) = Im(FA(m)),
|
|
C
|
|
C where m = 1,2,...,N+1.
|
|
C
|
|
C If INDI = 'I', then the routine evaluates the inverse Fourier
|
|
C transform of a complex signal which may itself be the discrete
|
|
C Fourier transform of a real signal.
|
|
C
|
|
C Let FA(m), m = 1,2,...,2*N, denote the full discrete Fourier
|
|
C transform of a real signal A(i), i=1,2,...,2*N. The relationship
|
|
C between FA and A is given by the formula:
|
|
C
|
|
C 2*N ((m-1)*(i-1))
|
|
C A(i) = SUM ( FA(m) * W ),
|
|
C m=1
|
|
C
|
|
C where W = exp(pi*j/N).
|
|
C
|
|
C Let
|
|
C
|
|
C XR(m) = Re(FA(m)) and XI(m) = Im(FA(m)) for m = 1,2,...,N+1,
|
|
C
|
|
C be the contents of the arrays XR and XI on entry to the routine
|
|
C DG01NY with INDI = 'I', then on exit the first N samples of the
|
|
C complex signal FZ are returned in XR and XI such that
|
|
C
|
|
C XR(k) = Re(FZ(k)), XI(k) = Im(FZ(k)) and k = 1,2,...,N.
|
|
C
|
|
C Next, an inverse Fourier transform is performed on FZ (e.g. by
|
|
C calling SLICOT Library routine DG01MD), to give the complex signal
|
|
C Z, whose i-th component is given by the formula:
|
|
C
|
|
C N ((k-1)*(i-1))
|
|
C Z(i) = SUM ( FZ(k) * V ),
|
|
C k=1
|
|
C
|
|
C where i = 1,2,...,N and V = exp(2*pi*j/N).
|
|
C
|
|
C Finally, the 2*N samples of the real signal A can then be obtained
|
|
C directly from Z. That is,
|
|
C
|
|
C A(2*i-1) = Re(Z(i)) and A(2*i) = Im(Z(i)), for i = 1,2,...N.
|
|
C
|
|
C Note that a discrete Fourier transform, followed by an inverse
|
|
C transform will result in a signal which is a factor 2*N larger
|
|
C than the original input signal.
|
|
C
|
|
C REFERENCES
|
|
C
|
|
C [1] Rabiner, L.R. and Rader, C.M.
|
|
C Digital Signal Processing.
|
|
C IEEE Press, 1972.
|
|
C
|
|
C NUMERICAL ASPECTS
|
|
C
|
|
C The algorithm requires 0( N*log(N) ) operations.
|
|
C
|
|
C CONTRIBUTORS
|
|
C
|
|
C Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1997.
|
|
C Supersedes Release 2.0 routine DG01BD by R. Dekeyser, and
|
|
C F. Dumortier, State University of Gent, Belgium.
|
|
C
|
|
C REVISIONS
|
|
C
|
|
C -
|
|
C
|
|
C KEYWORDS
|
|
C
|
|
C Complex signals, digital signal processing, fast Fourier
|
|
C transform, real signals.
|
|
C
|
|
C ******************************************************************
|
|
C
|
|
C .. Scalar Arguments ..
|
|
CHARACTER INDI
|
|
INTEGER INFO, N
|
|
C .. Array Arguments ..
|
|
DOUBLE PRECISION XI(*), XR(*)
|
|
C .. Local Scalars ..
|
|
INTEGER J
|
|
LOGICAL LINDI
|
|
C .. External Functions ..
|
|
LOGICAL LSAME
|
|
EXTERNAL LSAME
|
|
C .. External Subroutines ..
|
|
EXTERNAL DG01MD, DG01NY, XERBLA
|
|
C .. Intrinsic Functions ..
|
|
INTRINSIC MOD
|
|
C .. Executable Statements ..
|
|
C
|
|
INFO = 0
|
|
LINDI = LSAME( INDI, 'D' )
|
|
C
|
|
C Test the input scalar arguments.
|
|
C
|
|
IF( .NOT.LINDI .AND. .NOT.LSAME( INDI, 'I' ) ) THEN
|
|
INFO = -1
|
|
ELSE
|
|
J = 0
|
|
IF( N.GE.2 ) THEN
|
|
J = N
|
|
C WHILE ( MOD( J, 2 ).EQ.0 ) DO
|
|
10 CONTINUE
|
|
IF ( MOD( J, 2 ).EQ.0 ) THEN
|
|
J = J/2
|
|
GO TO 10
|
|
END IF
|
|
C END WHILE 10
|
|
END IF
|
|
IF ( J.NE.1 ) INFO = -2
|
|
END IF
|
|
C
|
|
IF ( INFO.NE.0 ) THEN
|
|
C
|
|
C Error return.
|
|
C
|
|
CALL XERBLA( 'DG01ND', -INFO )
|
|
RETURN
|
|
END IF
|
|
C
|
|
C Compute the Fourier transform of Z = (XR,XI).
|
|
C
|
|
IF ( .NOT.LINDI ) CALL DG01NY( INDI, N, XR, XI )
|
|
C
|
|
CALL DG01MD( INDI, N, XR, XI, INFO )
|
|
C
|
|
IF ( LINDI ) CALL DG01NY( INDI, N, XR, XI )
|
|
C
|
|
RETURN
|
|
C *** Last line of DG01ND ***
|
|
END
|