IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 12154


Ignore:
Timestamp:
Mar 1, 2007, 1:35:33 PM (19 years ago)
Author:
gusciora
Message:

Formally tap_psImageFFT2.c tap_psVectorFFT2.c. Since much of the tests
in the original files of this name test psLib functions which were removed
from the SDRS, I simply took Paul's tests for the new FFT functions, added
some tests for bad input parameter combinations, and renamed them here.

Will remove the tap_psImageFFT2.c tap_psVectorFFT2.c from CVS tree.

Location:
trunk/psLib/test/fft
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/test/fft/tap_psImageFFT.c

    r11685 r12154  
    1 /** @file  tst_psImageFFT.c
    2  *
    3  *  @brief Contains the tests for psFFT.[ch]
    4  *
    5  *
    6  *  @author Robert DeSonia, MHPCC
    7  *
    8  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-02-07 22:50:18 $
    10  *
    11  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    12  */
    131#include <stdio.h>
    14 #include <string.h>
     2#include <math.h>
    153#include <pslib.h>
     4
    165#include "tap.h"
    176#include "pstap.h"
    187
    19 #define GENIMAGE(img,c,r,TYP, valueFcn) \
    20 img = psImageAlloc(c,r,PS_TYPE_##TYP); \
    21 for (psU32 row=0;row<r;row++) { \
    22     ps##TYP* imgRow = img->data.TYP[row]; \
    23     for (psU32 col=0;col<c;col++) { \
    24         imgRow[col] = (ps##TYP)(valueFcn); \
    25     } \
     8#define TOL 2.0e-6                      // Tolerance for comparison
     9
     10
     11// Generate image with single high pixel
     12static psImage *generateImage(int numCols, int numRows)
     13{
     14    psImage *image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     15    for (int y = 0; y < numRows; y++) {
     16        for (int x = 0; x < numCols; x++) {
     17            image->data.F32[y][x] = 1.2 * cos(2.0 * M_PI * x / numCols + M_PI / 4.0) +
     18                3.4 * sin(2.0 * M_PI * y / numRows + M_PI);
     19        }
     20    }
     21    return image;
    2622}
    2723
    28 psS32 main(psS32 argc, char* argv[])
     24// FFT forward, then back --- do I get what I started with?
     25// A total of 6 tests here.
     26static void testFFT(int numCols, int numRows)
    2927{
    30     psLogSetFormat("HLNM");
    31     psLogSetLevel(PS_LOG_INFO);
    32     plan_tests(68);
     28    psMemId id = psMemGetId();
    3329
    34     // psImageFFT(void)
     30    diag("Testing %dx%d", numCols, numRows);
     31    psImage *old = generateImage(numCols, numRows);
     32    psImage *fftReal = NULL, *fftImag = NULL;
     33    bool result = psImageForwardFFT(&fftReal, &fftImag, old);
     34    ok(result, "forward fft result");
     35    skip_start(!result || !fftReal || !fftImag, 3, "forward fft failed");
     36    ok(fftReal->type.type == PS_TYPE_F32 && fftImag->type.type == PS_TYPE_F32, "forward fft types");
     37    psImage *new = NULL;
     38    result = psImageBackwardFFT(&new, fftReal, fftImag, old->numCols);
     39    ok(result, "backward fft result");
     40    skip_start(!result || !new, 2, "backward fft failed");
     41    ok(new->type.type == PS_TYPE_F32, "backward fft type");
     42    float maxDev = 0.0;                 // Maximum deviation from expected
     43    for (int y = 0; y < old->numRows; y++) {
     44        for (int x = 0; x < old->numCols; x++) {
     45            float dev = fabs(new->data.F32[y][x] / numCols / numRows - old->data.F32[y][x]);
     46            if (dev > maxDev) {
     47                maxDev = dev;
     48            }
     49        }
     50    }
     51    ok(maxDev < TOL, "maximum deviation: %f", maxDev);
     52    psFree(new);
     53    skip_end();
     54    skip_end();
     55
     56    psFree(fftReal);
     57    psFree(fftImag);
     58    psFree(old);
     59    ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     60
     61    return;
     62}
     63
     64
     65int main(int argc, char *argv[])
     66{
     67    plan_tests(8 + 6 * 5);
     68
     69    // Test with NULL real arg
    3570    {
    3671        psMemId id = psMemGetId();
    37         psImage* img = NULL;
    38         psImage* img2 = NULL;
    39         psImage* img3 = NULL;
    40         psU32 m = 128;
    41         psU32 n = 64;
    42         psImage* img4 = NULL;
    43         psImage* img5 = NULL;
    44 
    45         // 1. assign a image to a radial sinisoid
    46         // 2. perform forward transform
    47         // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
    48         // 4. perform reverse transform
    49         // 5. compare to original (should be equal to within a reasonable error)
    50 
    51         // 1. assign a image to a radial sinisoid
    52         GENIMAGE(img,m,n,F32, sinf((32.0f-row)/32.0f*M_PI)+sinf((64.0f-col)/64.0f*M_PI));
    53 
    54         // 2. perform forward transform
    55         img2 = psImageFFT(img2,img,PS_FFT_FORWARD);
    56         ok(img2 != NULL, "psImageFFT() returned non-NULL");
    57         skip_start(img2 == NULL, 1, "Skipping tests because psImageFFT() returned NULL");
    58         ok(img2->type.type == PS_TYPE_C32, "FFT produced complex values");
    59         ok(img2->numCols == m && img2->numRows == n, "FFT produced proper size result (%dx%d vs. expected %dx%d).",
    60            img2->numCols,img2->numRows,m,n);
    61 
    62         // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
    63         bool errorFlag = false;
    64         for (psU32 row=0;row<n;row++)
    65         {
    66             psC32* img2Row = img2->data.C32[row];
    67             for (psU32 col=0;col<m;col++) {
    68                 psF32 mag = cabsf(img2Row[col])/m/n;
    69                 if (mag > 0.1f) {
    70                     // must be (0,1) or (0,n-1) or (1,0) or (m-1,0)
    71                     if (! (col == 0 && (row == 1 || row == n-1))
    72                             && ! (row == 0 && (col==1 || col == m-1)) ) {
    73                         diag("Result incorrect at %d,%d (%.2f)",col,row,mag);
    74                         errorFlag = true;
    75                     }
    76                 } else {
    77                     if ( (col == 0 && (row == 1 || row == n-1))
    78                             || (row == 0 && (col==1 || col == m-1)) ) {
    79                         diag("Result incorrect at %d,%d (%.2f)",col,row,mag);
    80                         errorFlag = true;
    81                     }
    82                 }
    83             }
    84         }
    85         ok(!errorFlag, "FFT produced correct data values");
    86 
    87 
    88 
    89         // 4. perform reverse transform
    90         img3 = psImageFFT(img3,img2,PS_FFT_REVERSE);
    91         ok(img3 != NULL, "psImageFFT() returned non-NULL");
    92         skip_start(img3 == NULL, 1, "Skipping tests because psImageFFT() returned NULL");
    93         ok(img3->type.type == PS_TYPE_C32, "FFT produced complex values");
    94 
    95         ok(img3->numCols == m && img3->numRows == n, "FFT didt produce proper size result (%dx%d vs. expected %dx%d).",
    96            img3->numCols,img3->numRows,m,n);
    97 
    98 
    99 
    100 
    101 
    102 
    103 
    104 
    105 
    106 
    107 
    108 
    109 
    110 
    111 
    112 
    113         errorFlag = false;
    114         for (psU32 row=0;row<n;row++)
    115         {
    116             psC32* img3Row = img3->data.C32[row];
    117             psF32* imgRow = img->data.F32[row];
    118             for (psU32 col=0;col<m;col++) {
    119                 psF32 pixel = creal(img3Row[col])/m/n;
    120                 if (fabsf(pixel-imgRow[col]) > 0.1) {
    121                     diag("Reverse FFT gave original image back (%d,%d %.2f vs %.2f)",
    122                          col,row,pixel,imgRow[col]);
    123                     errorFlag = true;
    124                 }
    125             }
    126         }
    127         ok(!errorFlag, "FFT produced correct data values");
    128         ok(!errorFlag, "FFT produced correct data values");
    129 
    130 
    131 
    132         // 4. perform reverse transform to real result
    133         img3 = psImageFFT(img3,img2,PS_FFT_REVERSE|PS_FFT_REAL_RESULT);
    134         ok(img3 != NULL, "psImageFFT() returned non-NULL");
    135         skip_start(img3 == NULL, 1, "Skipping tests because psImageFFT() returned NULL");
    136         ok(img3->type.type == PS_TYPE_F32, "FFT asked to make real result");
    137         ok(img3->numCols == m && img3->numRows == n, "FFT produced proper size result (%dx%d vs. expected %dx%d).",
    138            img3->numCols,img3->numRows,m,n);
    139 
    140         errorFlag = false;
    141         for (psU32 row=0;row<n;row++)
    142         {
    143             psF32* img3Row = img3->data.F32[row];
    144             psF32* imgRow = img->data.F32[row];
    145             for (psU32 col=0;col<m;col++) {
    146                 psF32 pixel = img3Row[col]/m/n;
    147                 if (fabsf(pixel-imgRow[col]) > 0.1) {
    148                     diag("Reverse FFT gave original image back (%d,%d %.2f vs %.2f)",
    149                          col,row,pixel,imgRow[col]);
    150                     errorFlag = true;
    151                 }
    152             }
    153         }
    154         ok(!errorFlag, "FFT produced correct data values");
    155         ok(!errorFlag, "FFT produced correct data values");
    156 
    157 
    158 
    159         // check if error occurs if FORWARD and REVERSE are both given.
    160         // Following should be an error
    161         // XXX: werify error
    162         ok(psImageFFT(NULL,img2,PS_FFT_REVERSE|PS_FFT_FORWARD) == NULL,
    163            "PS_FFT_REVERSE|PS_FFT_FORWARD returned NULL");
    164 
    165         // Following should be an error
    166         // XXX: werify error
    167         ok(psImageFFT(NULL,img2,PS_FFT_FORWARD|PS_FFT_REAL_RESULT) == NULL,
    168            "PS_FFT_FORWARD|PS_FFT_REAL_RESULT returned NULL");
    169 
    170         // Verify return null and program execution doesn't stop if input image is null
    171         img4 = psImageFFT(NULL,NULL,PS_FFT_FORWARD);
    172         ok(img4 == NULL, "psImageFFT should return null for a null input image");
    173 
    174         // Verify return null and program execution doesn't stop if input image is incorrect direction
    175         // Following should generate error for incorrect direction
    176         // XXX: werify error
    177         GENIMAGE(img4,8,8,S8,row+col);
    178         img5 = psImageFFT(NULL,img4,PS_FFT_REAL_RESULT);
    179         ok(img5 == NULL, "psImageFFT should return null for an incorrect FFT direction");
    180 
    181         psFree(img4);
    182         psFree(img);
    183         psFree(img2);
    184         psFree(img3);
    185         skip_end();
    186         skip_end();
    187         skip_end();
    188         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     72        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
     73        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
     74        psImage *in = psImageAlloc(512, 512, PS_TYPE_F32);
     75        bool rc = psImageForwardFFT(NULL, &imag, in);
     76        ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL real image input");
     77        psFree(real);
     78        psFree(imag);
     79        psFree(in);
     80        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    18981    }
    19082
    191     // 1. create a C64 complex vector with distinctly different real and imaginary parts.
    192     // 2. call psImageReal and psImageImaginary
    193     // 3. compare results to the real/imaginary components of input
     83    // Test with NULL imag arg
    19484    {
    19585        psMemId id = psMemGetId();
    196         psImage* c64Img = NULL;
    197         psImage* c64Img2 = NULL;
    198         psImage* c64Img3 = NULL;
    199         psU32 m = 128;
    200         psU32 n = 64;
    201 
    202         // XXX: What is I?
    203         GENIMAGE(c64Img,m,n,C64, row + I * col);
    204         c64Img2 = psImageReal(c64Img2,c64Img);
    205         ok(c64Img2 != NULL, "psImageReal() returned non-NULL");
    206         ok(c64Img2->type.type == PS_TYPE_F64, "psImageReal() returned the correct type");
    207         c64Img3 = psImageImaginary(c64Img3,c64Img);
    208         ok(c64Img3 != NULL, "psImageImaginary() returned non-NULL");
    209         ok(c64Img3->type.type == PS_TYPE_F64, "psImageImaginary() returned the correct type");
    210 
    211         bool errorFlag = false;
    212         for (psU32 row=0;row<n;row++)
    213         {
    214             psF64* img2Row = c64Img2->data.F64[row];
    215             psF64* img3Row = c64Img3->data.F64[row];
    216             for (psU32 col=0;col<m;col++) {
    217                 if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
    218                     diag("psImageReal didn't return the real portion at n=%d", n);
    219                     errorFlag = true;
    220                 }
    221                 if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
    222                     diag("psImageImaginary didn't return the imag portion at n=%d", n);
    223                     errorFlag = true;
    224                 }
    225             }
    226         }
    227         ok(!errorFlag, "psImageReal() and psImageImaginary() returned the correct data");
    228         psFree(c64Img);
    229         psFree(c64Img2);
    230         psFree(c64Img3);
    231         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     86        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
     87        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
     88        psImage *in = psImageAlloc(512, 512, PS_TYPE_F32);
     89        bool rc = psImageForwardFFT(&real, NULL, in);
     90        ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL imaginary image input");
     91        psFree(real);
     92        psFree(imag);
     93        psFree(in);
     94        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    23295    }
    23396
    234 
    235 
     97    // Test with NULL input arg
    23698    {
    23799        psMemId id = psMemGetId();
    238         psImage* ncImg = NULL;
    239         psImage* ncImg2 = NULL;
    240         psImage* ncImg3 = NULL;
    241         psU32 m = 128;
    242         psU32 n = 64;
    243 
    244         GENIMAGE(ncImg,m,n,F32,row+col);
    245         ncImg2 = psImageReal(ncImg2,ncImg);
    246         ncImg3 = psImageImaginary(ncImg3,ncImg);
    247         ok(ncImg2 != NULL, "psImageReal() returned non-NULL");
    248         ok(ncImg2->type.type == PS_TYPE_F32, "psImageReal() returned the correct type");
    249         ok(ncImg3 != NULL, "psImageImaginary() returned non-NULL");
    250         ok(ncImg3->type.type == PS_TYPE_F32, "psImageImaginary() returned the correct type");
    251 
    252         bool errorFlag = false;
    253         for(psU32 row=0; row<n; row++)
    254         {
    255             psF32* ncImg2Row = ncImg2->data.F32[row];
    256             psF32* ncImg3Row = ncImg3->data.F32[row];
    257             for(psU32 col=0; col<m; col++) {
    258                 if(fabsf(ncImg2Row[col] - (row+col)) > FLT_EPSILON) {
    259                     diag("psImageReal didn't return the real portion");
    260                     errorFlag = true;
    261                 }
    262                 if(fabsf(ncImg3Row[col] - 0) > FLT_EPSILON) {
    263                     diag("psImageImaginary didn't return the imaginary portion");
    264                     errorFlag = true;
    265                 }
    266             }
    267         }
    268         ok(!errorFlag, "psImageReal() and psImageImaginary() returned the correct data");
    269         psFree(ncImg);
    270         psFree(ncImg2);
    271         psFree(ncImg3);
    272         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     100        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
     101        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
     102        psImage *in = psImageAlloc(512, 512, PS_TYPE_F32);
     103        bool rc = psImageForwardFFT(&real, &imag, NULL);
     104        ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL real image input");
     105        psFree(real);
     106        psFree(imag);
     107        psFree(in);
     108        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    273109    }
    274110
    275 
    276 
    277     // Perform psImageReal with null input
     111    // Test with incorrect input image type
    278112    {
    279113        psMemId id = psMemGetId();
    280         ok(psImageReal(NULL,NULL) == NULL, "psImageReal() returned NULL with NULL inputs");
    281         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     114        psImage *real = psImageAlloc(512, 512, PS_TYPE_F32);
     115        psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32);
     116        psImage *in = psImageAlloc(512, 512, PS_TYPE_F64);
     117        bool rc = psImageForwardFFT(NULL, &imag, in);
     118        ok(rc == false, "psImageForwardFFT() returned FALSE with incorrect input image type");
     119        psFree(real);
     120        psFree(imag);
     121        psFree(in);
     122        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    282123    }
    283124
    284 
    285     // Perform psImageImaginary with null input
    286     {
    287         psMemId id = psMemGetId();
    288         ok(psImageImaginary(NULL,NULL) == NULL, "psImageImaginary() returned NULL with NULL inputs");
    289         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    290     }
    291 
    292 
    293     // testImageComplex()
    294     // 1. create two unique psF32 vectors of the same size
    295     // 2. call psImageComplex
    296     // 3. verify that the result is a psC32
    297     // 4. use crealf and cimagf on step 2 results
    298     // 5. compare step 4 results to input.
    299     // 6. create a psF32 and a psF64 vector of the same size
    300     // 7. call psImageComplex
    301     // 8. verify that an appropriate error occurred.
    302     // 9. create two psf32 vectors of different sizes
    303     // 10. call psImageComplex
    304     // 11. verify thet an appropriate error occurred.
    305     {
    306         psMemId id = psMemGetId();
    307         psImage* img = NULL;
    308         psImage* img2 = NULL;
    309         psImage* img3 = NULL;
    310         psImage* c64Img = NULL;
    311         psImage* c64Img2 = NULL;
    312         psImage* c64Img3 = NULL;
    313         psImage* pImg = NULL;
    314         psImage* pImg2 = NULL;
    315         psImage* pImg3 = NULL;
    316         psU32 m = 128;
    317         psU32 n = 64;
    318         GENIMAGE(img,m,n,F32,row);
    319         GENIMAGE(img2,m,n,F32,col);
    320         GENIMAGE(c64Img,m,n,F64,row);
    321         GENIMAGE(c64Img2,m,n,F64,col);
    322         GENIMAGE(pImg,m,n,S16,row);
    323         GENIMAGE(pImg2,m,n,S16,col);
    324         img3 = psImageComplex(img3,img,img2);
    325         ok(img3 != NULL, "psImageComplex() returned non-NULL");
    326         ok(img3->type.type == PS_TYPE_C32, "psImageComplex() returned the correct type");
    327         c64Img3 = psImageComplex(c64Img3,c64Img,c64Img2);
    328         ok(c64Img3 != NULL, "psImageComplex() returned non-NULL");
    329         ok(c64Img3->type.type == PS_TYPE_C64, "psImageComplex() returned the correct type");
    330         bool errorFlag = false;
    331         for (psU32 row=0;row<n;row++)
    332         {
    333             psC32* img3Row = img3->data.C32[row];
    334             psC64* c64Img3Row = c64Img3->data.C64[row];
    335             for (psU32 col=0;col<m;col++) {
    336                 if (fabsf(crealf(img3Row[col]) - row) > FLT_EPSILON ||
    337                         fabsf(cimagf(img3Row[col]) - col) > FLT_EPSILON) {
    338                     diag("psImageComplex result is incorrect (%d,%d, %.2f+%.2fi)",
    339                          col,row,crealf(img3Row[col]),cimagf(img3Row[col]));
    340                     errorFlag = true;
    341                 }
    342                 if (fabsf(crealf(c64Img3Row[col]) - row) > FLT_EPSILON ||
    343                         fabsf(cimagf(c64Img3Row[col]) - col) > FLT_EPSILON) {
    344                     diag("psImageComplex result is incorrect");
    345                     errorFlag = true;
    346 
    347                 }
    348             }
    349         }
    350         ok(!errorFlag, "psImageComplex() returned correct results");
    351 
    352         img2 = psImageRecycle(img2,m,n,PS_TYPE_F64);
    353 
    354         // Following should be an error (type mismatch)
    355         // Verify that an appropriate error occurred
    356         img3 = psImageComplex(img3,img,img2);
    357         ok(img3 == NULL, "psImageComplex() returned NULL when input types mismatched.");
    358 
    359         // Following should be an error (size mismatch)
    360         img2 = psImageRecycle(img2,m/2,n,PS_TYPE_F32);
    361         img3 = psImageComplex(img3,img,img2);
    362         ok(img3 == NULL, "psImageComplex() returned a NULL when input sizes mismatched");
    363 
    364         // Perform psImageComplex with incorrect type
    365         // Following should generate an error message.");
    366         pImg3 = psImageComplex(pImg3,pImg,pImg2);
    367         ok(pImg3 == NULL, "psImageComplex returned NULL with incorrect type input");
    368 
    369         psFree(img);
    370         psFree(img2);
    371         psFree(img3);
    372         psFree(c64Img);
    373         psFree(c64Img2);
    374         psFree(c64Img3);
    375         psFree(pImg);
    376         psFree(pImg2);
    377 
    378         // Perform psImageComplex with null input
    379         ok(psImageComplex(NULL,NULL,NULL) == NULL, "psImageComplex() returned NULL with null input");
    380         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    381     }
    382 
    383     // 1. create a psC32 with unique real and imaginary values.
    384     // 2. call psImageConjugate
    385     // 3. verify result is psC32
    386     // 4. verify each value is conjugate of input (a+bi -> a-bi)
    387     // testImageConjugate()
    388     {
    389         psMemId id = psMemGetId();
    390         psImage* img = NULL;
    391         psImage* img2 = NULL;
    392         psImage* c64Img = NULL;
    393         psImage* c64Img2 = NULL;
    394         psImage* pImg = NULL;
    395         psImage* pImg2 = NULL;
    396         psU32 m = 128;
    397         psU32 n = 64;
    398         GENIMAGE(img,m,n,C32, row + I * col);
    399         GENIMAGE(c64Img,m,n,C64,row + I*col);
    400         GENIMAGE(pImg,m,n,F32,row+col);
    401 
    402 
    403         img2 = psImageConjugate(img2,img);
    404         ok(img2 != NULL, "psImageConjugate() returned non-NULL");
    405         c64Img2 = psImageConjugate(c64Img2,c64Img);
    406         ok(c64Img2 != NULL, "psImageConjugate() returned non-NULL");
    407         pImg2 = psImageConjugate(pImg2,pImg);
    408         ok(pImg2 != NULL, "psImageConjugate() returned non-NULL");
    409 
    410         ok(img2->type.type == PS_TYPE_C32, "psImageConjugate() returned the correct type");
    411         ok(c64Img2->type.type == PS_TYPE_C64, "psImageConjugate() returned the correct type");
    412         ok(pImg2->type.type == PS_TYPE_F32, "psImageConjugate() returned the correct type");
    413 
    414         bool errorFlag = false;
    415         for (psU32 row=0;row<n;row++)
    416         {
    417             psC32* img2Row = img2->data.C32[row];
    418             psC64* c64Img2Row = c64Img2->data.C64[row];
    419             psF32* pImg2Row = pImg2->data.F32[row];
    420             for (psU32 col=0;col<m;col++) {
    421                 if (fabsf(crealf(img2Row[col]) - row) > FLT_EPSILON ||
    422                         fabsf(cimagf(img2Row[col]) + col) > FLT_EPSILON) {
    423                     diag("psImageComplex result is incorrect (%d,%d, %.2f+%.2fi)",
    424                          col,row,crealf(img2Row[col]),cimagf(img2Row[col]));
    425                     errorFlag = true;
    426                 }
    427                 if (fabsf(crealf(c64Img2Row[col]) - row) > FLT_EPSILON ||
    428                         fabsf(cimagf(c64Img2Row[col]) + col) > FLT_EPSILON) {
    429                     diag("psImageComplex result is incorrect");
    430                     errorFlag = true;
    431                 }
    432                 if (fabsf(pImg2Row[col] - (row+col)) > FLT_EPSILON) {
    433                     diag("psImageComplex result is incorrect");
    434                     errorFlag = true;
    435                 }
    436             }
    437         }
    438         ok(!errorFlag, "psImageConjugate() generated the correct data values");
    439         psFree(img);
    440         psFree(img2);
    441         psFree(c64Img);
    442         psFree(c64Img2);
    443         psFree(pImg);
    444         psFree(pImg2);
    445 
    446         // Perform psImageConjugate with null input
    447         ok(psImageConjugate(NULL,NULL) == NULL, "psImageConjugate() returned NULL with NULL input");
    448         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    449     }
    450 
    451     // testImagePowerSpectrum()
    452     // 1. create a psC32 vector with unique real and imaginary components
    453     // 2. call psImagePowerSpectrum
    454     // 3. verify result is psF32
    455     // 4. verify the values are the square of the absolute values of the original
    456     {
    457         psMemId id = psMemGetId();
    458         psImage* img = NULL;
    459         psImage* img2 = NULL;
    460         psImage* c64Img = NULL;
    461         psImage* c64Img2 = NULL;
    462         psImage* pImg = NULL;
    463         psU32 m = 128;
    464         psU32 n = 64;
    465 
    466         GENIMAGE(img,m,n,C32, row + I * col);
    467         GENIMAGE(c64Img,m,n,C64,row+I*col);
    468         GENIMAGE(pImg,m,n,F32,row+col);
    469 
    470         img2 = psImagePowerSpectrum(img2,img);
    471         c64Img2 = psImagePowerSpectrum(c64Img2, c64Img);
    472         ok(img2 != NULL, "psImagePowerSpectrum() returned non-NULL");
    473         ok(c64Img2 != NULL, "psImagePowerSpectrum() returned non-NULL");
    474         ok(img2->type.type == PS_TYPE_F32, "psImagePowerSpectrum() returned the correct type");
    475         ok(c64Img2->type.type == PS_TYPE_F64, "psImagePowerSpectrum() returned the correct type");
    476 
    477         bool errorFlag = false;
    478         for (psU32 row=0;row<n;row++)
    479         {
    480             psC32* imgRow = img->data.C32[row];
    481             psF32* img2Row = img2->data.F32[row];
    482             psC64* c64ImgRow = c64Img->data.C64[row];
    483             psF64* c64Img2Row = c64Img2->data.F64[row];
    484             for (psU32 col=0;col<m;col++) {
    485                 psF32 power = cabs(imgRow[col]);
    486                 psF64 power64 = cabs(c64ImgRow[col]);
    487                 power *= power/n/n/m/m;
    488                 power64 *= power64/n/n/m/m;
    489 
    490                 if (fabsf(img2Row[col] - power) > 2.0f*FLT_EPSILON) {
    491                     diag("psImagePowerSpectrum result is incorrect (%d,%d, %.2f vs %.2f)",
    492                          col,row,img2Row[col],power);
    493                     errorFlag = true;
    494                 }
    495                 if (fabsf(c64Img2Row[col] - power64) > 2.0f*FLT_EPSILON) {
    496                     diag("psImagePowerSpectrum result is incorrect");
    497                     errorFlag = true;
    498                 }
    499             }
    500         }
    501         ok(!errorFlag, "psImagePowerSPectrum() generated the correct data values");
    502         psFree(img);
    503         psFree(img2);
    504         psFree(c64Img);
    505         psFree(c64Img2);
    506 
    507         // Perform psImagePowerSpectrum with incorrect input
    508         // Following should generate error message
    509         // XXX: Verify error
    510         ok(psImagePowerSpectrum(NULL,pImg) == NULL, "psImagePowerSpectrum() returned NULL with incorrect type");
    511         psFree(pImg);
    512 
    513         // Perform psImagePowerSpectrum with NULL input
    514         ok(psImagePowerSpectrum(NULL,NULL) == NULL, "psImagePowerSpectrum() returned NULL with NULL input");
    515         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    516     }
    517 
    518 
    519     // testImageRealImaginary()
    520     // 1. create a C32 complex image with distinctly different real and imaginary parts
    521     // 2. call psImageReal and psImageImaginary
    522     // 3. compare results to the real/imaginary components of input
    523     // XXX: If we put this block above the previous 2 blocks, then we get memory errors
    524     {
    525         psMemId id = psMemGetId();
    526         psImage* img = NULL;
    527         psImage* img3 = NULL;
    528         psU32 m = 128;
    529         psU32 n = 64;
    530         GENIMAGE(img,m,n,C32, row + I * col);
    531         psImage* img2 = psImageReal(NULL,img);
    532         ok(img2 != NULL, "psImageReal returned non-NULL");
    533         skip_start(img2 == NULL, 4, "Skipping tests because psImageReal() returned NULL");
    534         ok(img2->type.type == PS_TYPE_F32, "psImageReal returned the correct type");
    535         img3 = psImageImaginary(img3,img);
    536         ok(img3 != NULL, "psImageImaginary() returned non-NULL");
    537         skip_start(img3 == NULL, 2, "Skipping tests because psImageImaginary() returned NULL");
    538         ok(img3->type.type == PS_TYPE_F32, "psImageImaginary() returned the correct type");
    539 
    540         bool errorFlag = false;
    541         for (psU32 row=0;row<n;row++)
    542         {
    543             psF32* img2Row = img2->data.F32[row];
    544             psF32* img3Row = img3->data.F32[row];
    545             for (psU32 col=0;col<m;col++) {
    546                 if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
    547                     diag("psImageReal didn't return the real portion at n=%d", n);
    548                     errorFlag = true;
    549                 }
    550                 if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
    551                     diag("psImageImaginary didn't return the imag portion at n=%d", n);
    552                     errorFlag = true;
    553                 }
    554             }
    555         }
    556         ok(!errorFlag, "psImageReal(), psImageImaginary() returned the correct data");
    557         skip_end();
    558         skip_end();
    559         psFree(img);
    560         psFree(img2);
    561         psFree(img3);
    562         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    563     }
    564 
    565 
     125    testFFT(10, 10);                    // Real quick test
     126    testFFT(10, 20);                    // Testing differing numCols, numRows
     127    testFFT(20, 10);                    // Testing differing numCols, numRows
     128    testFFT(611, 610);                  // Test something like an OTA cell
     129    testFFT(2048, 4096);                // Test something like a megacam chip
    566130}
  • trunk/psLib/test/fft/tap_psVectorFFT.c

    r11692 r12154  
    1 /** @file  tst_psVectorFFT.c
    2 *
    3 *  @brief Contains the tests for psFFT.[ch]
    4 *
    5 *
    6 *  @author Robert DeSonia, MHPCC
    7 *
    8 *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    9 *  @date $Date: 2007-02-08 01:37:33 $
    10 *
    11 * XXX: Must add skip_start() macros
    12 *
    13 *
    14 *
    15 *
    16 *
    17 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
    18 */
    191#include <stdio.h>
    20 #include <string.h>
     2#include <math.h>
    213#include <pslib.h>
     4
    225#include "tap.h"
    236#include "pstap.h"
    247
    25 #define GENIMAGE(img,c,r,TYP, valueFcn) \
    26 img = psImageAlloc(c,r,PS_TYPE_##TYP); \
    27 for (psU32 row=0;row<r;row++) { \
    28     ps##TYP* imgRow = img->data.TYP[row]; \
    29     for (psU32 col=0;col<c;col++) { \
    30         imgRow[col] = (ps##TYP)(valueFcn); \
    31     } \
     8#define TOL 2.5e-5                      // Tolerance for comparison
     9
     10
     11// Generate image with single high pixel
     12static psVector *generateVector(long num)
     13{
     14    psVector *vector = psVectorAlloc(num, PS_TYPE_F32);
     15    for (long i = 0; i < num; i++) {
     16        vector->data.F32[i] = 1.2 * cos(2.0 * M_PI * i / num + M_PI / 4.0) +
     17            3.4 * sin(0.5 * 2.0 * M_PI * i / num + M_PI);
     18    }
     19    return vector;
    3220}
    3321
    34 psS32 main( psS32 argc, char* argv[] )
     22// FFT forward, then back --- do I get what I started with?
     23// A total of 6 tests here.
     24static void testFFT(long num)
    3525{
    36     psLogSetFormat("HLNM");
    37     psLogSetLevel(PS_LOG_INFO);
    38     plan_tests(58);
     26    psMemId id = psMemGetId();
    3927
    40     // testVectorFFT()
    41     // 1. assign a vector to a sinisoid
    42     // 2. perform forward transform
    43     //  3. verify that the only significant component cooresponds to the freqency of the input in step 1.
    44     //  4. perform reverse transform
    45     //  5. compare to original (should be equal to within a reasonable error)
     28    diag("Testing %d", num);
     29    psVector *old = generateVector(num);
     30    psVector *fftReal = NULL, *fftImag = NULL;
     31    bool result = psVectorForwardFFT(&fftReal, &fftImag, old);
     32    ok(result, "forward fft result");
     33    skip_start(!result || !fftReal || !fftImag, 3, "forward fft failed");
     34    ok(fftReal->type.type == PS_TYPE_F32 && fftImag->type.type == PS_TYPE_F32, "forward fft types");
     35    psVector *new = NULL;
     36    result = psVectorBackwardFFT(&new, fftReal, fftImag, old->n);
     37    ok(result, "backward fft result");
     38    skip_start(!result || !new, 2, "backward fft failed");
     39    ok(new->type.type == PS_TYPE_F32, "backward fft type");
     40    float maxDev = 0.0;                 // Maximum deviation from expected
     41    for (long i = 0; i < old->n; i++) {
     42        float dev = fabs(new->data.F32[i] / num - old->data.F32[i]);
     43        if (dev > maxDev) {
     44            maxDev = dev;
     45        }
     46    }
     47    ok(maxDev < TOL, "maximum deviation: %f", maxDev);
     48    psFree(new);
     49    skip_end();
     50    skip_end();
     51
     52    psFree(fftReal);
     53    psFree(fftImag);
     54    psFree(old);
     55    ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     56
     57    return;
     58}
     59
     60
     61int main(int argc, char *argv[])
     62{
     63    plan_tests(8 + 6 * 3);
     64
     65    // Test with NULL real arg
    4666    {
    4767        psMemId id = psMemGetId();
    48         psVector *vec = NULL;
    49         psVector* vec2 = NULL;
    50         psVector* vec3 = NULL;
    51         psVector* vec4 = NULL;
    52 
    53         vec = psVectorAlloc(100, PS_TYPE_F32);
    54         vec->n = vec->nalloc;
    55         for ( psU32 n = 0; n < 100; n++ )
    56         {
    57             vec->data.F32[ n ] = sinf( ( psF32 ) n / 50.0f * M_PI );
    58         }
    59 
    60         vec2 = psVectorFFT(NULL, vec, PS_FFT_FORWARD);
    61         ok(vec2 != NULL, "psVectorFFT() returned non-NULL");
    62         ok(vec2->type.type == PS_TYPE_C32, "psVectorFFT() returned the correct type");
    63         ok(vec2->n == vec->n, "psVectorFFT() returned the correct size vector");
    64 
    65         bool errorFlag = false;
    66         for ( psU32 n = 0; n < 100; n++ )
    67         {
    68             if ( n == 1 || n == 99 ) {
    69                 if ( fabsf( cabsf( vec2->data.C32[ n ] ) - 50.0f ) > 0.1f ) {
    70                     diag("FFT didn't work for vector (n=%d)", n );
    71                     errorFlag = true;
    72                 }
    73             } else {
    74                 if ( fabsf( cabsf( vec2->data.C32[ n ] ) ) > 0.1f ) {
    75                     diag("FFT didn't work for vector (n=%d)", n );
    76                     errorFlag = true;
    77                 }
    78             }
    79         }
    80         ok(!errorFlag, "psVectorFFT() returned the correct data values");
    81 
    82         vec3 = psVectorFFT( NULL, vec2, PS_FFT_REVERSE );
    83         ok(vec3 != NULL, "psVectorFFT() returned non-NULL");
    84         ok(vec3->type.type == PS_TYPE_C32, "psVectorFFT() returned the correct type");
    85         ok(vec3->n == vec2->n, "psVectorFFT() returned the correct size vectors");
    86 
    87         errorFlag = false;
    88         for ( psU32 n = 0; n < 100; n++ )
    89         {
    90             psF32 val = sinf( ( psF32 ) n / 50.0f * M_PI );
    91             psF32 vecVal = crealf( vec3->data.C32[ n ] ) / 100;
    92             if ( fabsf( vecVal - val ) > 0.1f ) {
    93                 diag("Reverse FFT didn't give me the original vector back (n=%d) (%.2f vs %.2f)",
    94                      n, vecVal, val );
    95                 errorFlag = true;
    96             }
    97         }
    98         ok(!errorFlag, "psVectorFFT() returned the correct data values");
    99 
    100         // Perform reverse transform with real flag set
    101         vec4 = psVectorFFT(NULL,vec2, (PS_FFT_REVERSE | PS_FFT_REAL_RESULT));
    102         ok(vec4->type.type == PS_TYPE_F32, "FFT with real result did produce real values");
    103 
    104         // Perform vector FFT with incorrect direction flags
    105         // Following should generate an error message
    106         // XXX: Verify error
    107         ok(psVectorFFT(NULL,vec2,(psFFTFlags)0) == NULL, "psVectorFFT() returned NULL with incorrect direction");
    108         psFree(vec);
    109         psFree(vec2);
    110         psFree(vec3);
    111         psFree(vec4);
    112 
    113         // Perform vector FFT with null input
    114         ok(psVectorFFT(NULL,NULL,PS_FFT_FORWARD) == NULL, "psVectorFFT() returned NULL with null input vector");
    115         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     68        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
     69        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
     70        psVector *in = psVectorAlloc(512, PS_TYPE_F32);
     71        bool rc = psVectorForwardFFT(NULL, &imag, in);
     72        ok(rc == false, "psVectorForwardFFT() returned FALSE with a null real vector input");
     73        psFree(real);
     74        psFree(imag);
     75        psFree(in);
     76        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    11677    }
    11778
    118 
    119     // testVectorRealImaginary()
    120     // 1. create a C32 complex vector with distinctly different real and imaginary parts.
    121     // 2. call psVectorReal and psVectorImaginary
    122     // 3. compare results to the real/imaginary components of input
     79    // Test with NULL imag arg
    12380    {
    12481        psMemId id = psMemGetId();
    125         psVector * vec = NULL;
    126         psVector* vec2 = NULL;
    127         psVector* vec3 = NULL;
    128         psVector* vec4 = NULL;
    129         psVector* vec5 = NULL;
    130         psVector* vec6 = NULL;
    131         psVector* vec7 = NULL;
    132         psVector* vec8 = NULL;
    133         psVector* vec9 = NULL;
    134         psVector* vec10 = NULL;
    135         psVector* vec11 = NULL;
    136 
    137         vec = psVectorAlloc( 100, PS_TYPE_C32 );
    138         vec8 = psVectorAlloc( 100, PS_TYPE_C64 );
    139         vec10 = psVectorAlloc( 100, PS_TYPE_C64 );
    140         vec->n = vec->nalloc;
    141         vec8->n = vec8->nalloc;
    142         vec10->n = vec10->nalloc;
    143         for ( psU32 n = 0; n < 100; n++ )
    144         {
    145             vec->data.C32[ n ] = n + I * ( n * 2 );
    146             vec8->data.C64[n] = n + I * ( n * 2 );
    147             vec10->data.C64[n] = n + I * ( n * 2 );
    148         }
    149         vec4 = psVectorAlloc( 100, PS_TYPE_F32);
    150         vec4->n = vec4->nalloc;
    151         vec6 = psVectorAlloc( 100, PS_TYPE_F32);
    152         vec6->n = vec6->nalloc;
    153         for ( psU32 n = 0; n < 100; n++ )
    154         {
    155             vec4->data.F32[n] = n;
    156             vec6->data.F32[n] = n;
    157         }
    158 
    159         vec2 = psVectorReal( vec2, vec );
    160         ok(vec2 != NULL, "psVectorReal() returned non-NULL");
    161         ok(vec2->type.type == PS_TYPE_F32, "psVectorReal() returned the correct type");
    162 
    163         // Following should generate a warning
    164         // XXX: Verify warning
    165         vec5 = psVectorReal(vec5, vec4);
    166         ok(vec5 != NULL, "psVectorReal() returned non-NULL");
    167         ok(vec5->type.type == PS_TYPE_F32, "psVectorReal() returned the correct type");
    168 
    169         vec9 = psVectorReal(vec9,vec8);
    170         ok(vec9 != NULL, "psVectorReal() returned non-NULL");
    171         ok(vec9->type.type == PS_TYPE_F64, "psVectorReal() returned the correct type");
    172 
    173         // Following should generate a warning
    174         // XXX: Verify warning
    175         vec3 = psVectorImaginary( vec3, vec );
    176         ok(vec3 != NULL, "psVectorImaginary() returned non-NULL");
    177         ok(vec3->type.type == PS_TYPE_F32, "psVectorImaginary() returned the correct type");
    178 
    179         vec7 = psVectorImaginary(vec7, vec6);
    180         ok(vec7 != NULL, "psVectorImaginary() returned non-NULL");
    181         ok(vec7->type.type == PS_TYPE_F32, "psVectorImaginary() returned the correct type");
    182 
    183         vec11 = psVectorImaginary(vec11, vec10);
    184         ok(vec11 != NULL, "psVectorImaginary() returned non-NULL");
    185         ok(vec11->type.type == PS_TYPE_F64, "psVectorImaginary() returned the correct type");
    186 
    187 
    188         // 3. compare results to the real/imaginary components of input
    189         bool errorFlag = false;
    190         for ( psU32 n = 0; n < 100; n++ )
    191         {
    192             psF32 r = n;
    193             psF32 i = ( n * 2 );
    194             psF64 rr = n;
    195             psF64 ii = ( n * 2 );
    196             if ( fabsf( vec2->data.F32[ n ] - r ) > FLT_EPSILON ) {
    197                 diag("psVectorReal didn't return the real portion at n=%d", n);
    198                 errorFlag = true;
    199             }
    200             if ( fabsf( vec3->data.F32[ n ] - i ) > FLT_EPSILON ) {
    201                 diag("psVectorImaginary didn't return the real portion at n=%d", n);
    202                 errorFlag = true;
    203             }
    204             if ( fabsf( vec5->data.F32[n] - r) > FLT_EPSILON) {
    205                 diag("psVectorReal didn't return the real portion at n=%d",n);
    206                 errorFlag = true;
    207             }
    208             if ( fabsf( vec7->data.F32[n] - 0) > FLT_EPSILON) {
    209                 diag("psVectorImaginary did not return the imaginary portion at n=%d",n);
    210                 errorFlag = true;
    211             }
    212             if ( fabsf(vec9->data.F64[n] - rr) > FLT_EPSILON ) {
    213                 diag("psVectorReal did not return the real portion at n=%d",n);
    214                 errorFlag = true;
    215             }
    216             if ( fabsf(vec11->data.F64[n] - ii) > FLT_EPSILON) {
    217                 diag("psVectorImaginary did not return the imaginary portion at n=%d",n);
    218                 errorFlag = true;
    219             }
    220         }
    221         ok(!errorFlag, "psVectorImaginary() returned the correct data values");
    222 
    223         psFree( vec );
    224         psFree( vec2 );
    225         psFree( vec3 );
    226         psFree( vec4 );
    227         psFree( vec5 );
    228         psFree( vec6 );
    229         psFree( vec7 );
    230         psFree( vec8 );
    231         psFree( vec9 );
    232         psFree( vec10 );
    233         psFree( vec11 );
    234 
    235         // Perform vector Real with null input
    236         ok(psVectorReal(NULL,NULL) == NULL, "psVectorReal returned NULL with NULL input");
    237         ok(psVectorImaginary(NULL,NULL) == NULL, "psVectorImaginary returned NULL with NULL input");
    238         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     82        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
     83        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
     84        psVector *in = psVectorAlloc(512, PS_TYPE_F32);
     85        bool rc = psVectorForwardFFT(&real, NULL, in);
     86        ok(rc == false, "psVectorForwardFFT() returned FALSE with a null imag vector input");
     87        psFree(real);
     88        psFree(imag);
     89        psFree(in);
     90        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    23991    }
    24092
    241 
    242     // testVectorComplex()
    243     // 1. create two unique psF32 vectors of the same size
    244     // 2. call psVectorComplex
    245     // 3. verify that the result is a psC32
    246     // 4. call psVectorReal and psVectorImaginary on step 2 results
    247     // 5. compare step 4 results to input.
    248     // 6. create a psF32 and a psF64 vector of the same size
    249     // 7. call psVectorComplex
    250     // 8. verify that an appropriate error occurred.
    251     // 9. create two psf32 vectors of different sizes
    252     // 10. call psVectorComplex
    253     // 11. verify thet an appropriate error occurred.
     93    // Test with NULL input arg
    25494    {
    25595        psMemId id = psMemGetId();
    256         psVector * vec = NULL;
    257         psVector* vec2 = NULL;
    258         psVector* vec3 = NULL;
    259         psVector* vec4 = NULL;
    260         psVector* vec5 = NULL;
    261         psVector* vec6 = NULL;
    262 
    263         // 1. create two unique psF32 vectors of the same size
    264         vec = psVectorAlloc( 100, PS_TYPE_F32 );
    265         vec2 = psVectorAlloc( 100, PS_TYPE_F32 );
    266         vec4 = psVectorAlloc( 100, PS_TYPE_F64 );
    267         vec5 = psVectorAlloc( 100, PS_TYPE_F64 );
    268         vec->n = vec->nalloc;
    269         vec2->n = vec2->nalloc;
    270         vec4->n = vec4->nalloc;
    271         vec5->n = vec5->nalloc;
    272         for ( psU32 n = 0; n < 100; n++ )
    273         {
    274             vec->data.F32[ n ] = n;
    275             vec2->data.F32[ n ] = ( n * 2 );
    276             vec4->data.F64[ n ] = n;
    277             vec5->data.F64[ n ] = ( n * 2 );
    278         }
    279 
    280         vec3 = psVectorComplex( vec3, vec, vec2 );
    281         ok(vec3 != NULL, "psVectorComplex() returned non-NULL");
    282         ok(vec3->type.type == PS_TYPE_C32, "psVectorComplex() returned the correct type");
    283         bool errorFlag = false;
    284         for ( psU32 n = 0; n < 100; n++ )
    285         {
    286             if ( fabsf( crealf( vec3->data.C32[ n ] ) - n ) > FLT_EPSILON ||
    287                     fabsf( cimagf( vec3->data.C32[ n ] ) - ( n * 2 ) ) > FLT_EPSILON ) {
    288                 diag("psVectorComplex result is incorrect (n=%d, %.2f+%.2fi)",
    289                      n, crealf( vec3->data.C32[ n ] ), cimagf( vec3->data.C32[ n ] ) );
    290                 errorFlag = true;
    291             };
    292         }
    293         ok(!errorFlag, "psVectorComplex() returned the correct data values");
    294 
    295 
    296         vec2 = psVectorRecycle( vec2, 100, PS_TYPE_F64 );
    297         // Following should be an error (type mismatch)
    298         // Verify error
    299         vec3 = psVectorComplex( vec3, vec, vec2 );
    300         ok(vec3 == NULL, "psVectorComplex() returned NULL when input types mismatched." );
    301 
    302         vec2 = psVectorRecycle( vec2, 200, PS_TYPE_F32 );
    303         vec3 = psVectorComplex( vec3, vec, vec2 );
    304         ok(vec3->n == 100, "psVectorComplex() returned the correct size vector");
    305 
    306         // Verify the function works with psF64 type
    307         vec6 = psVectorComplex(vec6, vec4, vec5);
    308         ok(vec6->type.type == PS_TYPE_C64, "psVectorComplex() returned the correct type (C64)");
    309 
    310         // Verify error message generated with input of incorrect type
    311         // Following should generate an error message
    312         vec4->type.type = PS_TYPE_S8;
    313         vec5->type.type = PS_TYPE_S8;
    314         vec6 = psVectorComplex(vec6, vec4, vec5);
    315         ok(vec6 == NULL, "psVectorComplex() returned NULL for incorrect type");
    316         vec4->type.type = PS_TYPE_F64;
    317         vec5->type.type = PS_TYPE_F64;
    318         psFree(vec);
    319         psFree(vec2);
    320         psFree(vec3);
    321         psFree(vec4);
    322         psFree(vec5);
    323 
    324         // Perform vector complex with null input
    325         ok(psVectorComplex(NULL,NULL,NULL) == NULL, "psVectorComplex() returned NULL with null input vector");
    326         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     96        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
     97        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
     98        psVector *in = psVectorAlloc(512, PS_TYPE_F32);
     99        bool rc = psVectorForwardFFT(&real, &imag, NULL);
     100        ok(rc == false, "psVectorForwardFFT() returned FALSE with a null input vector input");
     101        psFree(real);
     102        psFree(imag);
     103        psFree(in);
     104        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    327105    }
    328106
    329 
    330     // testVectorConjugate()
    331     // 1. create a psC32 with unique real and imaginary values.
    332     // 2. call psVectorConjugate
    333     // 3. verify result is psC32
    334     // 4. verify each value is conjugate of input (a+bi -> a-bi)
     107    // Test with incorrect type for input arg
    335108    {
    336109        psMemId id = psMemGetId();
    337         psVector * vec = NULL;
    338         psVector* vec2 = NULL;
    339 
    340         vec = psVectorAlloc( 100, PS_TYPE_C32 );
    341         vec->n = vec->nalloc;
    342         for ( psU32 n = 0; n < 100; n++ )
    343         {
    344             vec->data.C32[ n ] = n + I * ( n * 2 );
    345         }
    346 
    347         vec2 = psVectorConjugate(vec2, vec);
    348         ok(vec2 != NULL, "psVectorConjugate() returned non-NULL");
    349         ok(vec2->type.type == PS_TYPE_C32, "psVectorConjugate() returned the correct type");
    350 
    351         bool errorFlag = false;
    352         for ( psU32 n = 0; n < 100; n++ )
    353         {
    354             if ( fabsf( crealf( vec->data.C32[ n ] ) - crealf( vec2->data.C32[ n ] ) ) > FLT_EPSILON ||
    355                     fabsf( cimagf( vec->data.C32[ n ] ) + cimagf( vec2->data.C32[ n ] ) ) > FLT_EPSILON ) {
    356                 diag("psVectorConjugate result is incorrect (n=%d, %.2f+%.2fi)",
    357                      n, crealf( vec2->data.C32[ n ] ), cimagf( vec2->data.C32[ n ] ) );
    358                 errorFlag = true;
    359             };
    360         }
    361         ok(!errorFlag, "psVectorConjugate() returned the correct data values");
    362         psFree(vec);
    363 
    364         // Perform conjugate for non-complex number
    365         vec = psVectorAlloc( 100, PS_TYPE_F32 );
    366         vec->n = vec->nalloc;
    367         for ( psU32 n = 0; n < 100; n++ )
    368         {
    369             vec->data.F32[ n ] = n;
    370         }
    371         // Following should generate a warning message
    372         // XXX: verify warning
    373         vec2 = psVectorConjugate(vec2,vec);
    374         ok(vec2->type.type == PS_TYPE_F32, "psVectorConjugate did return a F32 vector");
    375 
    376         errorFlag = false;
    377         for ( psU32 n = 0; n < 100; n++ )
    378         {
    379             if( vec->data.F32[n] != vec2->data.F32[n] ) {
    380                 diag("psVectorConjugate result is incorrect (n=%d)",n);
    381                 errorFlag = true;
    382             }
    383         }
    384         ok(!errorFlag, "psVectorConjugate() returned the correct data values");
    385         psFree(vec);
    386 
    387         // Perform vector conjugate with C64 type
    388         vec = psVectorAlloc( 100, PS_TYPE_C64 );
    389         vec->n = vec->nalloc;
    390         for ( psU32 n = 0; n < 100; n++ )
    391         {
    392             vec->data.C64[n] = n + I * ( n * 2 );
    393         }
    394         vec2 = psVectorConjugate(vec2,vec);
    395         ok(vec2 != NULL, "psVectorConjugate() returned non-NULL");
    396         ok(vec2->type.type == PS_TYPE_C64, "psVectorConjugate() returned the correct type");
    397         errorFlag = false;
    398         for ( psU32 n = 0; n < 100; n++ )
    399         {
    400             if ( fabsf( crealf(vec->data.C64[n]) - crealf(vec2->data.C64[n])) > FLT_EPSILON ||
    401                     fabsf( cimagf(vec->data.C64[n]) + cimagf(vec2->data.C64[n])) > FLT_EPSILON ) {
    402                 diag("psVectorConjugate result is incorrect (n=%d)",n);
    403                 errorFlag = true;
    404             }
    405         }
    406         ok(!errorFlag, "psVectorConjugate() returned the correct data values");
    407         psFree(vec);
    408 
    409         // Perform vector conjugate with null input (vec2 should be freed too)
    410         ok(psVectorConjugate(vec2,NULL) == NULL, "psVectorConjugate() returned NULL with null input vector");
    411         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
     110        psVector *real = psVectorAlloc(512, PS_TYPE_F32);;
     111        psVector *imag = psVectorAlloc(512, PS_TYPE_F32);
     112        psVector *in = psVectorAlloc(512, PS_TYPE_F64);
     113        bool rc = psVectorForwardFFT(&real, &imag, in);
     114        ok(rc == false, "psVectorForwardFFT() returned FALSE with a incorrect input vector type");
     115        psFree(real);
     116        psFree(imag);
     117        psFree(in);
     118        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
    412119    }
    413120
    414 
    415     // testVectorPowerSpectrum()
    416     // 1. create a psC32 vector with unique real and imaginary components
    417     // 2. call psVectorPowerSpectrum
    418     // 3. verify result is psF32
    419     // 4. verify the values are the square of the absolute values of the original
    420     {
    421         psMemId id = psMemGetId();
    422         psVector * vec = NULL;
    423         psVector* vec2 = NULL;
    424         psVector* vec3 = NULL;
    425         psVector* vec4 = NULL;
    426         psF32 val;
    427         psF64 val1;
    428 
    429         vec = psVectorAlloc( 100, PS_TYPE_C32 );
    430         vec->n = vec->nalloc;
    431         vec3 = psVectorAlloc(100,PS_TYPE_C64);
    432         vec3->n = vec3->nalloc;
    433         for ( psU32 n = 0; n < 100; n++ )
    434         {
    435             vec->data.C32[ n ] = n + I * sinf( ( ( psF32 ) n ) / 50.f * M_PI );
    436             vec3->data.C64[ n ] = n + I * sinf( ( ( psF64 ) n ) / 50.f * M_PI );
    437         }
    438 
    439         vec2 = psVectorPowerSpectrum(vec2, vec);
    440         ok(vec2 != NULL, "psVectorPowerSpectrum() returned non-NULL");
    441         vec4 = psVectorPowerSpectrum(vec4, vec3);
    442         ok(vec4 != NULL, "psVectorPowerSpectrum() returned non-NULL");
    443         // XXX: These next two tests fail
    444         ok(vec2->type.type == PS_TYPE_F32, "psVectorPowerSpectrum() returned the correct type");
    445         ok(vec4->type.type == PS_TYPE_F64, "psVectorPowerSpectrum() returned the correct type");
    446 
    447         val = cabsf( vec->data.C32[ 0 ] ) * cabsf( vec->data.C32[ 0 ] ) / 100 / 100;
    448         val1= cabsf( vec3->data.C64[0] ) * cabsf(vec3->data.C64[0])/100/100;
    449         ok(fabsf(vec2->data.F32[ 0 ] - val ) <= FLT_EPSILON,
    450            "psVectorPowerSpectrum result is correct (n=0, %.2f %.2f)",
    451            vec2->data.F32[ 0 ], val );
    452         ok(fabsf( vec4->data.C64[0] - val1 ) <= FLT_EPSILON,
    453            "psVectorPowerSpectrum result is correct (n=0)");
    454 
    455         bool errorFlag = false;
    456         for ( psU32 n = 1; n < 50; n++ )
    457         {
    458             val = ( cabsf( vec->data.C32[ n ] ) * cabsf( vec->data.C32[ n ] ) +
    459                     cabsf( vec->data.C32[ 100 - n ] ) * cabsf( vec->data.C32[ 100 - n ] ) ) / 100 / 100;
    460             val1 = (cabsf(vec3->data.C64[n]) * cabsf(vec3->data.C64[n]) +
    461                     cabsf(vec3->data.C64[100-n]) * cabsf(vec3->data.C64[100-n]))/100/100;
    462             if ( fabsf( val - vec2->data.F32[ n ] ) > 10*FLT_EPSILON ) {
    463                 diag("psVectorPowerSpectrum result is incorrect (n=%d, %.2f %.2f)",
    464                      n, vec2->data.F32[ n ], val );
    465                 errorFlag = true;
    466             }
    467             if (fabsf(val1 - vec4->data.F64[n]) > 10*FLT_EPSILON) {
    468                 diag("psVectorPowerSpectrum result is incorrect (n=%d, %.2f %.2f)",n,vec4->data.F64[n],val1);
    469                 errorFlag = true;
    470             }
    471         }
    472         ok(!errorFlag, "psVectorPowerSpectrum() returned the correct data values");
    473 
    474         val = cabsf( vec->data.C32[ 50 ] ) * cabsf( vec->data.C32[ 50 ] ) / 100 / 100;
    475         ok(fabsf( vec2->data.F32[ 50 ] - val ) <= 10*FLT_EPSILON,
    476            "psVectorPowerSpectrum result is correct (n=50, %.2f %.2f)",
    477            vec2->data.F32[ 0 ], val );
    478         psFree( vec );
    479         psFree( vec2 );
    480         psFree( vec3 );
    481         psFree( vec4 );
    482 
    483         // Perform vector power spectrum with non-complex number
    484         vec = psVectorAlloc(100,PS_TYPE_F32);
    485         vec->n = vec->nalloc;
    486         for( psU32 n=0; n<100; n++)
    487         {
    488             vec->data.F32[n] = n;
    489         }
    490 
    491         // Following should generate an error message
    492         // XXX: Verify error
    493         ok(psVectorPowerSpectrum(NULL,vec) == NULL,
    494            "psVectorPowerSpectrum() did return a NULL vector.");
    495         // Perform vector power spectrum with null input
    496         ok(psVectorPowerSpectrum(NULL,NULL) == NULL,
    497            "psVectorPowerSpectrum() did return NULL with null input vector");
    498 
    499         psFree(vec);
    500         ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
    501     }
     121    testFFT(128);                       // Real quick test
     122    testFFT(2048);                      // Test something big
     123    testFFT(123456);                    // Test something really big
    502124}
Note: See TracChangeset for help on using the changeset viewer.