Skip to content

Commit

Permalink
Dev (#193)
Browse files Browse the repository at this point in the history
* Dirichlet(k::Integer, α) = Dirichlet(Fill(α, k))

* export TransformVariables as TV

* drop redundant import

* 0.0 => zero(Float64)

* drop outdated Dists.logpdf

* update StudentT

* drop redundant import

* update Uniform

* bump MeasureBase version

* reworking beta

* small update to StudentT

* basemeasure for discrete Distributions

* using LogExpFunctions => import LogExpFunctions

* quoteof(::Chain)

* prettyprinting and chain-mucking

* Some refactoring for Markov chains

* import MeasureBase: ≪

* version bound for PrettyPrinting

* copy(rng) might change its type (e.g. GLOBAL_RNG)

* tests pass

* cleaning up

* more cleanup

* big update

* get tests passing

* formatting

* oops typo

* move affine to MeasureTheory

* updating

* Val => StaticSymbol

* more fixes

* fix fix fix

* more logdesnity => logdensity_def

* more logdesnity fixes

* debugging

* formatting

* bugfixes

* working on tests

* updates

* working on tests

* tests passing!

* refactor

* working on tests

* drop static weight for now

* fix sampling from ProductMeasure{<:Base.Generator}

* tests passing!!

* more stuff

* constructor => constructorof

* constructor =? construtorof

* updates

* working on tests

* fix Dirichlet

* update Bernoulli

* working on tests

* bugfixes for RealizedSamples

* tests passing!!

* tighten down inference

* as(::PowerMeasure)

* drop type-level stuff

* using InverseFunctions.jl

* update license

* affero

* copyright

* update CI to 1.6

* xform => TV.as

* oops missed a conflict

* fix merge corruption

* typo

* fix license

* Update README.md

* merge

* enumerate instead of zip

* bugfix

* inline rand

* drop `static` from `insupport` results

* update proxies

* Move ConditionalMeasure to MeasureBase

* IfElse.ifelse(p::Bernoulli, t, f)

* IfElseMeasure

* update some base measures

* test broken :(

* fix some redundancies

* instance_type => Core.Typeof

* update testvalue for Bernoulli and Binomial

* un-break broken test (now passing)

* Fall-back `For` method for when inference fails

* drop extra spaces

* more whitespace

* bump MeasureBase dependency version

* add newline

* tidy up

* ifelse tests

* OEF newline

* avoid type piracy

* add Julia 1.7 to CI

* make Julia 1.6 happy

* approx instead of ==

* Require at least Julia 1.6

* Try Sebastian's idea test_measures ::Any[]

* Another Any[]

* Drop Likelihood test

* drop 1.7 CI (seems buggy?)

* bump version

* export likelihood

* Snedecor's F

* Gamma distribution

* more gamma stuff

* Beroulli()

* inverse Gaussian

* Getting modifed GLM.jl tests to pass

* drop pdf and logpdf

* Poisson bugfix

* update Normal(μ, σ²)

* Gamma(μ, ϕ) for GLMs

* updates for GLM support

* start on truncated

* update parameterized measures

* drop FactoredBase

* drop old LazyArrays dependency

* insupport(::Distribution)

* Left out"Dists."

* don't export `ifelse` (#192)

* Kleisli => TransitionKernel

* depend on StatsBase

* tests passing

* bump MeasureBase version

* work on truncated and censored

* improve func_string

* Simplify logdensity_def(::For, x)

* Move truncated and censored updates to separate branches

* newline

* comment out in-progress stuff

* newline

* bump version

* update formatting spec

* more formatting

* tweedie docs

* drop redundant exports

* update exports

* omega => lambda

* drop SequentialEx

* get tests passing

* add kernel tests

* gitignore

* better `Pretty.tile` for Affine and AffineTransforms

* formatting

* kleisli => kernel

* update tile(::For)

* update Compat version

* bump MB version

* update gamma

* Let's come back to InverseGaussian

* CI on 1.7

* update IfElse

* formatting
  • Loading branch information
cscherrer authored May 24, 2022
1 parent d8210ef commit 50d90d7
Show file tree
Hide file tree
Showing 43 changed files with 563 additions and 271 deletions.
2 changes: 1 addition & 1 deletion .JuliaFormatter.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ whitespace_ops_in_indices = false
remove_extra_newlines = true
import_to_using = false
pipe_to_function_call = false
short_to_long_function_def = false
short_to_long_function_def = true
always_use_return = false
whitespace_in_kwargs = true
annotate_untyped_fields_with_any = false
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
matrix:
version:
- '1.6'
- '1.7'
os:
- ubuntu-latest
- macOS-latest
Expand Down
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@
/.vscode/
/coverage
coverage-lcov.info
paper/paper.aux
paper/paper.bbl
paper/paper.blg
paper/paper.fdb_latexmk
paper/paper.fls
paper/paper.log
paper/paper.out
paper/paper.synctex.gz
15 changes: 7 additions & 8 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MeasureTheory"
uuid = "eadaa1a4-d27c-401d-8699-e962e1bbc33b"
authors = ["Chad Scherrer <[email protected]> and contributors"]
version = "0.15.1"
version = "0.16.0"

[deps]
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
Expand All @@ -12,14 +12,12 @@ ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
DynamicIterators = "6c76993d-992e-5bf1-9e63-34920a5a5a38"
FLoops = "cc61a311-1640-44b5-9fba-1b764f453329"
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
Infinities = "e1ba4f0e-776d-440f-acd9-e1d2e9742647"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
KeywordCalls = "4d827475-d3e4-43d6-abe3-9688362ede9f"
LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
Expand All @@ -35,31 +33,31 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
TransformVariables = "84d833dd-6860-57f9-a1a7-6da5db126cff"
Tricks = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775"

[compat]
Accessors = "0.1"
ChangesOfVariables = "0.1"
Compat = "3.35"
Compat = "3.35, 4"
ConcreteStructs = "0.2"
ConstructionBase = "1.3"
DensityInterface = "0.4"
Distributions = "0.25"
DynamicIterators = "0.4"
FLoops = "0.2"
FillArrays = "0.12, 0.13"
IfElse = "0.1"
Infinities = "0.1"
InverseFunctions = "0.1"
KeywordCalls = "0.2"
LazyArrays = "0.21, 0.22"
LogExpFunctions = "0.3.3"
MLStyle = "0.4"
MacroTools = "0.5"
MappedArrays = "0.4"
MeasureBase = "0.7"
MeasureBase = "0.9"
NamedTupleTools = "0.13, 0.14"
NestedTuples = "0.3"
PositiveFactorizations = "0.2"
Expand All @@ -68,7 +66,8 @@ Reexport = "1"
SpecialFunctions = "1, 2"
Static = "0.5, 0.6"
StaticArrays = "1.3"
StatsFuns = "0.9"
StatsBase = "0.32, 0.33"
StatsFuns = "0.9, 1"
TransformVariables = "0.5, 0.6"
Tricks = "0.1"
julia = "1.6"
Expand Down
10 changes: 5 additions & 5 deletions docs/src/affine.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ Here the `- logdet(σ)` is the "log absolute Jacobian", required to account for

The above requires solving a linear system, which adds some overhead. Even with the convenience of a lower triangular system, it's still not quite as efficient as multiplication.

In addition to the covariance ``Σ``, it's also common to parameterize a multivariate normal by its _precision matrix_, defined as the inverse of the covariance matrix, ``Ω = Σ⁻¹``. Similar to our use of ``σ`` for the lower Cholesky factor of `Σ`, we'll use ``ω`` for the lower Cholesky factor of ``Ω``.
In addition to the covariance ``Σ``, it's also common to parameterize a multivariate normal by its _precision matrix_, defined as the inverse of the covariance matrix, ``Ω = Σ⁻¹``. Similar to our use of ``σ`` for the lower Cholesky factor of `Σ`, we'll use ``λ`` for the lower Cholesky factor of ``Ω``.

This parameterization enables more efficient calculation of the log-density using only multiplication and addition,

```julia
logdensity_def(d::Normal{(:μ,:ω)}, x) = logdensity_def(d.ω * (x - d.μ)) + logdet(d.ω)
logdensity_def(d::Normal{(:μ,:λ)}, x) = logdensity_def(d.λ * (x - d.μ)) + logdet(d.λ)
```

## `AffineTransform`

Transforms like ``z → σ z + μ`` and ``z → ω \ z + μ`` can be specified in MeasureTheory.jl using an `AffineTransform`. For example,
Transforms like ``z → σ z + μ`` and ``z → λ \ z + μ`` can be specified in MeasureTheory.jl using an `AffineTransform`. For example,

```julia
julia> f = AffineTransform((μ=3.=2.))
Expand All @@ -91,11 +91,11 @@ julia> f(1.0)

In the univariate case this is relatively simple to invert. But if `σ` is a matrix, matrix inversion becomes necessary. This is not always possible as lower triangular matrices are not closed under matrix inversion and as such are not guaranteed to exist.

With multiple parameterizations of a given family of measures, we can work around these issues. The inverse transform of a ``(μ,σ)`` transform will be in terms of ``(μ,ω)``, and vice-versa. So
With multiple parameterizations of a given family of measures, we can work around these issues. The inverse transform of a ``(μ,σ)`` transform will be in terms of ``(μ,λ)``, and vice-versa. So

```julia
julia> f⁻¹ = inverse(f)
AffineTransform{(:μ, :ω), Tuple{Float64, Float64}}((μ = -1.5, ω = 2.0))
AffineTransform{(:μ, :λ), Tuple{Float64, Float64}}((μ = -1.5, λ = 2.0))

julia> f(f⁻¹(4))
4.0
Expand Down
32 changes: 19 additions & 13 deletions src/MeasureTheory.jl
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
module MeasureTheory

using Random
using FLoops

using MeasureBase
using MLStyle
using NestedTuples
import TransformVariables
const TV = TransformVariables

using TransformVariables: as, asℝ₊, as𝕀, asℝ
using TransformVariables: asℝ₊, as𝕀, asℝ, transform

import Base
import Distributions
const Dists = Distributions

export TV
export transform
export
export gentype
export For
Expand All @@ -30,7 +30,7 @@ export CountingMeasure
export TrivialMeasure
export Likelihood
export testvalue
export basekleisli
export basekernel

using Infinities
using DynamicIterators
Expand All @@ -45,15 +45,14 @@ import LogExpFunctions
import NamedTupleTools
import InverseFunctions: inverse
export inverse
export ifelse

import MeasureBase: insupport, instance, marginals
import MeasureBase:
testvalue,
logdensity_def,
density_def,
basemeasure,
kleisli,
kernel,
params,
paramnames,
∫,
Expand All @@ -62,7 +61,13 @@ import MeasureBase:
import MeasureBase:
using MeasureBase: BoundedInts, BoundedReals, CountingMeasure, IntegerDomain, IntegerNumbers
using MeasureBase: weightedmeasure, restrict
using MeasureBase: AbstractKleisli
using MeasureBase: AbstractTransitionKernel

import Statistics: mean, var, std

import MeasureBase: likelihood
export likelihood
export log_likelihood_ratio

using StaticArrays

Expand All @@ -74,8 +79,8 @@ import Base: rand

using Reexport
@reexport using MeasureBase
import IfElse: ifelse
@reexport using IfElse
import IfElse
using IfElse

using Tricks: static_hasmethod

Expand All @@ -87,6 +92,7 @@ export AffineTransform
export insupport
export For

using MeasureBase: kernel
using MeasureBase: Returns
import MeasureBase: proxy, @useproxy
import MeasureBase: basemeasure_depth
Expand All @@ -101,10 +107,6 @@ gentype(μ::AbstractMeasure) = typeof(testvalue(μ))

# gentype(μ::AbstractMeasure) = gentype(basemeasure(μ))

import Distributions: logpdf, pdf

export pdf, logpdf

xlogx(x::Number) = LogExpFunctions.xlogx(x)
xlogx(x, y) = x * log(x)

Expand All @@ -114,6 +116,8 @@ xlogy(x, y) = x * log(y)
xlog1py(x::Number, y::Number) = LogExpFunctions.xlog1py(x, y)
xlog1py(x, y) = x * log(1 + y)

as(args...; kwargs...) = TV.as(args...; kwargs...)

include("utils.jl")
include("const.jl")
include("combinators/for.jl")
Expand All @@ -126,7 +130,6 @@ include("combinators/weighted.jl")
include("combinators/product.jl")
include("combinators/transforms.jl")
include("combinators/exponential-families.jl")

include("resettable-rng.jl")
include("realized.jl")
include("combinators/chain.jl")
Expand All @@ -151,6 +154,9 @@ include("parameterized/binomial.jl")
include("parameterized/multinomial.jl")
include("parameterized/lkj-cholesky.jl")
include("parameterized/negativebinomial.jl")
include("parameterized/gamma.jl")
include("parameterized/snedecorf.jl")
include("parameterized/inverse-gaussian.jl")

include("combinators/ifelse.jl")

Expand Down
Loading

2 comments on commit 50d90d7

@cscherrer
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/60954

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.16.0 -m "<description of version>" 50d90d7aa42f60324a7fb9ba9dc45d4e2cac9d8e
git push origin v0.16.0

Please sign in to comment.