✅ 操作成功!

蝶形运算

发布时间:2023-06-05 作者:admin 来源:文学

蝶形运算

蝶形运算

七百字作文-疯狂作文

2023年2月19日发(作者:瀑布图)

【Java】快速傅⾥叶变换FFT的程序实现(时间抽取的基-2FFT、倒位计算、蝶

形运算)

Java——快速傅⾥叶变换(FFT)的程序实现

好久没来更新了,阿汪⼤三了。

这学期阿汪要学习两门课《数字信号处理》和《Java程序设计》,刚好前⼏天⽼师告诉我们不久后会有个实验,要求我们编写⼀个程序实现

快速傅⾥叶变换(FFT)。

所以,阿汪⽤Java写了⼀下。

//废话和原理就不多说了,直接上程序

//阿汪先⽣的博客.ws

r;

.*;

//对数函数

classLog{

staticpublicdoublelog(doublevalue,doublebase){

(value)/(base);

}

}

//乘⽅运算

classPow{

publicstaticintpowNM(intn,intm){

if(m==1)

returnn;

else

returnn*powNM(n,m-1);

//(m,n);

}

}

publicclassDFT_FFT{

publicstaticvoidmain(String[]args){

//初始化变量

finaldoublePI=3.141;

intN1=0;//序列的长度

intM=0;//序列的级数,数组的长度为2^M

intarraylength;//数组长度

inti=0;//输⼊数组的循环次数

intt=0;//输出数组的循环次数

///

//输⼊合法化

Scannersc=newScanner();

while(N1<2){

n("请确定你输⼊序列的长度!");

N1=t();

}

///

//判断长度并初始化数组

//确定N=2^M的级数M

M=((N1,2)==(int)(N1,2))?(int)(N1,2):((int)(N1,2))+1;

//确定数字长度

arraylength=(int)(2,M);

("序列长度N1为%d时,数组长度为%d,级数M为%d!n",N1,arraylength,M);

("序列长度N1为%d时,数组长度为%d,级数M为%d!n",N1,arraylength,M);

float[]Array=newfloat[arraylength];//实部

float[]IArray=newfloat[arraylength];//虚部

///

//输⼊序列

floatjc;//暂存转换后的数据

Stringxy;

("请依次输⼊序列的%d个值:n",N1);

n("");

while(i

("x[%d]实部:n",i);

xy=();

if(((0)57)){//输⼊不是数字

n("阿汪先⽣(a_wang_xian_sheng)的博客!");

break;//跳出循环输⼊

}

if(((0)>=48|(0)<=57)){//输⼊数字

jc=loat(xy);//String转化成float类型

Array[i]=jc;//保存String转存下来的数字

}

("x[%d]虚部:n",i);//输⼊虚部

IArray[i]=oat();//录⼊数字

i++;

}

n("");

n("输⼊结果如下:");

while(t

("x[%d]=",t);

(Array[t]);

("+j(%f)n",IArray[t]);

t++;

}

//

intw=0;//倒序处理时的外循环次数

intj=0;//倒序处理时的内循环次数

floatws=0;//倒序处理时的数组间值传递变量

intp=0;//倒序处理时下⼀倒位序的确定变量

intw1=0;//倒序处理时的外循环次数

intj1=0;//倒序处理时的内循环次数

floatws1=0;//倒序处理时的数组间值传递变量

intp1=0;//倒序处理时下⼀倒位序的确定变量

//倒序处理(实部)

for(w=1,j=arraylength/2;w

{

if(w

{

ws=Array[j];

Array[j]=Array[w];

Array[w]=ws;

}

p=arraylength/2;//求j的下⼀个倒位序

while(p<=j)//如果k<=j,表⽰j的最⾼位为1

{

j=j-p;//把最⾼位变成0

p=p/2;//k/2,⽐较次⾼位,依次类推,逐个⽐较,直到某个位为0

}

j=j+p;//把0改为1

}

//倒序处理(虚部)

for(w1=1,j1=arraylength/2;w1

{

if(w1

{

{

ws1=IArray[j1];

IArray[j1]=IArray[w1];

IArray[w1]=ws1;

}

p1=arraylength/2;//求j的下⼀个倒位序

while(p1<=j1)//如果k<=j,表⽰j的最⾼位为1

{

j1=j1-p1;//把最⾼位变成0

p1=p1/2;//k/2,⽐较次⾼位,依次类推,逐个⽐较,直到某个位为0

}

j1=j1+p1;//把0改为1

}

//

//蝶形运算变量定义并初始化

intL=1;//蝶形运算级数,⽤于循环

intN=2;//蝶形运算数据量,⽤于循环,WN(k)*X(k+N/2)中的N

intdistance=1;//蝶形运算两节点间的距离,⽤于循环(distance=N/2)

intgroup=arraylength/2;//蝶形运算的组数,长度为数组长度的⼀半

doubletempr1,tempr2,tempi1,tempi2;//临时变量

intk=0;//WN(k)*X(k+N/2)中的k

//蝶形运算

for(;L<=M;L++){//第L级的蝶形运算

for(i=0;i

for(k=0;k

floattheta=(float)(-2*PI*k/N);//旋转因⼦,WN(k)

tempr1=Array[N*i+k];

tempi1=IArray[N*i+k];

tempr2=(theta)*Array[N*i+k+distance]-(theta)*IArray[N*i+k+distance];//CB的实数

tempi2=(theta)*Array[N*i+k+distance]+(theta)*IArray[N*i+k+distance];//CB的复数

Array[N*i+k]=(float)(tempr1+tempr2);//(A+CB)的实数

IArray[N*i+k]=(float)(tempi1+tempi2);//(A+CB)的复数

Array[N*i+k+distance]=(float)(tempr1-tempr2);//(A-CB)的实数

IArray[N*i+k+distance]=(float)(tempi1-tempi2);//(A-CB)的复数

}

}

N=N*2;//下⼀级蝶形运算中循环分母N*2

distance*=2;//下⼀级蝶形运算两节点间的距离增加

group/=2;//下⼀级蝶形运算的组数减半

}

//

//输出运算结果

intt1=0;//数组输出的循环次数

n("");

n("FFT运算结果如下:");

while(t1

("X[%d]=%ft+j(%f)n",t1,Array[t1],IArray[t1]);

t1++;

}

}

}

//阿汪先⽣的博客.ws

程序效果

1、复数输⼊

2、输⼊实部时,输⼊任⼀⾮数字字符(串),⾃动结束录⼊过程,剩余序列位⾃动补零;

在Matlab中验算

x=[1230];

X=fft(x,4);

X

⼀些说明:

1、可复数输⼊,输⼊位数不⾜2^N次,⾃动补位;

2、输⼊实部时,输⼊任⼀⾮数字字符,⾃动结束录⼊过程,剩余序列位⾃动补零;

3、倒位运算采⽤了雷德算法;

4、计算机运算时位数的限制导致上述的两段程序结果的误差,问题不⼤;

5、修改因⼦W_N^K中的N可算任意N点的FFT运算,本程序中的N为(2^M),具有⼀定局限性。

//只要在输⼊时单独赋值,即可实现序列任意N点(可奇数点)的FFT运算。

👁️ 阅读量:0