二维傅里叶变换转一维傅里叶变换

问题描述

二维傅里叶变换转一维傅里叶变换
看了一个论文说二维傅里叶变换图谱经圆积分计算后可以得到一维傅里叶变换,求大神推导公式或者过程

解决方案

 // ==============================================================================// 快速离散傅里叶变换和功率谱// 一维快速傅里叶变换FFT1和二维快速傅里叶变换FFT2// 测试环境 C++ builder 2010// MinGW (GCC) 4.5// wuxuping 2010-08-10// 一定要将文件保存为UTF-8的格式这是MinGW的默认格式.// ==============================================================================#ifndef FFT_H#define FFT_H// --------------------#include <vector>#include<complex>#include<bitset>#include <iterator>#include <algorithm>#include <iostream>#include <sstream>using namespace std;const double pai = 3.1415926535897932384626433832795028841971; // 圆周率typedef vector<vector<complex<double> > >VVCD;typedef vector<vector<double> >VVD;// -------------------------------------------------class FFT1 {private:    unsigned N; // 数据长度    unsigned NFFT; // 使用快速傅里叶变化所计算的长度    unsigned r; // 数据长度NFFT=2^r且2^(r-1)<N<<NFFT    vector<complex<double> >TS; // 时间域序列    vector<complex<double> >FS; // 频率域序列FrequencySeries    vector<double>PSD; // PSD功率谱密度(离散谱)    vector<double>PS; // 返回PS=PSD*Frequency    int sign;    // sign > 0为正变换否则为逆变换    // ------------------------------------    void Set_NFFT_r(unsigned n);    unsigned RevBit(unsigned num);    void GetIndex(unsigned L unsigned ALindex unsigned &AL_1index0        unsigned &AL_1index1 unsigned &Windex);    // ------------------------------------    void doFFT1();    // 执行傅里叶变换    // ------------------------------------public:    // ------实序列构造函数-------------    FFT1(vector<double>TimeSeries int sign_ = 1) {        N = TimeSeries.size();        if (sign_ > 0) {            sign = 1.0; // 正变换        }        else {            sign = -1.0; // 逆变换        }        Set_NFFT_r(N);        complex<double>W0(0.0 0.0); // 旋转因子        // --------------------------------        for (unsigned i = 0; i < NFFT; i++) { // 赋初值            if (i < N) {                FS.push_back(W0);                complex<double>Wi(TimeSeries[i] 0.0); // 旋转因子                TS.push_back(Wi);            }            else {                FS.push_back(W0); // 补零                TS.push_back(W0); // 补零            }        }        // --------------------------------        doFFT1(); // 执行傅里叶变换        // --------------------------------    };    // -------复序列构造函数-------------    FFT1(vector<complex<double> >TimeSeries int sign_ = 1) { // 赋初值        N = TimeSeries.size();        if (sign_ > 0) {            sign = 1.0; // 正变换        }        else {            sign = -1.0; // 逆变换        }        Set_NFFT_r(N);        complex<double>W0(0.0 0.0); // 旋转因子        // --------------------------------        for (unsigned i = 0; i < NFFT; i++) { // 赋初值            if (i < N) {                FS.push_back(W0);                TS.push_back(TimeSeries[i]);            }            else {                FS.push_back(W0); // 补零                TS.push_back(W0); // 补零            }        }        // --------------------------------        doFFT1(); // 执行傅里叶变换        // --------------------------------    };    // ----------成员函数------    // ----------成员函数 -------------    vector<complex<double> >GetFS() { // 返回频率域序列FrequencySeries        return FS;    };    // ----------成员函数 -------------    vector<double>GetFrequency() { // 返回频率        vector<double>Frequency;        // ----------------------        for (unsigned int i = 0; i < FS.size(); i++) {            Frequency.push_back(i);        }        return Frequency;    };    // ----------成员函数 -------------    vector<double>GetPSD() { // 返回FS^2        if (PSD.size() > 0) {            PSD.clear();        }        // ----------------------        for (unsigned int i = 0; i < FS.size(); i++) {            PSD.push_back(real(FS[i] * conj(FS[i])));        }        return PSD;    };    vector<double>GetPS() { // 返回PS=PSD*Frequency        if (PS.size() > 0) {            PS.clear();        }        // ----------------------        for (unsigned int i = 0; i < FS.size(); i++) {            PS.push_back(i * 1.0 * real(FS[i] * conj(FS[i])));        }        return PS;    };    // ----------析构函数 -------------    ~FFT1() {    };    // -----------------------------------};// ------设置NFFT和r的值--------void FFT1::Set_NFFT_r(unsigned n) {    bitset<32>bsn(n);    r = 0;    while ((n >> r) > 0) {        r++;    }    if ((bsn.count() == 1) && (r > 0)) {        r--;    }    bitset<32>bsNFFT(0);    bsNFFT.set(r);    NFFT = (unsigned)bsNFFT.to_ulong();};// ---- 比特倒序函数unsigned FFT1::RevBit(unsigned num) {    bitset<32>bs(num);    bitset<32>bsR;    // ---------逆序    for (unsigned i = 0; i < r; i++) {        bsR.set(i bs[r - i - 1]);    }    return(unsigned)bsR.to_ulong();};// ------------------------------------------------------------------------------// 计算公式中的索引AL(ALindex)=AL-1(AL_1index0)+AL-1(AL_1index1)W(Windex)// ------------------------------------------------------------------------------void FFT1::GetIndex(unsigned L unsigned ALindex unsigned &AL_1index0    unsigned &AL_1index1 unsigned &Windex) {    // ALindex为AL()的索引    // AL_1index0 = 0; // AL-1()的第一项索引    // AL_1index1 = 0; // AL-1()的第二项索引    // Windex = 0; // 相位角中的索引    bitset<32>bs(ALindex);    bitset<32>bs1(ALindex);    bs1.set(r - L 0);    AL_1index0 = bs1.to_ulong();    // -----------------------------------    bitset<32>bs2(ALindex);    bs2.set(r - L 1);    AL_1index1 = bs2.to_ulong();    // -----------------------------------    bitset<32>bs3; // 左L位    for (unsigned i = 0; i < L; i++) {        bs3.set(r - L + i bs[r - i - 1]);    }    Windex = bs3.to_ulong();}// ------------------------------------void FFT1::doFFT1() { // 一维快速Fourier变换    unsigned AL_1index0 = 0; // AL-1()的第一项索引    unsigned AL_1index1 = 0; // AL-1()的第二项索引    unsigned Windex = 0; // 相位角中的索引    double alpha; // 相位角    // ----------------------------    vector<complex<double> >X = TS; // X中间临时变量    for (unsigned L = 1; L <= r; L++) { // 蝶形计算过程        for (unsigned ALindex = 0; ALindex < NFFT; ALindex++) {            // ALindex为AL()的索引            GetIndex(L ALindex AL_1index0 AL_1index1 Windex);            alpha = -2.0 * sign * pai * Windex / (1.0 * NFFT); // 旋转因子的相位角            complex<double>W(cos(alpha) sin(alpha)); // 旋转因子            FS[ALindex] = X[AL_1index0] + X[AL_1index1] * W;        }        X = FS; // 复制数组    }    //    if (sign > 0) { // 为正变换        for (unsigned i = 0; i < NFFT; i++) {            FS[i] = X[RevBit(i)]; // 索引按二进制倒序        }    }    else { // 为逆变换        complex<double>WN(NFFT 0.0); // 数据的个数        for (unsigned i = 0; i < NFFT; i++) {            FS[i] = X[RevBit(i)] / WN; // 索引按二进制倒序        }    }}// ==============================================================================// 计算二维快速傅里叶变换FFT2// ==============================================================================// ----------------------------------------------class FFT2 {private:    // ----------------------------------------------    unsigned N1; // 数据行长度 0<=k1<N1  0<=j1<N1    unsigned N2; // 数据列长度 0<=k2<N2  0<=j2<N2    int sign; // sign > 0为正变换否则为逆变换    VVCD Tk1k2; // 二维时间域序列行k1列k2    VVCD Yj1k2; // 中间序列对 Ak1k2每一行(k1)做傅里叶变换的结果    VVCD Fj1j2; // 频率域序列FrequencySeries    VVD PSD; // PSD功率谱密度(离散谱)    VVD PS; // 返回PS=PSD*Frequency    // ------------------------------------    VVCD TranspositionVVCD(VVCD dv); // 矩阵转置    // ------------------------------------public:    // ------实序列构造函数-------------    FFT2(VVD TK1K2 int sign_ = 1) { // 赋初值        N1 = TK1K2.size(); // 获取行数        Tk1k2.resize(N1);        for (unsigned k1 = 0; k1 < N1; k1++) {            N2 = TK1K2[k1].size();            Tk1k2[k1].resize(N2);            for (unsigned k2 = 0; k2 < N2; k2++) {                complex<double>W(TK1K2[k1][k2] 0.0);                Tk1k2[k1][k2] = W;            }        }        // -----------------------------------------        for (unsigned k1 = 0; k1 < N1; k1++) {            FFT1 fft1(Tk1k2[k1] sign_);            Yj1k2.push_back(fft1.GetFS());        }        // -----------------------------------------        Yj1k2 = TranspositionVVCD(Yj1k2); // 将矩阵转置        // -----------------------------------------        N2 = Yj1k2.size(); // 获取列数        for (unsigned k2 = 0; k2 < N2; k2++) {            FFT1 fft1(Yj1k2[k2] sign_);            Fj1j2.push_back(fft1.GetFS());        }        // --------------        Fj1j2 = TranspositionVVCD(Fj1j2); // 将矩阵转置        // -----------------------    };    // -------复序列构造函数-------------    FFT2(VVCD TK1K2 int sign_ = 1) { // 赋初值        Tk1k2 = TK1K2;        N1 = Tk1k2.size(); // 获取行数        for (unsigned k1 = 0; k1 < N1; k1++) {            FFT1 fft1(Tk1k2[k1] sign_);            Yj1k2.push_back(fft1.GetFS());        }        // -----------------------------------------        Yj1k2 = TranspositionVVCD(Yj1k2); // 将矩阵转置        // -----------------------------------------        N2 = Yj1k2.size(); // 获取列数        for (unsigned k2 = 0; k2 < N2; k2++) {            FFT1 fft1(Yj1k2[k2] sign_);            Fj1j2.push_back(fft1.GetFS());        }        // --------------        Fj1j2 = TranspositionVVCD(Fj1j2); // 将矩阵转置        // -----------------------    };    // ----------成员函数 -------------    VVCD GetFS() { // 返回频率域序列Fj1j2        return Fj1j2;    };    // ----------成员函数 -------------    VVD GetPSD() { // 返回FS^2        PSD.resize(Fj1j2.size());        for (unsigned i = 0; i < Fj1j2.size(); i++) {            PSD[i].resize(Fj1j2[i].size());        }        // ----------------------        for (unsigned i = 0; i < Fj1j2.size(); i++) {            for (unsigned j = 0; j < Fj1j2[i].size(); j++) {                PSD[i][j] = real(Fj1j2[i][j] * conj(Fj1j2[i][j]));            }        }        return PSD;    };    // ----------成员函数 -------------    VVD GetPS() { // 返回PS=PSD*Frequency        PS.resize(Fj1j2.size());        for (unsigned i = 0; i < Fj1j2.size(); i++) {            PS[i].resize(Fj1j2[i].size());        }        // ----------------------        for (unsigned i = 0; i < Fj1j2.size(); i++) {            for (unsigned j = 0; j < Fj1j2[i].size(); j++) {                PS[i][j] = (double)i * (double)j * real                    (Fj1j2[i][j] * conj(Fj1j2[i][j]));            }        }        return PS;    };    // ----------析构函数 -------------    ~FFT2() {    };    // -----------------------------------};// ----------------------------------------VVCD FFT2::TranspositionVVCD(VVCD dv) { // 将矩阵转置    unsigned dvRow = dv.size();    unsigned maxcol = 0;    unsigned mincol = 99999;    VVCD temp;    if (dv.size() > 0) {        // ------------------------------        for (unsigned i = 0; i < dvRow; i++) {            if (maxcol < dv[i].size()) {                maxcol = dv[i].size();            }            if (mincol > dv[i].size()) {                mincol = dv[i].size();            }        }        // ------------------------------        if (mincol == maxcol && mincol > 0) {            temp.resize(mincol);            for (unsigned i = 0; i < mincol; i++) {                temp[i].resize(dvRow);            }            for (unsigned i = 0; i < dvRow; i++) {                for (unsigned j = 0; j < mincol; j++) {                    temp[j][i] = dv[i][j];                }            }        }    }    return temp;}// ==============================================================================// 此处定义的函数是为了控制台输出查看方便// ==============================================================================// VVCD==vector<vector<complex<double> > >// VVD== vector<vector<double> >// ---------------------------------void PrintVVCD(vector<vector<complex<double> > >Data) {    cout << ""Data : "" << endl;    for (unsigned i = 0; i < Data.size(); i++) {        cout << ""Row["" << i << ""]=	"";        vector<complex<double> >v = Data[i];        copy(v.begin() v.end() ostream_iterator<complex<double> >(cout	""));        cout << endl;    }}// ---------------------------------void PrintVCD(vector<vector<double> >Data) {    cout << ""Data : "" << endl;    for (unsigned i = 0; i < Data.size(); i++) {        cout << ""Row["" << i << ""]=	"";        vector<double>v = Data[i];        copy(v.begin() v.end() ostream_iterator<double>(cout	""));        cout << endl;    }}// ---------------------------------// --------------------------------------------------------------------------------#endif

