diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index defeab66..adc0f86e 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2023-12-16T09:48:23","documenter_version":"1.2.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.0","generation_timestamp":"2024-01-16T09:48:20","documenter_version":"1.2.1"}} \ No newline at end of file diff --git a/dev/adding/index.html b/dev/adding/index.html index 382c3d25..6346acbb 100644 --- a/dev/adding/index.html +++ b/dev/adding/index.html @@ -21,4 +21,4 @@ gentype(::Lebesgue{ℝ₊}) = Float64 gentype(::Lebesgue{𝕀}) = Float64 -logdensity_def(::Lebesgue, x) = zero(float(x))

We haven't yet talked about gentype. When you call rand without specifying a type, there needs to be a default. That default is the gentype. This only needs to be defined for primitive measures, because others will fall back on

gentype(μ::AbstractMeasure) = gentype(basemeasure(μ))
+logdensity_def(::Lebesgue, x) = zero(float(x))

We haven't yet talked about gentype. When you call rand without specifying a type, there needs to be a default. That default is the gentype. This only needs to be defined for primitive measures, because others will fall back on

gentype(μ::AbstractMeasure) = gentype(basemeasure(μ))
diff --git a/dev/affine/index.html b/dev/affine/index.html index e6516b99..6b5a18a0 100644 --- a/dev/affine/index.html +++ b/dev/affine/index.html @@ -13,4 +13,4 @@ 4.0

AffinePushfwd

Of particular interest (the whole point of all of this, really) is to have a natural way to work with affine transformations of measures. In accordance with the principle of "common things should have shorter names", we call this AffinePushfwd.

The structure of AffinePushfwd is relatively simple:

struct AffinePushfwd{N,M,T} <: AbstractMeasure
     f::AffineTransform{N,T}
     parent::M
-end
+end diff --git a/dev/api_index/index.html b/dev/api_index/index.html index 7b9a9364..29dea17e 100644 --- a/dev/api_index/index.html +++ b/dev/api_index/index.html @@ -1,2 +1,2 @@ -Index · MeasureTheory.jl

Index

+Index · MeasureTheory.jl

Index

diff --git a/dev/api_measurebase/index.html b/dev/api_measurebase/index.html index dc9736de..404b17f4 100644 --- a/dev/api_measurebase/index.html +++ b/dev/api_measurebase/index.html @@ -86,4 +86,4 @@ x = randn(); k1(x) == k2(x) == k3(x) == k4(x)

This function is not exported, because "kernel" can have so many other meanings. See for example https://github.com/JuliaGaussianProcesses/KernelFunctions.jl for another common use of this term.

Reference

source
MeasureBase.likelihood_ratioMethod
likelihood_ratio(ℓ::Likelihood, p, q)

Compute the log of the likelihood ratio, in order to compare two choices for parameters. This is equal to

density_rel(ℓ.k(p), ℓ.k(q), ℓ.x)

but is computed using LogarithmicNumbers.jl to avoid underflow and overflow. Since density_rel can leave common base measure unevaluated, this can be more efficient than

logdensityof(ℓ.k(p), ℓ.x) - logdensityof(ℓ.k(q), ℓ.x)
source
MeasureBase.likelihoodofFunction
likelihoodof(k::AbstractTransitionKernel, x; constraints...)
 likelihoodof(k::AbstractTransitionKernel, x, constraints::NamedTuple)

A likelihood is not a measure. Rather, a likelihood acts on a measure, through the "pointwise product" , yielding another measure.

source
MeasureBase.log_likelihood_ratioMethod
log_likelihood_ratio(ℓ::Likelihood, p, q)

Compute the log of the likelihood ratio, in order to compare two choices for parameters. This is computed as

logdensity_rel(ℓ.k(p), ℓ.k(q), ℓ.x)

Since logdensity_rel can leave common base measure unevaluated, this can be more efficient than

logdensityof(ℓ.k(p), ℓ.x) - logdensityof(ℓ.k(q), ℓ.x)
source
MeasureBase.logdensity_defFunction

logdensity_def is the standard way to define a log-density for a new measure. Note that this definition does not include checking for membership in the support; this is instead checked using insupport. logdensity_def is a low-level function, and should typically not be called directly. See logdensityof for more information and other alternatives.


logdensity_def(m, x)

Compute the log-density of the measure m at the point x, relative to basemeasure(m), and assuming insupport(m, x).


logdensity_def(m1, m2, x)

Compute the log-density of m1 relative to m2 at the point x, assuming insupport(m1, x) and insupport(m2, x).

source
MeasureBase.logdensity_relMethod
logdensity_rel(m1, m2, x)

Compute the log-density of m1 relative to m2 at x. This function checks whether x is in the support of m1 or m2 (or both, or neither). If x is known to be in the support of both, it can be more efficient to call unsafe_logdensity_rel.

