4. Phạm vi luận án Error! Bookmark not defined.
8.3. Cài đặt thuật toán FFT Cooley-Tookey
Trình tự thuật toán FFT được thực hiện qua các bước sau:
- Kiểm tra độ dài mẫu tín hiệu đầu vào có là bội của 2 ( ) , nếu không là bội của 2 thì ta thêm các mẫu vào sau sao cho thỏa mãn yêu cầu, tính toán lưu lại giá trị i, chiều dài mẫu tín hiệu đầu vào:
//---
if (IsPowerOfTwo(end-begin+1)) {
length = end - begin + 1;
bitsInLength = Log2(length) - 1; }
else
{
bitsInLength = Log2(end - begin + 1); length = 1 << bitsInLength;
// the items will be pad with zeros }
//---
- Sắp xếp mảng đầu vào theo một trật tự mới, bằng phương pháp đảo bit, phương pháp đảo bit có thể hình dung như sau: xét mảng đầu vào x(N), phần tử tại vị trí 3=0x011 sẽ lưu giá trị của phần tử tại vị trí 0x110=6, nghĩa là x[3]=x[6], và ngược lại. Như vậy dựa vào vị trí ta tiến hành đảo ngược các bit này cho ra vị trí mới, gán giá trị lại theo trật tự mới.
//---
// bit reversa
//- Sắp xếp lưu vào mảng mới data, mỗi phần tử được xem như số phức, gồm 2 phần: phần thực, và phần ảo, khởi gán cho các giá trị đầu tiên phần ảo=0
ComplexNumber[] data = newComplexNumber[length]; for (int i = begin; i <= end; i++)
{
int j = ReverseBits(i, bitsInLength); data[j] = new ComplexNumber(x[i]); }
//-Phương thức Dịch chuyển bit
privatestaticint ReverseBits(int n, int bitsCount) {
int reversed = 0;
for (int i = 0; i < bitsCount; i++) {
int nextBit = n & 1; n >>= 1; reversed <<= 1; reversed |= nextBit; } return reversed; } //---
- Dữ liệu đầu vào đã được sắp xếp, áp dụng công thức (1.5), cài đặt thuật toán FFT Cooley-Tookey:
//---
// Cooley-Tukey
for (int i = 0; i < bitsInLength; i++) {
int m = 1 << i; int n = m * 2;
double alpha = -(2 * Math.PI / n);
for (int k = 0; k < m; k++) {
// e^(-2*pi/N*k)
ComplexNumber oddPartMultiplier = newComplexNumber(0, alpha * k).PoweredE();
for (int j = k; j < length; j += n) {
ComplexNumber evenPart = data[j];
ComplexNumber oddPart = oddPartMultiplier * data[j + m]; data[j] = evenPart + oddPart;
data[j + m] = evenPart - oddPart; }
} }
//---
Giải thích: Cooley-Tookey dựa trên ý tưởng chia để trị, với mẫu có độ dài 2^i thì số lần đệ quy chia sẽ là i lần, tương ứng với vòng for đầu tiên. Tại mỗi lần chia ta tính toán các giá trị đầu ra của DFT theo công thức (1.5).
//---
// calculate spectrogram
PublicVar.spectrogram = newdouble[length];
for (int i = 0; i < PublicVar.spectrogram.Length; i++) {
PublicVar.spectrogram[i] = data[i].AbsPower2(); }
// Phương thức AbsPower2
publicdouble AbsPower2() {
return Re * Re + Im * Im; }
//---
Như vậy ta đã thu được mảng giá trị là phổ tần số của tín hiệu đầu vào.