怎么在Java中实现一个傅里叶变化算法

怎么在Java中实现一个傅里叶变化算法?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

FFT.class 傅里叶变化功能实现代码

怎么在Java中实现一个傅里叶变化算法

packagefft.test;
publicclassFFT{
//computetheFFTofx[],assumingitslengthisapowerof2
publicstaticComplex[]fft(Complex[]x){
intN=x.length;
//basecase
if(N==1)
returnnewComplex[]{x[0]};
//radix2Cooley-TukeyFFT
if(N%2!=0){
thrownewRuntimeException("Nisnotapowerof2");
}
//fftofeventerms
Complex[]even=newComplex[N/2];
for(intk=0;k<N/2;k++){
even[k]=x[2*k];
}
Complex[]q=fft(even);
//fftofoddterms
Complex[]odd=even;//reusethearray
for(intk=0;k<N/2;k++){
odd[k]=x[2*k+1];
}
Complex[]r=fft(odd);
//combine
Complex[]y=newComplex[N];
for(intk=0;k<N/2;k++){
doublekth=-2*k*Math.PI/N;
Complexwk=newComplex(Math.cos(kth),Math.sin(kth));
y[k]=q[k].plus(wk.times(r[k]));
y[k+N/2]=q[k].minus(wk.times(r[k]));
}
returny;
}
//computetheinverseFFTofx[],assumingitslengthisapowerof2
publicstaticComplex[]ifft(Complex[]x){
intN=x.length;
Complex[]y=newComplex[N];
//takeconjugate
for(inti=0;i<N;i++){
y[i]=x[i].conjugate();
}
//computeforwardFFT
y=fft(y);
//takeconjugateagain
for(inti=0;i<N;i++){
y[i]=y[i].conjugate();
}
//dividebyN
for(inti=0;i<N;i++){
y[i]=y[i].scale(1.0/N);
}
returny;
}
//computethecircularconvolutionofxandy
publicstaticComplex[]cconvolve(Complex[]x,Complex[]y){
//shouldprobablypadxandywith0ssothattheyhavesamelength
//andarepowersof2
if(x.length!=y.length){
thrownewRuntimeException("Dimensionsdon'tagree");
}
intN=x.length;
//computeFFTofeachsequence,求值
Complex[]a=fft(x);
Complex[]b=fft(y);
//point-wisemultiply,点值乘法
Complex[]c=newComplex[N];
for(inti=0;i<N;i++){
c[i]=a[i].times(b[i]);
}
//computeinverseFFT,插值
returnifft(c);
}
//computethelinearconvolutionofxandy
publicstaticComplex[]convolve(Complex[]x,Complex[]y){
ComplexZERO=newComplex(0,0);
Complex[]a=newComplex[2*x.length];//2n次数界,高阶系数为0.
for(inti=0;i<x.length;i++)
a[i]=x[i];
for(inti=x.length;i<2*x.length;i++)
a[i]=ZERO;
Complex[]b=newComplex[2*y.length];
for(inti=0;i<y.length;i++)
b[i]=y[i];
for(inti=y.length;i<2*y.length;i++)
b[i]=ZERO;
returncconvolve(a,b);
}
//displayanarrayofComplexnumberstostandardoutput
publicstaticvoidshow(Complex[]x,Stringtitle){
System.out.println(title);
System.out.println("-------------------");
intcomplexLength=x.length;
for(inti=0;i<complexLength;i++){
//输出复数
//System.out.println(x[i]);
//输出幅值需要*2/length
System.out.println(x[i].abs()*2/complexLength);
}
System.out.println();
}
/**
*将数组数据重组成2的幂次方输出
*
*@paramdata
*@return
*/
publicstaticDouble[]pow2DoubleArr(Double[]data){
//创建新数组
Double[]newData=null;
intdataLength=data.length;
intsumNum=2;
while(sumNum<dataLength){
sumNum=sumNum*2;
}
intaddLength=sumNum-dataLength;
if(addLength!=0){
newData=newDouble[sumNum];
System.arraycopy(data,0,newData,0,dataLength);
for(inti=dataLength;i<sumNum;i++){
newData[i]=0d;
}
}else{
newData=data;
}
returnnewData;
}
/**
*去偏移量
*
*@paramoriginalArr
*原数组
*@return目标数组
*/
publicstaticDouble[]deskew(Double[]originalArr){
//过滤不正确的参数
if(originalArr==null||originalArr.length<=0){
returnnull;
}
//定义目标数组
Double[]resArr=newDouble[originalArr.length];
//求数组总和
Doublesum=0D;
for(inti=0;i<originalArr.length;i++){
sum+=originalArr[i];
}
//求数组平均值
Doubleaver=sum/originalArr.length;
//去除偏移值
for(inti=0;i<originalArr.length;i++){
resArr[i]=originalArr[i]-aver;
}
returnresArr;
}
publicstaticvoidmain(String[]args){
//intN=Integer.parseInt(args[0]);
Double[]data={-0.35668879080953375,-0.6118094913035987,0.8534269560320435,-0.6699697478438837,0.35425500561437717,
0.8910250650549392,-0.025718699518642918,0.07649691490732002};
//去除偏移量
data=deskew(data);
//个数为2的幂次方
data=pow2DoubleArr(data);
intN=data.length;
System.out.println(N+"数组N中数量....");
Complex[]x=newComplex[N];
//originaldata
for(inti=0;i<N;i++){
//x[i]=newComplex(i,0);
//x[i]=newComplex(-2*Math.random()+1,0);
x[i]=newComplex(data[i],0);
}
show(x,"x");
//FFToforiginaldata
Complex[]y=fft(x);
show(y,"y=fft(x)");
//takeinverseFFT
Complex[]z=ifft(y);
show(z,"z=ifft(y)");
//circularconvolutionofxwithitself
Complex[]c=cconvolve(x,x);
show(c,"c=cconvolve(x,x)");
//linearconvolutionofxwithitself
Complex[]d=convolve(x,x);
show(d,"d=convolve(x,x)");
}
}
/*********************************************************************
*%javaFFT8x--------------------0.35668879080953375-0.6118094913035987
*0.8534269560320435-0.66996974784388370.354255005614377170.8910250650549392
*-0.0257186995186429180.07649691490732002
*
*y=fft(x)-------------------0.5110172121330208-1.245776663065442+
*0.7113504894129803i-0.8301420417085572-0.8726884066879042i
*-0.17611092978238008+2.4696418005143532i1.1395317305034673
*-0.17611092978237974-2.4696418005143532i-0.8301420417085572+
*0.8726884066879042i-1.2457766630654419-0.7113504894129803i
*
*z=ifft(y)--------------------0.35668879080953375-0.6118094913035987+
*4.2151962932466006E-17i0.8534269560320435-2.691607282636124E-17i
*-0.6699697478438837+4.1114763914420734E-17i0.35425500561437717
*0.8910250650549392-6.887033953004965E-17i-0.025718699518642918+
*2.691607282636124E-17i0.07649691490732002-1.4396387316837096E-17i
*
*c=cconvolve(x,x)--------------------1.0786973139009466-
*2.636779683484747E-16i1.2327819138980782+2.2180047699856214E-17i
*0.4386976685553382-1.3815636262919812E-17i-0.5579612069781844+
*1.9986455722517509E-16i1.432390480003344+2.636779683484747E-16i
*-2.2165857430333684+2.2180047699856214E-17i-0.01255525669751989+
*1.3815636262919812E-17i1.0230680492494633-2.4422465262488753E-16i
*
*d=convolve(x,x)-------------------0.12722689348916738+
*3.469446951953614E-17i0.43645117531775324-2.78776395788635E-18i
*-0.2345048043334932-6.907818131459906E-18i-0.5663280251946803+
*5.829891518914417E-17i1.2954076913348198+1.518836016779236E-16i
*-2.212650940696159+1.1090023849928107E-17i-0.018407034687857718-
*1.1306778366296569E-17i1.023068049249463-9.435675069681485E-17i
*-1.205924207390114-2.983724378680108E-16i0.796330738580325+
*2.4967811657742562E-17i0.6732024728888314-6.907818131459906E-18i
*0.00836681821649593+1.4156564203603091E-16i0.1369827886685242+
*1.1179436667055108E-16i-0.00393480233720922+1.1090023849928107E-17i
*0.005851777990337828+2.512241462921638E-17i1.1102230246251565E-16-
*1.4986790192807268E-16i
*********************************************************************/

