如何在Java中给定一个复杂的 2D 数组执行 2D FFT?
快速傅立叶变换 (FFT) 是一种计算离散傅立叶变换 (DFT) 及其逆的算法。傅里叶分析将时间(或空间)转换为频率,反之亦然。 FFT 减少了计算离散傅立叶变换所需的计算时间,并通过直接评估 DFT 将性能提高了 100 倍或更多。 FFT 通过将 DFT 矩阵分解为稀疏乘积来计算此类变换。
在这里,我们使用了一个 2D 数组,它将帮助我们找到快速傅立叶变换。该算法在模式识别中很有用。
例子
Input:
Enter the size:
2
Enter the elements:
2 3
4 2
Output:
2.5 + 0.0 i
5.5 + 0.0 i
-0.5 + -1.8369701987210297E-16 i
0.5 + -3.0616169978683826E-16 i
2.5 + 0.0 i
-0.5 + -3.6739403974420594E-16 i
-0.5 + -1.8369701987210297E-16 i
-1.5 + -1.8369701987210297E-16 i
Input:
Enter the size:
2
Enter the elements :
5 1
2 1
Output:
3.0 + 0.0 i
4.5 + 0.0 i
2.0 + -6.123233995736766E-17 i
2.5 + -1.2246467991473532E-16 i
3.0 + 0.0 i
1.5 + -1.8369701987210297E-16 i
2.0 + -6.123233995736766E-17 i
1.5 + -6.123233995736765E-17 i
方法:
- 输入数组的大小。
- 我们将采用 4 个数据类型为 double 的数组,分别命名为 input、realOut、imaginary。
- 给出二维数组的输入。
- 现在让我们调用一个函数dft ,它将帮助我们计算
- 现在,我们将计算输入数据的高度和宽度。
- 现在,让我们迭代循环的高度和宽度,
- 现在要计算DFT ,我们将得到它的指数形式,可以将其转换为余弦和正弦项,标记为实部和虚部。这些可以通过使用这些公式来计算。
- 使用高度和宽度迭代它我们计算realOut ,使用公式:
realOut[y][x]+=(input[y1][x1]*Math.cos(2*Math.PI*((1.0*x*x1/width)+(1.0*y*y1/height))))/Math.sqrt(width*height);
- 同样,我们将使用这个公式得到虚输出:
imagOut[y][x]-=(input[y1][x1]*Math.sin(2*Math.PI*((1.0*x*x1/width)+(1.0*y*y1/height))))/Math.sqrt(width*height);
- 现在,我们将以a+ib的形式打印这些值。
例子:
Java
// Java program to perform a 2D FFT Inplace Given a Complex
// 2D Array
// Declare the needed libraries
import java.io.*;
import java.util.Scanner;
public class GFG {
public static void main(String[] args)
{
// enter the size of the matrix
System.out.println("Enter the size:");
// declaring the scan element
Scanner sc = new Scanner(System.in);
// scan the size of the matrix
int n = sc.nextInt();
// Declaring the matrices in double datatype
// Declaring the input variable where we take in the
// input
double[][] input = new double[n][n];
// Taking the matrices for real value
double[][] realOut = new double[n][n];
// Taking the matrices for imaginary output
double[][] imagOut = new double[n][n];
// Enter the values of elements of the DFT Matrix
System.out.println("Enter the elements:");
// Taking the input of the array
// By iterating the two loops
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
input[i][j] = sc.nextDouble();
}
}
// Calling the function discrete
discrete(input, realOut, imagOut);
// Closing the function scanner
sc.close();
}
// Now by taking the discrete function
// This is the declaration of the function
// This function includes 4 parameters
// The parameters are the 4 matrices.
static void discrete(double[][] input,
double[][] realOut,
double[][] imagOut)
{
// Height is the variable of data type int
// the length of the input variable is stored in
// variable height
int height = input.length;
// The input of the first index length is stored in
// variable width
int width = input[0].length;
// Iterating the input till height stored in
// variable y
for (int y = 0; y < height; y++) {
// Taking the input iterating till width in
// variable x
for (int x = 0; x < width; x++) {
// Taking another variable y1 which will be
// the continuation of
// the variable y
// This y1 will be iterating till height
// This index of the variable starts at 0
for (int y1 = 0; y1 < height; y1++) {
// This index x1 iterates till width
// This x1 is continuation of x
// The variables y1 and x1 are the
// continuation of summable of x and y
for (int x1 = 0; x1 < width; x1++) {
// realOut is the variable which
// lets us know the real output as
// we do te summation of exponential
// signal
// we get cos as real term and sin
// as imaginary term
// so taking the consideration of
// above properties we write the
// formula of real as
// summing till x and y and
// multiplying it with cos2pie
// and then dividing it with width
// *height gives us the real term
realOut[y][x]
+= (input[y1][x1]
* Math.cos(
2 * Math.PI
* ((1.0 * x * x1
/ width)
+ (1.0 * y * y1
/ height))))
/ Math.sqrt(width * height);
// Now imagOut is the imaginary term
// That is the sine term
// This sine term can be obtained
// using sin2pie and then we divide
// it using width*height The
// formulae is same as real
imagOut[y][x]
-= (input[y1][x1]
* Math.sin(
2 * Math.PI
* ((1.0 * x * x1
/ width)
+ (1.0 * y * y1
/ height))))
/ Math.sqrt(width * height);
}
// Now we will print the value of
// realOut and imaginary outputn The
// ppoutput of imaginary output will end
// with value 'i'.
System.out.println(realOut[y][x] + " +"
+ imagOut[y][x]
+ "i");
}
}
}
}
}
输出: