Index: /trunk/psLib/test/fft/tap_psImageFFT.c
===================================================================
--- /trunk/psLib/test/fft/tap_psImageFFT.c	(revision 12153)
+++ /trunk/psLib/test/fft/tap_psImageFFT.c	(revision 12154)
@@ -1,566 +1,130 @@
-/** @file  tst_psImageFFT.c
- *
- *  @brief Contains the tests for psFFT.[ch]
- *
- *
- *  @author Robert DeSonia, MHPCC
- *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-02-07 22:50:18 $
- *
- *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
- */
 #include <stdio.h>
-#include <string.h>
+#include <math.h>
 #include <pslib.h>
+
 #include "tap.h"
 #include "pstap.h"
 
-#define GENIMAGE(img,c,r,TYP, valueFcn) \
-img = psImageAlloc(c,r,PS_TYPE_##TYP); \
-for (psU32 row=0;row<r;row++) { \
-    ps##TYP* imgRow = img->data.TYP[row]; \
-    for (psU32 col=0;col<c;col++) { \
-        imgRow[col] = (ps##TYP)(valueFcn); \
-    } \
+#define TOL 2.0e-6                      // Tolerance for comparison
+
+
+// Generate image with single high pixel
+static psImage *generateImage(int numCols, int numRows)
+{
+    psImage *image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    for (int y = 0; y < numRows; y++) {
+        for (int x = 0; x < numCols; x++) {
+            image->data.F32[y][x] = 1.2 * cos(2.0 * M_PI * x / numCols + M_PI / 4.0) +
+                3.4 * sin(2.0 * M_PI * y / numRows + M_PI);
+        }
+    }
+    return image;
 }
 
-psS32 main(psS32 argc, char* argv[])
+// FFT forward, then back --- do I get what I started with?
+// A total of 6 tests here.
+static void testFFT(int numCols, int numRows)
 {
-    psLogSetFormat("HLNM");
-    psLogSetLevel(PS_LOG_INFO);
-    plan_tests(68);
+    psMemId id = psMemGetId();
 
-    // psImageFFT(void)
+    diag("Testing %dx%d", numCols, numRows);
+    psImage *old = generateImage(numCols, numRows);
+    psImage *fftReal = NULL, *fftImag = NULL;
+    bool result = psImageForwardFFT(&fftReal, &fftImag, old);
+    ok(result, "forward fft result");
+    skip_start(!result || !fftReal || !fftImag, 3, "forward fft failed");
+    ok(fftReal->type.type == PS_TYPE_F32 && fftImag->type.type == PS_TYPE_F32, "forward fft types");
+    psImage *new = NULL;
+    result = psImageBackwardFFT(&new, fftReal, fftImag, old->numCols);
+    ok(result, "backward fft result");
+    skip_start(!result || !new, 2, "backward fft failed");
+    ok(new->type.type == PS_TYPE_F32, "backward fft type");
+    float maxDev = 0.0;                 // Maximum deviation from expected
+    for (int y = 0; y < old->numRows; y++) {
+        for (int x = 0; x < old->numCols; x++) {
+            float dev = fabs(new->data.F32[y][x] / numCols / numRows - old->data.F32[y][x]);
+            if (dev > maxDev) {
+                maxDev = dev;
+            }
+        }
+    }
+    ok(maxDev < TOL, "maximum deviation: %f", maxDev);
+    psFree(new);
+    skip_end();
+    skip_end();
+
+    psFree(fftReal);
+    psFree(fftImag);
+    psFree(old);
+    ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
+
+    return;
+}
+
+
+int main(int argc, char *argv[])
+{
+    plan_tests(8 + 6 * 5);
+
+    // Test with NULL real arg
     {
         psMemId id = psMemGetId();
-        psImage* img = NULL;
-        psImage* img2 = NULL;
-        psImage* img3 = NULL;
-        psU32 m = 128;
-        psU32 n = 64;
-        psImage* img4 = NULL;
-        psImage* img5 = NULL;
-
-        // 1. assign a image to a radial sinisoid
-        // 2. perform forward transform
-        // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
-        // 4. perform reverse transform
-        // 5. compare to original (should be equal to within a reasonable error)
-
-        // 1. assign a image to a radial sinisoid
-        GENIMAGE(img,m,n,F32, sinf((32.0f-row)/32.0f*M_PI)+sinf((64.0f-col)/64.0f*M_PI));
-
-        // 2. perform forward transform
-        img2 = psImageFFT(img2,img,PS_FFT_FORWARD);
-        ok(img2 != NULL, "psImageFFT() returned non-NULL");
-        skip_start(img2 == NULL, 1, "Skipping tests because psImageFFT() returned NULL");
-        ok(img2->type.type == PS_TYPE_C32, "FFT produced complex values");
-        ok(img2->numCols == m && img2->numRows == n, "FFT produced proper size result (%dx%d vs. expected %dx%d).",
-           img2->numCols,img2->numRows,m,n);
-
-        // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
-        bool errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psC32* img2Row = img2->data.C32[row];
-            for (psU32 col=0;col<m;col++) {
-                psF32 mag = cabsf(img2Row[col])/m/n;
-                if (mag > 0.1f) {
-                    // must be (0,1) or (0,n-1) or (1,0) or (m-1,0)
-                    if (! (col == 0 && (row == 1 || row == n-1))
-                            && ! (row == 0 && (col==1 || col == m-1)) ) {
-                        diag("Result incorrect at %d,%d (%.2f)",col,row,mag);
-                        errorFlag = true;
-                    }
-                } else {
-                    if ( (col == 0 && (row == 1 || row == n-1))
-                            || (row == 0 && (col==1 || col == m-1)) ) {
-                        diag("Result incorrect at %d,%d (%.2f)",col,row,mag);
-                        errorFlag = true;
-                    }
-                }
-            }
-        }
-        ok(!errorFlag, "FFT produced correct data values");
-
-
-
-        // 4. perform reverse transform
-        img3 = psImageFFT(img3,img2,PS_FFT_REVERSE);
-        ok(img3 != NULL, "psImageFFT() returned non-NULL");
-        skip_start(img3 == NULL, 1, "Skipping tests because psImageFFT() returned NULL");
-        ok(img3->type.type == PS_TYPE_C32, "FFT produced complex values");
-
-        ok(img3->numCols == m && img3->numRows == n, "FFT didt produce proper size result (%dx%d vs. expected %dx%d).",
-           img3->numCols,img3->numRows,m,n);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-        errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psC32* img3Row = img3->data.C32[row];
-            psF32* imgRow = img->data.F32[row];
-            for (psU32 col=0;col<m;col++) {
-                psF32 pixel = creal(img3Row[col])/m/n;
-                if (fabsf(pixel-imgRow[col]) > 0.1) {
-                    diag("Reverse FFT gave original image back (%d,%d %.2f vs %.2f)",
-                         col,row,pixel,imgRow[col]);
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "FFT produced correct data values");
-        ok(!errorFlag, "FFT produced correct data values");
-
-
-
-        // 4. perform reverse transform to real result
-        img3 = psImageFFT(img3,img2,PS_FFT_REVERSE|PS_FFT_REAL_RESULT);
-        ok(img3 != NULL, "psImageFFT() returned non-NULL");
-        skip_start(img3 == NULL, 1, "Skipping tests because psImageFFT() returned NULL");
-        ok(img3->type.type == PS_TYPE_F32, "FFT asked to make real result");
-        ok(img3->numCols == m && img3->numRows == n, "FFT produced proper size result (%dx%d vs. expected %dx%d).",
-           img3->numCols,img3->numRows,m,n);
-
-        errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psF32* img3Row = img3->data.F32[row];
-            psF32* imgRow = img->data.F32[row];
-            for (psU32 col=0;col<m;col++) {
-                psF32 pixel = img3Row[col]/m/n;
-                if (fabsf(pixel-imgRow[col]) > 0.1) {
-                    diag("Reverse FFT gave original image back (%d,%d %.2f vs %.2f)",
-                         col,row,pixel,imgRow[col]);
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "FFT produced correct data values");
-        ok(!errorFlag, "FFT produced correct data values");
-
-
-
-        // check if error occurs if FORWARD and REVERSE are both given.
-        // Following should be an error
-        // XXX: werify error
-        ok(psImageFFT(NULL,img2,PS_FFT_REVERSE|PS_FFT_FORWARD) == NULL,
-           "PS_FFT_REVERSE|PS_FFT_FORWARD returned NULL");
-
-        // Following should be an error
-        // XXX: werify error
-        ok(psImageFFT(NULL,img2,PS_FFT_FORWARD|PS_FFT_REAL_RESULT) == NULL,
-           "PS_FFT_FORWARD|PS_FFT_REAL_RESULT returned NULL");
-
-        // Verify return null and program execution doesn't stop if input image is null
-        img4 = psImageFFT(NULL,NULL,PS_FFT_FORWARD);
-        ok(img4 == NULL, "psImageFFT should return null for a null input image");
-
-        // Verify return null and program execution doesn't stop if input image is incorrect direction
-        // Following should generate error for incorrect direction
-        // XXX: werify error
-        GENIMAGE(img4,8,8,S8,row+col);
-        img5 = psImageFFT(NULL,img4,PS_FFT_REAL_RESULT);
-        ok(img5 == NULL, "psImageFFT should return null for an incorrect FFT direction");
-
-        psFree(img4);
-        psFree(img);
-        psFree(img2);
-        psFree(img3);
-        skip_end();
-        skip_end();
-        skip_end();
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *in = psImageAlloc(512, 512, PS_TYPE_F32);
+        bool rc = psImageForwardFFT(NULL, &imag, in);
+        ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL real image input");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-    // 1. create a C64 complex vector with distinctly different real and imaginary parts.
-    // 2. call psImageReal and psImageImaginary
-    // 3. compare results to the real/imaginary components of input
+    // Test with NULL imag arg
     {
         psMemId id = psMemGetId();
-        psImage* c64Img = NULL;
-        psImage* c64Img2 = NULL;
-        psImage* c64Img3 = NULL;
-        psU32 m = 128;
-        psU32 n = 64;
-
-        // XXX: What is I?
-        GENIMAGE(c64Img,m,n,C64, row + I * col);
-        c64Img2 = psImageReal(c64Img2,c64Img);
-        ok(c64Img2 != NULL, "psImageReal() returned non-NULL");
-        ok(c64Img2->type.type == PS_TYPE_F64, "psImageReal() returned the correct type");
-        c64Img3 = psImageImaginary(c64Img3,c64Img);
-        ok(c64Img3 != NULL, "psImageImaginary() returned non-NULL");
-        ok(c64Img3->type.type == PS_TYPE_F64, "psImageImaginary() returned the correct type");
-
-        bool errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psF64* img2Row = c64Img2->data.F64[row];
-            psF64* img3Row = c64Img3->data.F64[row];
-            for (psU32 col=0;col<m;col++) {
-                if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
-                    diag("psImageReal didn't return the real portion at n=%d", n);
-                    errorFlag = true;
-                }
-                if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
-                    diag("psImageImaginary didn't return the imag portion at n=%d", n);
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "psImageReal() and psImageImaginary() returned the correct data");
-        psFree(c64Img);
-        psFree(c64Img2);
-        psFree(c64Img3);
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *in = psImageAlloc(512, 512, PS_TYPE_F32);
+        bool rc = psImageForwardFFT(&real, NULL, in);
+        ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL imaginary image input");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-
-
+    // Test with NULL input arg
     {
         psMemId id = psMemGetId();
-        psImage* ncImg = NULL;
-        psImage* ncImg2 = NULL;
-        psImage* ncImg3 = NULL;
-        psU32 m = 128;
-        psU32 n = 64;
-
-        GENIMAGE(ncImg,m,n,F32,row+col);
-        ncImg2 = psImageReal(ncImg2,ncImg);
-        ncImg3 = psImageImaginary(ncImg3,ncImg);
-        ok(ncImg2 != NULL, "psImageReal() returned non-NULL");
-        ok(ncImg2->type.type == PS_TYPE_F32, "psImageReal() returned the correct type");
-        ok(ncImg3 != NULL, "psImageImaginary() returned non-NULL");
-        ok(ncImg3->type.type == PS_TYPE_F32, "psImageImaginary() returned the correct type");
-
-        bool errorFlag = false;
-        for(psU32 row=0; row<n; row++)
-        {
-            psF32* ncImg2Row = ncImg2->data.F32[row];
-            psF32* ncImg3Row = ncImg3->data.F32[row];
-            for(psU32 col=0; col<m; col++) {
-                if(fabsf(ncImg2Row[col] - (row+col)) > FLT_EPSILON) {
-                    diag("psImageReal didn't return the real portion");
-                    errorFlag = true;
-                }
-                if(fabsf(ncImg3Row[col] - 0) > FLT_EPSILON) {
-                    diag("psImageImaginary didn't return the imaginary portion");
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "psImageReal() and psImageImaginary() returned the correct data");
-        psFree(ncImg);
-        psFree(ncImg2);
-        psFree(ncImg3);
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *in = psImageAlloc(512, 512, PS_TYPE_F32);
+        bool rc = psImageForwardFFT(&real, &imag, NULL);
+        ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL real image input");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-
-
-    // Perform psImageReal with null input
+    // Test with incorrect input image type
     {
         psMemId id = psMemGetId();
-        ok(psImageReal(NULL,NULL) == NULL, "psImageReal() returned NULL with NULL inputs");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
+        psImage *in = psImageAlloc(512, 512, PS_TYPE_F64);
+        bool rc = psImageForwardFFT(NULL, &imag, in);
+        ok(rc == false, "psImageForwardFFT() returned FALSE with incorrect input image type");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-
-    // Perform psImageImaginary with null input
-    {
-        psMemId id = psMemGetId();
-        ok(psImageImaginary(NULL,NULL) == NULL, "psImageImaginary() returned NULL with NULL inputs");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
-    }
-
-
-    // testImageComplex()
-    // 1. create two unique psF32 vectors of the same size
-    // 2. call psImageComplex
-    // 3. verify that the result is a psC32
-    // 4. use crealf and cimagf on step 2 results
-    // 5. compare step 4 results to input.
-    // 6. create a psF32 and a psF64 vector of the same size
-    // 7. call psImageComplex
-    // 8. verify that an appropriate error occurred.
-    // 9. create two psf32 vectors of different sizes
-    // 10. call psImageComplex
-    // 11. verify thet an appropriate error occurred.
-    {
-        psMemId id = psMemGetId();
-        psImage* img = NULL;
-        psImage* img2 = NULL;
-        psImage* img3 = NULL;
-        psImage* c64Img = NULL;
-        psImage* c64Img2 = NULL;
-        psImage* c64Img3 = NULL;
-        psImage* pImg = NULL;
-        psImage* pImg2 = NULL;
-        psImage* pImg3 = NULL;
-        psU32 m = 128;
-        psU32 n = 64;
-        GENIMAGE(img,m,n,F32,row);
-        GENIMAGE(img2,m,n,F32,col);
-        GENIMAGE(c64Img,m,n,F64,row);
-        GENIMAGE(c64Img2,m,n,F64,col);
-        GENIMAGE(pImg,m,n,S16,row);
-        GENIMAGE(pImg2,m,n,S16,col);
-        img3 = psImageComplex(img3,img,img2);
-        ok(img3 != NULL, "psImageComplex() returned non-NULL");
-        ok(img3->type.type == PS_TYPE_C32, "psImageComplex() returned the correct type");
-        c64Img3 = psImageComplex(c64Img3,c64Img,c64Img2);
-        ok(c64Img3 != NULL, "psImageComplex() returned non-NULL");
-        ok(c64Img3->type.type == PS_TYPE_C64, "psImageComplex() returned the correct type");
-        bool errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psC32* img3Row = img3->data.C32[row];
-            psC64* c64Img3Row = c64Img3->data.C64[row];
-            for (psU32 col=0;col<m;col++) {
-                if (fabsf(crealf(img3Row[col]) - row) > FLT_EPSILON ||
-                        fabsf(cimagf(img3Row[col]) - col) > FLT_EPSILON) {
-                    diag("psImageComplex result is incorrect (%d,%d, %.2f+%.2fi)",
-                         col,row,crealf(img3Row[col]),cimagf(img3Row[col]));
-                    errorFlag = true;
-                }
-                if (fabsf(crealf(c64Img3Row[col]) - row) > FLT_EPSILON ||
-                        fabsf(cimagf(c64Img3Row[col]) - col) > FLT_EPSILON) {
-                    diag("psImageComplex result is incorrect");
-                    errorFlag = true;
-
-                }
-            }
-        }
-        ok(!errorFlag, "psImageComplex() returned correct results");
-
-        img2 = psImageRecycle(img2,m,n,PS_TYPE_F64);
-
-        // Following should be an error (type mismatch)
-        // Verify that an appropriate error occurred
-        img3 = psImageComplex(img3,img,img2);
-        ok(img3 == NULL, "psImageComplex() returned NULL when input types mismatched.");
-
-        // Following should be an error (size mismatch)
-        img2 = psImageRecycle(img2,m/2,n,PS_TYPE_F32);
-        img3 = psImageComplex(img3,img,img2);
-        ok(img3 == NULL, "psImageComplex() returned a NULL when input sizes mismatched");
-
-        // Perform psImageComplex with incorrect type
-        // Following should generate an error message.");
-        pImg3 = psImageComplex(pImg3,pImg,pImg2);
-        ok(pImg3 == NULL, "psImageComplex returned NULL with incorrect type input");
-
-        psFree(img);
-        psFree(img2);
-        psFree(img3);
-        psFree(c64Img);
-        psFree(c64Img2);
-        psFree(c64Img3);
-        psFree(pImg);
-        psFree(pImg2);
-
-        // Perform psImageComplex with null input
-        ok(psImageComplex(NULL,NULL,NULL) == NULL, "psImageComplex() returned NULL with null input");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
-    }
-
-    // 1. create a psC32 with unique real and imaginary values.
-    // 2. call psImageConjugate
-    // 3. verify result is psC32
-    // 4. verify each value is conjugate of input (a+bi -> a-bi)
-    // testImageConjugate()
-    {
-        psMemId id = psMemGetId();
-        psImage* img = NULL;
-        psImage* img2 = NULL;
-        psImage* c64Img = NULL;
-        psImage* c64Img2 = NULL;
-        psImage* pImg = NULL;
-        psImage* pImg2 = NULL;
-        psU32 m = 128;
-        psU32 n = 64;
-        GENIMAGE(img,m,n,C32, row + I * col);
-        GENIMAGE(c64Img,m,n,C64,row + I*col);
-        GENIMAGE(pImg,m,n,F32,row+col);
-
-
-        img2 = psImageConjugate(img2,img);
-        ok(img2 != NULL, "psImageConjugate() returned non-NULL");
-        c64Img2 = psImageConjugate(c64Img2,c64Img);
-        ok(c64Img2 != NULL, "psImageConjugate() returned non-NULL");
-        pImg2 = psImageConjugate(pImg2,pImg);
-        ok(pImg2 != NULL, "psImageConjugate() returned non-NULL");
-
-        ok(img2->type.type == PS_TYPE_C32, "psImageConjugate() returned the correct type");
-        ok(c64Img2->type.type == PS_TYPE_C64, "psImageConjugate() returned the correct type");
-        ok(pImg2->type.type == PS_TYPE_F32, "psImageConjugate() returned the correct type");
-
-        bool errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psC32* img2Row = img2->data.C32[row];
-            psC64* c64Img2Row = c64Img2->data.C64[row];
-            psF32* pImg2Row = pImg2->data.F32[row];
-            for (psU32 col=0;col<m;col++) {
-                if (fabsf(crealf(img2Row[col]) - row) > FLT_EPSILON ||
-                        fabsf(cimagf(img2Row[col]) + col) > FLT_EPSILON) {
-                    diag("psImageComplex result is incorrect (%d,%d, %.2f+%.2fi)",
-                         col,row,crealf(img2Row[col]),cimagf(img2Row[col]));
-                    errorFlag = true;
-                }
-                if (fabsf(crealf(c64Img2Row[col]) - row) > FLT_EPSILON ||
-                        fabsf(cimagf(c64Img2Row[col]) + col) > FLT_EPSILON) {
-                    diag("psImageComplex result is incorrect");
-                    errorFlag = true;
-                }
-                if (fabsf(pImg2Row[col] - (row+col)) > FLT_EPSILON) {
-                    diag("psImageComplex result is incorrect");
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "psImageConjugate() generated the correct data values");
-        psFree(img);
-        psFree(img2);
-        psFree(c64Img);
-        psFree(c64Img2);
-        psFree(pImg);
-        psFree(pImg2);
-
-        // Perform psImageConjugate with null input
-        ok(psImageConjugate(NULL,NULL) == NULL, "psImageConjugate() returned NULL with NULL input");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
-    }
-
-    // testImagePowerSpectrum()
-    // 1. create a psC32 vector with unique real and imaginary components
-    // 2. call psImagePowerSpectrum
-    // 3. verify result is psF32
-    // 4. verify the values are the square of the absolute values of the original
-    {
-        psMemId id = psMemGetId();
-        psImage* img = NULL;
-        psImage* img2 = NULL;
-        psImage* c64Img = NULL;
-        psImage* c64Img2 = NULL;
-        psImage* pImg = NULL;
-        psU32 m = 128;
-        psU32 n = 64;
-
-        GENIMAGE(img,m,n,C32, row + I * col);
-        GENIMAGE(c64Img,m,n,C64,row+I*col);
-        GENIMAGE(pImg,m,n,F32,row+col);
-
-        img2 = psImagePowerSpectrum(img2,img);
-        c64Img2 = psImagePowerSpectrum(c64Img2, c64Img);
-        ok(img2 != NULL, "psImagePowerSpectrum() returned non-NULL");
-        ok(c64Img2 != NULL, "psImagePowerSpectrum() returned non-NULL");
-        ok(img2->type.type == PS_TYPE_F32, "psImagePowerSpectrum() returned the correct type");
-        ok(c64Img2->type.type == PS_TYPE_F64, "psImagePowerSpectrum() returned the correct type");
-
-        bool errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psC32* imgRow = img->data.C32[row];
-            psF32* img2Row = img2->data.F32[row];
-            psC64* c64ImgRow = c64Img->data.C64[row];
-            psF64* c64Img2Row = c64Img2->data.F64[row];
-            for (psU32 col=0;col<m;col++) {
-                psF32 power = cabs(imgRow[col]);
-                psF64 power64 = cabs(c64ImgRow[col]);
-                power *= power/n/n/m/m;
-                power64 *= power64/n/n/m/m;
-
-                if (fabsf(img2Row[col] - power) > 2.0f*FLT_EPSILON) {
-                    diag("psImagePowerSpectrum result is incorrect (%d,%d, %.2f vs %.2f)",
-                         col,row,img2Row[col],power);
-                    errorFlag = true;
-                }
-                if (fabsf(c64Img2Row[col] - power64) > 2.0f*FLT_EPSILON) {
-                    diag("psImagePowerSpectrum result is incorrect");
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "psImagePowerSPectrum() generated the correct data values");
-        psFree(img);
-        psFree(img2);
-        psFree(c64Img);
-        psFree(c64Img2);
-
-        // Perform psImagePowerSpectrum with incorrect input
-        // Following should generate error message
-        // XXX: Verify error
-        ok(psImagePowerSpectrum(NULL,pImg) == NULL, "psImagePowerSpectrum() returned NULL with incorrect type");
-        psFree(pImg);
-
-        // Perform psImagePowerSpectrum with NULL input
-        ok(psImagePowerSpectrum(NULL,NULL) == NULL, "psImagePowerSpectrum() returned NULL with NULL input");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
-    }
-
-
-    // testImageRealImaginary()
-    // 1. create a C32 complex image with distinctly different real and imaginary parts
-    // 2. call psImageReal and psImageImaginary
-    // 3. compare results to the real/imaginary components of input
-    // XXX: If we put this block above the previous 2 blocks, then we get memory errors
-    {
-        psMemId id = psMemGetId();
-        psImage* img = NULL;
-        psImage* img3 = NULL;
-        psU32 m = 128;
-        psU32 n = 64;
-        GENIMAGE(img,m,n,C32, row + I * col);
-        psImage* img2 = psImageReal(NULL,img);
-        ok(img2 != NULL, "psImageReal returned non-NULL");
-        skip_start(img2 == NULL, 4, "Skipping tests because psImageReal() returned NULL");
-        ok(img2->type.type == PS_TYPE_F32, "psImageReal returned the correct type");
-        img3 = psImageImaginary(img3,img);
-        ok(img3 != NULL, "psImageImaginary() returned non-NULL");
-        skip_start(img3 == NULL, 2, "Skipping tests because psImageImaginary() returned NULL");
-        ok(img3->type.type == PS_TYPE_F32, "psImageImaginary() returned the correct type");
-
-        bool errorFlag = false;
-        for (psU32 row=0;row<n;row++)
-        {
-            psF32* img2Row = img2->data.F32[row];
-            psF32* img3Row = img3->data.F32[row];
-            for (psU32 col=0;col<m;col++) {
-                if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
-                    diag("psImageReal didn't return the real portion at n=%d", n);
-                    errorFlag = true;
-                }
-                if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
-                    diag("psImageImaginary didn't return the imag portion at n=%d", n);
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "psImageReal(), psImageImaginary() returned the correct data");
-        skip_end();
-        skip_end();
-        psFree(img);
-        psFree(img2);
-        psFree(img3);
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
-    }
-
-
+    testFFT(10, 10);                    // Real quick test
+    testFFT(10, 20);                    // Testing differing numCols, numRows
+    testFFT(20, 10);                    // Testing differing numCols, numRows
+    testFFT(611, 610);                  // Test something like an OTA cell
+    testFFT(2048, 4096);                // Test something like a megacam chip
 }
Index: /trunk/psLib/test/fft/tap_psVectorFFT.c
===================================================================
--- /trunk/psLib/test/fft/tap_psVectorFFT.c	(revision 12153)
+++ /trunk/psLib/test/fft/tap_psVectorFFT.c	(revision 12154)
@@ -1,502 +1,124 @@
-/** @file  tst_psVectorFFT.c
-*
-*  @brief Contains the tests for psFFT.[ch]
-*
-*
-*  @author Robert DeSonia, MHPCC
-*
-*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2007-02-08 01:37:33 $
-*
-* XXX: Must add skip_start() macros
-*
-*
-*
-*
-*
-*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
-*/
 #include <stdio.h>
-#include <string.h>
+#include <math.h>
 #include <pslib.h>
+
 #include "tap.h"
 #include "pstap.h"
 
-#define GENIMAGE(img,c,r,TYP, valueFcn) \
-img = psImageAlloc(c,r,PS_TYPE_##TYP); \
-for (psU32 row=0;row<r;row++) { \
-    ps##TYP* imgRow = img->data.TYP[row]; \
-    for (psU32 col=0;col<c;col++) { \
-        imgRow[col] = (ps##TYP)(valueFcn); \
-    } \
+#define TOL 2.5e-5                      // Tolerance for comparison
+
+
+// Generate image with single high pixel
+static psVector *generateVector(long num)
+{
+    psVector *vector = psVectorAlloc(num, PS_TYPE_F32);
+    for (long i = 0; i < num; i++) {
+        vector->data.F32[i] = 1.2 * cos(2.0 * M_PI * i / num + M_PI / 4.0) +
+            3.4 * sin(0.5 * 2.0 * M_PI * i / num + M_PI);
+    }
+    return vector;
 }
 
-psS32 main( psS32 argc, char* argv[] )
+// FFT forward, then back --- do I get what I started with?
+// A total of 6 tests here.
+static void testFFT(long num)
 {
-    psLogSetFormat("HLNM");
-    psLogSetLevel(PS_LOG_INFO);
-    plan_tests(58);
+    psMemId id = psMemGetId();
 
-    // testVectorFFT()
-    // 1. assign a vector to a sinisoid
-    // 2. perform forward transform
-    //  3. verify that the only significant component cooresponds to the freqency of the input in step 1.
-    //  4. perform reverse transform
-    //  5. compare to original (should be equal to within a reasonable error)
+    diag("Testing %d", num);
+    psVector *old = generateVector(num);
+    psVector *fftReal = NULL, *fftImag = NULL;
+    bool result = psVectorForwardFFT(&fftReal, &fftImag, old);
+    ok(result, "forward fft result");
+    skip_start(!result || !fftReal || !fftImag, 3, "forward fft failed");
+    ok(fftReal->type.type == PS_TYPE_F32 && fftImag->type.type == PS_TYPE_F32, "forward fft types");
+    psVector *new = NULL;
+    result = psVectorBackwardFFT(&new, fftReal, fftImag, old->n);
+    ok(result, "backward fft result");
+    skip_start(!result || !new, 2, "backward fft failed");
+    ok(new->type.type == PS_TYPE_F32, "backward fft type");
+    float maxDev = 0.0;                 // Maximum deviation from expected
+    for (long i = 0; i < old->n; i++) {
+        float dev = fabs(new->data.F32[i] / num - old->data.F32[i]);
+        if (dev > maxDev) {
+            maxDev = dev;
+        }
+    }
+    ok(maxDev < TOL, "maximum deviation: %f", maxDev);
+    psFree(new);
+    skip_end();
+    skip_end();
+
+    psFree(fftReal);
+    psFree(fftImag);
+    psFree(old);
+    ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
+
+    return;
+}
+
+
+int main(int argc, char *argv[])
+{
+    plan_tests(8 + 6 * 3);
+
+    // Test with NULL real arg
     {
         psMemId id = psMemGetId();
-        psVector *vec = NULL;
-        psVector* vec2 = NULL;
-        psVector* vec3 = NULL;
-        psVector* vec4 = NULL;
-
-        vec = psVectorAlloc(100, PS_TYPE_F32);
-        vec->n = vec->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec->data.F32[ n ] = sinf( ( psF32 ) n / 50.0f * M_PI );
-        }
-
-        vec2 = psVectorFFT(NULL, vec, PS_FFT_FORWARD);
-        ok(vec2 != NULL, "psVectorFFT() returned non-NULL");
-        ok(vec2->type.type == PS_TYPE_C32, "psVectorFFT() returned the correct type");
-        ok(vec2->n == vec->n, "psVectorFFT() returned the correct size vector");
-
-        bool errorFlag = false;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            if ( n == 1 || n == 99 ) {
-                if ( fabsf( cabsf( vec2->data.C32[ n ] ) - 50.0f ) > 0.1f ) {
-                    diag("FFT didn't work for vector (n=%d)", n );
-                    errorFlag = true;
-                }
-            } else {
-                if ( fabsf( cabsf( vec2->data.C32[ n ] ) ) > 0.1f ) {
-                    diag("FFT didn't work for vector (n=%d)", n );
-                    errorFlag = true;
-                }
-            }
-        }
-        ok(!errorFlag, "psVectorFFT() returned the correct data values");
-
-        vec3 = psVectorFFT( NULL, vec2, PS_FFT_REVERSE );
-        ok(vec3 != NULL, "psVectorFFT() returned non-NULL");
-        ok(vec3->type.type == PS_TYPE_C32, "psVectorFFT() returned the correct type");
-        ok(vec3->n == vec2->n, "psVectorFFT() returned the correct size vectors");
-
-        errorFlag = false;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            psF32 val = sinf( ( psF32 ) n / 50.0f * M_PI );
-            psF32 vecVal = crealf( vec3->data.C32[ n ] ) / 100;
-            if ( fabsf( vecVal - val ) > 0.1f ) {
-                diag("Reverse FFT didn't give me the original vector back (n=%d) (%.2f vs %.2f)",
-                     n, vecVal, val );
-                errorFlag = true;
-            }
-        }
-        ok(!errorFlag, "psVectorFFT() returned the correct data values");
-
-        // Perform reverse transform with real flag set
-        vec4 = psVectorFFT(NULL,vec2, (PS_FFT_REVERSE | PS_FFT_REAL_RESULT));
-        ok(vec4->type.type == PS_TYPE_F32, "FFT with real result did produce real values");
-
-        // Perform vector FFT with incorrect direction flags
-        // Following should generate an error message
-        // XXX: Verify error
-        ok(psVectorFFT(NULL,vec2,(psFFTFlags)0) == NULL, "psVectorFFT() returned NULL with incorrect direction");
-        psFree(vec);
-        psFree(vec2);
-        psFree(vec3);
-        psFree(vec4);
-
-        // Perform vector FFT with null input
-        ok(psVectorFFT(NULL,NULL,PS_FFT_FORWARD) == NULL, "psVectorFFT() returned NULL with null input vector");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
+        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
+        psVector *in = psVectorAlloc(512, PS_TYPE_F32);
+        bool rc = psVectorForwardFFT(NULL, &imag, in);
+        ok(rc == false, "psVectorForwardFFT() returned FALSE with a null real vector input");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-
-    // testVectorRealImaginary()
-    // 1. create a C32 complex vector with distinctly different real and imaginary parts.
-    // 2. call psVectorReal and psVectorImaginary
-    // 3. compare results to the real/imaginary components of input
+    // Test with NULL imag arg
     {
         psMemId id = psMemGetId();
-        psVector * vec = NULL;
-        psVector* vec2 = NULL;
-        psVector* vec3 = NULL;
-        psVector* vec4 = NULL;
-        psVector* vec5 = NULL;
-        psVector* vec6 = NULL;
-        psVector* vec7 = NULL;
-        psVector* vec8 = NULL;
-        psVector* vec9 = NULL;
-        psVector* vec10 = NULL;
-        psVector* vec11 = NULL;
-
-        vec = psVectorAlloc( 100, PS_TYPE_C32 );
-        vec8 = psVectorAlloc( 100, PS_TYPE_C64 );
-        vec10 = psVectorAlloc( 100, PS_TYPE_C64 );
-        vec->n = vec->nalloc;
-        vec8->n = vec8->nalloc;
-        vec10->n = vec10->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec->data.C32[ n ] = n + I * ( n * 2 );
-            vec8->data.C64[n] = n + I * ( n * 2 );
-            vec10->data.C64[n] = n + I * ( n * 2 );
-        }
-        vec4 = psVectorAlloc( 100, PS_TYPE_F32);
-        vec4->n = vec4->nalloc;
-        vec6 = psVectorAlloc( 100, PS_TYPE_F32);
-        vec6->n = vec6->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec4->data.F32[n] = n;
-            vec6->data.F32[n] = n;
-        }
-
-        vec2 = psVectorReal( vec2, vec );
-        ok(vec2 != NULL, "psVectorReal() returned non-NULL");
-        ok(vec2->type.type == PS_TYPE_F32, "psVectorReal() returned the correct type");
-
-        // Following should generate a warning
-        // XXX: Verify warning
-        vec5 = psVectorReal(vec5, vec4);
-        ok(vec5 != NULL, "psVectorReal() returned non-NULL");
-        ok(vec5->type.type == PS_TYPE_F32, "psVectorReal() returned the correct type");
-
-        vec9 = psVectorReal(vec9,vec8);
-        ok(vec9 != NULL, "psVectorReal() returned non-NULL");
-        ok(vec9->type.type == PS_TYPE_F64, "psVectorReal() returned the correct type");
-
-        // Following should generate a warning
-        // XXX: Verify warning
-        vec3 = psVectorImaginary( vec3, vec );
-        ok(vec3 != NULL, "psVectorImaginary() returned non-NULL");
-        ok(vec3->type.type == PS_TYPE_F32, "psVectorImaginary() returned the correct type");
-
-        vec7 = psVectorImaginary(vec7, vec6);
-        ok(vec7 != NULL, "psVectorImaginary() returned non-NULL");
-        ok(vec7->type.type == PS_TYPE_F32, "psVectorImaginary() returned the correct type");
-
-        vec11 = psVectorImaginary(vec11, vec10);
-        ok(vec11 != NULL, "psVectorImaginary() returned non-NULL");
-        ok(vec11->type.type == PS_TYPE_F64, "psVectorImaginary() returned the correct type");
-
-
-        // 3. compare results to the real/imaginary components of input
-        bool errorFlag = false;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            psF32 r = n;
-            psF32 i = ( n * 2 );
-            psF64 rr = n;
-            psF64 ii = ( n * 2 );
-            if ( fabsf( vec2->data.F32[ n ] - r ) > FLT_EPSILON ) {
-                diag("psVectorReal didn't return the real portion at n=%d", n);
-                errorFlag = true;
-            }
-            if ( fabsf( vec3->data.F32[ n ] - i ) > FLT_EPSILON ) {
-                diag("psVectorImaginary didn't return the real portion at n=%d", n);
-                errorFlag = true;
-            }
-            if ( fabsf( vec5->data.F32[n] - r) > FLT_EPSILON) {
-                diag("psVectorReal didn't return the real portion at n=%d",n);
-                errorFlag = true;
-            }
-            if ( fabsf( vec7->data.F32[n] - 0) > FLT_EPSILON) {
-                diag("psVectorImaginary did not return the imaginary portion at n=%d",n);
-                errorFlag = true;
-            }
-            if ( fabsf(vec9->data.F64[n] - rr) > FLT_EPSILON ) {
-                diag("psVectorReal did not return the real portion at n=%d",n);
-                errorFlag = true;
-            }
-            if ( fabsf(vec11->data.F64[n] - ii) > FLT_EPSILON) {
-                diag("psVectorImaginary did not return the imaginary portion at n=%d",n);
-                errorFlag = true;
-            }
-        }
-        ok(!errorFlag, "psVectorImaginary() returned the correct data values");
-
-        psFree( vec );
-        psFree( vec2 );
-        psFree( vec3 );
-        psFree( vec4 );
-        psFree( vec5 );
-        psFree( vec6 );
-        psFree( vec7 );
-        psFree( vec8 );
-        psFree( vec9 );
-        psFree( vec10 );
-        psFree( vec11 );
-
-        // Perform vector Real with null input
-        ok(psVectorReal(NULL,NULL) == NULL, "psVectorReal returned NULL with NULL input");
-        ok(psVectorImaginary(NULL,NULL) == NULL, "psVectorImaginary returned NULL with NULL input");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
+        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
+        psVector *in = psVectorAlloc(512, PS_TYPE_F32);
+        bool rc = psVectorForwardFFT(&real, NULL, in);
+        ok(rc == false, "psVectorForwardFFT() returned FALSE with a null imag vector input");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-
-    // testVectorComplex()
-    // 1. create two unique psF32 vectors of the same size
-    // 2. call psVectorComplex
-    // 3. verify that the result is a psC32
-    // 4. call psVectorReal and psVectorImaginary on step 2 results
-    // 5. compare step 4 results to input.
-    // 6. create a psF32 and a psF64 vector of the same size
-    // 7. call psVectorComplex
-    // 8. verify that an appropriate error occurred.
-    // 9. create two psf32 vectors of different sizes
-    // 10. call psVectorComplex
-    // 11. verify thet an appropriate error occurred.
+    // Test with NULL input arg
     {
         psMemId id = psMemGetId();
-        psVector * vec = NULL;
-        psVector* vec2 = NULL;
-        psVector* vec3 = NULL;
-        psVector* vec4 = NULL;
-        psVector* vec5 = NULL;
-        psVector* vec6 = NULL;
-
-        // 1. create two unique psF32 vectors of the same size
-        vec = psVectorAlloc( 100, PS_TYPE_F32 );
-        vec2 = psVectorAlloc( 100, PS_TYPE_F32 );
-        vec4 = psVectorAlloc( 100, PS_TYPE_F64 );
-        vec5 = psVectorAlloc( 100, PS_TYPE_F64 );
-        vec->n = vec->nalloc;
-        vec2->n = vec2->nalloc;
-        vec4->n = vec4->nalloc;
-        vec5->n = vec5->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec->data.F32[ n ] = n;
-            vec2->data.F32[ n ] = ( n * 2 );
-            vec4->data.F64[ n ] = n;
-            vec5->data.F64[ n ] = ( n * 2 );
-        }
-
-        vec3 = psVectorComplex( vec3, vec, vec2 );
-        ok(vec3 != NULL, "psVectorComplex() returned non-NULL");
-        ok(vec3->type.type == PS_TYPE_C32, "psVectorComplex() returned the correct type");
-        bool errorFlag = false;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            if ( fabsf( crealf( vec3->data.C32[ n ] ) - n ) > FLT_EPSILON ||
-                    fabsf( cimagf( vec3->data.C32[ n ] ) - ( n * 2 ) ) > FLT_EPSILON ) {
-                diag("psVectorComplex result is incorrect (n=%d, %.2f+%.2fi)",
-                     n, crealf( vec3->data.C32[ n ] ), cimagf( vec3->data.C32[ n ] ) );
-                errorFlag = true;
-            };
-        }
-        ok(!errorFlag, "psVectorComplex() returned the correct data values");
-
-
-        vec2 = psVectorRecycle( vec2, 100, PS_TYPE_F64 );
-        // Following should be an error (type mismatch)
-        // Verify error
-        vec3 = psVectorComplex( vec3, vec, vec2 );
-        ok(vec3 == NULL, "psVectorComplex() returned NULL when input types mismatched." );
-
-        vec2 = psVectorRecycle( vec2, 200, PS_TYPE_F32 );
-        vec3 = psVectorComplex( vec3, vec, vec2 );
-        ok(vec3->n == 100, "psVectorComplex() returned the correct size vector");
-
-        // Verify the function works with psF64 type
-        vec6 = psVectorComplex(vec6, vec4, vec5);
-        ok(vec6->type.type == PS_TYPE_C64, "psVectorComplex() returned the correct type (C64)");
-
-        // Verify error message generated with input of incorrect type
-        // Following should generate an error message
-        vec4->type.type = PS_TYPE_S8;
-        vec5->type.type = PS_TYPE_S8;
-        vec6 = psVectorComplex(vec6, vec4, vec5);
-        ok(vec6 == NULL, "psVectorComplex() returned NULL for incorrect type");
-        vec4->type.type = PS_TYPE_F64;
-        vec5->type.type = PS_TYPE_F64;
-        psFree(vec);
-        psFree(vec2);
-        psFree(vec3);
-        psFree(vec4);
-        psFree(vec5);
-
-        // Perform vector complex with null input
-        ok(psVectorComplex(NULL,NULL,NULL) == NULL, "psVectorComplex() returned NULL with null input vector");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
+        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
+        psVector *in = psVectorAlloc(512, PS_TYPE_F32);
+        bool rc = psVectorForwardFFT(&real, &imag, NULL);
+        ok(rc == false, "psVectorForwardFFT() returned FALSE with a null input vector input");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-
-    // testVectorConjugate()
-    // 1. create a psC32 with unique real and imaginary values.
-    // 2. call psVectorConjugate
-    // 3. verify result is psC32
-    // 4. verify each value is conjugate of input (a+bi -> a-bi)
+    // Test with incorrect type for input arg
     {
         psMemId id = psMemGetId();
-        psVector * vec = NULL;
-        psVector* vec2 = NULL;
-
-        vec = psVectorAlloc( 100, PS_TYPE_C32 );
-        vec->n = vec->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec->data.C32[ n ] = n + I * ( n * 2 );
-        }
-
-        vec2 = psVectorConjugate(vec2, vec);
-        ok(vec2 != NULL, "psVectorConjugate() returned non-NULL");
-        ok(vec2->type.type == PS_TYPE_C32, "psVectorConjugate() returned the correct type");
-
-        bool errorFlag = false;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            if ( fabsf( crealf( vec->data.C32[ n ] ) - crealf( vec2->data.C32[ n ] ) ) > FLT_EPSILON ||
-                    fabsf( cimagf( vec->data.C32[ n ] ) + cimagf( vec2->data.C32[ n ] ) ) > FLT_EPSILON ) {
-                diag("psVectorConjugate result is incorrect (n=%d, %.2f+%.2fi)",
-                     n, crealf( vec2->data.C32[ n ] ), cimagf( vec2->data.C32[ n ] ) );
-                errorFlag = true;
-            };
-        }
-        ok(!errorFlag, "psVectorConjugate() returned the correct data values");
-        psFree(vec);
-
-        // Perform conjugate for non-complex number
-        vec = psVectorAlloc( 100, PS_TYPE_F32 );
-        vec->n = vec->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec->data.F32[ n ] = n;
-        }
-        // Following should generate a warning message
-        // XXX: verify warning
-        vec2 = psVectorConjugate(vec2,vec);
-        ok(vec2->type.type == PS_TYPE_F32, "psVectorConjugate did return a F32 vector");
-
-        errorFlag = false;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            if( vec->data.F32[n] != vec2->data.F32[n] ) {
-                diag("psVectorConjugate result is incorrect (n=%d)",n);
-                errorFlag = true;
-            }
-        }
-        ok(!errorFlag, "psVectorConjugate() returned the correct data values");
-        psFree(vec);
-
-        // Perform vector conjugate with C64 type
-        vec = psVectorAlloc( 100, PS_TYPE_C64 );
-        vec->n = vec->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec->data.C64[n] = n + I * ( n * 2 );
-        }
-        vec2 = psVectorConjugate(vec2,vec);
-        ok(vec2 != NULL, "psVectorConjugate() returned non-NULL");
-        ok(vec2->type.type == PS_TYPE_C64, "psVectorConjugate() returned the correct type");
-        errorFlag = false;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            if ( fabsf( crealf(vec->data.C64[n]) - crealf(vec2->data.C64[n])) > FLT_EPSILON ||
-                    fabsf( cimagf(vec->data.C64[n]) + cimagf(vec2->data.C64[n])) > FLT_EPSILON ) {
-                diag("psVectorConjugate result is incorrect (n=%d)",n);
-                errorFlag = true;
-            }
-        }
-        ok(!errorFlag, "psVectorConjugate() returned the correct data values");
-        psFree(vec);
-
-        // Perform vector conjugate with null input (vec2 should be freed too)
-        ok(psVectorConjugate(vec2,NULL) == NULL, "psVectorConjugate() returned NULL with null input vector");
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
+        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
+        psVector *in = psVectorAlloc(512, PS_TYPE_F64);
+        bool rc = psVectorForwardFFT(&real, &imag, in);
+        ok(rc == false, "psVectorForwardFFT() returned FALSE with a incorrect input vector type");
+        psFree(real);
+        psFree(imag);
+        psFree(in);
+        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     }
 
-
-    // testVectorPowerSpectrum()
-    // 1. create a psC32 vector with unique real and imaginary components
-    // 2. call psVectorPowerSpectrum
-    // 3. verify result is psF32
-    // 4. verify the values are the square of the absolute values of the original
-    {
-        psMemId id = psMemGetId();
-        psVector * vec = NULL;
-        psVector* vec2 = NULL;
-        psVector* vec3 = NULL;
-        psVector* vec4 = NULL;
-        psF32 val;
-        psF64 val1;
-
-        vec = psVectorAlloc( 100, PS_TYPE_C32 );
-        vec->n = vec->nalloc;
-        vec3 = psVectorAlloc(100,PS_TYPE_C64);
-        vec3->n = vec3->nalloc;
-        for ( psU32 n = 0; n < 100; n++ )
-        {
-            vec->data.C32[ n ] = n + I * sinf( ( ( psF32 ) n ) / 50.f * M_PI );
-            vec3->data.C64[ n ] = n + I * sinf( ( ( psF64 ) n ) / 50.f * M_PI );
-        }
-
-        vec2 = psVectorPowerSpectrum(vec2, vec);
-        ok(vec2 != NULL, "psVectorPowerSpectrum() returned non-NULL");
-        vec4 = psVectorPowerSpectrum(vec4, vec3);
-        ok(vec4 != NULL, "psVectorPowerSpectrum() returned non-NULL");
-        // XXX: These next two tests fail
-        ok(vec2->type.type == PS_TYPE_F32, "psVectorPowerSpectrum() returned the correct type");
-        ok(vec4->type.type == PS_TYPE_F64, "psVectorPowerSpectrum() returned the correct type");
-
-        val = cabsf( vec->data.C32[ 0 ] ) * cabsf( vec->data.C32[ 0 ] ) / 100 / 100;
-        val1= cabsf( vec3->data.C64[0] ) * cabsf(vec3->data.C64[0])/100/100;
-        ok(fabsf(vec2->data.F32[ 0 ] - val ) <= FLT_EPSILON,
-           "psVectorPowerSpectrum result is correct (n=0, %.2f %.2f)",
-           vec2->data.F32[ 0 ], val );
-        ok(fabsf( vec4->data.C64[0] - val1 ) <= FLT_EPSILON,
-           "psVectorPowerSpectrum result is correct (n=0)");
-
-        bool errorFlag = false;
-        for ( psU32 n = 1; n < 50; n++ )
-        {
-            val = ( cabsf( vec->data.C32[ n ] ) * cabsf( vec->data.C32[ n ] ) +
-                    cabsf( vec->data.C32[ 100 - n ] ) * cabsf( vec->data.C32[ 100 - n ] ) ) / 100 / 100;
-            val1 = (cabsf(vec3->data.C64[n]) * cabsf(vec3->data.C64[n]) +
-                    cabsf(vec3->data.C64[100-n]) * cabsf(vec3->data.C64[100-n]))/100/100;
-            if ( fabsf( val - vec2->data.F32[ n ] ) > 10*FLT_EPSILON ) {
-                diag("psVectorPowerSpectrum result is incorrect (n=%d, %.2f %.2f)",
-                     n, vec2->data.F32[ n ], val );
-                errorFlag = true;
-            }
-            if (fabsf(val1 - vec4->data.F64[n]) > 10*FLT_EPSILON) {
-                diag("psVectorPowerSpectrum result is incorrect (n=%d, %.2f %.2f)",n,vec4->data.F64[n],val1);
-                errorFlag = true;
-            }
-        }
-        ok(!errorFlag, "psVectorPowerSpectrum() returned the correct data values");
-
-        val = cabsf( vec->data.C32[ 50 ] ) * cabsf( vec->data.C32[ 50 ] ) / 100 / 100;
-        ok(fabsf( vec2->data.F32[ 50 ] - val ) <= 10*FLT_EPSILON,
-           "psVectorPowerSpectrum result is correct (n=50, %.2f %.2f)",
-           vec2->data.F32[ 0 ], val );
-        psFree( vec );
-        psFree( vec2 );
-        psFree( vec3 );
-        psFree( vec4 );
-
-        // Perform vector power spectrum with non-complex number
-        vec = psVectorAlloc(100,PS_TYPE_F32);
-        vec->n = vec->nalloc;
-        for( psU32 n=0; n<100; n++)
-        {
-            vec->data.F32[n] = n;
-        }
-
-        // Following should generate an error message
-        // XXX: Verify error
-        ok(psVectorPowerSpectrum(NULL,vec) == NULL,
-           "psVectorPowerSpectrum() did return a NULL vector.");
-        // Perform vector power spectrum with null input
-        ok(psVectorPowerSpectrum(NULL,NULL) == NULL,
-           "psVectorPowerSpectrum() did return NULL with null input vector");
-
-        psFree(vec);
-        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
-    }
+    testFFT(128);                       // Real quick test
+    testFFT(2048);                      // Test something big
+    testFFT(123456);                    // Test something really big
 }