解决方案二:
傅里叶变换(转)
什么是傅里叶变换
小波变换与傅里叶变换

解决方案三:
DSP好像有具体的求解证明过程。

时间: 2024-10-01 08:33:05

二维傅里叶变换转一维傅里叶变换的相关文章

将二维数组转为一维数组的2种方法_php技巧

如何将下面的二维数组转为一维数组. 复制代码 代码如下: $msg = array( array( 'id'=>'45', 'name'=>'jack' ), array( 'id'=>'34', 'name'=>'mary' ), array( 'id'=>'78', 'name'=>'lili' ),); 第一种方法: 复制代码 代码如下: foreach($msg as $k => $v){ $ids[] = $id; $names[] = $name; }

php实现搜索一维数组元素并删除二维数组对应元素的方法_php技巧

本文实例讲述了php实现搜索一维数组元素并删除二维数组对应元素的方法.分享给大家供大家参考.具体如下: 定义一个一维数组一个二维数组如下 $fruit=array('apple','orange'); $products = array( array('name'=>'apple','price'=>23.4), array('name'=>'orange','price'=>45.3), array('name'=>'biscuit','number'=>5,'pri

string-C#一维数组存入二维数组的其中一维

问题描述 C#一维数组存入二维数组的其中一维 我定义 int num=20000; string[,] str2=new str[20,num]; for(int i=0;i<20;i++) { string[] str1=new str1[num]; str1=GetData(i); //一维数组是动态变化中,我随时提取 <<?这里该怎么写,我要将str1放入str2[i, ]中,就是将20个一维数组组合成了二维数组,请求大神帮忙 } 解决方案 一维数组与二维数组黑马程序员-一维数组和

详解C++中的一维数组和二维数组_C 语言

C++一维数组 定义一维数组 定义一维数组的一般格式为:     类型标识符  数组名[常量表达式]; 例如: int a[10]; 它表示数组名为a,此数组为整型,有10个元素. 关于一维数组的几点说明: 1) 数组名定名规则和变量名相同,遵循标识符定名规则. 2) 用方括号括起来的常量表达式表示下标值,如下面的写法是合法的: int a[10]; int a[2*5]; int a[n*2]; //假设前面已定义了n为常变量 3) 常量表达式的值表示元素的个数,即数组长度.例如,在"int

