Simulink环境下不定长信号的均值计算问题
实现实时累积均值(针对未知长度的连续输入信号)
首先得明确:你要的不是移动平均滤波器(固定窗口的滑动平均),而是累积均值(Running/Cumulative Mean)——每一步都计算从第一个输入到当前输入的整体平均值,刚好匹配你的需求:第一个值直接输出,第二个值是前两个的平均,后续每个值都和之前所有值的均值再平均(本质就是更新整体均值)。
核心思路:用递推公式避免存储所有历史数据
不需要保存每一个输入值,只需要维护两个状态变量:
- 当前的累积均值(记为
mean_prev) - 已经接收的样本总数(记为
count_prev)
递推公式非常简洁:
count_new = count_prev + 1 mean_new = (mean_prev * count_prev + x_current) / count_new
这个公式完美适配你的需求:
- 当第一个信号输入时,
count_prev=0,mean_prev=0,代入后count_new=1,mean_new=(0*0 + x1)/1 = x1,直接输出第一个值,符合要求; - 第二个信号输入时,
count_prev=1,mean_prev=x1,代入得mean_new=(x1*1 +x2)/2,就是前两个的平均; - 后续每一步都会自动更新为所有历史值的平均,完全不需要管信号总长度。
关于初始条件:能不能设为0?
完全可以!而且用上面的递推公式时,初始设mean_prev=0、count_prev=0是最优解——既不需要额外判断第一个输入的特殊情况,又能自动输出正确的第一个值,完全适配“信号长度未知、持续接收”的场景。
Simulink实现步骤
用几个基础模块就能快速搭建:
- 状态存储:用两个
Memory模块,分别保存mean_prev(初始值0)和count_prev(初始值0); - 计算新计数:用
Add模块,把count_prev和常数1相加,得到count_new; - 计算分子项:用
Product模块计算mean_prev * count_prev,再用Add模块加上当前输入信号x_current; - 计算新均值:用
Divide模块,把分子项除以count_new,得到mean_new; - 反馈与输出:把
mean_new同时作为输出信号,和反馈到保存mean_prev的Memory模块;把count_new反馈到保存count_prev的Memory模块。
为什么移动平均滤波器不适用?
移动平均是取最近N个样本的平均(N是固定窗口大小),而你需要的是从第一个样本到当前所有样本的平均,两者的计算逻辑完全不同。如果用移动平均,要么窗口设得极大(但信号长度未知,无法确定窗口大小),要么得到的结果不符合你的需求。
内容的提问来源于stack exchange,提问作者user5603723




