Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何获得与Matlab使用FFTW时相同的希尔伯特变换结果?_C_Signal Processing_Fft_Absolute_Fftw - Fatal编程技术网

C 如何获得与Matlab使用FFTW时相同的希尔伯特变换结果?

C 如何获得与Matlab使用FFTW时相同的希尔伯特变换结果?,c,signal-processing,fft,absolute,fftw,C,Signal Processing,Fft,Absolute,Fftw,我需要计算希尔伯特变换,从我的信号中得到它的绝对数。 我安装了FFTW并进行了跟踪,两者都运行良好 然而,我像视频一样实现了希尔伯特变换,我没有得到与Matlab计算的值相同的值 我读过一些人,他们仅仅通过FFT和其他计算来解决这个问题,但他们没有给出足够清晰的答案。 谁能给我提供几行基于FFTW的代码,让结果与Matlab计算结果一致 下面是我在视频中看到的希尔伯特变换代码: void hilbert(const double* in, fftw_complex* out) { //

我需要计算希尔伯特变换,从我的信号中得到它的绝对数。 我安装了FFTW并进行了跟踪,两者都运行良好

然而,我像视频一样实现了希尔伯特变换,我没有得到与Matlab计算的值相同的值

我读过一些人,他们仅仅通过FFT和其他计算来解决这个问题,但他们没有给出足够清晰的答案。 谁能给我提供几行基于FFTW的代码,让结果与Matlab计算结果一致

下面是我在视频中看到的希尔伯特变换代码:

void hilbert(const double* in, fftw_complex* out)
{
    // copy the data to the complex array
    for (int i = 0; i < N; ++i) {
        out[i][REAL] = in[i];
        out[i][IMAG] = 0;
    }
    // creat a DFT plan and execute it
    fftw_plan plan = fftw_plan_dft_1d(N, out, out, FFTW_FORWARD, FFTW_ESTIMATE);
    fftw_execute(plan);
    // destroy a plan to prevent memory leak
    fftw_destroy_plan(plan);
    int hN = N >> 1; // half of the length (N/2)
    int numRem = hN; // the number of remaining elements
    // multiply the appropriate value by 2
    //(those should multiplied by 1 are left intact because they wouldn't change)
    for (int i = 1; i < hN; ++i) {
        out[i][REAL] *= 2;
        out[i][IMAG] *= 2;
    }
    // if the length is even, the number of the remaining elements decrease by 1
    if (N % 2 == 0)
        numRem--;
    else if (N > 1) {
        out[hN][REAL] *= 2;
        out[hN][IMAG] *= 2;
    }
    // set the remaining value to 0
    // (multiplying by 0 gives 0, so we don't care about the multiplicands)
    memset(&out[hN + 1][REAL], 0, numRem * sizeof(fftw_complex));
    // creat a IDFT plan and execute it
    plan = fftw_plan_dft_1d(N, out, out, FFTW_BACKWARD, FFTW_ESTIMATE);
    fftw_execute(plan);
    // do some cleaning
    fftw_destroy_plan(plan);
    fftw_cleanup();
    // scale the IDFT output
    for (int i = 0; i < N; ++i) {
        out[i][REAL] /= N;
        out[i][IMAG] /= N;
    }
}
void hilbert(常数双*in,fftw\u复数*out)
{
//将数据复制到复杂数组中
对于(int i=0;i>1;//长度的一半(N/2)
int numRem=hN;//剩余元素的数量
//将适当的值乘以2
//(那些应该乘以1的值保持不变,因为它们不会改变)
对于(int i=1;i1){
out[hN][REAL]*=2;
out[hN][IMAG]*=2;
}
//将剩余值设置为0
//(乘以0等于0,所以我们不关心被乘数)
memset(&out[hN+1][REAL],0,numRem*sizeof(fftw_复合体));
//创建IDFT计划并执行
plan=fftw\U plan\U dft\U 1d(N,out,out,fftw\U向后,fftw\U估算);
fftw_执行(计划);
//打扫
fftw销毁计划(计划);
fftw_cleanup();
//缩放IDFT输出
对于(int i=0;i
我的主要计算程序是:

pi16Buffer = (int16 *)pBuffer;
        //int16* ch1Buffer; 
        //int16* ch2Buffer;
        
        double* ch1Buffer = NULL;
        double* ch2Buffer = NULL;
        fftw_complex result[N] ; // output array
        
        // Allocate size to ch1 and ch2
        ch1Buffer       = (double*)calloc(u32Size, sizeof(double));
        ch2Buffer       = (double*)calloc(u32Size, sizeof(double));
        
        //ch1ch2ch1ch2... fulfill the buffer
        for (i = 0; i < u32Size/2; i++)
        {
            ch1Buffer[i] += (double)pi16Buffer[i*2];
            ch2Buffer[i] += (double)pi16Buffer[i * 2 + 1];
        }

        // here hilbert on the whole ch2
        hilbert(ch2Buffer, result); //hilbert(inputarray, outputarray)

        for (i = 0; i < u32Size; i++)
        {
            if (ch1Buffer[i] > max1)  //Find max value in each segs of ch1 and ch2
                max1 = ch1Buffer[i];

            if (abs(result[i]) > max2)
                max2 = abs(result[i]); // Calculate the absolute value of hilbert result;

    
        }
        Corrected = max2 / max1; //do the signal correction
        free(ch1Buffer); //free buffer
        free(ch2Buffer);

        
        
    }
    return Corrected;
pi16Buffer=(int16*)pBuffer;
//int16*CH1缓冲器;
//int16*CH2缓冲器;
double*ch1Buffer=NULL;
double*ch2Buffer=NULL;
fftw_复数结果[N];//输出阵列
//将大小分配给ch1和ch2
ch1Buffer=(双*)calloc(u32Size,sizeof(双));
ch2Buffer=(双*)calloc(u32Size,sizeof(双));
//ch1ch2ch1ch2。。。完成缓冲
对于(i=0;imax1)//在ch1和ch2的每个分段中查找最大值
max1=ch1Buffer[i];
如果(abs(结果[i])>max2)
max2=abs(结果[i]);//计算希尔伯特结果的绝对值;
}
校正=最大值2/最大值1//做信号校正
免费(ch1Buffer)//自由缓冲区
免费(ch2Buffer);
}
回程修正;

我很难理解您的代码。
这是我的测试代码,在一个简单的N=4情况下。
它应该至少适用于所有偶数大小的输入。要使用奇数输入进行检查

此代码计算分析信号。matlab的
hilbert
函数也有同样的作用

它的实部对应于输入的实部信号。
希尔伯特变换对应于虚值

其原理是确保负频率的FFT值为零。
这是通过在频域中进行简单的加窗来实现的

#include <stdio.h>
#include <complex.h>

// Analytic signal calculation
// The real part of it corresponds to the input real signal
// The hilbert transform corresponds to the imaginary value

void print (complex *x, int n) {
    for (int i = 0; i < n; ++i) {
        printf ("(%lf, %lf) ", creal(x[i]), cimag(x[i]));
    }
    printf ("\n");
}

void fft4 (complex *x, int n, int inversion) {
    complex t0, t1, t2, t3;
    t0 = x[0] + x[2];
    t1 = x[1] + x[3];
    t2 = x[0] - x[2];
    if (!inversion) t3 = I * (x[1] - x[3]);
    else t3 = -I * (x[1] - x[3]);
    x[0] = t0 + t1;
    x[2] = t0 - t1;
    x[1] = t2 - t3;
    x[3] = t2 + t3;
}

#define N 4

int main() {
    const int n = N;
    complex x[N] = {1, 2, 3, 4};
    complex y[N] = {1, 2, 3, 4};
    
    fft4 (y, n, 0); // direct FFT size 4
    
    print (x, n);
    print (y, n);
    
    for (int i = 1; i < n/2; ++i) y[i] *= 2.0;
    for (int i = n/2+1; i < n; ++i) y[i] = 0.0;
    
    fft4 (y, n, 1);     // inverse FFT
    for (int i = 0; i < n; ++i) y[i] /= n;  // normalisation
    print (y, n);       // print analytical signal

    return 0;
}
#包括
#包括
//解析信号计算
//它的实部对应于输入实信号
//希尔伯特变换对应于虚值
无效打印(复数*x,整数n){
对于(int i=0;i
如果我们看不到代码,则很难更正代码。此外,您应该使用比youtube视频更可靠的来源,例如Hi@Damien,感谢您的通知,我现在附上了我的代码。请注意,matlab函数将原始值放在实部,将Hilbert变换值放在虚部。您可以提供一个非常简单的输入(4或8个元素),以及您的输出和matlab outputHi@Damien,谢谢您的回复,但我不太明白您的想法。请你写一个例子,例如代码,以便更清楚地解释?谢谢我不使用fftw,而是使用我自己的FFT函数。我可以尝试提供一个简单DFT函数的示例。但是,我没有matlab,如果有一个好的输入/输出Hanks的例子,它会帮助我!很抱歉,我应该提供更多关于我的代码和