FFT变换Android代码及解析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gkw421178132/article/details/71512613

FFT变换Android代码及意义解析备注

雷德算法

/** 雷德算法 奇偶排序  01234567 - 04261537 */
private short[] AlgorithmRador(short[] shorts)
{
    int length = shorts.length;
    int i,j,k;
    short tempByte;
    for (j = 0,i = 0; i < length-1; i++)
    {
        if (i<j)    // Exchange
        {
            tempByte = shorts[i];
            shorts[i] = shorts[j];
            shorts[j] = tempByte;
        }
        k = length >> 1;    //求j的下一个倒序
        while (k <= j)      //j的最高位为1
        {
            j = j - k;      //把最高位变为0
            k >>= 1;        //比较次高位
        }
        j = j + k;          //把0变为1
    }
    return shorts;
}


FFT变换

/**  蝶形运算  */
private short[] AlgorithmFFT(short[] shorts)
{
    int length = shorts.length;
    int l=0;
    //int power = (int)(Math.log(length)/Math.log(2));
    int power = 12; // 4096=2^12

    ComplexCalculation complexCalculation = new ComplexCalculation();
    ComplexNumber tempProduct,tempUp,tempDown;
    ComplexNumber[] tempRotate = ComplexRotate(length);     /**  初始化得到旋转系数数组   FFT查表计算 */
    ComplexNumber[] complexNumber = complexCalculation.Short2Complex(shorts);     /**  输入字节数组 变换为 复数数组 */

    /** N点FFT分为m=log2(N)级  每级=N/2个蝶形  3层循环*/
    for (int i=0;i<power;i++)            /** 第一层 m级运算 */
    {
        l = 1<<i;
        for(int j=0;j<length;j=j+2*l)    /** 第二层 第L级有2^(L-1)个蝶形因子(乘数) 选择W*/
        {
            for (int k=0;k<l;k++)        /** 第三层 第L级有 N/2^L个群 同级内不同群乘数相同 执行不同群众具有相同W的蝶形运算*/
            {
                tempProduct = complexCalculation.ComplexMultiply(complexNumber[j+k+l],tempRotate[length*k/2/l]);
                tempUp = complexCalculation.ComplexAdd(complexNumber[j+k],tempProduct);
                tempDown = complexCalculation.ComplexMinus(complexNumber[j+k],tempProduct);
                complexNumber[j+k] = tempUp;
                complexNumber[j+k+l] = tempDown;
            }
        }
    }

    /** FFT变换后的 复数数组 变换为 幅值字节数组 取前一半数组 */
    short[] ShortOut = new short[length/2];
    for (int i=0; i<length/2; i++)
    {
        ShortOut[i] = complexCalculation.ComplexMagnitudeShort(complexNumber[i]);
    }
    return ShortOut;
}


复数类

/**  类  定义复数  */
public class ComplexNumber
{
    private double real;
    private double img;
}


复数运算类

/**  类  定义复数:加法 减法 乘法 取模 short转复数 */
public class ComplexCalculation
{
    ComplexCalculation()
    {
        super();
    }
    /**  复数加法  */
    private ComplexNumber ComplexAdd(ComplexNumber temp1,ComplexNumber temp2)
    {
        ComplexNumber result = new ComplexNumber();
        result.real = temp1.real + temp2.real;
        result.img = temp1.img + temp2.img;
        return result;
    }
    /**  复数减法  */
    private ComplexNumber ComplexMinus(ComplexNumber temp1,ComplexNumber temp2)
    {
        ComplexNumber result = new ComplexNumber();
        result.real = temp1.real - temp2.real;
        result.img = temp1.img - temp2.img;
        return result;
    }
    /**  复数乘法  */
    private ComplexNumber ComplexMultiply(ComplexNumber temp1,ComplexNumber temp2)
    {
        ComplexNumber result = new ComplexNumber();
        result.real = temp1.real * temp2.real - temp1.img * temp2.img;
        result.img = temp1.real * temp2.img + temp1.img * temp2.real;
        return result;
    }
    /**  取模  */
    private double ComplexMagnitudeDouble(ComplexNumber complexNumber)
    {
        return Math.hypot(complexNumber.real,complexNumber.img);
    }
    private short ComplexMagnitudeShort(ComplexNumber complexNumber)
    {
        double result = Math.hypot(complexNumber.real,complexNumber.img)/4;
        if (result<=0)
            result = 0;
        if (result>=32767)
            result = 32767;
        return (short) result;
    }
    /**  short[]扩展为ComplexNumber[]  */
    private ComplexNumber[] Short2Complex(short[] shorts)
    {
        int length = shorts.length;
        ComplexNumber[] result = new ComplexNumber[length];
        /**  需要对每个result初始化,不然会报空指针错误  */
        for (int i = 0;i<length;i++)
        {
            result[i] = new ComplexNumber();
            result[i].real = (double) shorts[i];
            result[i].img = (double) 0;
        }
        return result;
    }
}


旋转矩阵函数,为查表做准备

/**  旋转因子 函数  */
private ComplexNumber[] ComplexRotate(int N)    // n:输入序列第n个元素   k:输出序列第k个  N:N点FFT
{
    double PI = 3.14159;
    ComplexNumber[] result = new ComplexNumber[N];
    /**  需要对每个result初始化,不然会报空指针错误  */
    for (int i=0; i<N; i++)
    {
        result[i] = new ComplexNumber();
        result[i].real = Math.cos((double)2*PI*i/N);
        result[i].img = -Math.sin((double)2*PI*i/N);     //  符号double类型int类型
    }
    return result;
}



展开阅读全文

没有更多推荐了,返回首页