欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > C数学运算库 GSL的使用-快速傅里叶变换

C数学运算库 GSL的使用-快速傅里叶变换

2025/9/18 14:28:22 来源:https://blog.csdn.net/qq_41931610/article/details/142254355  浏览:    关键词:C数学运算库 GSL的使用-快速傅里叶变换

一、GSL 下载与安装

下载GSL安装文件: http://mirrors.ustc.edu.cn/gnu/gsl/

GSL文档在线:https://www.gnu.org/software/gsl/doc/html/index.html

GSL文档下载:https://www.gnu.org/software/gsl/doc/latex/gsl-ref.pdf

MSVC依赖库:https://download.csdn.net/download/qq_41931610/89708341?spm=1001.2014.3001.5503icon-default.png?t=O83Ahttps://download.csdn.net/download/qq_41931610/89708341?spm=1001.2014.3001.5503

二、快速傅里叶变换

2.1 GSL 中FFT 的定义

正变换(forward):

逆变换(inverse):

反变换(backward):

2.2 实数FFT与复数FFT

FFT是计算DFT的快速算法,但是它是基于复数的,所以计算实数DFT的时候需要将其转换为复数的格式。

下图展示了实数DFT和虚数DFT的情况,实数DFT将时域中N点信号转换成2个(N/2+1)点的频域信号,其中1个(N/2+1)点的信号称之为实部,另一个(N/2+1)点的信号称之为虚部,实部和虚部分别是正弦和余弦信号的幅度。相比较而言,复数DFT将2个N点的时域信号转换为2个N点的频域信号。时域和频域中,1个N点信号是实部,另1个N点信号是虚部。

如果要计算N点实数DFT,则将这个N个点作为时域中的实部,另取N个0点作为时域的虚部,用FFT计算这样一个复数信号的DFT得到2个N点的频域信号,1个N点是实部另1个N点是虚部,在这两个N点的信号中,从0到N/2个点就是须计算的N点实数的DFT频域。

2.3 复数FFT

分配空间

gsl_fft_complex_wavetable *wavetable = gsl_fft_complex_wavetable_alloc (N);

gsl_fft_complex_workspace * workspace = gsl_fft_complex_workspace_alloc (N);

选择需要的运算

gsl_fft_complex_forward (data, stride, N, wavetable, workspace );
gsl_fft_complex_transform (data, stride, N, wavetable, workspace, sign);
gsl_fft_complex_backward  (data, stride, N, wavetable, workspace );
gsl_fft_complex_inverse  (data, stride, N, wavetable, workspace );

释放分配空间

gsl_fft_complex_workspace_free (workspace);
gsl_fft_complex_wavetable_free (wavetable);

例子

#include <stdio.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_fft_complex.h>#define REAL(z,i) ((z)[2*(i)])
#define IMAG(z,i) ((z)[2*(i)+1])int main (void)
{int i;const int n = 630;double data[2*n];gsl_fft_complex_wavetable * wavetable;gsl_fft_complex_workspace * workspace;for (i = 0; i < n; i++){REAL(data,i) = 0.0;IMAG(data,i) = 0.0;}data[0] = 1.0;for (i = 1; i <= 10; i++){REAL(data,i) = REAL(data,n-i) = 1.0;}for (i = 0; i < n; i++){printf ("%d: %e %e\n", i, REAL(data,i), IMAG(data,i));}printf ("\n");wavetable = gsl_fft_complex_wavetable_alloc (n);workspace = gsl_fft_complex_workspace_alloc (n);for (i = 0; i < wavetable->nf; i++){printf ("# factor %d: %d\n", i,wavetable->factor[i]);}gsl_fft_complex_forward (data, 1, n, wavetable, workspace);for (i = 0; i < n; i++){printf ("%d: %e %e\n", i, REAL(data,i), IMAG(data,i));}gsl_fft_complex_wavetable_free (wavetable);gsl_fft_complex_workspace_free (workspace);return 0;}

2.4 实数FFT

2.4.1 当N为偶数时

complex[0].img = 0

complex[N/2].img = 0

2.4.2 当N为奇数时

complex[0].img = 0

2.4.3 使用

可以把实数数组转换为复数数组,就可以用复数fft 函数来计算了。

int gsl_fft_real_unpack (const double real_coefficient[], gsl_complex_packed_array complex_coefficient[], size_t stride, size_t n)

正变换调用

gsl_fft_real_wavetable * gsl_fft_real_wavetable_alloc (size_t n);
gsl_fft_real_workspace * gsl_fft_real_workspace_alloc (size_t n);int gsl_fft_real_transform (double data[], size_t stride, size_t n, const gsl_fft_real_wavetable * wavetable, gsl_fft_real_workspace * work);void gsl_fft_real_workspace_free (gsl_fft_real_workspace * workspace);
gsl_fft_real_wavetable_free (gsl_fft_real_wavetable * wavetable);

逆变换调用

gsl_fft_halfcomplex_wavetable * gsl_fft_halfcomplex_wavetable_alloc (size_t n);
gsl_fft_real_workspace * gsl_fft_real_workspace_alloc (size_t n);int gsl_fft_halfcomplex_transform (double data[], size_t stride, size_t n, const gsl_fft_halfcomplex_wavetable * wavetable, gsl_fft_real_workspace * work);void gsl_fft_real_workspace_free (gsl_fft_real_workspace * workspace);
gsl_fft_halfcomplex_wavetable_free (gsl_fft_halfcomplex_wavetable * wavetable);

2.4.4 幅值与相位

假设原始信号的峰值为A,那么FFT的结果的每个点(除了第一个点直流分量之外)的模值就是A的N/2倍。而第一个点就是直流分量,它的模值就是直流分量的N倍。

直流分量:output[0] = data[0] / N

幅值:output[ i ] = sqrt(data[ i ] * data[ i ]  +  data[ i+1 ] * data[ i+1 ]) / (N/2)

相位:output[ i+1 ] = atan2 (data[ i+1 ] , data[ i ])  

相关文章:

GSL(C数学运算库)安装和使用教程

Windows系统编译GSL2.7用于C语言编程(2022.5.8)

Qt5配置开源GSL数学库

GSL 学习笔记(快速傅立叶变换)

FFT快速傅立叶变换的工作原理

信号傅里叶变换后的实数和虚数部分理解

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com