谁有用delphi编写的FFT程序,急用!!!
发布网友
发布时间:2022-07-27 00:48
我来回答
共2个回答
热心网友
时间:2023-10-23 19:10
unit FFT;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, VarCmplx;
type
//自定义复数类型
TComplexData = record
vReal,vImaginary: Double;
end;
TComplexDataArray = array of TComplexData; //实数数组
TExtendedArray = array of Extended; //复数数组
procere DoFFT(TD:TExtendedArray; var FD:TExtendedArray; r:Integer);
implementation
//复数相加
function ComplexAdd(c1,c2:TComplexData):TComplexData;
begin
result.vReal:=c1.vReal+c2.vReal;
result.vImaginary:=c1.vImaginary+c2.vImaginary;
end;
//复数相减
function ComplexMinus(c1,c2:TComplexData):TComplexData;
begin
result.vReal:=c1.vReal-c2.vReal;
result.vImaginary:=c1.vImaginary-c2.vImaginary;
end;
//复数相乘
function ComplexMultiply(c1,c2:TComplexData):TComplexData;
begin
result.vReal:=c1.vReal*c2.vReal-c1.vImaginary*c2.vImaginary;
result.vImaginary:=c1.vReal*c2.vImaginary+c1.vImaginary*c2.vReal;
end;
//复数数组互换
procere ComplexArrayWrap(var a1,a2:TComplexDataArray);
var
a:TComplexDataArray;
begin
a:=a1;
a1:=a2;
a2:=a;
Setlength(a,0);
end;
procere DoFFT(TD:TExtendedArray; var FD:TExtendedArray; r:Integer);
var
count : Longint; //傅立叶变换点数
i,j,k : Integer; //循环变量
bfsize,p : Integer; //中间变量
angle : Double; //角度
W,X1,X2 : TComplexDataArray;
begin
count:= 1 shl r; //傅立叶变换点数
// 分配运算所需存储器
SetLength(W, count div 2);
SetLength(X1,count);
SetLength(X2,count);
// 计算加权系数
for i:=0 to count div 2 -1 do
begin
angle := -i * PI * 2 / count;
W[i].vReal := cos(angle);
W[i].vImaginary := sin(angle);
end;
// 将时域点写入X1
for i:=0 to count-1 do
begin
X1[i].vReal:=TD[i];
X1[i].vImaginary:=0;
end;
// 采用蝶形算法进行快速傅立叶变换
for k:=0 to r-1 do
begin
for j:=0 to (1 shl k)-1 do
begin
bfsize:= 1 shl (r-k);
for i:=0 to bfsize div 2 -1 do
begin
p := j * bfsize;
X2[i+p]:=ComplexAdd(X1[i+p],X1[i+p+bfsize div 2]);
X2[i+p+bfsize div 2]:=ComplexMultiply(
ComplexMinus(X1[i+p],X1[i+p+ bfsize div 2]),
W[i*(1 shl k)]);
end;
end;
ComplexArrayWrap(X1,X2);
end;
// 重新排序
Setlength(Fd,count div 2);
for j:=0 to count div 2 - 1 do
begin
p := 0;
for i:=0 to r-1 do
begin
if (j and (1 shl i))>0 then
p:=p+(1 shl (r-i-1));
end;
FD[j]:=X1[p].vReal;
end;
// 释放内存
Setlength(W,0);
Setlength(X1,0);
Setlength(X2,0);
end;
end.
热心网友
时间:2023-10-23 19:11
我没有