Skip to contents

Using this function, two distributions, given as ddf objects, can be convolved.

Usage

conv(dist1, dist2, desc = "A convolution")

# S4 method for class 'ddf,ddf'
e1 * e2

Source

Under the hood, this functions uses a C++ implementation for calculating the convolution in order to get significant performance gains, compare convolve_cpp().

Arguments

dist1

A ddf object, the first distribution.

dist2

A ddf object, the second distribution.

desc

A character, the description for the resulting ddf object (optional)

e1

ddf object, the first distribution.

e2

ddf object, the second distribution.

Value

Convolution as a ddf object.

Details

In general, given two functions \(f\) and \(g\) defined on the set \(\mathbb{Z}\) of integers, the discrete convolution of \(f\) and \(g\) is given by $$(f \ast g)(n) = \sum_{m=-\infty}^{\infty} f(n-m) g(m).$$ Note how the sum on the right hand side ranges over all products where the arguments of \(f\) and \(g\) are integers \(k,l\in\mathbb{Z}\) such that \(k+l=n\).

This implementation of the convolution uses this last observation as its basis which makes it possible to also calculate the convolution if the domains are not (subsets of) \(\mathbb{Z}\) (but of course still discrete).

For a stochastic interpretation of the convolution, recall that given two independent random variables \(X\) and \(Y\) with probability mass functions \(p_X\) and \(p_Y\), the sum \(X + Y\) has probability mass function \(p_X \ast p_Y\). Hence, convolving two ddf distributions gives the distribution corresponding to their sum.

See also

Other convolution functions: conv_n(), convolve_cpp()

Examples

# Calculate the distribution of the sum of throwing a dice twice
dice <- ddf(1:6)
conv(dice, dice, desc = "Distribution of throwing a dice twice")
#> Distribution of throwing a dice twice 
#> 
#> Support:
#>  [1]  2  3  4  5  6  7  8  9 10 11 12
#> 
#> Probabilities:
#>  [1] 0.02777778 0.05555556 0.08333333 0.11111111 0.13888889 0.16666667
#>  [7] 0.13888889 0.11111111 0.08333333 0.05555556 0.02777778
# (Up to description) equivalent call using generic method
dice * dice
#> A convolution 
#> 
#> Support:
#>  [1]  2  3  4  5  6  7  8  9 10 11 12
#> 
#> Probabilities:
#>  [1] 0.02777778 0.05555556 0.08333333 0.11111111 0.13888889 0.16666667
#>  [7] 0.13888889 0.11111111 0.08333333 0.05555556 0.02777778


# Note that for distributions which are approximated without
# also being normalized, approximation errors can propagate
# when convolving:
try(conv(unif(5), geometric(0.9, normalize = FALSE)))
#> Error in h(simpleError(msg, call)) : 
#>   error in evaluating the argument 'dist' in selecting a method for function 'supp': invalid class “ddf” object: probabilities have to sum up to approximately 1

# This can be corrected by using a better approximation
conv(unif(5), geometric(0.9, eps = 1e-11, normalize = FALSE))
#> A convolution 
#> 
#> Support:
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
#> 
#> Probabilities:
#>  [1] 1.80000e-01 1.98000e-01 1.99800e-01 1.99980e-01 1.99998e-01 1.99998e-02
#>  [7] 1.99998e-03 1.99998e-04 1.99998e-05 1.99998e-06 1.99998e-07 1.99980e-08
#> [13] 1.99800e-09 1.98000e-10 1.80000e-11

# Or simply by normalizing
conv(unif(5), geometric(0.9))
#> A convolution 
#> 
#> Support:
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14
#> 
#> Probabilities:
#>  [1] 1.80000e-01 1.98000e-01 1.99800e-01 1.99980e-01 1.99998e-01 1.99998e-02
#>  [7] 1.99998e-03 1.99998e-04 1.99998e-05 1.99998e-06 1.99980e-07 1.99800e-08
#> [13] 1.98000e-09 1.80000e-10


# When one is interested in the difference instead of
# the sum, one can use the generic `-` which multiplies
# the support of a distribution with -1
conv(unif(6), -unif(6))
#> A convolution 
#> 
#> Support:
#>  [1] -5 -4 -3 -2 -1  0  1  2  3  4  5
#> 
#> Probabilities:
#>  [1] 0.02777778 0.05555556 0.08333333 0.11111111 0.13888889 0.16666667
#>  [7] 0.13888889 0.11111111 0.08333333 0.05555556 0.02777778