hilbert C语言 程序有问题

希尔伯特变换

程序有问题,详情参考评论

连续时间信号的希尔伯特变换

定义:给定一连续的时间信号x(n),其希尔伯特变换 x ^ ( t ) \widehat{x}(t) x (t)定义为

x ^ ( t ) = 1 π ∫ − ∞ ∞ x ( τ ) t − τ d ( τ ) \widehat{x}(t)=\frac{1}{\pi}\int^{\infty}_{-\infty}\frac{x(\tau)}{t-\tau}d(\tau) x (t)=π1tτx(τ)d(τ)

= 1 π ∫ − ∞ ∞ x ( t − τ ) τ d ( τ ) = x ( t ) ∗ 1 p i ∗ t =\frac{1}{\pi}\int^{\infty}_{-\infty}\frac{x(t-\tau)}{\tau}d(\tau)=x(t)*\frac{1}{pi*t} =π1τx(tτ)d(τ)=x(t)pit1

x ^ ( t ) \widehat{x}(t) x (t)可以看成是x(t)通过一滤波器的输出,该滤波器的单位冲激响应 h ( t ) = 1 π ∗ t h(t)=\frac{1}{\pi*t} h(t)=πt1

离散时间信号的希尔伯特变换

定义:设离散时间信号x(n)的希尔伯特变换是 x ^ ( n ) \widehat{x}(n) x (n),希尔伯特变换器的单位抽样响应为h(n),由连续时间信号希尔伯特变换的性质及H(jΩ)和 H ( e j w ) H(e^{jw}) Hejw的关系,得到

在这里插入图片描述

因此

