java实现FFT算法(附完整源码)

时间: 2023-11-30 18:21:28 浏览: 63
下面是Java实现FFT算法的代码: ```java import java.util.Arrays; public class FFT { public static Complex[] fft(Complex[] x) { int N = x.length; // base case if (N == 1) return new Complex[] { x[0] }; // radix 2 Cooley-Tukey FFT if (N % 2 != 0) { throw new RuntimeException("N is not a power of 2"); } // fft of even terms Complex[] even = new Complex[N/2]; for (int k = 0; k < N/2; k++) { even[k] = x[2*k]; } Complex[] q = fft(even); // fft of odd terms Complex[] odd = even; // reuse the array for (int k = 0; k < N/2; k++) { odd[k] = x[2*k + 1]; } Complex[] r = fft(odd); // combine Complex[] y = new Complex[N]; for (int k = 0; k < N/2; k++) { double kth = -2 * k * Math.PI / N; Complex wk = new Complex(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])); } return y; } public static void main(String[] args) { Complex[] x = { new Complex(1, 0), new Complex(2, 0), new Complex(3, 0), new Complex(4, 0) }; // FFT of original data Complex[] y = fft(x); // print results System.out.println("x"); System.out.println("-------------------"); for (int i = 0; i < x.length; i++) { System.out.println(x[i]); } System.out.println(); System.out.println("y = fft(x)"); System.out.println("-------------------"); for (int i = 0; i < y.length; i++) { System.out.println(y[i]); } System.out.println(); System.out.println("y = ifft(y)"); System.out.println("-------------------"); Complex[] z = ifft(y); for (int i = 0; i < z.length; i++) { System.out.println(z[i]); } System.out.println(); } public static Complex[] ifft(Complex[] x) { int N = x.length; Complex[] y = new Complex[N]; // take conjugate for (int i = 0; i < N; i++) { y[i] = x[i].conjugate(); } // compute forward FFT y = fft(y); // take conjugate again for (int i = 0; i < N; i++) { y[i] = y[i].conjugate(); } // divide by N for (int i = 0; i < N; i++) { y[i] = y[i].times(1.0 / N); } return y; } } class Complex { private final double re; // the real part private final double im; // the imaginary part // create a new object with the given real and imaginary parts public Complex(double real, double imag) { re = real; im = imag; } // return a string representation of the invoking Complex object public String toString() { if (im == 0) return re + ""; if (re == 0) return im + "i"; if (im < 0) return re + " - " + (-im) + "i"; return re + " + " + im + "i"; } // return abs/modulus/magnitude and angle/phase/argument public double abs() { return Math.hypot(re, im); } // Math.sqrt(re*re + im*im) public double phase() { return Math.atan2(im, re); } // between -pi and pi // return a new Complex object whose value is (this + b) public Complex plus(Complex b) { Complex a = this; // invoking object double real = a.re + b.re; double imag = a.im + b.im; return new Complex(real, imag); } // return a new Complex object whose value is (this - b) public Complex minus(Complex b) { Complex a = this; double real = a.re - b.re; double imag = a.im - b.im; return new Complex(real, imag); } // return a new Complex object whose value is (this * b) public Complex times(Complex b) { Complex a = this; double real = a.re * b.re - a.im * b.im; double imag = a.re * b.im + a.im * b.re; return new Complex(real, imag); } // scalar multiplication // return a new object whose value is (this * alpha) public Complex times(double alpha) { return new Complex(alpha * re, alpha * im); } // return a new Complex object whose value is the conjugate of this public Complex conjugate() { return new Complex(re, -im); } // return a new Complex object whose value is the reciprocal of this public Complex reciprocal() { double scale = re*re + im*im; return new Complex(re / scale, -im / scale); } // return the real or imaginary part public double re() { return re; } public double im() { return im; } // return a / b public Complex divides(Complex b) { Complex a = this; return a.times(b.reciprocal()); } // return a new Complex object whose value is the complex exponential of this public Complex exp() { return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) * Math.sin(im)); } // return a new Complex object whose value is the complex sine of this public Complex sin() { return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)); } // return a new Complex object whose value is the complex cosine of this public Complex cos() { return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)); } // return a new Complex object whose value is the complex tangent of this public Complex tan() { return sin().divides(cos()); } // a static version of plus public static Complex plus(Complex a, Complex b) { double real = a.re + b.re; double imag = a.im + b.im; Complex sum = new Complex(real, imag); return sum; } } ``` 上面的代码实现了FFT算法和IFFT算法,其中FFT算法使用递归实现,而IFFT算法则是在FFT算法的基础上进行了一些简单的变换。代码中用到了一个名为Complex的复数类,这里直接使用了作者提供的实现。 代码中的FFT算法输入为一个长度为2的n次方的复数数组,输出为进行了FFT变换后的复数数组;IFFT算法输入为一个进行了FFT变换后的复数数组,输出为进行了IFFT变换后的复数数组。 需要注意的是,这里的FFT算法只适用于输入长度为2的n次方的复数数组,输入长度不符合要求时会抛出异常。

相关推荐

最新推荐

recommend-type

用fft算法实现相关的MATLAB仿真

用fft算法实现相关的MATLAB仿真,该方法易于在FPGA上实现相关算法,比直接用相乘来得简单,而且但相关点数越多计算量相对而言比直接求解减少
recommend-type

基于Xilinx FPGA IP核的FFT算法的设计与实现

本文介绍了一种基于Xilinx IP核的FFT算法的设计与实现方法。在分析FFT算法模块图的基础上,以Xilinx Spartan-3A DSP系列FPGA为平台,通过调用FFT IP核,验证FFT算法在中低端FPGA中的可行性和可靠性。
recommend-type

DFT和FFT算法的比较

很明显,目前已经有许多途径可以实现DFT。现在就从图中给出的算法中选定一种短DFT算法开始介绍。而且短DFT可以用Cooley-Tukey、Good-Thomas或Winograd提出的索引模式来开发长DFT。选择实现的共同目标就是将乘法的...
recommend-type

基2FFT算法的MATLAB实现

基2FFT算法的MATLAB实现,自己编写的代码与MATLAB函数fft的仿真结果进行对比,编写的代码可以实现fft功能。
recommend-type

STM32FFT算法的实现说明

STM32FFT算法的实现说明,有详细的说明具体的求解过程适合新手学习哦
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

解答下列问题:S—>S;T|T;T—>a 构造任意项目集规范族,构造LR(0)分析表,并分析a;a

对于这个文法,我们可以构造以下项目集规范族: I0: S -> .S S -> .T T -> .a I1: S -> S. [$ T -> T. [$ I2: S -> T. I3: S -> S.;S S -> S.;T T -> T.;a 其中,点(.)表示已经被扫描过的符号,;$表示输入串的结束符号。 根据项目集规范族,我们可以构造出LR(0)分析表: 状态 | a | $ ---- | - | - I0 | s3| I1 | |acc I2 | | 其中s3表示移进到状态3,acc表示接受。在分析字符串a;a时,我们可以按照以下步骤进行
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。