{"id":16499283,"url":"https://github.com/mschauer/dynamiciterators.jl","last_synced_at":"2025-03-01T18:20:34.579Z","repository":{"id":53514148,"uuid":"156825921","full_name":"mschauer/DynamicIterators.jl","owner":"mschauer","description":"Iterators with message passing and feedback loops","archived":false,"fork":false,"pushed_at":"2023-04-14T21:53:21.000Z","size":112,"stargazers_count":22,"open_issues_count":4,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-21T14:25:07.399Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mschauer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-11-09T07:28:16.000Z","updated_at":"2024-05-30T05:46:36.000Z","dependencies_parsed_at":"2024-01-13T18:24:19.256Z","dependency_job_id":"f76b14b9-c40f-45e2-a3be-7e4d252322e1","html_url":"https://github.com/mschauer/DynamicIterators.jl","commit_stats":{"total_commits":77,"total_committers":2,"mean_commits":38.5,"dds":"0.012987012987012991","last_synced_commit":"d346b269e8e6d2bc1a35b1aff1ab136ac2d1150b"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschauer%2FDynamicIterators.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschauer%2FDynamicIterators.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschauer%2FDynamicIterators.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mschauer%2FDynamicIterators.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mschauer","download_url":"https://codeload.github.com/mschauer/DynamicIterators.jl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241404950,"owners_count":19957735,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T14:51:51.103Z","updated_at":"2025-03-01T18:20:34.540Z","avatar_url":"https://github.com/mschauer.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DynamicIterators.jl\n\n## `DynamicIterator`\nIterators combine to a tree of iterators, but dynamic iterators combine to a network of interacting entities.\n\nDynamic iterators subtype `\u003c:DynamicIterator`. They extend the iteration protocol and define\n```julia\n    dyniterate(iter, somemessage(state))\n```\nor\n```julia\n    dyniterate(iter, othermessage(state), arg)\n```\nwhere message wraps a state or other relevant information.\nFor example the definition\n```julia\nstruct Start{T} \u003c: Message\n    value::T\nend\ndyniterate(iter, Start(value))\n```\ncommunicates that `iter` should start at `value` (if this is implemented).\nThis is similar to `iterate(iter)` communicating that `iter` should start at a predefined\nvalue. In fact a fallback\n```julia\ndyniterate(iter, ::Nothing) = iterate(iter)\n```\nis in place.\n\nSome messages make the iterator accept a third argument.\nA simple example using `bind` to bind an iterator to an iterator using the three-argument form of `dyniterate`:\n```julia\nusing DynamicIterators\nimport DynamicIterators: dyniterate\n\nstruct Summed \u003c: DynamicIterator\nend\n\nfunction dyniterate(::Summed, ::Nothing, y)\n    y, y\nend\n\nfunction dyniterate(::Summed, i, y)\n    i + y, i + y\nend\n\n@show collect(bind(1:5, Summed()))\n```\n\nA 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\nto allow resource management (e.g. closing of files of child iterators) at the end of iteration of the parent.\n\nA preliminary list of supported messages:\n\nMessage (and third argument) | Meaning\n----------------------------|--------------------\n`state` or `State(state)`   | ordinary iteration\n`Start(noting)`             | start the iterator at its default\n`Start(x)`                  | start the iterate from the state corresponding to value `x`\n`Value(x, state)`           | continue to iterate from the state corresponding to iterate `x`\n`NextKey(state, nextkey)`   | advance an iterator over pairs of `key=\u003evalues` to `nextkey`\n`Steps(state, n)`           | advance the iterator `n` steps or possibly rewind if `n` negative\n`Control(state), control`   | control term as in the Kalman filter provided as third argument to dyniterate⋆\n`Sample(state[,rng])`       | sample from iterates⋆\n`NextKeys(state), key`      | advance iterator to the keys provided as third argument to dyniterate⋆\n\n\n⋆persistent messages: `dyniterate` returns a state again wrapped by the message\n\n\n## `Evolution`: Evolution-type dynamic iterators\nTypically, the state of an iterator is opaque. But for some iterators\nthe iterates *are* the states:\n\n```julia\njulia\u003e value, state = iterate('A':'Z')\n('A', 'A')\n\njulia\u003e value, state = iterate('A':'Z', 'X')\n('Y', 'Y')\n```\n\nThis means that the states/iterates of an iterator can be modified in a\ntransparent way. This allows iterators not only to depend on each other, but to\n*interact*.\n\n`DynamicIterators.jl` embeds a constrained iterator protocol for\niterators subtyping `\u003c:Evolution`, which define\n```julia\nevolve(iterator, x) -\u003e y\ndub(x) = x === nothing ? nothing : (x,x)\niterate(iterator::Evolution, x) = dub(evolve(iterator, x))\n```\nwhich guarantees `value == state` and introduces a powerful set of combinators\nfor such iterators.\n\n## Combinators\n\nAs a simple example take a Metropolis-Hastings chain\n\nIt can be described as a simple Evolution.\n```julia\nfunction evolve(MH::MetropolisHastings, (t,x)::Pair)\n    P = MH.P\n    Q = MH.proposal(x)\n    xᵒ = rand(Q)\n    Qᵒ = MH.proposal(xᵒ)\n    if log(rand(MH.rng)) \u003c MH.logpdf(P, xᵒ) - MH.logpdf(P, x) + MH.logpdf(Qᵒ, x) - MH.logpdf(Q, xᵒ)\n        x = xᵒ\n    end\n    (t+1 =\u003e x)\nend\n```\n\nThe following example shows that the `Mixture` iterator combinator can be used to combine two Metropolis-Hastings chains into a component wise MetropolisHastings sampler:\n\n```julia\nusing DynamicIterators\nusing Distributions\n\nD = MvNormal([1.0, 0.5], [1.0 0.5; 0.5 1.5] )\nstruct Move{T}\n    x::T\n    σ::Float64\n    i::Int\nend\nm1(x) = Move(x, 0.1, 1)\nm2(x) = Move(x, 0.1, 2)\nBase.rand(M::Move) = M.x + M.σ*randn()*[M.i-1, 2-M.i]\nDistributions.logpdf(M::Move, x) = logpdf(Normal(M.x[M.i], M.σ), x[M.i])\nMH1 = MetropolisHastings(D, m1, logpdf)\nMH2 = MetropolisHastings(D, m2, logpdf)\n\nI = Evolve(i-\u003erand(1:2))\n\nMH = mixture(I, (MH1, MH2))\n\nX = values(trace(MH, 1=\u003e(1, [0.0, 0.0]), endtime(2000)))\n```\n\n![img](https://raw.githubusercontent.com/mschauer/DynamicIterators.jl/master/asset/mh.png)\n\n## Lifting time\n\nLetting\n```julia\nevolve(E, (i, x)::Pair) = i + 1 =\u003e evolve(E, x)\n```\nconstitutes a \"lifting\" of discrete time. This corresponds to enumerating the iterates of an evolution `x = f(x)` as `(1 =\u003e x1, 2 =\u003e x2, ...)`.\n\n`DynamicIterators` control keywords treat `Pair`s as pair of key and value in concordance with the package `Trajectories` and somewhat in line with Julia's general convention.\n\n\n## Traces\n\n## Controlled Dynamic Iterators\n\n\n## Examples\n\nTo illustrates the range of this I have picked some examples of very diverse nature.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmschauer%2Fdynamiciterators.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmschauer%2Fdynamiciterators.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmschauer%2Fdynamiciterators.jl/lists"}