source
MeasureBase.log𝒹Method
log𝒹(μ, base)

Compute the log-density (Radom-Nikodym derivative) of μ with respect to base. This is a shorthand form for logdensity_rel(μ, base)

source
MeasureBase.massofMethod
massof(m)

Get the mass of a measure - that is, integrate the measure over its support.

massof


massof(m, dom)

Integrate the measure m over the "domain" dom. Note that domains are not defined universally, but may be specific to a given measure. If m is <:AbstractMeasure, users can also write m(dom). For new measures, users should not add new "call" methods, but instead extend MeasureBase.massof.

For example, for many univariate measures m with rootmeasure(m) == LebesgueBase(), users can call massof(m, a_b) where a_b::IntervalSets.Interval.

massof often returns a Real. But in many cases we may only know the mass is finite, or we may know nothing at all about it. For these cases, it will return UnknownFiniteMass or UnknownMass, respectively. When no massof method exists, it defaults to UnknownMass.

source
MeasureBase.maybestatic_lengthMethod
MeasureBase.maybestatic_length(x)::IntegerLike

Returns the length of x as a dynamic or static integer.

source
MeasureBase.maybestatic_sizeMethod
MeasureBase.maybestatic_size(x)::Tuple{Vararg{IntegerLike}}

Returns the size of x as a tuple of dynamic or static integers.

source
MeasureBase.one_toMethod
MeasureBase.one_to(n::IntegerLike)

Creates a range from one to n.

Returns an instance of Base.OneTo or Static.SOneTo, depending on the type of n.

source
MeasureBase.paramnamesFunction

paramnames(μ) returns the names of the parameters of μ. This is equivalent to

paramnames(μ) == (keys ∘ params)(μ)

but depends only on the type. In particular, the default implementation is

paramnames(μ::M) where {M} = paramnames(M)

New ParameterizedMeasures will automatically have a paramnames method. For other measures, this method is optional, but can be added by defining

paramnames(::Type{M}) where {M} = ...

See also params

source
MeasureBase.paramsFunction

params(μ) returns the parameters of a measure μ, as a NamedTuple. The default method is

params(μ) = NamedTuple()

See also paramnames

source
MeasureBase.proxyFunction

function proxy end

It's often useful to delegate methods like logdensity and basemeasure to those of a different measure. For example, a Normal{(:μ,:σ)} is equivalent to an affine transformation of a Normal{()}.

We could just have calls like Normal(μ=2,σ=4) directly construct a transformed measure, but this would make dispatch awkward.

source
MeasureBase.pullbackFunction
pullback(f, μ, volcorr = WithVolCorr())

A pullback is a dual concept to a pushforward. While a pushforward needs a map from the support of a measure, a pullback requires a map into the support of a measure. The log-density is then computed through function composition, together with a volume correction as needed.

This can be useful, since the log-density of a PushforwardMeasure is computing in terms of the inverse function; the "forward" function is not used at all. In some cases, we may be focusing on log-density (and not, for example, sampling).

To manually specify an inverse, call pullback(InverseFunctions.setinverse(f, finv), μ, volcorr).

source
MeasureBase.pushfwdFunction
pushfwd(f, μ, volcorr = WithVolCorr())

Return the pushforward measure from μ the measurable function f.

To manually specify an inverse, call pushfwd(InverseFunctions.setinverse(f, finv), μ, volcorr).

source
MeasureBase.rebaseMethod
rebase(μ, ν)

Express μ in terms of a density over ν. Satisfies

basemeasure(rebase(μ, ν)) == ν
 density(rebase(μ, ν)) == 𝒹(μ,ν)
source
MeasureBase.require_insupportFunction
MeasureBase.require_insupport(μ, x)::Nothing

Checks if x is in the support of distribution/measure μ, throws an ArgumentError if not.

source
MeasureBase.rootmeasureMethod
rootmeasure(μ::AbstractMeasure)

It's sometimes important to be able to find the fix point of a measure under basemeasure. That is, to start with some measure and apply basemeasure repeatedly until there's no change. That's what this does.

source
MeasureBase.schemaFunction
schema(::Type)

schema turns a type into a value that's easier to work with. Example: julia> nt = (a=(b=[1,2],c=(d=[3,4],e=[5,6])),f=[7,8]); julia> NT = typeof(nt) NamedTuple{(:a, :f),Tuple{NamedTuple{(:b, :c),Tuple{Array{Int64,1},NamedTuple{(:d, :e),Tuple{Array{Int64,1},Array{Int64,1}}}}},Array{Int64,1}}} julia> schema(NT) (a = (b = Array{Int64,1}, c = (d = Array{Int64,1}, e = Array{Int64,1})), f = Array{Int64,1})

