FFT、IFFT和DCT、IDCT和WALSH、IWALSH

#include "stdafx.h"
#include "math.h"
#include "complex"
#include "iostream"
using namespace std;

 

#define PI 3.1415926

 

void FFT(complex<double>* TD, complex<double>* FD, int r)
{      
       long count;                            // 傅立叶变换点数
       int i, j, k;                            // 循环变量
       int offset, p;
       double angle;                            // 角度
       complex<double> *W, *X1, *X2, *X;
       
       count = 1 << r;                     // 计算傅立叶变换点数
      
       // 分配运算所需存储器
       W = new complex<double>[count / 2];
       X1 = new complex<double>[count];
       X2 = new complex<double>[count];
      
       // 计算加权系数
       for(i = 0; i < count / 2; i++)
       {
              angle = -i * PI * 2 / count;
              W[i] = complex<double> (cos(angle), sin(angle));
       }
      
       // 将时域点写入X1
       memcpy(X1, TD, sizeof(complex<double>) * count);
      
       // 采用蝶形算法进行快速傅立叶变换
       for(k = 0; k < r; k++)
       {
              offset = 1 << (r-k);
              for(j = 0; j < 1 << k; j++)
              {
                     p = j * offset;
                     for(i = 0; i < offset / 2; i++)
                     {
                           
                            X2[i + p] = X1[i + p] + X1[i + p + offset / 2];
                            X2[i + p + offset / 2] = (X1[i + p] - X1[i + p + offset / 2])
                                   * W[i * (1 << k)];
                     }
              }
              X = X1;
              X1 = X2;
              X2 = X;
       }
      
       // 重新排序
       for(j = 0; j < count; j++)
       {
              p = 0;
              for(i = 0; i < r; i++)
              {
                     if (j&(1 << i))
                     {
                            p += 1 << (r-i-1);
                     }
              }
              FD[j] = X1[p];
       }
      
       delete []W;
       delete []X1;
       delete []X2;
}

 

void IFFT(complex<double>* FD, complex<double>* TD, int r)
{      
       long count;                                   // 傅立叶变换点数      
       int i;                                                 // 循环变量      
       complex<double> *X;       
       
       count = 1 << r;                                   // 计算傅立叶变换点数
       X = new complex<double>[count];       // 分配运算所需存储器
       memcpy(X, FD, sizeof(complex<double>) * count);       // 将频域点写入X
      
       // 求共轭
       for(i = 0; i < count; i++)
       {
              X[i] = complex<double> (X[i].real(), -X[i].imag());
       }
      
       FFT(X, TD, r);                                   // 调用快速傅立叶变换
      
       // 求时域点的共轭
       for(i = 0; i < count; i++)
       {
              TD[i] = complex<double> (TD[i].real() / count, -TD[i].imag() / count);
       }
      
       delete []X;
}

 

void DCT(double* TD, double* FD, int r)
{      
       long count;                     // 离散余弦变换点数      
       int i;                            // 循环变量      
       double factor;
       complex<double> *X;
             
       count = 1 << r;                     // 计算离散余弦变换点数      

       X = new complex<double>[count * 2];
       memset(X, 0, sizeof(complex<double>) * count * 2);       // 赋初值为
      
       // 将时域点写入数组X
       for(i=0;i<count;i++)
       {
              X[i] = complex<double> (TD[i], 0);
       }
             
       FFT(X, X, r + 1);                            // 调用快速傅立叶变换             
       factor = 1 / sqrt((double)count);              // 调整系数             
       FD[0] = X[0].real() * factor;       // 求F[0]      
       factor *= sqrt(2.0);
      
       // 求F[u]      
       for(i = 1; i < count; i++)
       {
              FD[i] = (X[i].real() * cos(i * PI / (count * 2)) + X[i].imag() *
                     sin(i * PI / (count * 2))) * factor;
       }
      
       delete []X;
}

void IDCT(double* FD, double* TD, int r)
{
       long count;                     // 离散余弦反变换点数
       int i;                            // 循环变量
       double factor, factor0;
       complex<double> *X;
             
       count = 1 << r;                     // 计算离散余弦变换点数

       X = new complex<double>[count * 2];
       memset(X, 0, sizeof(complex<double>) * count * 2);       // 赋初值为
      
       // 将频域变换后点写入数组X
       for(i = 0;i < count;i++)
       {
              X[i] = complex<double> (FD[i] * cos(i * PI / (count * 2)), FD[i] *
                     sin(i * PI / (count * 2)));
       }
      
       IFFT(X, X, r + 1);              // 调用快速傅立叶反变换
      
       // 调整系数
       factor = sqrt(2.0 / count);
       factor0 = (sqrt(1.0 / count) - factor) * FD[0];
      
       for(i = 0; i < count; i++)
       {
              TD[i] = factor0 + X[i].real() * factor * 2 * count;
       }
      
       delete []X;
}

 

