过滤函数的简单示例,特别是递归选项
Posted
技术标签:
【中文标题】过滤函数的简单示例,特别是递归选项【英文标题】:simple examples of filter function, recursive option specifically 【发布时间】:2012-12-31 15:01:36 【问题描述】:我正在为 R 中的 filter
函数寻找一些简单的(即 - 没有数学符号,长格式可重现代码)示例
我想我对卷积方法有一定的了解,但我一直在推广递归选项。我已经阅读并与各种文档作斗争,但对我来说帮助有点不透明。
以下是我目前发现的示例:
# Set some values for filter components
f1 <- 1; f2 <- 1; f3 <- 1;
我们继续:
# basic convolution filter
filter(1:5,f1,method="convolution")
[1] 1 2 3 4 5
#equivalent to:
x[1] * f1
x[2] * f1
x[3] * f1
x[4] * f1
x[5] * f1
# convolution with 2 coefficients in filter
filter(1:5,c(f1,f2),method="convolution")
[1] 3 5 7 9 NA
#equivalent to:
x[1] * f2 + x[2] * f1
x[2] * f2 + x[3] * f1
x[3] * f2 + x[4] * f1
x[4] * f2 + x[5] * f1
x[5] * f2 + x[6] * f1
# convolution with 3 coefficients in filter
filter(1:5,c(f1,f2,f3),method="convolution")
[1] NA 6 9 12 NA
#equivalent to:
NA * f3 + x[1] * f2 + x[2] * f1 #x[0] = doesn't exist/NA
x[1] * f3 + x[2] * f2 + x[3] * f1
x[2] * f3 + x[3] * f2 + x[4] * f1
x[3] * f3 + x[4] * f2 + x[5] * f1
x[4] * f3 + x[5] * f2 + x[6] * f1
现在我正在伤害我可怜的小脑干。 我设法在这篇文章中找到了使用信息的最基本示例:https://***.com/a/11552765/496803
filter(1:5, f1, method="recursive")
[1] 1 3 6 10 15
#equivalent to:
x[1]
x[2] + f1*x[1]
x[3] + f1*x[2] + f1^2*x[1]
x[4] + f1*x[3] + f1^2*x[2] + f1^3*x[1]
x[5] + f1*x[4] + f1^2*x[3] + f1^3*x[2] + f1^4*x[1]
有人可以提供与我上面的代码类似的代码,用于递归版本的卷积示例filter = c(f1,f2)
和filter = c(f1,f2,f3)
?
答案应该与函数的结果相匹配:
filter(1:5, c(f1,f2), method="recursive")
[1] 1 3 7 14 26
filter(1:5, c(f1,f2,f3), method="recursive")
[1] 1 3 7 15 30
编辑
使用@agstudy 的简洁答案完成:
> filter(1:5, f1, method="recursive")
Time Series:
Start = 1
End = 5
Frequency = 1
[1] 1 3 6 10 15
> y1 <- x[1]
> y2 <- x[2] + f1*y1
> y3 <- x[3] + f1*y2
> y4 <- x[4] + f1*y3
> y5 <- x[5] + f1*y4
> c(y1,y2,y3,y4,y5)
[1] 1 3 6 10 15
还有……
> filter(1:5, c(f1,f2), method="recursive")
Time Series:
Start = 1
End = 5
Frequency = 1
[1] 1 3 7 14 26
> y1 <- x[1]
> y2 <- x[2] + f1*y1
> y3 <- x[3] + f1*y2 + f2*y1
> y4 <- x[4] + f1*y3 + f2*y2
> y5 <- x[5] + f1*y4 + f2*y3
> c(y1,y2,y3,y4,y5)
[1] 1 3 7 14 26
还有……
> filter(1:5, c(f1,f2,f3), method="recursive")
Time Series:
Start = 1
End = 5
Frequency = 1
[1] 1 3 7 15 30
> y1 <- x[1]
> y2 <- x[2] + f1*y1
> y3 <- x[3] + f1*y2 + f2*y1
> y4 <- x[4] + f1*y3 + f2*y2 + f3*y1
> y5 <- x[5] + f1*y4 + f2*y3 + f3*y2
> c(y1,y2,y3,y4,y5)
[1] 1 3 7 15 30
【问题讨论】:
将filter
视为遍历原始向量,在每一步应用权重和求和。递归滤波器和卷积滤波器一样,只是权重 f1, ..., fn 自动变为 c(1, f1, ..., fn),并且在每一步将 1 应用于当前值,而 f1, ..., fn 应用于正在创建的新校正向量的最后 n 个值,而不是原始值。使用卷积(默认边 = 2),权重跨越当前值,一侧是下 n/2 个原始值,另一侧是前 n/2 个原始值。
filter
的行为对于两个method
s 而言根本不同。 IMO 这是可恶的包/功能设计:它们应该有不同的名称。
【参考方案1】:
我花了一个小时读完这篇,下面是我的总结,与 Matlab 对比
NOTATION:Matlab 中的命令 = R 中的命令
filter([1,1,1], 1, data) = filter(data, [1,1,1], method = "convolution") ; but the difference is that the first 2 elements are NA
filter(1, [1,-1,-1,-1], data) = filter(data, [1,1,1], method = "recursive")
如果你从 DSP 知道一些,那么递归用于 IIR,卷积用于 FIR
【讨论】:
【参考方案2】:在递归的情况下,我认为没有必要用 xi 来展开表达式。 “递归”的关键是用前一个 y 来表达右手表达式。
我更喜欢考虑过滤器大小。
过滤器大小=1
y1 <- x1
y2 <- x2 + f1*y1
y3 <- x3 + f1*y2
y4 <- x4 + f1*y3
y5 <- x5 + f1*y4
过滤器大小 = 2
y1 <- x1
y2 <- x2 + f1*y1
y3 <- x3 + f1*y2 + f2*y1 # apply the filter for the past value and add current input
y4 <- x4 + f1*y3 + f2*y2
y5 <- x5 + f1*y4 + f2*y3
【讨论】:
说得好:"recursive"
(与"convolution"
不同)的关键是用 y 表示 RHS。
感谢您的回答。你不知道你把一个看似复杂的概念变得多么简单!【参考方案3】:
使用递归,“过滤器”的序列是序列的先前总和或输出值的相加系数。使用filter=c(1,1)
,您是在说“在我的序列 x 中取第 i 个分量,并将上一步的结果加到它的 1 倍和前一步的结果的 1 倍”。这里有几个例子来说明
我认为滞后效应符号如下所示:
## only one filter, so autoregressive cumsum only looks "one sequence behind"
> filter(1:5, c(2), method='recursive')
Time Series:
Start = 1
End = 5
Frequency = 1
[1] 1 4 11 26 57
1 = 1
2*1 + 2 = 4
2*(2*1 + 2) + 3 = 11
...
## filter with lag in it, looks two sequences back
> filter(1:5, c(0, 2), method='recursive')
Time Series:
Start = 1
End = 5
Frequency = 1
[1] 1 2 5 8 15
1= 1
0*1 + 2 = 2
2*1 + 0*(0*1 + 2) + 3 = 5
2*(0*1 + 2) + 0 * (2*1 + 0*(0*1 + 2) + 3) + 4 = 8
2*(2*1 + 0*(0*1 + 2) + 3) + 0*(2*(0*1 + 2) + 0 * (2*1 + 0*(0*1 + 2) + 3) + 4) + 5 = 15
你看到那里的累积模式了吗?换个说法。
1 = 1
0*1 + 2 = 2
2*1 + 0*2 + 3 = 5
2*2 + 0*5 + 4 = 8
2*5 + 0*8 + 5 = 15
【讨论】:
【参考方案4】:这是我发现对可视化递归过滤的实际作用最有帮助的示例:
(x <- rep(1, 10))
# [1] 1 1 1 1 1 1 1 1 1 1
as.vector(filter(x, c(1), method="recursive")) ## Equivalent to cumsum()
# [1] 1 2 3 4 5 6 7 8 9 10
as.vector(filter(x, c(0,1), method="recursive"))
# [1] 1 1 2 2 3 3 4 4 5 5
as.vector(filter(x, c(0,0,1), method="recursive"))
# [1] 1 1 1 2 2 2 3 3 3 4
as.vector(filter(x, c(0,0,0,1), method="recursive"))
# [1] 1 1 1 1 2 2 2 2 3 3
as.vector(filter(x, c(0,0,0,0,1), method="recursive"))
# [1] 1 1 1 1 1 2 2 2 2 2
【讨论】:
以上是关于过滤函数的简单示例,特别是递归选项的主要内容,如果未能解决你的问题,请参考以下文章