source
MeasureBase.smfFunction
smf(μ, x::Real) ::Real

Compute the Stieltjes measure function (SMF) of the measure μ at the point x.

The SMF is the measure-theoretic generalization of the cumulative distribution function (CDF) from probability theory. An SMF F(x) = smf(μ, x) must have the following properties:

  1. F is nondecreasing
  2. F is right-continuous: F(x) should be the same as lim_{δ→0} F(x + |δ|).
  3. μ((a,b]) = F(b) - F(a)

Note that unlike the CDF, an SMF is only determined up to addition by a constant. For many applications, this leads to a need to evaluate an SMF at -∞. It's therefore important that smf(μ, -Inf) be fast. In practice, this will usually be called as smf(μ, static(-Inf)). It's then easy to ensure speed and avoid complex control flow by adding a method smf(μ::M, ::StaticFloat64{-Inf}).

Users who pronounce sinh as "sinch" are advised to pronounce smf as "smurf".

source
MeasureBase.to_originFunction
MeasureBase.to_origin(ν, y)

Pull y from ν back to MeasureBase.transport_origin(ν).

source
MeasureBase.transport_defFunction
transport_def(ν, μ, x)

Transforms a value x distributed according to μ to a value y distributed according to ν.

If no specialized transport_def(::MU, ::NU, ...) is available then the default implementation oftransport_def(ν, μ, x) uses the following strategy:

  • Evaluate transport_origin for μ and ν. Transform between each and it's origin, if available, and use the origin(s) as intermediate measures for another transformation.

  • If all else fails, try to transform from μ to a standard multivariate uniform measure and then to ν.

See transport_to.

source
MeasureBase.transport_originFunction
MeasureBase.transport_origin(ν)

Default measure to pullback to resp. pushforward from when transforming between ν and another measure.

source
MeasureBase.transport_toFunction
f = transport_to(ν, μ)

Generates a measurable function f that transforms a value x distributed according to measure μ to a value y = f(x) distributed according to a measure ν.

The pushforward measure from μ under f is is equivalent to ν.

If terms of random values this implies that f(rand(μ)) is equivalent to rand(ν) (if rand(μ) and rand(ν) are supported).

The resulting function f should support ChangesOfVariables.with_logabsdet_jacobian(f, x) if mathematically well-defined, so that densities of ν can be derived from densities of μ via f (using appropriate base measures).

Returns NoTransportOrigin{typeof(ν),typeof(μ)} if no transformation from μ to ν can be found.

To add transformation rules for a measure type MyMeasure, specialize

  • MeasureBase.transport_def(ν::SomeStdMeasure, μ::CustomMeasure, x) = ...
  • MeasureBase.transport_def(ν::MyMeasure, μ::SomeStdMeasure, x) = ...

and/or

  • MeasureBase.transport_origin(ν::MyMeasure) = SomeMeasure(...)
  • MeasureBase.from_origin(μ::MyMeasure, x) = y
  • MeasureBase.to_origin(μ::MyMeasure, y) = x

and ensure MeasureBase.getdof(μ::MyMeasure) is defined correctly.

A standard measure type like StdUniform, StdExponential or StdLogistic may also be used as the source or target of the transform:

f_to_uniform(StdUniform, μ)
-f_to_uniform(ν, StdUniform)

Depending on getdof(μ) (resp. ν), an instance of the standard distribution itself or a power of it (e.g. StdUniform() or StdUniform()^dof) will be chosen as the transformation partner.

source
MeasureBase.transport_toMethod
transport_to(ν, μ, x)

Transport x from the measure μ to the measure ν

source
MeasureBase.unsafe_logdensity_relMethod
unsafe_logdensity_rel(m1, m2, x)

Compute the log-density of m1 relative to m2 at x, assuming x is known to be in the support of both m1 and m2.

See also logdensity_rel.

source
MeasureBase.unsafe_logdensityofMethod
unsafe_logdensityof(m, x)

Compute the log-density of the measure m at x relative to rootmeasure(m). This is "unsafe" because it does not check insupport(m, x).

See also logdensityof.

source
MeasureBase.∫Method
∫(f, base::AbstractMeasure)

Define a new measure in terms of a density f over some measure base.

source
MeasureBase.∫expMethod
∫exp(f, base::AbstractMeasure)

Define a new measure in terms of a log-density f over some measure base.

source
MeasureBase.𝒹Method
𝒹(μ, base)

Compute the density (Radom-Nikodym derivative) of μ with respect to base. This is a shorthand form for density_rel(μ, base).

source
+f_to_uniform(ν, StdUniform)

Depending on getdof(μ) (resp. ν), an instance of the standard distribution itself or a power of it (e.g. StdUniform() or StdUniform()^dof) will be chosen as the transformation partner.