PHP实现一维数组转二维数组的方法_php技巧

本文实例讲述了PHP实现一维数组转二维数组的方法.分享给大家供大家参考.具体实现方法如下: <?php $asr[1] = array("a","b","c","d"); $asr[2] = array("a","b","c","d"); $asr[3] = array("a","b","c&

php将一维数组转换为每3个连续值组成的二维数组_php技巧

本文实例讲述了php实现将一维数组转换为每3个连续值组成的二维数组.分享给大家供大家参考,具体如下: <?php $aaa = array('aa','bb','cc','dd','ee','ff','gg','hh','ii'); for($i=0;$i<3;$i++) { $bbb[] = array_slice($aaa, $i * 3 ,3); } print_r($bbb); ?> 运行结果如下: Array ( [0] => Array ( [0] => aa [

java 怎么把二维数组转换成一维数组

问题描述 怎么把二维数组转换成一维数组详细点谢谢 解决方案 解决方案二:麻烦您说明白点.解决方案三:你看看C语言中二维数组的指针的原理,用指针访问就是类似访问一维的一样,所以你也可以把二维数组看成一维的.解决方案四:该回复于2011-02-16 13:48:21被版主删除解决方案五:Map<String,String>syncSendMessageByTemplate(StringsystemNo,StringtemplateId,Map<String,Map<String,Str

Java中增强for循环在一维数组和二维数组中的使用方法_java

一维数组: int[] a={1,2,3}; for(int i:a) { System.out.print(i+" "); } 输出:1 2 3 二维数组: import java.util.Scanner; public class tet { public static void main(String[] args) { //int[][] b={{1,2,3},{4,5,6}};行 int[][] a=new int[5][];//必须明确行数 for(int i=0;i&l

基于zxing生成与解析二维码、条形码

     基于zxing(https://github.com/zxing/zxing)与maven,针对二维码(包括带图片的二维码).条形码进行了简单的封装,以便在项目中更好的利用.     ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME.J2SE和Android      关于二维码的生成细节与原理,请参考:http://coolshell.cn/arti