【Java】快速傅里叶变换FFT的程序实现(时间抽取的基-2FFT、倒位计算、蝶形运算)
Java——快速傅里叶变换(FFT)的程序实现
好久没来更新了,阿汪大三了。
这学期阿汪要学习两门课《数字信号处理》和《Java程序设计》,刚好前几天老师告诉我们不久后会有个实验,要求我们编写一个程序实现快速傅里叶变换(FFT)。
所以,阿汪用Java写了一下。
//废话和原理就不多说了,直接上程序!!!
//阿汪先生的博客.ws
import java.util.Scanner;
import java.math.*;//对数函数class Log{static public double log(double value, double base) {return Math.log(value) / Math.log(base);}}//乘方运算
class Pow{ public static int powNM(int n,int m){if(m == 1)return n;elsereturn n*powNM(n,m-1);//Math.pow(m,n);}
}public class DFT_FFT { public static void main (String []args){//初始化变量final double PI=3.141;int N1=0; //序列的长度int M=0; //序列的级数,数组的长度为2^Mint arraylength; //数组长度int i=0; //输入数组的循环次数int t=0; //输出数组的循环次数 /// //输入合法化Scanner sc=new Scanner (System.in);while(N1<2){System.out.println("请确定你输入序列的长度!");N1=sc.nextInt();}
/// //判断长度并初始化数组//确定N=2^M的级数MM=(Log.log(N1, 2)==(int) Log.log(N1, 2))?(int) Log.log(N1, 2) : ((int)Log.log(N1, 2))+1;//确定数字长度arraylength=(int)Pow.powNM(2, M); System.out.printf("序列长度N1为%d时,数组长度为%d,级数M为%d !\n",N1,arraylength,M);float []Array=new float [ arraylength ]; //实部float []IArray=new float [ arraylength ]; //虚部
/// //输入序列float jc; //暂存转换后的数据String xy;System.out.printf("请依次输入序列的%d个值:\n",N1);System.out.println("");while(i<N1){System.out.printf("x[%d]实部:\n",i);xy=sc.next();if((xy.charAt(0)<48|xy.charAt(0)>57)){ //输入不是数字System.out.println("阿汪先生(a_wang_xian_sheng)的博客!");break; //跳出循环输入}if((xy.charAt(0)>=48|xy.charAt(0)<=57)){ //输入数字jc = Float.parseFloat(xy); //String转化成float类型Array[i]=jc; //保存String转存下来的数字}System.out.printf("x[%d]虚部:\n",i); //输入虚部IArray[i]=sc.nextFloat(); //录入数字i++;} System.out.println("");System.out.println("输入结果如下:");while(t<arraylength){System.out.printf("x[%d]=",t);System.out.print(Array[t]);System.out.printf("+j(%f)\n",IArray[t]);t++;}
// int w=0; //倒序处理时的外循环次数int j=0; //倒序处理时的内循环次数float ws=0; //倒序处理时的数组间值传递变量int p=0; //倒序处理时下一倒位序的确定变量int w1=0; //倒序处理时的外循环次数int j1=0; //倒序处理时的内循环次数float ws1=0; //倒序处理时的数组间值传递变量int p1=0; //倒序处理时下一倒位序的确定变量//倒序处理(实部)for(w=1,j=arraylength/2;w<arraylength-1;w++) { if(w<j) //如果i<j,即进行变址 { 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<arraylength-1;w1++) { if(w1<j1) //如果i<j,即进行变址 { 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 }
////蝶形运算变量定义并初始化int L=1;//蝶形运算级数,用于循环int N=2;//蝶形运算数据量,用于循环 ,WN(k)*X(k+N/2)中的Nint distance=1;//蝶形运算两节点间的距离,用于循环(distance=N/2) int group=arraylength/2; //蝶形运算的组数,长度为数组长度的一半double tempr1,tempr2,tempi1,tempi2;//临时变量int k=0; //WN(k)*X(k+N/2)中的k //蝶形运算for(;L<=M;L++){//第L级的蝶形运算for(i=0;i<group;i++){//第group组的蝶形运算 for(k=0;k<distance;k++){//第k次蝶形运算 float theta=(float)(-2*PI*k/N);//旋转因子,WN(k)tempr1=Array[N*i+k]; tempi1=IArray[N*i+k]; tempr2=Math.cos(theta)*Array[N*i+k+distance]-Math.sin(theta)*IArray[N*i+k+distance]; //CB的实数 tempi2=Math.sin(theta)*Array[N*i+k+distance]+Math.cos(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*2distance*=2; //下一级蝶形运算两节点间的距离增加group/=2; //下一级蝶形运算的组数减半}
////输出运算结果int t1=0; //数组输出的循环次数System.out.println("");System.out.println("FFT运算结果如下:");while(t1<arraylength){System.out.printf("X[%d]= %f\t+j(%f)\n",t1,Array[t1],IArray[t1]);t1++;}}
}//阿汪先生的博客.ws
程序效果
1、复数输入
2、输入实部时,输入任一非数字字符(串),自动结束录入过程,剩余序列位自动补零;
在Matlab中验算
x=[1 2 3 0];
X=fft(x,4);
X
一些说明:
1、可复数输入,输入位数不足2^N次,自动补位;
2、输入实部时,输入任一非数字字符,自动结束录入过程,剩余序列位自动补零;
3、倒位运算采用了雷德算法;
4、计算机运算时位数的限制导致上述的两段程序结果的误差,问题不大;
5、修改因子W_N^K中的N可算任意N点的FFT运算,本程序中的N为(2 ^M),具有一定局限性。
//只要在输入时单独赋值,即可实现序列任意N点(可奇数点)的FFT运算。
【Java】快速傅里叶变换FFT的程序实现(时间抽取的基-2FFT、倒位计算、蝶形运算)相关推荐
- 基2FFT算法matlab程序编写,按时间抽取的基2FFT算法分析及MATLAB实现
按时间抽取的基2FFT 算法分析及MATLAB 实现 1 DIT-FFT 算法的基本原理 有限长序列x (n )的N 点DFT 定义为:∑-==10 )()(N n n k N W n x k X , ...
- matlab基2时间抽选法,按时间抽取的基2FFT算法分析及MATLAB实现
电子技术研发ElectronicsR&D 电一子一技一术- 按时问抽取的基2FFT算法分析及MATLAB实现 张登奇李宏民李丹 (湖南理工学院信息与通信工程学院) 摘要:DFT是一种应用广泛的 ...
- Java编程实现快速傅里叶变换FFT
快速傅里叶变换的时间复杂度分析 1 快速傅里叶变换FFT 1.1 理论分析 1.1.1 离散傅里叶变换 1.1.2 快速傅里叶变换 1.2 编程实现 1.2.1 算法思想 1.2.2 实验结果 1 快 ...
- Java中实现快速傅里叶变换FFT
Java中实现快速傅里叶变换FFT 一.概述 1.傅里叶变换(FT) 2.离散傅里叶变换(DFT) 3.快速傅里叶变换(FFT) 1)单位根 2)快速傅里叶变换的思想 3)蝶形图 4)快速傅里叶变换的 ...
- OpenCV快速傅里叶变换(FFT)用于图像和视讯流的模糊检测
OpenCV快速傅里叶变换(FFT)用于图像和视频流的模糊检测 翻译自[OpenCV Fast Fourier Transform (FFT) for blur detection in images ...
- Matlab如何进行利用离散傅里叶变换DFT (快速傅里叶变换FFT)进行频谱分析
文章目录 1. 定义 2. 变换和处理 3. 函数 4. 实例演示 例1:单频正弦信号(整数周期采样) 例2:单频正弦信号(非整数周期采样) 例3:含有直流分量的单频正弦信号 例4:正弦复合信号 例5 ...
- matlab cftool光滑曲线导出为什么就不光滑了_快速傅里叶变换(FFT)中为什么要“补零”?...
为了大家能够复现各个图中的结果,我附上了所有我编写的MATLAB代码. 创作不易,未经允许,禁止转载. 另外,说明一下,用MATLAB做FFT并不要求数据点个数必须为以2为基数的整数次方.之所以很多资 ...
- 快速傅里叶c51语言程序,快速傅里叶变换及其C程序
变换常常可以简化问题的分析和求解过程.人们常会在这样那样的场合使用这一技巧.在科学研究的许多领域,人们发现傅里叶变换(FT)对于问题的求解和简化特别有用. 傅里叶变换方法又称为谱分析方法,具有普适性. ...
- 快速傅里叶变换FFT C语言实现 可用于嵌入式系统进行模拟采样频谱分析
快速傅里叶变换C语言实现 模拟采样进行频谱分析 FFT是DFT的快速算法用于分析确定信号(时间连续可积信号.不一定是周期信号)的频率(或相位.此处不研究相位)成分,且傅里叶变换对应的 ω \omega ...
最新文章
- Codeblocks更改编译器为VC++6.0
- java 格式化位数_java数字如何格式化?
- 数学从根本上:玩的是概念!而不是技巧
- 20 PP配置-生产计划-定义计划订单计划参数
- raspberry pi_适用于Linux,Raspberry Pi和开源的游戏:年度热门读物
- python2.7出现的错误
- Windows 7 Ultimate + Ubuntu 12.04 LTS双系统完美走起
- python找第二大的数索引_python – 在numpy数组中查找多个值的行索引
- 【项目实训】基于人脸识别的课堂签到管理系统(python+qt5+sqlite3+百度智能云)
- Flash与组件:制作Slider组件
- 网络性能测试工具iperf的安装与使用
- 微型计算机原理及应用实验报告清零实验,北京科技大学微机原理及应用实验报告.docx...
- 拖拉机大战贺岁版发布
- 网易Python爬虫:爬取网易科技频道文章存入MySQL数据库
- 程序员女朋友礼物python代码_程序员到底该怎么给女朋友挑礼物
- 实现基于股票收盘价的时间序列的统计(用Python实现)
- [硫化铂]treecnt
- Javaweb基础配置模板(mybatis+javaweb)
- 批处理与管道-过滤器
- 【内部接口】LVGL WIFI配网