#
# fftl02.rb
#
# $Id: fftl02.rb,v 1.2 2000/11/27 01:53:56 keiko Exp $
#
require "narray"
require "numru/dcl"
include NumRu
include Math
#-----------------------------------------------------------------------
module Tfftp
#
#
# PURPOSE TO DEMONSTRATE THE USE OF FFTPACK, AND TO
# TEST THE PERFORMANCE OF FFTPACK ON ONE
# WELL-CONDITIONED PROBLEM.
#
# USAGE CALL TFFTPK (IERROR)
#
# ARGUMENTS
#
# ON OUTPUT IERROR
# INTEGER VARIABLE SET TO ZERO IF FFTPACK
# CORRECTLY SOLVED THE TEST PROBLEM, AND
# ONE IF FFTPACK FAILED.
#
# I/O IF THE TEST SUCCEEDS(FAILS), THE MESSAGE
#
# FFTPACK TEST SUCCESSFUL (UNSUCCESSFUL)
#
# IS WRITTEN ON UNIT 6. IN THE CASE OF FAILURE,
# ADDITIONAL MESSAGES ARE WRITTEN IDENTIFYING THE
# FAILURE MORE EXPLICITLY.
#
# PRECISION SINGLE
#
# REQUIRED LIBRARY NONE
# FILES
#
# LANGUAGE FORTRAN
#
# HISTORY WRITTEN BY MEMBERS OF THE SCIENTIFIC
# COMPUTING DIVISION OF NCAR,
# BOULDER COLORADO.
#
# ALGORITHM FOR EACH OF THE ROUTINES, RFFTF, RFFTB, EZFFTF,
# AND EZFFTB IN THE FFTPACK PACKAGE A SIMILAR
# TEST IS RUN. AN APPROPIATE VECTOR, FOR WHICH
# THE EXACT TRANSFORM IS KNOWN IS USED AS THE
# INPUT VECTOR. THE ROUTINE IS CALLED TO PERFORM
# THE TRANSFORM. THE CALCULATED TRANSFORM VECTOR
# IS COMPARED WITH THE EXACT TRANSFORM TO SEE
# WHETHER THE PERFORMANCE CRITERION IS MET WITHIN
# THE SPECIFED TOLERANCE.
#
# FOR RFFTF AND EZFFTF, A REAL VECTOR, THE ELEMEN
# WHICH ARE EQUAL TO ONE, IS USED AS INPUT. THE
# TRANSFORMED VECTOR HAS THE FIRST ELEMENT EQUAL
# TO THE LENGTH OF THE INPUT VECTOR. ALL OTHER
# ELEMENTS ARE EQUAL TO ZERO.
#
# FOR RFFTB AND EZFFTB, THE INPUT VECTOR HAS FIRS
# ELEMENT EQUAL TO ONE AND ALL THE OTHER ELEMENTS
# EQUAL TO ZERO. THE TRANSFORMED VECTOR HAS ALL
# COMPONENTS EQUAL TO ONE.
#
# PORTABILITY ANSI STANDARD
#
#
N = 36
DIM1 = 2*N+15
DIM2 = 3*N+15
ND2 = N/2
TOL = 0.01
M998 = " FFTPACK TEST SUCCESSFUL\n"
M999 = " FFTPACK TEST UNSUCCESSFUL\n"
M1001 = " IN FFTPACK, ENTRY RFFTF RESULTS IN ERROR\n"
M1002 = " IN FFTPACK, ENTRY RFFTB RESULTS IN ERROR\n"
M1003 = " IN FFTPACK, ENTRY EZFFTF RESULTS IN ERROR\n"
M1004 = " IN FFTPACK, ENTRY EZFFTB RESULTS IN ERROR\n"
# def stores(x)
#
# FORCES THE ARGUMENT VALUE X TO BE STORED IN MEMORY LOCATION V.
#
# common /value/ v
# v=x
# end
def trunc(x)
#
# TRUNC IS A PORTABLE FORTRAN FUNCTION WHICH TRUNCATES A VALUE TO THE
# MACHINE SINGLE PRECISION WORD SIZE, REGARDLESS OF WHETHER LONGER
# PRECISION INTERNAL REGISTERS ARE USED FOR FLOATING POINT ARITHMETIC IN
# COMPUTING THE VALUE INPUT TO TRUNC. THE METHOD USED IS TO FORCE A
# STORE INTO MEMORY BY USING A COMMON BLOCK IN ANOTHER SUBROUTINE.
#
# common /value/ v
# stores(x)
# trunc=v
x.to_f #????
end
#
# STATEMENT FUNCTION SMALL(EX) IS FOR TESTING WHETHER X IS CLOSE TO ZERO
# INDEPENDENTLY OF MACHINE WORD SIZE. SMALL(EX) IS EXACTLY ZERO ONLY IF
# ABS(X) .LT. EPS/TOL, WHERE EPS IS THE MACHINE PRECESION AND TOL IS A
# TOLERANCE FACTOR USED TO CONTROL THE STRICTNESS OF THE TEST.
#
def small(ex)
trunc(1.0+TOL*ex.abs)-1.0
end
def fft_test
rldat = NArray.sfloat(N)
#
# CALL INITIALIZATION ROUTINE FOR RFFTF AND RFFTB.
#
wrfft = DCL::rffti(N)
#
# TEST OF RFFTF.
#
rldat.fill!(1.0)
#
result = DCL::rfftf(rldat, wrfft)
#
# TEST RESULTS OF RFFTF
#
error = (N.to_f - result[0]).abs
for i in 1..N-1
error = [error, (result[i]).abs].max
end
if (small(error) == 0)
ier1 = 0
else
ier1 = 1
print M1001
end
#
# TEST OF RFFTB.
#
rldat.fill!(0.0)
rldat[0] = 1.0
#
result = DCL::rfftb(rldat, wrfft)
#
# TEST RESULTS OF RFFTB
#
error = 0.0
for i in 0..N-1
error = [error, (1.0 - result[i]).abs].max
end
if (small(error) == 0)
ier2 = 0
else
ier2 = 1
print M1002
end
#
# CALL INITIALIZATION ROUTINE EZFFTI FOR EZFFTF AND EZFFTB
#
wezfft = DCL::ezffti(N)
#
# TEST OF EZFFTF.
#
rldat.fill!(1.0)
#
#
azero, a, b = DCL::ezfftf(rldat, wezfft)
#
# TEST RESULTS OF EZFFTF
#
error = (azero - 1.0).abs
for i in 0..ND2-1
error = [(a[i]).abs + (b[i]).abs, error].max
end
if (small(error) == 0)
ier3 = 0
else
ier3 = 1
print M1003
end
#
# TEST OF EZFFTB.
#
azero = 1.0
a[0..ND2-1] = 0.0
b[0..ND2-1] = 0.0
#
result = DCL::ezfftb(azero, a, b, wezfft)
#
# TEST RESULTS OF EZFFTB
#
error = 0.0
for i in 0..N-1
error = [(1.0 - result[i]).abs, error].max
end
if (small(error) == 0)
ier4 = 0
else
ier4 = 1
print M1004
end
#
#
ierror = ier1 + ier2 + ier3 + ier4
if (ierror == 0)
print M998
else
ierror = 1
print M999
end
ierror
end
end
include Tfftp
ier = Tfftp::fft_test
syntax highlighted by Code2HTML, v. 0.9.1