Complex.class 复数类

packagefft.test;
/******************************************************************************
*Compilation:javacComplex.java
*Execution:javaComplex
*
*Datatypeforcomplexnumbers.
*
*Thedatatypeis"immutable"soonceyoucreateandinitialize
*aComplexobject,youcannotchangeit.The"final"keyword
*whendeclaringreandimenforcesthisrule,makingita
*compile-timeerrortochangethe.reor.iminstancevariablesafter
*they'vebeeninitialized.
*
*%javaComplex
*a=5.0+6.0i
*b=-3.0+4.0i
*Re(a)=5.0
*Im(a)=6.0
*b+a=2.0+10.0i
*a-b=8.0+2.0i
*a*b=-39.0+2.0i
*b*a=-39.0+2.0i
*a/b=0.36-1.52i
*(a/b)*b=5.0+6.0i
*conj(a)=5.0-6.0i
*|a|=7.810249675906654
*tan(a)=-6.685231390246571E-6+1.0000103108981198i
*
******************************************************************************/
importjava.util.Objects;
publicclassComplex{
privatefinaldoublere;//therealpart
privatefinaldoubleim;//theimaginarypart
//createanewobjectwiththegivenrealandimaginaryparts
publicComplex(doublereal,doubleimag){
re=real;
im=imag;
}
//returnastringrepresentationoftheinvokingComplexobject
publicStringtoString(){
if(im==0)
returnre+"";
if(re==0)
returnim+"i";
if(im<0)
returnre+"-"+(-im)+"i";
returnre+"+"+im+"i";
}
//returnabs/modulus/magnitude
publicdoubleabs(){
returnMath.hypot(re,im);
}
//returnangle/phase/argument,normalizedtobebetween-piandpi
publicdoublephase(){
returnMath.atan2(im,re);
}
//returnanewComplexobjectwhosevalueis(this+b)
publicComplexplus(Complexb){
Complexa=this;//invokingobject
doublereal=a.re+b.re;
doubleimag=a.im+b.im;
returnnewComplex(real,imag);
}
//returnanewComplexobjectwhosevalueis(this-b)
publicComplexminus(Complexb){
Complexa=this;
doublereal=a.re-b.re;
doubleimag=a.im-b.im;
returnnewComplex(real,imag);
}
//returnanewComplexobjectwhosevalueis(this*b)
publicComplextimes(Complexb){
Complexa=this;
doublereal=a.re*b.re-a.im*b.im;
doubleimag=a.re*b.im+a.im*b.re;
returnnewComplex(real,imag);
}
//returnanewobjectwhosevalueis(this*alpha)
publicComplexscale(doublealpha){
returnnewComplex(alpha*re,alpha*im);
}
//returnanewComplexobjectwhosevalueistheconjugateofthis
publicComplexconjugate(){
returnnewComplex(re,-im);
}
//returnanewComplexobjectwhosevalueisthereciprocalofthis
publicComplexreciprocal(){
doublescale=re*re+im*im;
returnnewComplex(re/scale,-im/scale);
}
//returntherealorimaginarypart
publicdoublere(){
returnre;
}
publicdoubleim(){
returnim;
}
//returna/b
publicComplexdivides(Complexb){
Complexa=this;
returna.times(b.reciprocal());
}
//returnanewComplexobjectwhosevalueisthecomplexexponentialof
//this
publicComplexexp(){
returnnewComplex(Math.exp(re)*Math.cos(im),Math.exp(re)*Math.sin(im));
}
//returnanewComplexobjectwhosevalueisthecomplexsineofthis
publicComplexsin(){
returnnewComplex(Math.sin(re)*Math.cosh(im),Math.cos(re)*Math.sinh(im));
}
//returnanewComplexobjectwhosevalueisthecomplexcosineofthis
publicComplexcos(){
returnnewComplex(Math.cos(re)*Math.cosh(im),-Math.sin(re)*Math.sinh(im));
}
//returnanewComplexobjectwhosevalueisthecomplextangentofthis
publicComplextan(){
returnsin().divides(cos());
}
//astaticversionofplus
publicstaticComplexplus(Complexa,Complexb){
doublereal=a.re+b.re;
doubleimag=a.im+b.im;
Complexsum=newComplex(real,imag);
returnsum;
}
//SeeSection3.3.
publicbooleanequals(Objectx){
if(x==null)
returnfalse;
if(this.getClass()!=x.getClass())
returnfalse;
Complexthat=(Complex)x;
return(this.re==that.re)&&(this.im==that.im);
}
//SeeSection3.3.
publicinthashCode(){
returnObjects.hash(re,im);
}
//sampleclientfortesting
publicstaticvoidmain(String[]args){
Complexa=newComplex(3.0,4.0);
Complexb=newComplex(-3.0,4.0);
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("Re(a)="+a.re());
System.out.println("Im(a)="+a.im());
System.out.println("b+a="+b.plus(a));
System.out.println("a-b="+a.minus(b));
System.out.println("a*b="+a.times(b));
System.out.println("b*a="+b.times(a));
System.out.println("a/b="+a.divides(b));
System.out.println("(a/b)*b="+a.divides(b).times(b));
System.out.println("conj(a)="+a.conjugate());
System.out.println("|a|="+a.abs());
System.out.println("tan(a)="+a.tan());
}
}

看完上述内容,你们掌握怎么在Java中实现一个傅里叶变化算法的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注恰卡编程网行业资讯频道,感谢各位的阅读!

发布于 2021-04-08 13:37:44
收藏
分享
海报
0 条评论
167
上一篇:使用Html5怎么实现一个移动端弹幕动画效果 下一篇:怎么在Python中利用sklearn库实现一个分类算法
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码