#include "fftpack.h"
#include <math.h>
real;
integer;
f77complex;
#ifdef TESTING_FFTPACK
static real c_abs(f77complex *c) { return sqrt(c->r*c->r + c->i*c->i); }
static double dmax(double a, double b) { return a < b ? b : a; }
#endif
static void passfb(integer *nac, integer ido, integer ip, integer l1, integer idl1,
real *cc, real *c1, real *c2, real *ch, real *ch2, const real *wa, real fsign)
{ … }
#undef ch2_ref
#undef ch_ref
#undef cc_ref
#undef c2_ref
#undef c1_ref
static void passb2(integer ido, integer l1, const real *cc, real *ch, const real *wa1)
{ … }
#undef ch_ref
#undef cc_ref
static void passb3(integer ido, integer l1, const real *cc, real *ch, const real *wa1, const real *wa2)
{ … }
#undef ch_ref
#undef cc_ref
static void passb4(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2, const real *wa3)
{ … }
#undef ch_ref
#undef cc_ref
static void passfb5(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2, const real *wa3, const real *wa4, real fsign)
{ … }
#undef ch_ref
#undef cc_ref
static void passf2(integer ido, integer l1, const real *cc, real *ch, const real *wa1)
{ … }
#undef ch_ref
#undef cc_ref
static void passf3(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2)
{ … }
#undef ch_ref
#undef cc_ref
static void passf4(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2, const real *wa3)
{ … }
#undef ch_ref
#undef cc_ref
static void radb2(integer ido, integer l1, const real *cc, real *ch, const real *wa1)
{ … }
#undef ch_ref
#undef cc_ref
static void radb3(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2)
{ … }
#undef ch_ref
#undef cc_ref
static void radb4(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2, const real *wa3)
{ … }
#undef ch_ref
#undef cc_ref
static void radb5(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2, const real *wa3, const real *wa4)
{ … }
#undef ch_ref
#undef cc_ref
static void radbg(integer ido, integer ip, integer l1, integer idl1,
const real *cc, real *c1, real *c2, real *ch, real *ch2, const real *wa)
{ … }
#undef ch2_ref
#undef ch_ref
#undef cc_ref
#undef c2_ref
#undef c1_ref
static void radf2(integer ido, integer l1, const real *cc, real *ch,
const real *wa1)
{ … }
#undef ch_ref
#undef cc_ref
static void radf3(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2)
{ … }
#undef ch_ref
#undef cc_ref
static void radf4(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2, const real *wa3)
{ … }
#undef ch_ref
#undef cc_ref
static void radf5(integer ido, integer l1, const real *cc, real *ch,
const real *wa1, const real *wa2, const real *wa3, const real *wa4)
{ … }
#undef ch_ref
#undef cc_ref
static void radfg(integer ido, integer ip, integer l1, integer idl1,
real *cc, real *c1, real *c2, real *ch, real *ch2, const real *wa)
{ … }
#undef ch2_ref
#undef ch_ref
#undef cc_ref
#undef c2_ref
#undef c1_ref
static void cfftb1(integer n, real *c, real *ch, const real *wa, integer *ifac)
{ … }
void cfftb(integer n, real *c, real *wsave)
{ … }
static void cfftf1(integer n, real *c, real *ch, const real *wa, integer *ifac)
{ … }
void cfftf(integer n, real *c, real *wsave)
{ … }
static int decompose(integer n, integer *ifac, integer ntryh[4]) { … }
static void cffti1(integer n, real *wa, integer *ifac)
{ … }
void cffti(integer n, real *wsave)
{ … }
static void rfftb1(integer n, real *c, real *ch, const real *wa, integer *ifac)
{ … }
static void rfftf1(integer n, real *c, real *ch, const real *wa, integer *ifac)
{ … }
void rfftb(integer n, real *r, real *wsave)
{ … }
static void rffti1(integer n, real *wa, integer *ifac)
{ … }
void rfftf(integer n, real *r, real *wsave)
{ … }
void rffti(integer n, real *wsave)
{ … }
static void cosqb1(integer n, real *x, real *w, real *xh)
{ … }
void cosqb(integer n, real *x, real *wsave)
{ … }
static void cosqf1(integer n, real *x, real *w, real *xh)
{ … }
void cosqf(integer n, real *x, real *wsave)
{ … }
void cosqi(integer n, real *wsave)
{ … }
void cost(integer n, real *x, real *wsave)
{ … }
void costi(integer n, real *wsave)
{ … }
void sinqb(integer n, real *x, real *wsave)
{ … }
void sinqf(integer n, real *x, real *wsave)
{ … }
void sinqi(integer n, real *wsave)
{ … }
static void sint1(integer n, real *war, real *was, real *xh, real *
x, integer *ifac)
{ … }
void sinti(integer n, real *wsave)
{ … }
void sint(integer n, real *x, real *wsave)
{ … }
#ifdef TESTING_FFTPACK
#include <stdio.h>
int main(void)
{
static integer nd[] = { 120,91,54,49,32,28,24,8,4,3,2 };
real r1, r2, r3;
f77complex q1, q2, q3;
integer i, j, k, n;
real w[2000], x[200], y[200], cf, fn, dt;
f77complex cx[200], cy[200];
real xh[200];
integer nz, nm1, np1, ns2;
real arg, tfn;
real sum, arg1, arg2;
real sum1, sum2, dcfb;
integer modn;
real rftb, rftf;
real sqrt2;
real rftfb;
real costt, sintt, dcfftb, dcfftf, cosqfb, costfb;
real sinqfb;
real sintfb;
real cosqbt, cosqft, sinqbt, sinqft;
sqrt2 = sqrt(2.f);
int all_ok = 1;
for (nz = 1; nz <= (int)(sizeof nd/sizeof nd[0]); ++nz) {
n = nd[nz - 1];
modn = n % 2;
fn = (real) n;
tfn = fn + fn;
np1 = n + 1;
nm1 = n - 1;
for (j = 1; j <= np1; ++j) {
x[j - 1] = sin((real) j * sqrt2);
y[j - 1] = x[j - 1];
xh[j - 1] = x[j - 1];
}
rffti(n, w);
dt = (2*M_PI) / fn;
ns2 = (n + 1) / 2;
if (ns2 < 2) {
goto L104;
}
for (k = 2; k <= ns2; ++k) {
sum1 = 0.f;
sum2 = 0.f;
arg = (real) (k - 1) * dt;
for (i = 1; i <= n; ++i) {
arg1 = (real) (i - 1) * arg;
sum1 += x[i - 1] * cos(arg1);
sum2 += x[i - 1] * sin(arg1);
}
y[(k << 1) - 3] = sum1;
y[(k << 1) - 2] = -sum2;
}
L104:
sum1 = 0.f;
sum2 = 0.f;
for (i = 1; i <= nm1; i += 2) {
sum1 += x[i - 1];
sum2 += x[i];
}
if (modn == 1) {
sum1 += x[n - 1];
}
y[0] = sum1 + sum2;
if (modn == 0) {
y[n - 1] = sum1 - sum2;
}
rfftf(n, x, w);
rftf = 0.f;
for (i = 1; i <= n; ++i) {
r2 = rftf, r3 = (r1 = x[i - 1] - y[i - 1], fabs(r1));
rftf = dmax(r2,r3);
x[i - 1] = xh[i - 1];
}
rftf /= fn;
for (i = 1; i <= n; ++i) {
sum = x[0] * .5f;
arg = (real) (i - 1) * dt;
if (ns2 < 2) {
goto L108;
}
for (k = 2; k <= ns2; ++k) {
arg1 = (real) (k - 1) * arg;
sum = sum + x[(k << 1) - 3] * cos(arg1) - x[(k << 1) - 2] *
sin(arg1);
}
L108:
if (modn == 0) {
sum += (real)pow(-1, i-1) * .5f * x[n - 1];
}
y[i - 1] = sum + sum;
}
rfftb(n, x, w);
rftb = 0.f;
for (i = 1; i <= n; ++i) {
r2 = rftb, r3 = (r1 = x[i - 1] - y[i - 1], fabs(r1));
rftb = dmax(r2,r3);
x[i - 1] = xh[i - 1];
y[i - 1] = xh[i - 1];
}
rfftb(n, y, w);
rfftf(n, y, w);
cf = 1.f / fn;
rftfb = 0.f;
for (i = 1; i <= n; ++i) {
r2 = rftfb, r3 = (r1 = cf * y[i - 1] - x[i - 1], fabs(
r1));
rftfb = dmax(r2,r3);
}
dt = M_PI / fn;
for (i = 1; i <= nm1; ++i) {
x[i - 1] = xh[i - 1];
}
for (i = 1; i <= nm1; ++i) {
y[i - 1] = 0.f;
arg1 = (real) i * dt;
for (k = 1; k <= nm1; ++k) {
y[i - 1] += x[k - 1] * sin((real) k * arg1);
}
y[i - 1] += y[i - 1];
}
sinti(nm1, w);
sint(nm1, x, w);
cf = .5f / fn;
sintt = 0.f;
for (i = 1; i <= nm1; ++i) {
r2 = sintt, r3 = (r1 = x[i - 1] - y[i - 1], fabs(r1));
sintt = dmax(r2,r3);
x[i - 1] = xh[i - 1];
y[i - 1] = x[i - 1];
}
sintt = cf * sintt;
sint(nm1, x, w);
sint(nm1, x, w);
sintfb = 0.f;
for (i = 1; i <= nm1; ++i) {
r2 = sintfb, r3 = (r1 = cf * x[i - 1] - y[i - 1], fabs(
r1));
sintfb = dmax(r2,r3);
}
for (i = 1; i <= np1; ++i) {
x[i - 1] = xh[i - 1];
}
for (i = 1; i <= np1; ++i) {
y[i - 1] = (x[0] + (real) pow(-1, i+1) * x[n]) * .5f;
arg = (real) (i - 1) * dt;
for (k = 2; k <= n; ++k) {
y[i - 1] += x[k - 1] * cos((real) (k - 1) * arg);
}
y[i - 1] += y[i - 1];
}
costi(np1, w);
cost(np1, x, w);
costt = 0.f;
for (i = 1; i <= np1; ++i) {
r2 = costt, r3 = (r1 = x[i - 1] - y[i - 1], fabs(r1));
costt = dmax(r2,r3);
x[i - 1] = xh[i - 1];
y[i - 1] = xh[i - 1];
}
costt = cf * costt;
cost(np1, x, w);
cost(np1, x, w);
costfb = 0.f;
for (i = 1; i <= np1; ++i) {
r2 = costfb, r3 = (r1 = cf * x[i - 1] - y[i - 1], fabs(
r1));
costfb = dmax(r2,r3);
}
cf = .25f / fn;
for (i = 1; i <= n; ++i) {
y[i - 1] = xh[i - 1];
}
dt = M_PI / (fn + fn);
for (i = 1; i <= n; ++i) {
x[i - 1] = 0.f;
arg = dt * (real) i;
for (k = 1; k <= n; ++k) {
x[i - 1] += y[k - 1] * sin((real) (k + k - 1) * arg);
}
x[i - 1] *= 4.f;
}
sinqi(n, w);
sinqb(n, y, w);
sinqbt = 0.f;
for (i = 1; i <= n; ++i) {
r2 = sinqbt, r3 = (r1 = y[i - 1] - x[i - 1], fabs(r1))
;
sinqbt = dmax(r2,r3);
x[i - 1] = xh[i - 1];
}
sinqbt = cf * sinqbt;
for (i = 1; i <= n; ++i) {
arg = (real) (i + i - 1) * dt;
y[i - 1] = (real) pow(-1, i+1) * .5f * x[n - 1];
for (k = 1; k <= nm1; ++k) {
y[i - 1] += x[k - 1] * sin((real) k * arg);
}
y[i - 1] += y[i - 1];
}
sinqf(n, x, w);
sinqft = 0.f;
for (i = 1; i <= n; ++i) {
r2 = sinqft, r3 = (r1 = x[i - 1] - y[i - 1], fabs(r1))
;
sinqft = dmax(r2,r3);
y[i - 1] = xh[i - 1];
x[i - 1] = xh[i - 1];
}
sinqf(n, y, w);
sinqb(n, y, w);
sinqfb = 0.f;
for (i = 1; i <= n; ++i) {
r2 = sinqfb, r3 = (r1 = cf * y[i - 1] - x[i - 1], fabs(
r1));
sinqfb = dmax(r2,r3);
}
for (i = 1; i <= n; ++i) {
y[i - 1] = xh[i - 1];
}
for (i = 1; i <= n; ++i) {
x[i - 1] = 0.f;
arg = (real) (i - 1) * dt;
for (k = 1; k <= n; ++k) {
x[i - 1] += y[k - 1] * cos((real) (k + k - 1) * arg);
}
x[i - 1] *= 4.f;
}
cosqi(n, w);
cosqb(n, y, w);
cosqbt = 0.f;
for (i = 1; i <= n; ++i) {
r2 = cosqbt, r3 = (r1 = x[i - 1] - y[i - 1], fabs(r1))
;
cosqbt = dmax(r2,r3);
x[i - 1] = xh[i - 1];
}
cosqbt = cf * cosqbt;
for (i = 1; i <= n; ++i) {
y[i - 1] = x[0] * .5f;
arg = (real) (i + i - 1) * dt;
for (k = 2; k <= n; ++k) {
y[i - 1] += x[k - 1] * cos((real) (k - 1) * arg);
}
y[i - 1] += y[i - 1];
}
cosqf(n, x, w);
cosqft = 0.f;
for (i = 1; i <= n; ++i) {
r2 = cosqft, r3 = (r1 = y[i - 1] - x[i - 1], fabs(r1))
;
cosqft = dmax(r2,r3);
x[i - 1] = xh[i - 1];
y[i - 1] = xh[i - 1];
}
cosqft = cf * cosqft;
cosqb(n, x, w);
cosqf(n, x, w);
cosqfb = 0.f;
for (i = 1; i <= n; ++i) {
r2 = cosqfb, r3 = (r1 = cf * x[i - 1] - y[i - 1], fabs(r1));
cosqfb = dmax(r2,r3);
}
for (i = 1; i <= n; ++i) {
r1 = cos(sqrt2 * (real) i);
r2 = sin(sqrt2 * (real) (i * i));
q1.r = r1, q1.i = r2;
cx[i-1].r = q1.r, cx[i-1].i = q1.i;
}
dt = (2*M_PI) / fn;
for (i = 1; i <= n; ++i) {
arg1 = -((real) (i - 1)) * dt;
cy[i-1].r = 0.f, cy[i-1].i = 0.f;
for (k = 1; k <= n; ++k) {
arg2 = (real) (k - 1) * arg1;
r1 = cos(arg2);
r2 = sin(arg2);
q3.r = r1, q3.i = r2;
q2.r = q3.r * cx[k-1].r - q3.i * cx[k-1].i, q2.i =
q3.r * cx[k-1].i + q3.i * cx[k-1].r;
q1.r = cy[i-1].r + q2.r, q1.i = cy[i-1].i + q2.i;
cy[i-1].r = q1.r, cy[i-1].i = q1.i;
}
}
cffti(n, w);
cfftf(n, (real*)cx, w);
dcfftf = 0.f;
for (i = 1; i <= n; ++i) {
q1.r = cx[i-1].r - cy[i-1].r, q1.i = cx[i-1].i - cy[i-1]
.i;
r1 = dcfftf, r2 = c_abs(&q1);
dcfftf = dmax(r1,r2);
q1.r = cx[i-1].r / fn, q1.i = cx[i-1].i / fn;
cx[i-1].r = q1.r, cx[i-1].i = q1.i;
}
dcfftf /= fn;
for (i = 1; i <= n; ++i) {
arg1 = (real) (i - 1) * dt;
cy[i-1].r = 0.f, cy[i-1].i = 0.f;
for (k = 1; k <= n; ++k) {
arg2 = (real) (k - 1) * arg1;
r1 = cos(arg2);
r2 = sin(arg2);
q3.r = r1, q3.i = r2;
q2.r = q3.r * cx[k-1].r - q3.i * cx[k-1].i, q2.i =
q3.r * cx[k-1].i + q3.i * cx[k-1].r;
q1.r = cy[i-1].r + q2.r, q1.i = cy[i-1].i + q2.i;
cy[i-1].r = q1.r, cy[i-1].i = q1.i;
}
}
cfftb(n, (real*)cx, w);
dcfftb = 0.f;
for (i = 1; i <= n; ++i) {
q1.r = cx[i-1].r - cy[i-1].r, q1.i = cx[i-1].i - cy[i-1].i;
r1 = dcfftb, r2 = c_abs(&q1);
dcfftb = dmax(r1,r2);
cx[i-1].r = cy[i-1].r, cx[i-1].i = cy[i-1].i;
}
cf = 1.f / fn;
cfftf(n, (real*)cx, w);
cfftb(n, (real*)cx, w);
dcfb = 0.f;
for (i = 1; i <= n; ++i) {
q2.r = cf * cx[i-1].r, q2.i = cf * cx[i-1].i;
q1.r = q2.r - cy[i-1].r, q1.i = q2.i - cy[i-1].i;
r1 = dcfb, r2 = c_abs(&q1);
dcfb = dmax(r1,r2);
}
printf("%d\tRFFTF %10.3g\tRFFTB %10.ge\tRFFTFB %10.3g", n, rftf, rftb, rftfb);
printf( "\tSINT %10.3g\tSINTFB %10.ge\tCOST %10.3g\n", sintt, sintfb, costt);
printf( "\tCOSTFB %10.3g\tSINQF %10.ge\tSINQB %10.3g", costfb, sinqft, sinqbt);
printf( "\tSINQFB %10.3g\tCOSQF %10.ge\tCOSQB %10.3g\n", sinqfb, cosqft, cosqbt);
printf( "\tCOSQFB %10.3g\t", cosqfb);
printf( "\tCFFTF %10.ge\tCFFTB %10.3g\n", dcfftf, dcfftb);
printf( "\tCFFTFB %10.3g\n", dcfb);
#define CHECK …
CHECK(rftf); CHECK(rftb); CHECK(rftfb); CHECK(sintt); CHECK(sintfb); CHECK(costt);
CHECK(costfb); CHECK(sinqft); CHECK(sinqbt); CHECK(sinqfb); CHECK(cosqft); CHECK(cosqbt);
CHECK(cosqfb); CHECK(dcfftf); CHECK(dcfftb);
}
if (all_ok) printf("Everything looks fine.\n");
else printf("ERRORS WERE DETECTED.\n");
return all_ok ? 0 : 1;
}
#endif