h ( n ) = 1 2 ∗ π ∫ − π π H ( e j w e j w n d w = 1 2 π ∫ − π o j e j w n d w − 2 π ∫ π j e j w n d w h(n)=\frac{1}{2*\pi}\int^{\pi}_{-\pi}H(e^{jw}e^{jwn}dw=\frac{1}{2\pi}\int^{o}_{-\pi}je^{jwn}dw-2\pi\int^{\pi}je^{jwn}dw h(n)=2π1ππH(ejwejwndw=2π1πojejwndw2ππjejwndw

求解上式得积分,可得

h ( n ) = 1 − ( − 1 ) n n π = { 0 , n为偶数 2 n π n为奇数 h(n)=\frac{1-(-1)^n}{n\pi}=\begin{cases}0,&\text{n为偶数}\\\frac{2}{n\pi}&\text{n为奇数}\end{cases} h(n)=1(1)n={0,2n为偶数n为奇数

x ^ ( n ) = x ( n ) ∗ h ( n ) = 2 π ∑ m = − ∞ ∞ x ( n − 2 m − 1 ) 2 m + 1 \widehat{x}(n)=x(n)*h(n)=\frac{2}{\pi}\sum^{\infty}_{m=-\infty}\frac{x(n-2m-1)}{2m+1} x (n)=x(n)h(n)=π2m=2m+1x(n2m1)

则x(n)的解析信号

z ( n ) = x ( n ) + j x ^ ( n ) z(n)=x(n)+j\widehat{x}(n) z(n)=x(n)+jx (n)

也可用DFT方便地求出一个信号x(n)的解析信号及希尔伯特变换,步骤如下

  1. 对输入信号x(n)做 DFT,得X(k),k=0,…,N-1,注意k=\frac{N}{2},…,N-1对应负频率


  2. 在这里插入图片描述

  3. 对Z(k)做 逆DFT,得到x(n)的解析信号z(n).
    dft: X ( k ) = ∑ n = 0 N − 1 x ( n ) ∗ ( c o s ( 2 ∗ Π / N ∗ n ∗ k ) + i ∗ s i n ( 2 ∗ Π / N ∗ n ∗ k ) ) X(k)=\sum_{n=0}^{N-1}x(n)*(cos(2*\Pi/N*n*k)+i*sin(2*\Pi/N*n*k)) X(k)=n=0N1x(n)(cos(2Π/Nnk)+isin(2Π/Nnk))
    idft: x ( n ) = 1 N ∑ k = 0 N − 1 X ( k ) e x p ( j 2 π N n k ) x(n)=\frac{1}{N}\sum^{N-1}_{k=0}X(k)exp(j\frac{2\pi}{N}nk) x(n)=N1k=0N1X(k)exp(jN2πnk)

  4. 可求得希尔伯特变换 x ^ ( n ) = − j [ z ( n ) − x ( n ) ] \widehat{x}(n)=-j[z(n)-x(n)] x (n)=j[z(n)x(n)]

    C程序

    #include <stdio.h>
    #include <math.h>
    #define N 64
    #define pi  3.1415
    typedef struct
    {
        double real,imag;
    } complex;
    complex dft_out[100];
    complex dft_one[100];
    
    /*void idft(double z_r,double z_i)
    {
        int n,k;
        double a_r[100],a_i[100];
        double x_r[100],x_i[100];
        for(k=0; k<N; k++)//k循环
        {
            for(n=0; n<N; n++)//n循环
            {
    
                a_r[n]=z_r[n]*cos(2*pi/N*n*k);//实部信号
                a_i[n]=z_i[n]*sin(2*pi/N*n*k);//虚部信号
                x_r[k]+=x_r[n];
                x_i[k]+=x_i[n];//DFT后的实部,虚部相加
            }
            return x_r[k],x_i[k];
        }
    }*/
    /*void dftk(double x_r,double x_i)
    {
        int n;
        double z_r[100],z_i[100];
        for (n=0; n<N; n++)
        {
            if(n==0)
            {
                z_r[n]=x_r[n];
                z_i[n]=x_i[n];
    
            }
            if(1<=n&&n<N/2-1)
            {
                z_r[n]=2*x_r[n];
                z_i[n]=2*x_i[n];
    
            }
            if(N/2<=N&&n<=63)
            {
                z_r[n]=0;
                z_i[n]=0;
    
            }
        }
    }*/
    int main()
    {
        int n,k;
        double x_r[100],x_i[100];
        double z_r[100],z_i[100];
        double y_r[100],y_i[100];
        double s_r[100],s_i[100];
        double m_r[100],m_i[100];
        double xn,XK[100];
        double amp[100],xr[100],xi[100];
        for(k=0; k<N; k++)//DFT
        {
            for(n=0; n<N; n++)
            {
                xn=cos(n*pi/6);//原始信号
                dft_one[n].real=xn*cos(2*pi/N*n*k);//实部信号
                dft_one[n].imag=xn*sin(2*pi/N*n*k);//虚部信号
                dft_out[k].real+=dft_one[n].real;
                dft_out[k].imag+=dft_one[n].imag;//DFT后的实部,虚部相加
            }
            x_r[k]=dft_out[k].real;
            x_i[k]=dft_out[k].imag;
        }
        for (n=0; n<N; n++)//得到Z(K)
        {
            if(n==0)
            {
                z_r[n]=x_r[n];
                z_i[n]=x_i[n];
    
            }
            if(0<n&&n<N/2)
            {
                z_r[n]=2*x_r[n];
                z_i[n]=2*x_i[n];
    
            }
            if(N/2<=n&&n<64)
            {
                z_r[n]=0;
                z_i[n]=0;
    
            }
    
        }
        for(n=0; n<N; n++) //idft
        {
    
            for(k=0; k<N; k++)
            {
                m_r[n]+=z_r[k]*cos(2*pi/N*n*k)-z_i[k]*sin(2*pi/N*n*k);
                m_i[n]+=z_i[k]*cos(2*pi/N*n*k)+z_r[k]*sin(2*pi/N*n*k);
            }
            s_r[n]=1/N*m_r[n];
            s_i[n]=1/N*m_i[n];
        }
    
        for(n=0; n<N; n++)//输出
        {
            xr[n]=cos(n*pi/6);//原始信号
            y_r[n]=s_i[n];
            y_i[n]=xr[n]-s_r[n];
            amp[n]=sqrt(y_r[n]*y_r[n]+y_i[n]*y_i[n]);
            printf("%d    %f\n",n,y_i[n]);
        }
    }
    

matlab程序

N=64;

n=0:1:N;

n=0:1:63;

x=cos(n*pi/6);

y=hilbert(x);

figure

stem(n,y)

结果图

c的结果图
在这里插入图片描述

matlab的结果

在这里插入图片描述

对比的结果差异不大。

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

用户已经注册过

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值