Skip to content

Commit

Permalink
RFC: Sl/qnwdist (#202)
Browse files Browse the repository at this point in the history
* WIP: quadrature weights and nodes for distributions

* DOC: add docstring to qnwdist

* ENH: export qnwdist
  • Loading branch information
sglyon authored Mar 20, 2018
1 parent 9334727 commit be0a32e
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 10 deletions.
9 changes: 5 additions & 4 deletions src/QuantEcon.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ export
discrete_var, Even, Quantile, Quadrature,

# modeltools
AbstractUtility, LogUtility, CRRAUtility, CFEUtility, EllipticalUtility, derivative,
AbstractUtility, LogUtility, CRRAUtility, CFEUtility, EllipticalUtility,
derivative,

# gth_solve
gth_solve,
Expand Down Expand Up @@ -96,8 +97,8 @@ export
smooth, periodogram, ar_periodogram,

# util
meshgrid, gridmake, gridmake!, ckron, is_stable, num_compositions, simplex_grid, simplex_index,
next_k_array!, k_array_rank,
meshgrid, gridmake, gridmake!, ckron, is_stable, num_compositions,
simplex_grid, simplex_index, next_k_array!, k_array_rank,

# robustlq
RBLQ,
Expand All @@ -109,7 +110,7 @@ export

# quad
qnwlege, qnwcheb, qnwsimp, qnwtrap, qnwbeta, qnwgamma, qnwequi, qnwnorm,
qnwunif, qnwlogn, qnwmonomial1, qnwmonomial2,
qnwunif, qnwlogn, qnwmonomial1, qnwmonomial2, qnwdist,
quadrect,
do_quad,

Expand Down
72 changes: 66 additions & 6 deletions src/quad.jl
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,13 @@ function qnwgamma(n::Int, a::Real=1.0, b::Real=1.0)
end

# rootfinding iterations
it = 0
pp = 0.0
p2 = 0.0
for it = 1:maxit
err = 100.0
for it in 1:maxit
p1 = 1.0
p2 = 0.0
for j=1:n
for j in 1:n
# Recurrance relation for Laguerre polynomials
p3 = p2
p2 = p1
Expand All @@ -446,12 +446,13 @@ function qnwgamma(n::Int, a::Real=1.0, b::Real=1.0)
pp = (n*p1-(n+a)*p2)./z
z1 = z
z = z1-p1 ./ pp
if abs(z - z1) < 3e-14
err = abs(z - z1)
if err < 3e-14
break
end
end

if it >= maxit
end
if err > 3e-14
error("failure to converge.")
end

Expand Down Expand Up @@ -870,3 +871,62 @@ function qnwmonomial2(vcv::AbstractMatrix)
1/(n+2)^2 * ones(size(z2, 1)))
return ϵj, ωj
end


function _quadnodes(
d::Distributions.ContinuousUnivariateDistribution, N::Int,
q0::Real, qN::Real, ::Union{Even,Type{Even}}
)
collect(linspace(quantile(d, q0), quantile(d, qN), N))
end

function _quadnodes(
d::Distributions.ContinuousUnivariateDistribution, N::Int,
q0::Real, qN::Real, ::Union{Quantile,Type{Quantile}}
)
quantiles = linspace(q0, qN, N)
z = quantile.(d, quantiles)
end

"""
qnwdist(
d::Distributions.ContinuousUnivariateDistribution, N::Int,
q0::Real=0.001, qN::Real=0.999, method::Union{T,Type{T}}=Quantile
) where T
Construct `N` quadrature weights and nodes for distribution `d` from the
quantile `q0` to the quantile `qN`. `method` can be one of:
- `Even`: nodes will be evenly spaced between the quantiles
- `Quantile`: nodes will be placed at evenly spaced quantile values
To construct the weights, consider splitting the nodes into cells centered at
each node. Specifically, let notation `z_i` mean the `i`th node and let
`z_{i-1/2}` be 1/2 between nodes `z_{i-1}` and `z_i`. Then, weights are
determined as follows:
- `weights[1] = cdf(d, z_{1+1/2})`
- `weights[N] = 1 - cdf(d, z_{N-1/2})`
- `weights[i] = cdf(d, z_{i+1/2}) - cdf(d, z_{i-1/2})` for all i in 2:N-1
In effect, this strategy assigns node `i` all the probability associated with a
random variable occuring within the node `i`s cell.
The weights always sum to 1, so they can be used as a proper probability
distribution. This means that `E[f(x) | x ~ d] ≈ dot(f.(nodes), weights)`.
"""
function qnwdist(
d::Distributions.ContinuousUnivariateDistribution, N::Int,
q0::Real=0.001, qN::Real=0.999, method::Union{T,Type{T}}=Quantile
) where T

z = _quadnodes(d, N, q0, qN, method)
zprob = zeros(N)

for i in 2:N-1
zprob[i] = cdf(d, (z[i] + z[i+1])/2) - cdf(d, (z[i] + z[i-1])/2)
end
zprob[1] = cdf(d, (z[1] + z[2])/2)
zprob[end] = 1 - cdf(d, (z[end-1] + z[end])/2)
return z, zprob
end

0 comments on commit be0a32e

Please sign in to comment.