【发布时间】:2023-03-16 23:51:01
【问题描述】:
我试图在 C 中实现一个等效的 Matlab 函数 smooth(y, span)。 该函数的Matlab代码为:
n = length(y);
span = min(span,n);
width = span-1+mod(span,2); % force it to be odd
c = filter(ones(width,1)/width,1,y);
cbegin = cumsum(y(1:width-2));
cbegin = cbegin(1:2:end)./(1:2:(width-2))';
cend = cumsum(y(n:-1:n-width+3));
cend = cend(end:-2:1)./(width-2:-2:1)';
c = [cbegin;c(width:end);cend];
这是我的 C 代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// Compute cumulative sum of a signal of a given size.
void cumulative_sum(float *cum_vector, float *signal, int size)
{
int i;
cum_vector[0]=0;
cum_vector[1]=signal[0];
for(i=2;i<=size;i++)
{
cum_vector[i] = cum_vector[i-1] + signal[i-1];
}
}
// Moving average filter of a signal of a given size with a pre-defined span.
void moving_average(float *vector, int size, int span)
{
if (span > size)
{
span = size; //span = min(span,size);
}
int i;
int j=0;
int width = span - 1 + (span % 2); //force it to be odd
float *cum_x_tmp;
cum_x_tmp = (float *)malloc(size*sizeof(float));
cumulative_sum(cum_x_tmp,vector,size);
for (i=0;i<size;i++)
{
if (i< (width - 2)/2 +((width-2)%2 !=0))
{
vector[i] = cum_x_tmp[2*i+1]/(2*i+1);
}
else if (i>=(width - 2)/2 +((width-2)%2 !=0) && i<= (width - 2)/2 +((width-2)%2 !=0) + size - width)
{
int ind1 =i + floor(width/2)+1;
int ind2 =i - floor(width/2)-1+1;
vector[i] = (cum_x_tmp[ind1] - cum_x_tmp[ind2])/width;
}
else if (i>(width - 2)/2 +((width-2)%2 !=0) + size - width)
{
int ind4 = size-1-width+3-1+2*j+1;
vector[i] = (cum_x_tmp[size] - cum_x_tmp[ind4])/(width -2*(j+1));
j++;
}
}
}int main(int argc, const char * argv[]) {
int N=900;
float data;
FILE *fp;
fp = fopen("file.txt","r");
float *signal;
signal = (float*)malloc(N*sizeof(float));
int i;
for (i=0;i<N;i++)
{
fscanf(fp, "%f", &data);
signal[i]=data;
}
fclose(fp);
moving_average(signal,N,50);
free(signal);
return 0;}
我获得了与 Matlab 代码相同的值,直到代码中止的信号的某个索引。有谁知道为什么以及如何解决它?
提前致谢!
【问题讨论】:
-
for(i=2;i<=size;i++)是可疑的。我希望for(i=1;i<size;i++)。 -
是的,你是对的,它更符合逻辑。但是,它只是更大代码的一部分,我需要累积总和为 0,signal[0],signal[1],... 另一部分!
-
"直到代码中止的信号的某个索引。"请更具体。你知道在哪个索引?这将缩小您的循环中存在问题的情况。我建议你在 Valgrind 下运行你的程序,它会指出你是否以及在哪里访问了不属于你的程序的内存(这是最可能导致崩溃的原因)。