-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Paring down MeasureBase #176
Comments
Here are some details of the current state, with some ideas for where to go next. Not complete yet, I'll add more details soon MeasuresDensityMeasureConstructed using PointwiseProductMeasureConstructed using basemeasure(∫(ℓ, μ)) == μ
basemeasure(μ ⊙ ℓ) == basemeasure(μ) AffineRepresents a pushforward of a measure on RestrictedMeasure
struct RestrictedMeasure{F,M} <: AbstractMeasure
f::F
base::M
end
@inline function logdensity(d::RestrictedMeasure, x)
d.f(x) || return -Inf
return 0.0
end
function density(d::RestrictedMeasure, x)
d.f(x) || return 0.0
return 1.0
end HalfStarting with a symmetric univariate measure, this gives a new measure restricted to the half-line. Like SuperpositionMeasureVery much like mixture distributions, but without the reweighting. There are subtleties that come up here for determining the base measure; see the paper for details. Our implementation of this is not yet complete. SpikeMixtureSuperposition of a Dirac with a Lebesgue-dominated measure. Useful for building spike and slab priors, and used in Moritz's "sticky zigzag" sampler. FactoredBaseIt's very common for a log-density with respect to a primitive measure to be sum of three kinds of terms:
In addition, the support is often restricted by some predicate.
struct FactoredBase{R,C,V,B} <: AbstractMeasure
inbounds::R # A predicate for membership in the support
constℓ::C # A constant
varℓ::V # A nullary function (takes no args) carrying parameter-dependent terms
base::B # The base measure
end
@inline function logdensity(d::FactoredBase, x)
d.inbounds(x) || return -Inf
d.constℓ + d.varℓ()
end For example, here's how this can be used for unhalf(μ::Half) = μ.parent
@inline function basemeasure(μ::Half)
inbounds(x) = x > 0
constℓ = logtwo
varℓ() = 0.0
base = basemeasure(unhalf(μ))
FactoredBase(inbounds, constℓ, varℓ, base)
end I think this is kind of nice, but I'm not yet sure it's the "right" way to set up base measures. We still need to weigh some tradeoffs to get to an approach to advocate as idiomatic. KernelAbstractly, a kernel is a function mapping each value in the domain to a measure. But functions are opaque, and it can be important for us to have more information available statically. So we separate this into two components. In
For example, a Normal approximation to a Poisson could be represented as any of k1 = λ -> Normal(λ, λ^2)
k2 = kernel(k1)
k3 = kernel(Normal, λ -> (μ=λ, σ=λ^2))
k4 = kernel(Normal) do λ (μ=λ, σ=λ^2) end
k5 = kernel(Normal, (μ = identity, σ = λ -> λ^2)) The information available statically roughly increases at each step ( ProductMeasureThis takes a kernel and an array, and returns an abstraction representing the kernel applied to each value. For example, myprod = ProductMeasure(k, rand(10)) where TupleProductMeasureSame, but for tuples WeightedMeasureScale a measure by some positive constant ParamWeightedMeasureSimilar to a special case of struct ParamWeightedMeasure{L,N,T,B} <: AbstractWeightedMeasure
ℓ::L
par::NamedTuple{N,T}
base::B
end
basemeasure(d::ParamWeightedMeasure) = d.base
logdensity(d::ParamWeightedMeasure, x) = d.ℓ(d.par) Lebesgue"Volume" measure. This will probably be refactored to struct Lebesgue{T} <: PrimitiveMeasure
dimension :: T
end Then CountingMeasureThe counting measure of a set is its cardinality. Unless Lebesgue, this will probably never be used directly, but only as a base measure. So we could have struct CountingMeasure <: PrimitiveMeasure end DiracA point mass, with TrivialMeasureThe measure for which every set has measure zero. This is the identity element for superposition. For any measure TrivialMeasure() ≪ μ ≪ CountingMeasure() Measure-RelatedDensityAffineTransformLikelihoodDomainsIntegerRangeRealIntervalUtilitiesMapsToIterableNonIterableOutdatedExpIntegral |
The current MeasureTheory/MeasureBase partitioning is kind of ad hoc. What we really need is for MeasureBase to contain only
The biggest source of code will be the need to specify base measures. For example, MeasureBase needs to have
ProductMeasure
, or people won't be able to define anything having a product as a base measure.Let's identify things not required by the above criteria and discuss moving them to MeasureTheory, to allow MeasureBase to be lighter-weight.
The text was updated successfully, but these errors were encountered: