Скачиваний:
57
Добавлен:
16.04.2013
Размер:
1.97 Кб
Скачать
#define _USE_MATH_DEFINES
#include <math.h>
#undef _USE_MATH_DEFINES
#include <assert.h>
#include "utils.h"
#include "myfft.h"

extern double RTable[];
extern double ImTable[];

int DoFFT(ComplexArray* x, int inverse)
{
	unsigned int k, l, j, n, p2nk, p2k1, tablePos;

	assert(x != 0);

	n = (unsigned int)floor(log(x->count)/M_LN2);

	if (BitCount(x->count) != 1)		
		return 0;

	ComplexArrayInverseOrder(x);
	
	p2nk = x->count >> 1;
	p2k1 = 1;

	tablePos = 0;

	//Is ifft ?
	inverse = inverse?-1:1;

	for (k=1; k<=n; ++k, p2k1 <<= 1, p2nk >>= 1)
	{
		double omegaKReal, omegaKImag;
		unsigned int p2k = p2k1 << 1;
		
		omegaKReal = RTable[tablePos];
		omegaKImag = inverse*ImTable[tablePos];

		++tablePos;

		for (j=0; j<=(p2nk - 1); ++j)
		{
			unsigned int oui = j*p2k;
			unsigned int oli = oui + p2k1;			

			double okr = omegaKReal;
			double oki = omegaKImag;

			double xru = x->r[oui];
			double xiu = x->i[oui];
			double xrl = x->r[oli];
			double xil = x->i[oli];
			
			x->r[oui] = xru + xrl;
			x->i[oui] = xiu + xil;
			x->r[oli] = xru - xrl;			
			x->i[oli] = xiu - xil;

			for (l=1; l<=(p2k1 - 1); ++l)
			{				
				double oldOkr;
				unsigned int ui = oui + l;
				unsigned int li = ui + p2k1;				

				double temp1 = okr*x->r[li] - oki*x->i[li];
				double temp2 = okr*x->i[li] + oki*x->r[li];

				double xr = x->r[ui];
				double xi = x->i[ui];
				
				x->r[ui] = xr + temp1;
				x->i[ui] = xi + temp2;
				x->r[li] = xr - temp1;				
				x->i[li] = xi - temp2;												

				oldOkr = okr;

				okr = okr*omegaKReal - oki*omegaKImag;
				oki = oldOkr*omegaKImag + oki*omegaKReal;
			}
		}
	}

	if (inverse == -1)
	{ //Normalize
		for (k=0; k<x->count; ++k )
		{
			x->r[k] /= x->count;
			x->i[k] /= x->count;
		}
	}

	return 1;
}

int myfft(ComplexArray* x)
{
	return DoFFT(x, 0);
}

int myifft(ComplexArray* x)
{
	return DoFFT(x, 1);
}
Соседние файлы в папке fft