File: rfftTest2d.c

package info (click to toggle)
audacity 2.1.2-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 86,844 kB
  • sloc: ansic: 225,005; cpp: 221,240; sh: 27,327; python: 16,896; makefile: 8,186; lisp: 8,002; perl: 317; xml: 307; sed: 16
file content (158 lines) | stat: -rw-r--r-- 3,963 bytes parent folder | download | duplicates (16)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*  A program to test real 2d forward and inverse fast fourier transform routines	*/

#include <NR.H>	/* uses rlft3 from numerical recipes in C to verify rifft2d */
			/*change fmin in numerical recipes to fminnr to avoid conflict with fp.h */

#include <stdio.h>
#include <stdlib.h>
#include <fp.h>
#include <math.h>
#include "fftlib.h"
#include "fftext.h"
#include "fft2d.h"
#include <NRUTIL.H>	// uses ugly tensors from numerical recipes; so can call rlft3

#if macintosh
#include <timer.h>
#endif

#define NSIZES 	24		/* the number of different ffts sizes to test */

#define	BIPRAND(a) (2.0/(RAND_MAX+1.0)*a-1.0)

void main(){
long 	fftSize[NSIZES] = 	/* size of FFTs, must be powers of 2 */
		{2,		4, 		8,		16, 		32, 		64, 		128, 	256,
		512, 	1024, 	2048, 	4096, 	8192, 	16384, 	32768, 	65536,
		131072, 	262144, 	524288, 	1048576, 	2097152, 	4194304, 	8388608, 	16777216};
float	*a;
long 	N2 = 64;	/* the number of rows in 2d ffts, must be power of 2 */
long 	isize;
long 	i1;
long 	i2;
long 	TheErr;
long		N;
long		M;
long		M2;
float 	maxerrifft;
float 	maxerrfft;

float	***NRtensdata;	/* needed for rlft3 */
float	**NRmatdata;	/* needed for rlft3 */
float	*specdata;	/* needed for rlft3 */
float t1,t2;

unsigned int	randseed = 777;
int		rannum;
#if macintosh
	UnsignedWide 		TheTime1;
	Microseconds(&TheTime1);
	randseed = TheTime1.lo;
#endif

printf(" %6d  Byte Floats \n", sizeof(a[0]));
printf(" randseed = %10u\n", randseed);
for (isize = 0; isize < NSIZES; isize++){

	srand(randseed);
	N = fftSize[isize];
	M = roundtol(LOG2(N));
	N = POW2(M);
	M2 = roundtol(LOG2(N2));
	N2 = POW2(M2);

	printf("rffts size = %6d X%6d,  ", N2, N);

	TheErr = 0;
	TheErr = fft2dInit(M2, M);

	if(!TheErr){
		NRmatdata=matrix(1,1,1,2*N2);
		specdata = &NRmatdata[1][1];
		NRtensdata=f3tensor(1,1,1,N2,1,N);	// uses ugly tensors from NRUTIL; so can call rlft3
		a = &NRtensdata[1][1][1];
		if ((a == 0)||(specdata == 0)) TheErr = 2;
	}

	if(!TheErr){

			/*  set up a simple test case */
		for (i1=0; i1<N2*N; i1++){
			rannum = rand();
			a[i1] = BIPRAND(rannum);
		}

			/*  first use rlft3 from numerical recipes in C to verify rifft2d */
			/*  unfortunately  numerical recipes in C uses backwards time and space */
			/*  forward fft, so our answer comes out time and space reversed */

		rlft3(NRtensdata, NRmatdata, 1, N2, N, 1);
		
		/* move data to my in-place order */
		a[1] = a[N2/2*N];			// pack in nyquest wavenumber point for DC freq transform
		for (i2=0; i2<N2/2; i2++){ // move transform of nyquest frequency
			a[(N2/2+i2)*N] = specdata[i2*2];
			a[(N2/2+i2)*N+1] = specdata[i2*2+1];
		}
		a[N2/2*N+1] = specdata[N2];	// pack in nyquest wavenumber point for nyquest freq transform


		rifft2d(a, M2, M);

		srand(randseed);
		rannum = rand();
		maxerrifft = fabs(BIPRAND(rannum)-a[0]);
		for (i1=1; i1<N; i1++){
			rannum = rand();
		t1=BIPRAND(rannum);
		t2=a[N-i1];
			maxerrifft = fmax(maxerrifft, fabs(BIPRAND(rannum)-a[N-i1]));
		}
		for (i2=1; i2<N2; i2++){
			rannum = rand();
			t1=BIPRAND(rannum);
			t2=a[(N2-i2)*N];
			maxerrifft = fmax(maxerrifft, fabs(BIPRAND(rannum)-a[(N2-i2)*N]));
			for (i1=1; i1<N; i1++){
				rannum = rand();
			t1=BIPRAND(rannum);
			t2=a[(N2-i2)*N+N-i1];
				maxerrifft = fmax(maxerrifft, fabs(BIPRAND(rannum)-a[(N2-i2)*N+N-i1]));
			}
		}

		printf("maxerrifft = %6.4e,  ", maxerrifft);

			/*  now use rifft2d to verify rfft2d */
		srand(randseed);
		for (i1=0; i1<N2*N; i1++){
			rannum = rand();
			a[i1] = BIPRAND(rannum);
		}

		rifft2d(a, M2, M);
		rfft2d(a, M2, M);

		maxerrfft = 0;
		srand(randseed);
		for (i1=0; i1<N2*N; i1++){
			rannum = rand();
			maxerrfft = fmax(maxerrfft, fabs(BIPRAND(rannum)-a[i1]));
		}

		printf("maxerrfft = %6.4e\n", maxerrfft);

		fft2dFree();
		free_f3tensor(NRtensdata,1,1,1,N2,1,N);
		free_matrix(NRmatdata,1,1,1,2*N2);
		a = 0;
	}
	else{
		if(TheErr==2)	printf(" out of memory \n");
		else	printf(" error \n");
		fft2dFree();
	}
}
printf(" Done. \n");
return;
}