Overview
The goal of this package is to provide an intuitive and mathematically sound interface for taking expectations of random variables and their higherorder functions (i.e., if $X \sim N(0, 1)$, what is $\mathbb{E}[\sin(X)]$?).
The underlying random variables are assumed to be distributions from Distributions.jl
. Currently, only univariate distributions are supported.
Installation
To install, run (in v0.7):
julia> using Pkg
julia> Pkg.add("Expectations")
Resolving package versions...
Updating `~/.julia/environments/v1.0/Project.toml`
[no changes]
Updating `~/.julia/environments/v1.0/Manifest.toml`
[no changes]
julia> using Expectations
julia> Pkg.add("Distributions")
Resolving package versions...
Updating `~/.julia/environments/v1.0/Project.toml`
[31c24e10] + Distributions v0.16.4
Updating `~/.julia/environments/v1.0/Manifest.toml`
[no changes]
julia> using Distributions
Currently, Julia v0.6 and up are supported.
The Expectation Operator
The key object in this package is an expectation operator, or an object <: Expectation
. These include all objects capable of being called on a function; e.g. that support a method function (e::Expectation)(f::Function)
. You can create these as following:
julia> dist = Normal();
julia> E = expectation(dist)
IterableExpectation{Array{Float64,1},Array{Float64,1}}([9.70624, 8.68084, 7.82505, 7.0554, 6.34, 5.66238, 5.0126, 4.38402, 3.77189, 3.17263 … 3.17263, 3.77189, 4.38402, 5.0126, 5.66238, 6.34, 7.0554, 7.82505, 8.68084, 9.70624], [1.64081e21, 1.58556e17, 1.62408e14, 4.57343e12, 5.17846e10, 2.88218e8, 8.90909e7, 1.658e5, 0.000196513, 0.00154471 … 0.00154471, 0.000196513, 1.658e5, 8.90909e7, 2.88218e8, 5.17846e10, 4.57343e12, 1.62408e14, 1.58556e17, 1.64081e21])
You can also choose and algorithms and default parameters (see below for list):
julia> E = expectation(dist, Gaussian; n = 30) # Could have done expectation(dist) or expectation(dist; n = 30)
IterableExpectation{Array{Float64,1},Array{Float64,1}}([9.70624, 8.68084, 7.82505, 7.0554, 6.34, 5.66238, 5.0126, 4.38402, 3.77189, 3.17263 … 3.17263, 3.77189, 4.38402, 5.0126, 5.66238, 6.34, 7.0554, 7.82505, 8.68084, 9.70624], [1.64081e21, 1.58556e17, 1.62408e14, 4.57343e12, 5.17846e10, 2.88218e8, 8.90909e7, 1.658e5, 0.000196513, 0.00154471 … 0.00154471, 0.000196513, 1.658e5, 8.90909e7, 2.88218e8, 5.17846e10, 4.57343e12, 1.62408e14, 1.58556e17, 1.64081e21])
These objects can then be applied to functions:
julia> E(x > x)
2.889272167366858e17
julia> E(x > x^2)
0.9999999999999998
There is also a convenience function to evaluate expectations directly, without returning the operator:
julia> f = x > x^2
#5 (generic function with 1 method)
julia> expectation(f, dist)
0.9999999999999998
In general, expectation(f, dist, ...)
is equivalent to E(f)
, where E = expectation(dist, ...)
.
IterableExpectation
The only concrete subtype of Expectation
currently supported is IterableExpectation{NT, WT}
. These are expectations for which we have a discrete vector of quadrature nodes and weights, either defined by user fiat, or set algorithmically. These support some additional behavior:
julia> nodeList = nodes(E);
julia> vals = map(x > x^2, nodeList);
julia> E * vals
0.9999999999999998
julia> (2E) * vals
1.9999999999999996
The above behavior, in some sense, puts the "operator" in "expectation operator"; that is, it allows it to move elements of a vector space around, and to be scalarmultiplied.
UserDefined Nodes
There are some situations where we are forced to use a specific set of nodes. In those situations, E = expectation(dist, nodes)
will create the relevant object.
Supported Distributions, Algorithms, Keywords, and Defaults
Here is a list of currently supported distributions, along with keyword arguments and their defaults.
Distribution Name  Algorithm (Julia Type)  Keywords and Defaults  Restrictions 

Discrete Univariate  FiniteDiscrete <: QuadratureAlgorithm  N/A  Support must be finite. 
Continuous Univariate  GaussLegendre (Gaussian <: QuadratureAlgorithm)  n = 500  Support must be a compact interval $[a, b]$. 
Continuous Univariate  QNWDist^{1} (QuantileRange <: ...)  n = 50, q0 = 0.001, qN = 0.999  Distribution must be nondegenerate. 
Normal <: Continuous Univariate  GaussHermite (...)  n = 30  ... 
LogNormal <: ...  GaussHermite (...)  n = 30  ... 
Beta <: ...  GaussJacobi (...)  n = 32  ... 
Exponential <: ...  GaussLaguerre (...)  n = 32  ... 
Gamma <: ...  GaussLaguerre (...)  n = 32  ... 
Univariate  Trapezoidal <: ExplicitQuadratureAlgorithm  N/A  All nodes must be inside distribution's support. 
Mathematical Details and References
The specific quadrature algorithms come from the FastGaussQuadrature.jl
library, which is maintained by Alex Townsend of Cornell University. Much of the quadrature code came from the DistQuads.jl
library, which is maintained by Patrick K. Mogensen at the University of Copenhagen. In addition, there are some objects contributed by individual users; see docstring for citations.
WARNING: It is important to be aware of the deficiencies of numerical quadrature schemes. For example, it is recommended to be careful when using these methods for the following classes of functions and situations:
 Discontinuous or nondifferentiable functions (even if the function is a.e.differentiable)
 Periodic/oscillatory functions with a high frequency
 Extremely large numbers of quadrature nodes, which may lead to vanishingly small weights.
Contact
If you would like to get in touch, please do one of the following:
 Issue requests: Open an issue on the package repository with the tag
feature request
.  Bugs: Same as above, but with the tag
bug
.  Pull Request: We are always open to new functionality. If you have a feature you'd like to add (say, a new distribution or algorithm), once you prepare a PR with the feature and some tests, open it in the usual way.
 Other: You can reach out to Jesse Perla at
jesse.perla@ubc.ca
and Arnav Sood atarnav.sood@ubc.ca
 Citation: If this package was helpful in your research work, you may consider citing the package in whatever method is appropriate for your field.

This is a quadrature scheme written by Spencer Lyon (PhD. NYU) as part of the
QuantEcon
project. Used with permission. ↩