信号平滑算法(Matlab的移动平均值)

Mer*_*rin 1 matlab

我编写了一个简单的代码,该代码执行3点移动平均平滑算法。它旨在遵循与此处所述Matlab的smooth(...)函数相同的基本算法。

但是,我的代码结果与Matlab的结果有很大不同。Matlab的3点滤波器似乎执行了更加主动的平滑处理。

这是使用我的代码(红色)和Matlab函数(蓝色)平滑后的嘈杂数据的比较:

比较一下:

这是我以函数形式编写的代码:

function [NewSignal] = smoothing(signal)
NewSignal = signal;
for i = 2 : length(signal)-1
    NewSignal(i,:) = (NewSignal(i,:)+NewSignal(i-1,:)+NewSignal(i+1,:))./3;
end
end
Run Code Online (Sandbox Code Playgroud)

Matlab的功能如下:

signal = smooth(time, signal, 3, 'moving');

据我了解,Matlab的功能以相同的方式工作。它会将3个相邻箱平均为一个箱。因此,我期望两种算法都能产生相同的结果。

那么,出现差异的原因是什么?我如何调整代码以产生相同的结果?

编辑:

我的样本数据可以在这里找到。可以使用以下命令访问它:

M = csvread('DS0009.csv');
time = M(:,1);
signal = M(:,2);
Run Code Online (Sandbox Code Playgroud)

这是使用rinkert校正的新结果(红色曲线):

在此处输入图片说明

rin*_*ert 5

造成这种差异的一个原因可能是您在平滑过程中部分使用了平滑信号。在循环中,您将平滑后的值存储在中NewSignal(i,:),对于下一个平滑示例,该值将由调用NewSignal(i-1,:)

让它仅NewSignal由原始确定signal

function [NewSignal] = smoothing(signal)
    NewSignal = signal;
    for i = 2 : length(signal)-1
        NewSignal(i,:) = (signal(i,:)+signal(i-1,:)+signal(i+1,:))./3;
    end
end
Run Code Online (Sandbox Code Playgroud)

更新:为了显示上面的功能实际上与Matlab的smooth功能相同,让我们考虑以下MVCE

t = (0:0.01:10).';      % time vector 
y = sin(t) + 0.5*randn(size(t));

y_smooth1 = smooth(t,y,3,'moving');
y_smooth2 = smoothing(y);

difference_methods = abs(y_smooth1-y_smooth2);
Run Code Online (Sandbox Code Playgroud)

因此,创建一个正弦波,添加一些噪声,并确定两种方法之间的绝对差。如果将所有差异求和,您会发现这总计等于7.5137e-14,无法解释您看到的差异。

绘制平滑信号(蓝色原始,红色平滑):

figure(1); clf; hold on
plot(t,y)
plot(t,y_smooth2)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

然后绘制两种方法之间的差异:

figure(2); clf; hold on;
plot(t,y_smooth1-y_smooth2)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

如您所见,差异大约为1e-16,因此受浮点相对精度的影响(请参阅参考资料eps)。