0
点赞
收藏
分享

微信扫一扫

完整java版本的傅里叶变换函数(FFT)

夕颜合欢落 2022-03-11 阅读 61

1.前言
本函数完全是基于Java语言及其相关计算工具包完成,已经应用与实际。
众所周知,当我们需要对信号进行分析时,基本都会用到傅里叶变化函数,但是基于Java平台缺少相关的傅里叶函数,或者有的工具包里面虽然有包,但是在实际计算的时候却出现问题。因此需要自己根据傅里叶变换的原理写出相关函数,这样更加靠谱。傅里叶变换作用就是将时域波形转换到频域以观察信号的规律。
本函数首先包含一个计算工具类Complex类,这个类里面包含一些傅里叶变换需要用到的计算工具,其次就是傅里叶变换的类FFT,该类包含傅里叶变换的具体实现方法getFFT()。
废话少说,下面具体看算法的代码以及详解。
2.Complex类
具体代码:

public class Complex {
	public double i;
	public double j;// 虚数
	public Complex(double i, double j) {
		this.i = i;
		this.j = j;
	}

	public double getMod() {// 求复数的模
		return Math.sqrt(i * i + j * j);
	}

	public static Complex Add(Complex a, Complex b) {
		return new Complex(a.i + b.i, a.j + b.j);
	}

	public static Complex Subtract(Complex a, Complex b) {
		return new Complex(a.i - b.i, a.j - b.j);
	}

	public static Complex Mul(Complex a, Complex b) {// 乘法
		return new Complex(a.i * b.i - a.j * b.j, a.i * b.j + a.j * b.i);
	}

	public static Complex GetW(int k, int N) {
		return new Complex(Math.cos(-2 * Math.PI * k / N), Math.sin(-2 * Math.PI * k / N));
	}

	public static Complex[] butterfly(Complex a, Complex b, Complex w) {
		return new Complex[] { Add(a, Mul(w, b)), Subtract(a, Mul(w, b)) };
	}

	public static Double[] toModArray(Complex[] complex) {
		Double[] res = new Double[complex.length];
		for (int i = 0; i < complex.length; i++) {
			res[i] = complex[i].getMod();
		}
		return res;
	}

}

类名:Complex
函数名1:Complex(double i, double j)
变量说明:i是数据的实部,j是数据的虚部值。返回值是一个虚数值
作用:输出虚数(因为傅里叶变换是处理虚数值,需要将初始数据处理成虚数)
函数名2:public static Complex Add(Complex a, Complex b)
变量说明:a,b分别是不同的复数值,返回值是两个复数值得相加结果,返回值类型也是复数类型
作用:两个复数相加
函数名3:public static Complex Subtract(Complex a, Complex b)
变量说明:a,b分别是不同的复数值,返回值是两个复数值得相减结果,返回值类型也是复数类型
作用:两个复数相减
函数名4:public static Complex Mul(Complex a, Complex b)
变量说明:a,b分别是不同的复数值,返回值是两个复数值得相乘结果,返回值类型也是复数类型
作用:两个复数相乘
函数名5:public static Complex GetW(int k, int N)
变量说明:k,N是傅里叶变换里的系数,返回值是两个复数值在欧拉公式计算后的结果,返回值类型也是复数类型
作用:欧拉公式,将e的指数变换为复数的形式。
函数名6:public static Complex[] butterfly(Complex a, Complex b, Complex w)
变量说明:a是偶数序列(类型是复数),b是奇数数列(类型是复数),w是e的指数展开的复数(类型是复数),返回值是复数数组类型
作用:傅里叶变换的蝶形计算公式
函数名7:public static Double[] toModArray(Complex[] complex)
变量说明:complex是传入的复数数组,返回值是计算得到复数模值(类型是Double[])
作用:计算复数的模

3.FFT类

具体代码:

import complex_1.Complex;

public class FFT{
	public static Complex[] getFFT(Complex[] input, int N) {
	if ((N / 2) % 2 == 0) {
		Complex[] even = new Complex[N / 2];// 偶数
		Complex[] odd = new Complex[N / 2];// 奇数
		for (int i = 0; i < N / 2; i++) {
			even[i] = input[2 * i];
			odd[i] = input[2 * i + 1];
		}
		even = getFFT(even, N / 2);
		odd = getFFT(odd, N / 2);
		for (int i = 0; i < N / 2; i++) {
			Complex[] res = Complex.butterfly(even[i], odd[i], Complex.GetW(i, N));
			input[i] = res[0];
			input[i + N / 2] = res[1];
		}
		return input;
	} else {// 两点DFT,直接进行碟形运算
		Complex[] res = Complex.butterfly(input[0], input[1], Complex.GetW(0, N));
		return res;
	}
	}
}

类名:FFT
函数名:public static Complex[] getFFT(Complex[] input, int N)
变量说明:input是输入的数据(数据类型必须是Complex类型,需要调用Complex类里的Complex()方法把数据转换为复数),N是数据的长度(数据长度必须是2的幂)返回值是复数数组
调用Complex()方法将数据转换为复数举例:

double[] data= {-0.35668879080953375, -0.6118094913035987, 0.8534269560320435, -0.6699697478438837, 0.35425500561437717,
                0.8910250650549392, -0.025718699518642918, 0.07649691490732002};
		N=8;
		Complex[] input = new Complex[N];
		for (int i = 0; i <= N-1; i++){
			input[i] = new Complex(data[i], 0);}

注意:1.傅里叶变换之后得到的还是复数数组,需要调用Complex类里面的toModArray(input)方法把数据转换为实数。
举例:x=Complex.toModArray(input);
2.得到实数之后需要把得到的实数数组里面的数除以2N(N是数据长度)

上述就是所有的Java写的傅里叶变换函数及其工具函数,具体的数学原理这里就不详细介绍了,如果想具体了解如何计算的可以查阅关于傅里叶变换的具体数学推理。

举报

相关推荐

0 条评论