IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.