source
MeasureBase.transport_toMethod
transport_to(ν, μ, x)

Transport x from the measure μ to the measure ν

source
MeasureBase.unsafe_logdensity_relMethod
unsafe_logdensity_rel(m1, m2, x)

Compute the log-density of m1 relative to m2 at x, assuming x is known to be in the support of both m1 and m2.

See also logdensity_rel.

source
MeasureBase.unsafe_logdensityofMethod
unsafe_logdensityof(m, x)

Compute the log-density of the measure m at x relative to rootmeasure(m). This is "unsafe" because it does not check insupport(m, x).

See also logdensityof.

source
MeasureBase.∫Method
∫(f, base::AbstractMeasure)

Define a new measure in terms of a density f over some measure base.

source
MeasureBase.∫expMethod
∫exp(f, base::AbstractMeasure)

Define a new measure in terms of a log-density f over some measure base.

source
MeasureBase.𝒹Method
𝒹(μ, base)

Compute the density (Radom-Nikodym derivative) of μ with respect to base. This is a shorthand form for density_rel(μ, base).

source
diff --git a/dev/api_measuretheory/index.html b/dev/api_measuretheory/index.html index abf51be6..4f649835 100644 --- a/dev/api_measuretheory/index.html +++ b/dev/api_measuretheory/index.html @@ -29,4 +29,4 @@ par :: NamedTuple{N,T} end KeywordCalls.@kwstruct Normal(μ,σ) -Normal(μ,σ) = Normal((μ=μ, σ=σ))

See KeywordCalls.jl for details on @kwstruct.

source +Normal(μ,σ) = Normal((μ=μ, σ=σ))

See KeywordCalls.jl for details on @kwstruct.

source diff --git a/dev/index.html b/dev/index.html index 7451dd93..981a927a 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · MeasureTheory.jl

Home

MeasureTheory.jl is a package for building and reasoning about measures.

Why?

A distribution (as provided by Distributions.jl) is also called a probability measure, and carries with it the constraint of adding (or integrating) to one. Statistical work usually requires this "at the end of the day", but enforcing it at each step of a computation can have considerable overhead. For instance, Bayesian modeling often requires working with unnormalized posterior densities or improper priors.

As a generalization of the concept of volume, measures also have applications outside of probability theory.

Getting started

To install MeasureTheory.jl, open the Julia Pkg REPL (by typing ] in the standard REPL) and run

pkg> add MeasureTheory

To get an idea of the possibilities offered by this package, go to the documentation.

To know more about the underlying theory and its applications to probabilistic programming, check out our JuliaCon 2021 submission.

+Home · MeasureTheory.jl

Home

MeasureTheory.jl is a package for building and reasoning about measures.

Why?

A distribution (as provided by Distributions.jl) is also called a probability measure, and carries with it the constraint of adding (or integrating) to one. Statistical work usually requires this "at the end of the day", but enforcing it at each step of a computation can have considerable overhead. For instance, Bayesian modeling often requires working with unnormalized posterior densities or improper priors.

As a generalization of the concept of volume, measures also have applications outside of probability theory.

Getting started

To install MeasureTheory.jl, open the Julia Pkg REPL (by typing ] in the standard REPL) and run

pkg> add MeasureTheory

To get an idea of the possibilities offered by this package, go to the documentation.

To know more about the underlying theory and its applications to probabilistic programming, check out our JuliaCon 2021 submission.

diff --git a/dev/old_readme/index.html b/dev/old_readme/index.html index 21ac7551..a162cfa4 100644 --- a/dev/old_readme/index.html +++ b/dev/old_readme/index.html @@ -46,4 +46,4 @@ logdensity_def(d, x) = - (log(2) + log(π) - log(d.par.τ) + d.par.τ * (x - d.par.μ)^2) / 2 end

And another check:

julia> logdensity_def(Normal(μ=0.0, τ=4.0), 1.0)
 -2.2257913526447273

We can combine measures in a few ways, for now just scaling and superposition:

julia> 2.0*Lebesgue(Float64) + Normal(0.0,1.0)
-SuperpositionMeasure{Float64,2}((MeasureTheory.WeightedMeasure{Float64,Float64}(2.0, Lebesgue{Float64}()), Normal{NamedTuple{(:μ, :σ),Tuple{Float64,Float64}},Float64}((μ = 0.0, σ = 1.0))))

For an easy way to find expressions for the common log-densities, see this gist

+SuperpositionMeasure{Float64,2}((MeasureTheory.WeightedMeasure{Float64,Float64}(2.0, Lebesgue{Float64}()), Normal{NamedTuple{(:μ, :σ),Tuple{Float64,Float64}},Float64}((μ = 0.0, σ = 1.0))))

For an easy way to find expressions for the common log-densities, see this gist