convolve
or fft
solutions are to get a discrete result, rather than a function as you have defined in cfg
. They can give you the numeric solution to cfg
on some regular, discrete input.
fft
is for periodic functions (only) so that is not going to help. However, convolve
has a mode of operation called "open", which emulates the operation that is being performed by cfg
.
Note that with type="open"
, you must reverse the second sequence (see ?convolve
, "Details"). You also have to only use the first half of the result. Here is a pictoral example of the result of convolution of c(2,3,5)
with c(7,11,13)
as would be performed by 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
Note that evaluation the first three elements is similar to the results of your integration. The last three would be used for the reverse convolution.
Here is a comparison with your functions. Your function, vectorized, plotted with
y <- seq(0,10,by=.01)
plot(y, Vectorize(cfg)(y), type='l')

And an application of convolve
plotted with the following code. Note that there are 100 points per unit interval in y
so division by 100
is appropriate.
plot(y, convolve(f(y), rev(g(y)), type='open')[1:1001]/100, type='l')

These do not quite agree, but the convolution is much faster:
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