void WALSH(double* TD, double* FD, int r)
{      
       long count;                            // 沃尔什-哈达玛变换点数      
       int i, j, k;                            // 循环变量
       int offset, p;
       double *X1, *X2, *X;
             
       count = 1 << r;                            // 计算快速沃尔什变换点数      
       X1 = new double[count];              // 分配运算所需的数组
       X2 = new double[count];              // 分配运算所需的数组
             
       memcpy(X1, TD, sizeof(double) * count);       // 将时域点写入数组X1
      
       // 蝶形运算
       for(k = 0; k < r; k++)
       {
              offset = 1 << (r - k);
              for(j = 0; j < 1 << k; j++)
              {
                     p = j * offset;
                     for(i = 0; i < offset / 2; i++)
                     {                           
                            X2[i + p] = X1[i + p] + X1[i + p + offset / 2];
                            X2[i + p + offset / 2] = X1[i + p] - X1[i + p + offset / 2];
                     }
              }
             
              // 互换X1和X2 
              X = X1;
              X1 = X2;
              X2 = X;
       }
      
       // 调整系数
       for(j = 0; j < count; j++)
       {
              p = 0;
              for(i = 0; i < r; i++)
              {
                     if (j & (1 << i))
                     {
                            p += 1 << (r - i - 1);
                     }
              }

              FD[j] = X1[p] / count;
       }
      
       delete []X1;
       delete []X2;
}

 

void IWALSH(double* FD, double* TD, int r)
{      
       long count;                            // 变换点数      
       int i;                                   // 循环变量
             
       count = 1 << r;                            // 计算变换点数      
       WALSH(FD, TD, r);                            // 调用快速沃尔什-哈达玛变换进行反变换
             
       for(i = 0; i < count; i++)       // 调整系数
       {
              TD[i] *= count;
       }
}

你好!对于学习FFT(快速傅里叶变换)和IFFT(逆傅里叶变换),Matlab提供了丰富的函数和工具。FFTIFFT是一对互为逆运算的变换,用于在时域和频域之间进行转换。 要学习FFTIFFT的基本概念和原理,你可以参考相关的数学教材或在线教程。在Matlab中,你可以使用以下函数来进行FFTIFFT的计算: 1. fft(x):该函数用于计算输入信号x的FFT(快速傅里叶变换)。它将信号从时域转换为频域,并返回一个复数数组,表示频域上的幅度和相位信息。 2. ifft(X):该函数用于计算输入信号X的IFFT(逆傅里叶变换)。它将信号从频域转换回时域,并返回一个复数数组,表示时域上的原始信号。 这些函数的使用方法非常简单。你只需要将待处理的信号作为参数传递给相应的函数,然后使用输出结果进行进一步的分析或处理。例如,你可以使用fft函数计算信号的频谱,并使用ifft函数将频谱转换回原始信号。 以下是一个简单的示例代码,演示了如何使用fftifft函数: ```matlab % 生成一个测试信号 Fs = 1000; % 采样率 T = 1/Fs; % 采样周期 L = 1000; % 信号长度 t = (0:L-1)*T; % 时间向量 x = cos(2*pi*50*t) + 0.5*sin(2*pi*120*t); % 合成信号 % 计算信号的FFT X = fft(x); % 计算信号的频谱 P2 = abs(X/L); P1 = P2(1:L/2+1); P1(2:end-1) = 2*P1(2:end-1); f = Fs*(0:(L/2))/L; % 绘制频谱图 plot(f, P1) title('单边振幅谱') xlabel('频率 (Hz)') ylabel('幅度') % 计算信号的IFFT y = ifft(X); % 绘制原始信号和IFFT后的信号 subplot(2,1,1) plot(t, x) title('原始信号') xlabel('时间 (s)') ylabel('幅度') subplot(2,1,2) plot(t, real(y)) title('IFFT后的信号') xlabel('时间 (s)') ylabel('幅度') ``` 这段代码首先生成一个测试信号,然后使用fft函数计算信号的FFT,并绘制出频谱图。接下来,使用ifft函数对FFT结果进行逆变换,得到原始信号,并绘制出原始信号和逆变换后的信号。 希望这个简单的示例能帮助你入门FFTIFFT的学习。祝你学习愉快!如有任何问题,请随时向我提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值