Scade One 时序窗口 window 建模解析
Scade One建模工具中提供的时序窗口(temporal window)原语,为捕捉、存储和计算时序数据的历史值提供了解决方案。下面将从window原语的定义、数学逻辑出发,结合实际建模案例,解析其在时序数据处理中的应用。
window 原语:时序数据的 “历史容器”
window原语的核心作用,是构建一个固定大小的滑动窗口,用于存储输入信号的历史值,并支持基于这些历史数据进行后续计算。
基础建模形式
window原语的标准语法格式为:
w = window<<N>> (I) (e)
其中各参数的含义与作用如下:
<<N>>
:窗口大小,指定窗口内包含的历史值数量,即窗口可存储N个过去时刻的输入信号值。I
:初始数组,定义窗口的初始内容。这一特性是Scade One对传统 Scade 6中fby算子的补充,fby仅能基于单个前值初始化,而I可通过数组实现多值初始化,满足复杂场景的初始状态需求;e
:观测流,即窗口需要持续跟踪的输入信号流,窗口会随着e的时序变化,自动更新内部存储的历史值。w
:窗口输出数组,w[k](k取值 0 到N-1)对应窗口内第k个历史时刻的信号值。
数学含义:窗口的动态更新逻辑
window 原语的时序行为的含义为
w[0] = I[0] -> pre e
forall k in [1..N], w[k] = I[k] -> pre w[k-1]
公式的核心逻辑可拆解为两点:
- 初始时刻(k=0):窗口的第一个元素w[0],由初始数组的第一个元素I[0]与输入流e的前一时刻值(pre e)关联 —— 初始状态下,w[0]先取I[0],后续随着e的更新,始终存储e的上一时刻值。
- 后续时刻(k≥1):窗口的第K个元素w[K],由初始数组的第K个元素I[K]与窗口前一个元素w[K-1]的前一时刻值(pre w[K-1])关联 —— 这意味着窗口内的历史值会依次后移,始终保持N个历史值的存储规模,形成滑动效果。
案例 1:滑动加权平均 —— 单窗口的基础应用
滑动加权平均是时序数据处理中的经典场景,常用于信号平滑、噪声过滤等需求。下面通过Scade One的建模案例,看window原语如何实现这一功能。
建模代码与功能定义
node sliding_wa_t (x: float64)
returns (wa: float64)
{var w; let w = window<<4>> (0.^4) (x);-- 计算加权平均:当前x + 窗口内4个历史值的加权和,再除以总权重wa = (x + w[0]*c[0] + w[1]*c[1] + w[2]*c[2] + w[3]*c[3]) / d;
}constc: float64 ^4 = [0.5, 0.25, 0.125, 0.0625]; d: float64 = 1.0 + c[0] + c[1] + c[2] + c[3];
图形化模型如下
窗口逻辑与计算解析
该案例的核心是大小为 4 的 window 窗口,其工作逻辑与计算过程需注意两点:
- 窗口内容与历史值:
window<<4>> (0.^4) (x)
定义了一个存储 4 个历史值的窗口,初始时窗口内 4 个元素均为 0;随着x的时序更新,窗口始终存储x的最近4个过去值。 - 当前值与历史值的结合:由于window窗口仅存储过去值,当前时刻的 x 值并未包含在窗口w中,因此在计算加权平均时,需要将当前x单独加入公式,再与窗口内4个历史值的加权和相加,最终除以总权重d,得到平滑后的输出wa。
这一设计既利用了window对历史值的高效存储,又通过当前值和历史值的结合,实现了灵活的加权计算,满足信号平滑的需求。
案例 2:双窗口同步计算 —— 多流时序的协同处理
在实际建模中,常需要同时处理多个关联的时序流(如两个传感器的输出),并基于它们的历史值进行协同计算。window原语支持多窗口同步定义,可高效解决这类场景。
建模代码与功能定义
node sliding_q_t (x: float64; y: float64)
returns (q: float64)
{var wx; wy; let wx, wy = window <<9>> (0.^9, 1.^9) (x, y);-- 计算商:(x当前值 + wx内9个历史值的和) / (y当前值 + wy内9个历史值的和)q = (fold (+)) <<9>> (x, wx) / (fold (+)) <<9>> (y, wy);
}
图形化模型如下
多窗口特性与计算解析
该案例展现了window原语的多流协同能力,其逻辑如下:
- 多窗口同步定义:
window <<9>> (0.^9, 1.^9) (x, y)
,一次性定义了两个大小均为9的窗口wx和wy——wx跟踪x流,初始值为9个0;wy跟踪y流,初始值为9个1。这种方式避免了单独定义多个窗口的冗余,提升了建模效率。 - 窗口大小与总样本数的匹配:案例需要计算最近10个值的和,但窗口大小仅为 9—— 原因与案例1一致:window窗口仅存储过去值,因此需将当前时刻的x/y值与窗口内9个历史值结合,通过fold(+)算子计算10个值的总和。
- 差异化初始化为:wx初始为 0、wy初始为1的设计,体现了window原语多窗口差异化初始化的优势 —— 可根据不同信号的物理含义(如传感器的初始偏移),设置符合实际场景的初始状态,避免初始值偏差对计算结果的影响。