📜  如何在Java中给定一个复杂的 2D 数组执行 2D FFT?

📅  最后修改于: 2022-05-13 01:55:49.676000             🧑  作者: Mango

如何在Java中给定一个复杂的 2D 数组执行 2D FFT?

快速傅立叶变换 (FFT) 是一种计算离散傅立叶变换 (DFT) 及其逆的算法。傅里叶分析将时间(或空间)转换为频率,反之亦然。 FFT 减少了计算离散傅立叶变换所需的计算时间,并通过直接评估 DFT 将性能提高了 100 倍或更多。 FFT 通过将 DFT 矩阵分解为稀疏乘积来计算此类变换。

在这里,我们使用了一个 2D 数组,它将帮助我们找到快速傅立叶变换。该算法在模式识别中很有用。

例子

方法:

  • 输入数组的大小。
  • 我们将采用 4 个数据类型为 double 的数组,分别命名为 input、realOut、imaginary。
  • 给出二维数组的输入。
  • 现在让我们调用一个函数dft ,它将帮助我们计算
  • 现在,我们将计算输入数据的高度和宽度。
  • 现在,让我们迭代循环的高度和宽度,
  • 现在要计算DFT ,我们将得到它的指数形式,可以将其转换为余弦和正弦项,标记为实部和虚部。这些可以通过使用这些公式来计算。
  • 使用高度和宽度迭代它我们计算realOut ,使用公式:
  • 同样,我们将使用这个公式得到虚输出:
  • 现在,我们将以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");
                }
            }
        }
    }
}


输出:

给定复数二维数组的二维 FFT 输出