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、倒位计算、蝶形运算)相关推荐

  1. 基2FFT算法matlab程序编写,按时间抽取的基2FFT算法分析及MATLAB实现

    按时间抽取的基2FFT 算法分析及MATLAB 实现 1 DIT-FFT 算法的基本原理 有限长序列x (n )的N 点DFT 定义为:∑-==10 )()(N n n k N W n x k X , ...

  2. matlab基2时间抽选法,按时间抽取的基2FFT算法分析及MATLAB实现

    电子技术研发ElectronicsR&D 电一子一技一术- 按时问抽取的基2FFT算法分析及MATLAB实现 张登奇李宏民李丹 (湖南理工学院信息与通信工程学院) 摘要:DFT是一种应用广泛的 ...

  3. Java编程实现快速傅里叶变换FFT

    快速傅里叶变换的时间复杂度分析 1 快速傅里叶变换FFT 1.1 理论分析 1.1.1 离散傅里叶变换 1.1.2 快速傅里叶变换 1.2 编程实现 1.2.1 算法思想 1.2.2 实验结果 1 快 ...

  4. Java中实现快速傅里叶变换FFT

    Java中实现快速傅里叶变换FFT 一.概述 1.傅里叶变换(FT) 2.离散傅里叶变换(DFT) 3.快速傅里叶变换(FFT) 1)单位根 2)快速傅里叶变换的思想 3)蝶形图 4)快速傅里叶变换的 ...

  5. OpenCV快速傅里叶变换(FFT)用于图像和视讯流的模糊检测

    OpenCV快速傅里叶变换(FFT)用于图像和视频流的模糊检测 翻译自[OpenCV Fast Fourier Transform (FFT) for blur detection in images ...

  6. Matlab如何进行利用离散傅里叶变换DFT (快速傅里叶变换FFT)进行频谱分析

    文章目录 1. 定义 2. 变换和处理 3. 函数 4. 实例演示 例1:单频正弦信号(整数周期采样) 例2:单频正弦信号(非整数周期采样) 例3:含有直流分量的单频正弦信号 例4:正弦复合信号 例5 ...

  7. matlab cftool光滑曲线导出为什么就不光滑了_快速傅里叶变换(FFT)中为什么要“补零”?...

    为了大家能够复现各个图中的结果,我附上了所有我编写的MATLAB代码. 创作不易,未经允许,禁止转载. 另外,说明一下,用MATLAB做FFT并不要求数据点个数必须为以2为基数的整数次方.之所以很多资 ...

  8. 快速傅里叶c51语言程序,快速傅里叶变换及其C程序

    变换常常可以简化问题的分析和求解过程.人们常会在这样那样的场合使用这一技巧.在科学研究的许多领域,人们发现傅里叶变换(FT)对于问题的求解和简化特别有用. 傅里叶变换方法又称为谱分析方法,具有普适性. ...

  9. 快速傅里叶变换FFT C语言实现 可用于嵌入式系统进行模拟采样频谱分析

    快速傅里叶变换C语言实现 模拟采样进行频谱分析 FFT是DFT的快速算法用于分析确定信号(时间连续可积信号.不一定是周期信号)的频率(或相位.此处不研究相位)成分,且傅里叶变换对应的 ω \omega ...

最新文章

  1. Codeblocks更改编译器为VC++6.0
  2. java 格式化位数_java数字如何格式化?
  3. 数学从根本上:玩的是概念!而不是技巧
  4. 20 PP配置-生产计划-定义计划订单计划参数
  5. raspberry pi_适用于Linux,Raspberry Pi和开源的游戏:年度热门读物
  6. python2.7出现的错误
  7. Windows 7 Ultimate + Ubuntu 12.04 LTS双系统完美走起
  8. python找第二大的数索引_python – 在numpy数组中查找多个值的行索引
  9. 【项目实训】基于人脸识别的课堂签到管理系统(python+qt5+sqlite3+百度智能云)
  10. Flash与组件:制作Slider组件
  11. 网络性能测试工具iperf的安装与使用
  12. 微型计算机原理及应用实验报告清零实验,北京科技大学微机原理及应用实验报告.docx...
  13. 拖拉机大战贺岁版发布
  14. 网易Python爬虫:爬取网易科技频道文章存入MySQL数据库
  15. 程序员女朋友礼物python代码_程序员到底该怎么给女朋友挑礼物
  16. 实现基于股票收盘价的时间序列的统计(用Python实现)
  17. [硫化铂]treecnt
  18. Javaweb基础配置模板(mybatis+javaweb)
  19. 批处理与管道-过滤器
  20. 【内部接口】LVGL WIFI配网

热门文章

  1. 谈一谈|下载软件的门道你懂吗?
  2. 【C++】【Ctrl+CV即可食用】三维点拟合空间直线
  3. 大数据Hadoop这些年的发展回顾:致敬那些浪潮之巅的英雄
  4. android 动画开源框架,图文简介非常炫酷的Android开源框架之UI框架
  5. 玩赚你的网站-网站运营必备手册
  6. 网站发布网(发布号) 海量热点新闻小偷程序 V1.2
  7. Java 代码基于开源组件生成带头像的二维码
  8. 7-17 找最贵的书和最便宜的书
  9. 分形几何算法和实现(C语言)
  10. 972信息检索 | 第九章 网络信息检索与利用中的有关问题