FFT变换Android代码及解析

来源:互联网 发布:广西广电网络机顶盒ip 编辑:程序博客网 时间:2024/06/03 13:40

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;}



0 0
原创粉丝点击