zoukankan      html  css  js  c++  java
  • FFT(快速傅立叶算法 for java)

    package com.test.test2;

    public class FFT {
        public static final int FFT_N_LOG = 10; // FFT_N_LOG <= 13
        public static final int FFT_N = 1 << FFT_N_LOG;
        private static final float MINY = (float) ((FFT_N << 2) * Math.sqrt(2)); // (*)
        private final float[] real, imag, sintable, costable;
        private final int[] bitReverse;

        public FFT() {
            real = new float[FFT_N];
            imag = new float[FFT_N];
            sintable = new float[FFT_N >> 1];
            costable = new float[FFT_N >> 1];
            bitReverse = new int[FFT_N];

            int i, j, k, reve;
            for (i = 0; i < FFT_N; i++) {
                k = i;
                for (j = 0, reve = 0; j != FFT_N_LOG; j++) {
                    reve <<= 1;
                    reve |= (k & 1);
                    k >>>= 1;
                }
                bitReverse[i] = reve;
            }

            double theta, dt = 2 * 3.14159265358979323846 / FFT_N;
            for (i = 0; i < (FFT_N >> 1); i++) {
                theta = i * dt;
                costable[i] = (float) Math.cos(theta);
                sintable[i] = (float) Math.sin(theta);
            }
        }

        /**
         * 用于频谱显示的快速傅里叶变换
         *
         * @param realIO
         *            输入FFT_N个实数,也用它暂存fft后的FFT_N/2个输出值(复数模的平方)。
         */
        public void calculate(float[] realIO) {
            int i, j, k, ir, exchanges = 1, idx = FFT_N_LOG - 1;
            float cosv, sinv, tmpr, tmpi;
            for (i = 0; i != FFT_N; i++) {
                real[i] = realIO[bitReverse[i]];
                imag[i] = 0;
            }

            for (i = FFT_N_LOG; i != 0; i--) {
                for (j = 0; j != exchanges; j++) {
                    cosv = costable[j << idx];
                    sinv = sintable[j << idx];
                    for (k = j; k < FFT_N; k += exchanges << 1) {
                        ir = k + exchanges;
                        tmpr = cosv * real[ir] - sinv * imag[ir];
                        tmpi = cosv * imag[ir] + sinv * real[ir];
                        real[ir] = real[k] - tmpr;
                        imag[ir] = imag[k] - tmpi;
                        real[k] += tmpr;
                        imag[k] += tmpi;
                    }
                }
                exchanges <<= 1;
                idx--;
            }

            j = FFT_N >> 1;
            /*
             * 输出模的平方(的FFT_N倍):
             * for(i = 1; i <= j; i++)
             * realIO[i-1] = real[i] * real[i] + imag[i] * imag[i];
             *
             * 如果FFT只用于频谱显示,可以"淘汰"幅值较小的而减少浮点乘法运算. MINY的值
             * 和Spectrum.Y0,Spectrum.logY0对应.
             */
            sinv = MINY;
            cosv = -MINY;
            for (i = j; i != 0; i--) {
                tmpr = real[i];
                tmpi = imag[i];
                if (tmpr > cosv && tmpr < sinv && tmpi > cosv && tmpi < sinv)
                    realIO[i - 1] = 0;
                else
                    realIO[i - 1] = tmpr * tmpr + tmpi * tmpi;
            }
        }

        public static void main(String[] args) {
            FFT fft2 = new FFT();
            float[] realIo = { 1, 2 };
            fft2.calculate(realIo);
        }
    }

  • 相关阅读:
    haproxy 2.5 发布
    cube.js sql 支持简单说明
    基于graalvm 开发一个cube.js jdbc driver 的思路
    apache kyuubi Frontend 支持mysql 协议
    oceanbase 资源池删除说明
    基于obd 的oceanbase 扩容说明
    jfilter一个方便的spring rest 响应过滤扩展
    cube.js schema 定义多datasource 说明
    typescript 编写自定义定义文件
    meow 辅助开发cli 应用的工具
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3268533.html
Copyright © 2011-2022 走看看