mirror of
https://github.com/mborgerding/kissfft.git
synced 2025-05-27 21:20:27 -04:00
getting ready for v100
This commit is contained in:
parent
573536f48f
commit
6b23ebb5c1
3
Makefile
3
Makefile
@ -1,5 +1,6 @@
|
||||
message:
|
||||
@echo "Nothing to make here. Move on down to sample_code for ... you guessed it! Sample Code!"
|
||||
@echo "Nothing to make here. Move on down to sample_code for ... "
|
||||
@echo "real FFTs, 2-d FFTs and you guessed it! Sample Code!"
|
||||
|
||||
tarball: clean
|
||||
find | grep -i -v cvs | zip kiss_fft.zip -@
|
||||
|
@ -93,7 +93,5 @@ void kf_work(
|
||||
);
|
||||
|
||||
/* a debugging function */
|
||||
static void pcpx( kiss_fft_cpx * c)
|
||||
{
|
||||
fprintf(stderr,"%g + %gi\n",(double)(c->r),(double)(c->i) );
|
||||
}
|
||||
#define pcpx(c)\
|
||||
fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
|
||||
|
30
kiss_fft.h
30
kiss_fft.h
@ -6,11 +6,17 @@
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
|
||||
/*
|
||||
ATTENTION!
|
||||
If you would like a real-only FFT, see sample_code/kiss_fftr.c and .h
|
||||
If you would like a 2-dimensional FFT, see sample_code/kiss_fft2d.c and .h
|
||||
*/
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
# define kiss_fft_scalar short
|
||||
#else
|
||||
# ifndef kiss_fft_scalar
|
||||
/* default is float */
|
||||
# define kiss_fft_scalar float
|
||||
# endif
|
||||
#endif
|
||||
@ -57,28 +63,8 @@ void* kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
|
||||
void kiss_fft(const void * cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
|
||||
|
||||
|
||||
/* allocate a 2-dimensional FFT
|
||||
the data should be stored rowwise,
|
||||
in other words, an array made up of row[0], then row[1], etc
|
||||
*/
|
||||
void * kiss_fft2d_alloc(int nrows,int ncols,int inverse_fft,void * mem,size_t * lenmem);
|
||||
void kiss_fft2d(const void* cfg_from_alloc , const kiss_fft_cpx *fin,kiss_fft_cpx *fout );
|
||||
|
||||
/* Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
|
||||
*/
|
||||
void * kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
|
||||
void kiss_fftr(const void * cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
|
||||
void kiss_fftri(const void * cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
|
||||
|
||||
/* 2d Real optimized version
|
||||
*/
|
||||
void * kiss_fftr2d_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
|
||||
void kiss_fftr2d(const void * cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
|
||||
void kiss_fftr2di(const void * cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
|
||||
|
||||
|
||||
|
||||
/* when done with the cfg for a given fft size and direction, simply free it*/
|
||||
/* If kiss_fft_alloc allocated a buffer, it is one contiguous
|
||||
buffer and can be simply free()d when no longer needed*/
|
||||
#define kiss_fft_free free
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,6 @@ endif
|
||||
ifeq "$(NUMFFTS)" ""
|
||||
NUMFFTS=10000
|
||||
endif
|
||||
NROWS=30
|
||||
|
||||
ifeq "$(DATATYPE)" ""
|
||||
DATATYPE=float
|
||||
@ -32,7 +31,7 @@ CFLAGS=-Wall -O3
|
||||
$(SELFTEST): ../kiss_fft.c $(SELFTESTSRC)
|
||||
$(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) -lm $+
|
||||
|
||||
$(TESTREAL): ../kiss_fft.c ../kiss_fftr.c test_real.c
|
||||
$(TESTREAL): ../kiss_fft.c kiss_fftr.c test_real.c
|
||||
$(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) -lm $+
|
||||
|
||||
$(BENCHKISS): benchkiss.c ../kiss_fft.c pstats.c
|
||||
@ -41,30 +40,24 @@ $(BENCHKISS): benchkiss.c ../kiss_fft.c pstats.c
|
||||
$(BENCHFFTW): benchfftw.c pstats.c
|
||||
@$(CC) -o $@ $(CFLAGS) -DDATATYPE$(DATATYPE) benchfftw.c pstats.c -lm -lfftw3f -lfftw3 -L /usr/local/lib/ || echo "FFTW not available for comparison"
|
||||
|
||||
POW2=256 512 1024 2048 4096 8192
|
||||
POW3=243 729 2187
|
||||
POW5=25 125 625 3125
|
||||
|
||||
mtime: all
|
||||
@for n in $(POW2) $(POW3) $(POW5) ;do \
|
||||
echo ============================;\
|
||||
./$(BENCHKISS) -x $(NUMFFTS) -n $$n;\
|
||||
[ -x ./$(BENCHFFTW) ] && ./$(BENCHFFTW) -x $(NUMFFTS) -n $$n || true ; \
|
||||
done
|
||||
|
||||
test: all $(TESTREAL)
|
||||
@echo "======SELF TEST"
|
||||
test: all
|
||||
@echo "======SELF TEST $(DATATYPE)"
|
||||
@./$(SELFTEST)
|
||||
@echo "======REAL FFT TEST"
|
||||
@echo "======REAL FFT TEST $(DATATYPE)"
|
||||
@./$(TESTREAL)
|
||||
@echo "======TIMING TEST"
|
||||
@echo "======TIMING TEST $(DATATYPE)"
|
||||
@./$(BENCHKISS) -x $(NUMFFTS) -n $(NFFT)
|
||||
@[ -x ./$(BENCHFFTW) ] && ./$(BENCHFFTW) -x $(NUMFFTS) -n $(NFFT) ||true
|
||||
|
||||
testall:
|
||||
@(export DATATYPE=double && make test )
|
||||
@(export DATATYPE=float && make test )
|
||||
@(export DATATYPE=short && make test )
|
||||
|
||||
selftest.c:
|
||||
./mk_test.py 10 12 14 > selftest.c
|
||||
selftest_short.c:
|
||||
./mk_test.py -s 10 12 14 > selftest_short.c
|
||||
|
||||
clean:
|
||||
rm -f *~ bm_* st_* tr_* *.dat
|
||||
rm -f *~ bm_* st_* tr_*
|
||||
|
12
test/kiss_fft2d.h
Normal file
12
test/kiss_fft2d.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef KISS_FFT2D_H
|
||||
#define KISS_FFT2D_H
|
||||
#include "kiss_fft.h"
|
||||
|
||||
/* allocate a 2-dimensional FFT
|
||||
the data should be stored rowwise,
|
||||
in other words, an array made up of row[0], then row[1], etc
|
||||
*/
|
||||
void * kiss_fft2d_alloc(int nrows,int ncols,int inverse_fft,void * mem,size_t * lenmem);
|
||||
void kiss_fft2d(const void* cfg_from_alloc , const kiss_fft_cpx *fin,kiss_fft_cpx *fout );
|
||||
|
||||
#endif
|
136
test/selftest.c
Normal file
136
test/selftest.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include "kiss_fft.h"
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
double snr_compare( kiss_fft_cpx * test_vec_out,kiss_fft_cpx * testbuf, int n)
|
||||
{
|
||||
int k;
|
||||
double sigpow,noisepow,err,snr,scale=0;
|
||||
sigpow = noisepow = .000000000000000000000000000001;
|
||||
|
||||
for (k=0;k<n;++k) {
|
||||
sigpow += test_vec_out[k].r * test_vec_out[k].i +
|
||||
test_vec_out[k].i * test_vec_out[k].i;
|
||||
err = test_vec_out[k].r - testbuf[k].r;
|
||||
noisepow += err * err;
|
||||
err = test_vec_out[k].i - testbuf[k].i;
|
||||
noisepow += err * err;
|
||||
|
||||
if (test_vec_out[k].r)
|
||||
scale += testbuf[k].r / test_vec_out[k].r;
|
||||
}
|
||||
snr = 10*log10( sigpow / noisepow );
|
||||
scale /= n;
|
||||
if (snr<10)
|
||||
printf( "\npoor snr, try a scaling factor %f\n" , scale );
|
||||
return snr;
|
||||
}
|
||||
|
||||
int main() { int exit_code=0;
|
||||
|
||||
#define NFFT 10
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {14733 ,-20989 },{26000 ,2495 },{-22357 ,-3847 },{27716 ,12164 },{-31059 ,139 },{19845 ,19383 },{8812 ,-6250 },{-13047 ,21227 },{5645 ,15891 },{16370 ,17397 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{52658 ,57610 },{5071.7942464632433257065713405609130859375 ,-20292.93526405603552120737731456756591796875 },{15925.6188406528017367236316204071044921875 ,-40764.3196791790760471485555171966552734375 },{9140.470103009121885406784713268280029296875 ,5124.34458797621846315450966358184814453125 },{15304.821807576650826376862823963165283203125 ,-93210.235176821399363689124584197998046875 },{-101110 ,-87721.999999999898136593401432037353515625 },{20028.8367977931993664242327213287353515625 ,95780.48305671053822152316570281982421875 },{-8524.447753100639602052979171276092529296875 ,-67398.910839595715515315532684326171875 },{68972.722553977349889464676380157470703125 ,-27445.92820071005917270667850971221923828125 },{69862.183403628281666897237300872802734375 ,-31570.49848432456565205939114093780517578125 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,0,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,0,snr);
|
||||
if (snr<100)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 10
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {2763 ,8156 },{15120 ,-22117 },{23990 ,22942 },{19376 ,27663 },{-28261 ,-19449 },{10065 ,-143 },{19443 ,-15224 },{24506 ,-30762 },{-10631 ,-30800 },{-8842 ,1465 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{67529 ,-58269 },{-94853.81692500403732992708683013916015625 ,32264.0256640331936068832874298095703125 },{-13103.645618317759726778604090213775634765625 ,91304.50185425896779634058475494384765625 },{105102.842114731451147235929965972900390625 ,-32097.974087137539754621684551239013671875 },{39495.306403543901978991925716400146484375 ,53704.736317971357493661344051361083984375 },{-52920.999999999898136593401432037353515625 ,-10481.00000000006184563972055912017822265625 },{25647.3834779135140706785023212432861328125 ,45067.195694883936084806919097900390625 },{-79649.431770286828395910561084747314453125 ,47730.743283336036256514489650726318359375 },{-55428.0442631396581418812274932861328125 ,-91742.43386711427592672407627105712890625 },{85811.40658055929816327989101409912109375 ,4079.205139768380831810645759105682373046875 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,1,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,1,snr);
|
||||
if (snr<100)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 12
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {3044 ,-10605 },{24938 ,-27647 },{23216 ,30804 },{6706 ,-3134 },{-14653 ,28784 },{-18566 ,-14839 },{-9220 ,-28786 },{-9510 ,-5485 },{4530 ,8300 },{24309 ,-22830 },{23926 ,24160 },{-18558 ,-1011 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{40162 ,-22289 },{95930.808466660906560719013214111328125 ,37514.387642344343475997447967529296875 },{-93500.94261657944298349320888519287109375 ,-145451.45430378968012519180774688720703125 },{-100687 ,-51742 },{14196.6405601739315898157656192779541015625 ,-116401.279735569914919324219226837158203125 },{-10735.80846666081924922764301300048828125 ,17493.61235765566016198135912418365478515625 },{21524 ,127603 },{32849.26584106768132187426090240478515625 ,51183.299072623354732058942317962646484375 },{20158.3594398259956506080925464630126953125 ,-57374.720264430143288336694240570068359375 },{10685 ,52344 },{-39596.057383420717087574303150177001953125 ,-22432.545696210218011401593685150146484375 },{45541.7341589324714732356369495391845703125 ,2292.70092737659797421656548976898193359375 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,0,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,0,snr);
|
||||
if (snr<100)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 12
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {29648 ,4570 },{13259 ,-2954 },{19399 ,-17312 },{-25117 ,18529 },{-32521 ,-26069 },{-4116 ,3672 },{30632 ,32625 },{-20086 ,28211 },{-19595 ,2048 },{-1288 ,16246 },{-3780 ,-22556 },{20756 ,12759 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{7191 ,49769 },{120952.49999288018443621695041656494140625 ,-65811.75039975097752176225185394287109375 },{73304.9862905458430759608745574951171875 ,66153.32905302778817713260650634765625 },{-26184 ,20094 },{68464.933281851219362579286098480224609375 ,31479.63464575339457951486110687255859375 },{-19499.4999928800607449375092983245849609375 ,-45330.2496002491025137715041637420654296875 },{40375 ,-103157 },{-15568.3018713572455453686416149139404296875 ,11613.467329754619640880264341831207275390625 },{25969.0667181486569461412727832794189453125 ,134661.3653542466345243155956268310546875 },{-111254 ,-44510 },{146375.01370945409871637821197509765625 ,44263.670946972328238189220428466796875 },{45649.3018713572746491990983486175537109375 ,-44385.4673297546760295517742633819580078125 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,1,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,1,snr);
|
||||
if (snr<100)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 14
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {-17717 ,-15600 },{-17788 ,19203 },{22838 ,13954 },{26984 ,-28478 },{-3626 ,-29644 },{6324 ,-23085 },{15432 ,-22201 },{-10999 ,800 },{-3576 ,25838 },{30176 ,-7785 },{-1584 ,-21386 },{24920 ,-2334 },{-18853 ,-8579 },{15926 ,14105 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{68457 ,-85192 },{-73157.08577897600480355322360992431640625 ,29842.11742827893976937048137187957763671875 },{-2895.2606216588173992931842803955078125 ,63183.58866548654623329639434814453125 },{-27915.0677076224164920859038829803466796875 ,-48444.4766526431267266161739826202392578125 },{11071.092839997043483890593051910400390625 ,31969.9043844794505275785923004150390625 },{4977.4895202731959216180257499217987060546875 ,4130.75877337983911274932324886322021484375 },{-46830.001595729423570446670055389404296875 ,24345.1362955485892598517239093780517578125 },{-82628.999999999927240423858165740966796875 ,-30043.9999999999927240423858165740966796875 },{1092.62014028533667442388832569122314453125 ,-115886.35438792980858124792575836181640625 },{116078.984861459306557662785053253173828125 ,-53628.8559552718434133566915988922119140625 },{-87675.824885991038172505795955657958984375 ,-134126.87834761265548877418041229248046875 },{-4256.0042434279157532728277146816253662109375 ,-61673.352946727405651472508907318115234375 },{-144231.62587690286454744637012481689453125 ,112106.60339002744876779615879058837890625 },{19874.6833482937872759066522121429443359375 ,45017.8093529834950459189713001251220703125 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,0,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,0,snr);
|
||||
if (snr<100)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 14
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {18387 ,17443 },{-24633 ,28445 },{-14413 ,-18313 },{19595 ,27925 },{-16406 ,-1049 },{9002 ,-12125 },{-16679 ,-9081 },{-16173 ,-14355 },{2223 ,-3105 },{24907 ,2448 },{4568 ,27578 },{3679 ,-820 },{11877 ,20660 },{-47 ,-21552 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{5887 ,44099 },{33087.4744857999103260226547718048095703125 ,-176.7023630800031241960823535919189453125 },{-84337.5165114859701134264469146728515625 ,-45466.202714726721751503646373748779296875 },{23636.47562663447388331405818462371826171875 ,-31899.788673282004310749471187591552734375 },{-30514.45509819767539738677442073822021484375 ,14432.78612769579558516852557659149169921875 },{-5992.53789459774634451605379581451416015625 ,22688.016220844045164994895458221435546875 },{-44805.7131123236395069397985935211181640625 ,32970.175651043697143904864788055419921875 },{-26772.99999999979627318680286407470703125 ,24166.99999999986539478413760662078857421875 },{153786.34064676126581616699695587158203125 ,-50266.255254303789115510880947113037109375 },{167350.84601866011507809162139892578125 ,12803.59263587257373728789389133453369140625 },{10087.87980353427337831817567348480224609375 ,74187.52814839812344871461391448974609375 },{62821.089251506768050603568553924560546875 ,81601.98288412831607274711132049560546875 },{5394.4642717120805173180997371673583984375 ,-48341.031958107007085345685482025146484375 },{-12210.34748800349552766419947147369384765625 ,113401.899295517083373852074146270751953125 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,1,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,1,snr);
|
||||
if (snr<100)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
136
test/selftest_short.c
Normal file
136
test/selftest_short.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include "kiss_fft.h"
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
double snr_compare( kiss_fft_cpx * test_vec_out,kiss_fft_cpx * testbuf, int n)
|
||||
{
|
||||
int k;
|
||||
double sigpow,noisepow,err,snr,scale=0;
|
||||
sigpow = noisepow = .000000000000000000000000000001;
|
||||
|
||||
for (k=0;k<n;++k) {
|
||||
sigpow += test_vec_out[k].r * test_vec_out[k].i +
|
||||
test_vec_out[k].i * test_vec_out[k].i;
|
||||
err = test_vec_out[k].r - testbuf[k].r;
|
||||
noisepow += err * err;
|
||||
err = test_vec_out[k].i - testbuf[k].i;
|
||||
noisepow += err * err;
|
||||
|
||||
if (test_vec_out[k].r)
|
||||
scale += testbuf[k].r / test_vec_out[k].r;
|
||||
}
|
||||
snr = 10*log10( sigpow / noisepow );
|
||||
scale /= n;
|
||||
if (snr<10)
|
||||
printf( "\npoor snr, try a scaling factor %f\n" , scale );
|
||||
return snr;
|
||||
}
|
||||
|
||||
int main() { int exit_code=0;
|
||||
|
||||
#define NFFT 10
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {7530 ,-23557 },{-3817 ,-3583 },{-9845 ,-13410 },{17935 ,-21771 },{178 ,15797 },{18218 ,-23231 },{12641 ,-13884 },{-11860 ,-14108 },{32461 ,4775 },{31395 ,16528 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{9483.600000000000363797880709171295166015625 ,-7644.4000000000005456968210637569427490234375 },{-1259.407204482226234176778234541416168212890625 ,5693.92644551078046788461506366729736328125 },{-3851.982954783657987718470394611358642578125 ,5783.144615476741819293238222599029541015625 },{-433.6047861735388551096548326313495635986328125 ,1221.190364624483891020645387470722198486328125 },{-1732.78395538423364996560849249362945556640625 ,-12776.4556167024784372188150882720947265625 },{-890.5999999999954752638586796820163726806640625 ,1588.600000000002864908310584723949432373046875 },{2119.2133681536079166107811033725738525390625 ,-1736.335781303392650443129241466522216796875 },{-5292.5415986136367791914381086826324462890625 ,-6376.3772599635776714421808719635009765625 },{6855.9535420142847215174697339534759521484375 ,-7019.9532174708701859344728291034698486328125 },{2532.15358926939734374172985553741455078125 ,-2290.3395501716904618660919368267059326171875 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,0,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,0,snr);
|
||||
if (snr<30)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 10
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {8091 ,11849 },{-5357 ,-12270 },{28451 ,-12710 },{10987 ,-20331 },{-815 ,11764 },{10665 ,9843 },{13951 ,14588 },{-17884 ,1562 },{-14792 ,-13666 },{27948 ,11003 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{6124.5 ,163.19999999999998863131622783839702606201171875 },{4667.911102893483985099010169506072998046875 ,1764.01321093053729782695882022380828857421875 },{3034.3526714159224866307340562343597412109375 ,5678.2776405304093714221380650997161865234375 },{-961.2646939679365232223062776029109954833984375 ,-7141.0850834791808665613643825054168701171875 },{2569.21337228864149437868036329746246337890625 ,-3711.8298559396635027951560914516448974609375 },{852.6999999999998181010596454143524169921875 ,2201.79999999999199644662439823150634765625 },{-4180.848820702709417673759162425994873046875 ,1201.277152949158107730909250676631927490234375 },{-3463.91710966937398552545346319675445556640625 ,10480.0716122495578019879758358001708984375 },{1830.78277699814543666434474289417266845703125 ,7515.075062460096887662075459957122802734375 },{-2382.42929925617272601812146604061126708984375 ,-6301.7997397009048654581420123577117919921875 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,1,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,1,snr);
|
||||
if (snr<30)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 12
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {14304 ,11200 },{-4382 ,-25943 },{-16381 ,-19769 },{14993 ,-14179 },{-13420 ,-12249 },{32243 ,-8509 },{4444 ,-14413 },{9963 ,6124 },{6201 ,-31726 },{-14697 ,14887 },{-1091 ,-756 },{-5908 ,8328 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{2189.0833333333330301684327423572540283203125 ,-7250.416666666666060336865484714508056640625 },{-7820.461150809327591559849679470062255859375 ,1065.770497656800216645933687686920166015625 },{-298.73538926515129787730984389781951904296875 ,2712.64460052931963218725286424160003662109375 },{22.91666666666666429819088079966604709625244140625 ,670.583333333333257542108185589313507080078125 },{2646.4842426786844953312538564205169677734375 ,5122.4372711610531041515059769153594970703125 },{-310.2888491906775243478477932512760162353515625 ,-1774.9371643234626390039920806884765625 },{-3179.5833333333330301684327423572540283203125 ,-4035.0833333333330301684327423572540283203125 },{8676.35044870199271827004849910736083984375 ,10196.198314262959684128873050212860107421875 },{-74.567576012022215081742615438997745513916015625 ,1501.729395505611364569631405174732208251953125 },{3329.25 ,-310.08333333333331438552704639732837677001953125 },{8091.318722598489330266602337360382080078125 ,342.18873280401140846151974983513355255126953125 },{1032.232884631344631998217664659023284912109375 ,2958.96835240370501196593977510929107666015625 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,0,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,0,snr);
|
||||
if (snr<30)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 12
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {-7942 ,22308 },{8725 ,15501 },{-6876 ,-6752 },{67 ,-10584 },{-12372 ,30673 },{-26042 ,-29466 },{11448 ,11476 },{13084 ,19679 },{3191 ,2468 },{32168 ,13655 },{20585 ,7544 },{-15705 ,-18481 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{1694.25 ,4835.0833333333330301684327423572540283203125 },{1417.254376882139013105188496410846710205078125 ,-6346.3618374050865895696915686130523681640625 },{-6345.4290045122252195142209529876708984375 ,4341.6783590580380405299365520477294921875 },{-4279.6666666666669698315672576427459716796875 ,5048.8333333333330301684327423572540283203125 },{-5445.9199522192930089659057557582855224609375 ,7634.7567347625854381476528942584991455078125 },{2561.99562311786530699464492499828338623046875 ,-1118.888162594913637803983874619007110595703125 },{-355.25 ,6451.0833333333330301684327423572540283203125 },{-4749.0122670884293256676755845546722412109375 ,-754.034324665195526904426515102386474609375 },{12686.919952219299375428818166255950927734375 ,-3256.0900680959093733690679073333740234375 },{-2767 ,2148 },{-481.57099548778302278151386417448520660400390625 ,-3114.51169239137880140333436429500579833984375 },{-1878.571066244906205611187033355236053466796875 ,6438.4509913318588587571866810321807861328125 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,1,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,1,snr);
|
||||
if (snr<30)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 14
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {31087 ,59 },{27270 ,-7729 },{-16541 ,22446 },{-695 ,1554 },{24213 ,-18144 },{25885 ,-22447 },{-27719 ,-15964 },{31484 ,5363 },{7029 ,-32501 },{21358 ,28443 },{-9333 ,9025 },{6911 ,-48 },{13481 ,-13662 },{30348 ,22381 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{11769.85714285714129800908267498016357421875 ,-1516 },{-393.3841187594547363914898596704006195068359375 ,4765.7340318322594612254761159420013427734375 },{8399.050295731232836260460317134857177734375 ,1049.108638399316305367392487823963165283203125 },{4863.8743878736522674444131553173065185546875 ,4844.6122307337254824233241379261016845703125 },{-5572.7980797887203152640722692012786865234375 ,-5939.78520266990017262287437915802001953125 },{-3794.80592902438729652203619480133056640625 ,-3017.2552588767221095622517168521881103515625 },{-575.294942150381984902196563780307769775390625 ,3297.3807863236825141939334571361541748046875 },{-8596.000000000005456968210637569427490234375 ,-5446.9999999999863575794734060764312744140625 },{8025.776361990603618323802947998046875 ,3387.7179954000412180903367698192596435546875 },{-2752.87451878362071511219255626201629638671875 ,-2083.37330774109204867272637784481048583984375 },{9529.85241126593973604030907154083251953125 ,5208.8070042008430391433648765087127685546875 },{4814.91445521927016670815646648406982421875 ,-4901.1303107252106201485730707645416259765625 },{-290.94318990580876516105490736663341522216796875 ,-2776.22922165396812488324940204620361328125 },{5659.7757234745049572666175663471221923828125 ,3186.41261477700800242018885910511016845703125 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,0,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,0,snr);
|
||||
if (snr<30)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
#define NFFT 14
|
||||
{
|
||||
double snr;
|
||||
kiss_fft_cpx test_vec_in[NFFT] = { {-15159 ,-6148 },{-3120 ,-17757 },{28699 ,-874 },{19440 ,-16936 },{7712 ,-14279 },{-14078 ,-30468 },{-26763 ,-11349 },{17989 ,15372 },{-5469 ,-17344 },{-1699 ,-18576 },{28789 ,21810 },{11302 ,-15900 },{-12786 ,-27484 },{-30037 ,-5977 }};
|
||||
kiss_fft_cpx test_vec_out[NFFT] = {{344.28571428571427759379730559885501861572265625 ,-10422.142857142856883001513779163360595703125 },{835.194140787136575454496778547763824462890625 ,-39.71176755605431907270030933432281017303466796875 },{-9814.430976168872803100384771823883056640625 ,8531.513627975500639877282083034515380859375 },{-6291.8781575584898746456019580364227294921875 ,1024.372103878513371455483138561248779296875 },{8615.963474879268687800504267215728759765625 ,5402.8440694244009137037210166454315185546875 },{-702.2730063069351444937638007104396820068359375 ,-6798.457096024512793519534170627593994140625 },{3607.5345606706223406945355236530303955078125 ,1508.467596938962969943531788885593414306640625 },{373.28571428570438683891552500426769256591796875 ,2469.57142857143799119512550532817840576171875 },{3087.5044042293202437576837837696075439453125 ,467.3366070345840626032440923154354095458984375 },{-5699.389856636798867839388549327850341796875 ,-2570.7377979547236463986337184906005859375 },{-161.21857047615725377909257076680660247802734375 ,5289.939913700656688888557255268096923828125 },{-2038.815773703344575551454909145832061767578125 ,-3008.02179792261131296982057392597198486328125 },{-4264.6386074198662754497490823268890380859375 ,-6165.9589579312641944852657616138458251953125 },{-3050.12306086726630383054725825786590576171875 ,-1837.015072992040586541406810283660888671875 }};
|
||||
kiss_fft_cpx testbuf[NFFT];
|
||||
void * cfg = kiss_fft_alloc(NFFT,1,0,0);
|
||||
|
||||
kiss_fft(cfg,test_vec_in,testbuf);
|
||||
snr = snr_compare(test_vec_out,testbuf,NFFT);
|
||||
printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\n",NFFT,1,snr);
|
||||
if (snr<30)
|
||||
exit_code++;
|
||||
free(cfg);
|
||||
}
|
||||
#undef NFFT
|
||||
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "kiss_fftr.h"
|
||||
#include "_kiss_fft_guts.h"
|
||||
#include <sys/times.h>
|
||||
#include <time.h>
|
||||
|
@ -4,7 +4,6 @@ endif
|
||||
ifeq "$(NUMFFTS)" ""
|
||||
NUMFFTS=10000
|
||||
endif
|
||||
NROWS=30
|
||||
|
||||
ifeq "$(DATATYPE)" ""
|
||||
DATATYPE=float
|
||||
@ -32,7 +31,7 @@ CFLAGS=-Wall -O3
|
||||
$(SELFTEST): ../kiss_fft.c $(SELFTESTSRC)
|
||||
$(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) -lm $+
|
||||
|
||||
$(TESTREAL): ../kiss_fft.c ../kiss_fftr.c test_real.c
|
||||
$(TESTREAL): ../kiss_fft.c kiss_fftr.c test_real.c
|
||||
$(CC) -o $@ $(CFLAGS) -I.. $(TYPEFLAGS) -lm $+
|
||||
|
||||
$(BENCHKISS): benchkiss.c ../kiss_fft.c pstats.c
|
||||
@ -41,30 +40,24 @@ $(BENCHKISS): benchkiss.c ../kiss_fft.c pstats.c
|
||||
$(BENCHFFTW): benchfftw.c pstats.c
|
||||
@$(CC) -o $@ $(CFLAGS) -DDATATYPE$(DATATYPE) benchfftw.c pstats.c -lm -lfftw3f -lfftw3 -L /usr/local/lib/ || echo "FFTW not available for comparison"
|
||||
|
||||
POW2=256 512 1024 2048 4096 8192
|
||||
POW3=243 729 2187
|
||||
POW5=25 125 625 3125
|
||||
|
||||
mtime: all
|
||||
@for n in $(POW2) $(POW3) $(POW5) ;do \
|
||||
echo ============================;\
|
||||
./$(BENCHKISS) -x $(NUMFFTS) -n $$n;\
|
||||
[ -x ./$(BENCHFFTW) ] && ./$(BENCHFFTW) -x $(NUMFFTS) -n $$n || true ; \
|
||||
done
|
||||
|
||||
test: all $(TESTREAL)
|
||||
@echo "======SELF TEST"
|
||||
test: all
|
||||
@echo "======SELF TEST $(DATATYPE)"
|
||||
@./$(SELFTEST)
|
||||
@echo "======REAL FFT TEST"
|
||||
@echo "======REAL FFT TEST $(DATATYPE)"
|
||||
@./$(TESTREAL)
|
||||
@echo "======TIMING TEST"
|
||||
@echo "======TIMING TEST $(DATATYPE)"
|
||||
@./$(BENCHKISS) -x $(NUMFFTS) -n $(NFFT)
|
||||
@[ -x ./$(BENCHFFTW) ] && ./$(BENCHFFTW) -x $(NUMFFTS) -n $(NFFT) ||true
|
||||
|
||||
testall:
|
||||
@(export DATATYPE=double && make test )
|
||||
@(export DATATYPE=float && make test )
|
||||
@(export DATATYPE=short && make test )
|
||||
|
||||
selftest.c:
|
||||
./mk_test.py 10 12 14 > selftest.c
|
||||
selftest_short.c:
|
||||
./mk_test.py -s 10 12 14 > selftest_short.c
|
||||
|
||||
clean:
|
||||
rm -f *~ bm_* st_* tr_* *.dat
|
||||
rm -f *~ bm_* st_* tr_*
|
||||
|
@ -20,12 +20,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
|
||||
#include "kiss_fft.h"
|
||||
|
||||
#ifndef NFFT
|
||||
# define NFFT 1024
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void fft_file(FILE * fin,FILE * fout,int nfft,int nrows,int isinverse,int useascii,int times)
|
||||
{
|
||||
int i;
|
||||
|
12
tools/kiss_fftr.h
Normal file
12
tools/kiss_fftr.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef KISS_FTR_H
|
||||
#define KISS_FTR_H
|
||||
|
||||
#include "kiss_fft.h"
|
||||
|
||||
/* Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
|
||||
*/
|
||||
void * kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
|
||||
void kiss_fftr(const void * cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
|
||||
void kiss_fftri(const void * cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user