Code Monkey home page Code Monkey logo

dynamiciterators.jl's Introduction

DynamicIterators.jl

DynamicIterator

Iterators combine to a tree of iterators, but dynamic iterators combine to a network of interacting entities.

Dynamic iterators subtype <:DynamicIterator. They extend the iteration protocol and define

    dyniterate(iter, somemessage(state))

or

    dyniterate(iter, othermessage(state), arg)

where message wraps a state or other relevant information. For example the definition

struct Start{T} <: Message
    value::T
end
dyniterate(iter, Start(value))

communicates that iter should start at value (if this is implemented). This is similar to iterate(iter) communicating that iter should start at a predefined value. In fact a fallback

dyniterate(iter, ::Nothing) = iterate(iter)

is in place.

Some messages make the iterator accept a third argument. A simple example using bind to bind an iterator to an iterator using the three-argument form of dyniterate:

using DynamicIterators
import DynamicIterators: dyniterate

struct Summed <: DynamicIterator
end

function dyniterate(::Summed, ::Nothing, y)
    y, y
end

function dyniterate(::Summed, i, y)
    i + y, i + y
end

@show collect(bind(1:5, Summed()))

A more in-depth example showing the power of the approach is https://github.com/mschauer/DynamicIterators.jl/blob/master/example/ressourcemanagement.jl, showing how to extend the iterator protocol to allow resource management (e.g. closing of files of child iterators) at the end of iteration of the parent.

A preliminary list of supported messages:

Message (and third argument) Meaning
state or State(state) ordinary iteration
Start(noting) start the iterator at its default
Start(x) start the iterate from the state corresponding to value x
Value(x, state) continue to iterate from the state corresponding to iterate x
NextKey(state, nextkey) advance an iterator over pairs of key=>values to nextkey
Steps(state, n) advance the iterator n steps or possibly rewind if n negative
Control(state), control control term as in the Kalman filter provided as third argument to dyniterate⋆
Sample(state[,rng]) sample from iterates⋆
NextKeys(state), key advance iterator to the keys provided as third argument to dyniterate⋆

⋆persistent messages: dyniterate returns a state again wrapped by the message

Evolution: Evolution-type dynamic iterators

Typically, the state of an iterator is opaque. But for some iterators the iterates are the states:

julia> value, state = iterate('A':'Z')
('A', 'A')

julia> value, state = iterate('A':'Z', 'X')
('Y', 'Y')

This means that the states/iterates of an iterator can be modified in a transparent way. This allows iterators not only to depend on each other, but to interact.

DynamicIterators.jl embeds a constrained iterator protocol for iterators subtyping <:Evolution, which define

evolve(iterator, x) -> y
dub(x) = x === nothing ? nothing : (x,x)
iterate(iterator::Evolution, x) = dub(evolve(iterator, x))

which guarantees value == state and introduces a powerful set of combinators for such iterators.

Combinators

As a simple example take a Metropolis-Hastings chain

It can be described as a simple Evolution.

function evolve(MH::MetropolisHastings, (t,x)::Pair)
    P = MH.P
    Q = MH.proposal(x)
    xᵒ = rand(Q)
    Qᵒ = MH.proposal(xᵒ)
    if log(rand(MH.rng)) < MH.logpdf(P, xᵒ) - MH.logpdf(P, x) + MH.logpdf(Qᵒ, x) - MH.logpdf(Q, xᵒ)
        x = xᵒ
    end
    (t+1 => x)
end

The following example shows that the Mixture iterator combinator can be used to combine two Metropolis-Hastings chains into a component wise MetropolisHastings sampler:

using DynamicIterators
using Distributions

D = MvNormal([1.0, 0.5], [1.0 0.5; 0.5 1.5] )
struct Move{T}
    x::T
    σ::Float64
    i::Int
end
m1(x) = Move(x, 0.1, 1)
m2(x) = Move(x, 0.1, 2)
Base.rand(M::Move) = M.x + M.σ*randn()*[M.i-1, 2-M.i]
Distributions.logpdf(M::Move, x) = logpdf(Normal(M.x[M.i], M.σ), x[M.i])
MH1 = MetropolisHastings(D, m1, logpdf)
MH2 = MetropolisHastings(D, m2, logpdf)

I = Evolve(i->rand(1:2))

MH = mixture(I, (MH1, MH2))

X = values(trace(MH, 1=>(1, [0.0, 0.0]), endtime(2000)))

img

Lifting time

Letting

evolve(E, (i, x)::Pair) = i + 1 => evolve(E, x)

constitutes a "lifting" of discrete time. This corresponds to enumerating the iterates of an evolution x = f(x) as (1 => x1, 2 => x2, ...).

DynamicIterators control keywords treat Pairs as pair of key and value in concordance with the package Trajectories and somewhat in line with Julia's general convention.

Traces

Controlled Dynamic Iterators

Examples

To illustrates the range of this I have picked some examples of very diverse nature.

dynamiciterators.jl's People

Contributors

juliatagbot avatar mschauer avatar theogf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dynamiciterators.jl's Issues

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Ressource management

One could wonder if DynamicIterators should support the notion of closing iterators to facilitate ressource management.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.