我想对[0,Inf)定义的两个函数进行卷积,例如

f=function(x)
    (1+0.5*cos(2*pi*x))*(x>=0)


g=function(x)
    exp(-2*x)*(x>0)

使用R的积分功能,我可以做到这一点,
cfg=function(x)
    integrate(function(y) f(y)*g(x-y),0,x)$value

通过搜索网络,似乎有更有效(更准确)的方法(例如使用fft()convolve())。有经验的人可以解释如何取悦吗?
谢谢!

最佳答案

convolvefft解决方案将获得离散结果,而不是您在cfg中定义的函数。他们可以给您一些常规的离散输入的cfg数值解决方案。
fft仅用于周期性函数,因此无济于事。但是,convolve具有一种称为“open”的操作模式,该模式模仿cfg正在执行的操作。

请注意,使用type="open",您必须反转第二个序列(请参见?convolve的“详细信息”)。您还只需要使用结果的前半部分。这是c(2,3,5)c(7,11,13)进行卷积的结果的图形示例,该示例由convolve(c(2,3,5), rev(c(7,11,13)), type='open')执行:

             2  3  5       2  3  5   2  3  5    2  3  5      2  3  5
      13 11  7         13 11  7     13 11  7      13 11  7        13  11  7
 Sum:       14              43         94           94            65

请注意,对前三个元素的评估类似于您的集成结果。后三个将用于反卷积。

这是与您的功能的比较。您的函数,矢量化,用
y <- seq(0,10,by=.01)
plot(y, Vectorize(cfg)(y), type='l')

并用以下代码绘制了convolve的应用程序。请注意,y中每单位间隔有100个点,因此按100进行除法是适当的。
plot(y, convolve(f(y), rev(g(y)), type='open')[1:1001]/100, type='l')

这些不太一致,但是卷积要快得多:
max(abs(Vectorize(cfg)(y) - convolve(f(y), rev(g(y)), type='open')[1:1001]/100))
## [1] 0.007474999

benchmark(Vectorize(cfg)(y), convolve(f(y), rev(g(y)), type='open')[1:1001]/100, columns=c('test', 'elapsed', 'relative'))
##                                                   test elapsed relative
## 2 convolve(f(y), rev(g(y)), type = "open")[1:1001]/100   0.056        1
## 1                                    Vectorize(cfg)(y)   5.824      104

09-10 05:19