{"id":44988902,"url":"https://github.com/skleinbo/treeprocesses.jl","last_synced_at":"2026-02-18T20:52:26.688Z","repository":{"id":177519885,"uuid":"568461011","full_name":"skleinbo/TreeProcesses.jl","owner":"skleinbo","description":"binary tree generation algorithms","archived":false,"fork":false,"pushed_at":"2024-05-20T13:42:27.000Z","size":23,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-05-20T17:34:19.434Z","etag":null,"topics":["coalescent","julia","trees"],"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/skleinbo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-11-20T15:54:29.000Z","updated_at":"2024-05-20T13:42:30.000Z","dependencies_parsed_at":"2023-09-25T01:50:37.185Z","dependency_job_id":"7a871a7f-441d-40ca-b8a8-595610ae4916","html_url":"https://github.com/skleinbo/TreeProcesses.jl","commit_stats":{"total_commits":18,"total_committers":2,"mean_commits":9.0,"dds":0.05555555555555558,"last_synced_commit":"209dabe2466f2c11148124df472c314389589421"},"previous_names":["skleinbo/treeprocesses.jl"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/skleinbo/TreeProcesses.jl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skleinbo%2FTreeProcesses.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skleinbo%2FTreeProcesses.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skleinbo%2FTreeProcesses.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skleinbo%2FTreeProcesses.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skleinbo","download_url":"https://codeload.github.com/skleinbo/TreeProcesses.jl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skleinbo%2FTreeProcesses.jl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29595315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T18:54:29.675Z","status":"ssl_error","status_checked_at":"2026-02-18T18:50:50.517Z","response_time":162,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["coalescent","julia","trees"],"created_at":"2026-02-18T20:52:25.798Z","updated_at":"2026-02-18T20:52:26.677Z","avatar_url":"https://github.com/skleinbo.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TreeProcesses.jl\n\nSome (common) forward and backward processes to generate binary trees as seen\nfor example in population genetics.\n\nBased on [`BinaryTrees.jl`](https://github.com/skleinbo/BinaryTrees.jl), which in turn implements the interface from [`AbstractTrees.jl`](https://github.com/JuliaCollections/AbstractTrees.jl/)\n\n## Installation\n\nThe package is unregistered. Install it directly from GitHub.\n\n```\njulia\u003e ]add https://github.com/skleinbo/BinaryTrees.jl https://github.com/skleinbo/TreeProcesses.jl\n```\n\n## Currently implemented\n\n__Forward:__\n\n* `birth_death(n, T, d, b=1.0; N=0)`: Starting from `n` nodes, a randomly selected one splits with probability `b`. Independently, a node dies with probability `d`. Run for `T` time steps (a birth plus death event are one time step), or until `N` nodes are present unless `N==0` (default). Lineages that die out are automatically pruned, i.e. after sufficiently many (`O(n^2)`) time steps, a most recent common ancestor will be found. Returns all surviving root nodes.\n* `maximally_balanced(n)`\n* `maximally_unbalanced(n)`\n* `moran(n,T)`: `birth_death` with b/d probabilities both equal to `1` to maintain constant population size.\n* `yule(n)`: Starting from a root node, split leafs uniformly `n` times.\n\n__Backward:__\n\n* `coalescent(n)`: Neutral coalescent process. Starting from `n` nodes, pick two at random and merge until only one is left.\n* `preferential_coalescent(n, w; fuse=max)`: Like `coalescent`, but each node is assigned the respective weight from the vector `w` with which it coalesces.\nAncestral nodes' weights are computed from their children's weights by applying `fuse`. The standard coalescent is recovered by choosing all weights equal and setting `fuse=first`.\n\n## Node types\n\nEvery node is of type `BinaryTree{T}` where its internal state is stored in a variable of type `T`. The state is accessible through the `val` field. The appropriate `T` depends on the process and the observables one wishes to store. Required fields are detailed in the process's docstring. Sensible defaults are provided.\n\nAll included processes take a keyword argument `nodevalue` which is a callable that provides the default value when a node is first created.\n\n## Observables\n\n* `ACD!(t)`: Annotate each node of a tree with\n  * $A$: Number of nodes in the subtree, including itself.\n  * $C$: Cumulative number of nodes in the subtree, i.e. $\\sum A(i)$ for $i$ in the subtree, including the node itself.  \n  * $D$: Cumulative distance to all nodes in the subtree.\n  \n  Returns number of nodes, and vectors of `A`,`C` and `D`. The latter are in [post-order](https://en.wikipedia.org/wiki/Tree_traversal).\n\n  __Note__: The node storage `T` (see above) must have a field `observables\u003c:AbstractVector` with at least three elements. The values `A,C,D` are stored in the first three elements.\n\n## Example\n\n```\njulia\u003e using TreeProcesses\n\njulia\u003e T = preferential_coalescent(2^4, rand(2^4)) |\u003e first\n((w=0.9772233107834184, t=15, observables=[0, 0, 0])) 983bc8d17e328bad with 2 children and no parent.\n\n# calculate and return number of nodes, A \u0026 C\njulia\u003e ACD!(T)\n(31, [1, 1, 3, 1, 5, 1, 7, 1, 1, 3  …  9, 23, 1, 1, 3, 27, 1, 29, 1, 31], [1, 1, 5, 1, 11, 1, 19, 1, 1, 5  …  25, 91, 1, 1, 5, 123, 1, 153, 1, 185], [0, 0, 2, 0, 6, 0, 12, 0, 0, 2  …  16, 68, 0, 0, 2, 96, 0, 124, 0, 154])\n\n# the tree has been annotated with the observables\njulia\u003e T\n((w=0.9772233107834184, t=15, observables=[31, 185, 154])) 983bc8d17e328bad with 2 children and no parent\n\njulia\u003e using AbstractTrees\n\njulia\u003e print_tree(T, maxdepth=16)\n(w=0.977223, t=15, observables=[31, 185, 154])\n├─ (w=0.977223, t=14, observables=[29, 153, 124])\n│  ├─ (w=0.977223, t=13, observables=[27, 123, 96])\n│  │  ├─ (w=0.977223, t=11, observables=[23, 91, 68])\n│  │  │  ├─ (w=0.977223, t=9, observables=[13, 43, 30])\n│  │  │  │  ├─ (w=0.977223, t=7, observables=[7, 19, 12])\n│  │  │  │  │  ├─ (w=0.914926, t=5, observables=[5, 11, 6])\n│  │  │  │  │  │  ├─ (w=0.914926, t=3, observables=[3, 5, 2])\n│  │  │  │  │  │  │  ├─ (w=0.876, t=0, observables=[1, 1, 0])\n│  │  │  │  │  │  │  └─ (w=0.914926, t=0, observables=[1, 1, 0])\n│  │  │  │  │  │  └─ (w=0.397427, t=0, observables=[1, 1, 0])\n│  │  │  │  │  └─ (w=0.977223, t=0, observables=[1, 1, 0])\n│  │  │  │  └─ (w=0.333037, t=4, observables=[5, 11, 6])\n│  │  │  │     ├─ (w=0.333037, t=1, observables=[3, 5, 2])\n│  │  │  │     │  ├─ (w=0.333037, t=0, observables=[1, 1, 0])\n│  │  │  │     │  └─ (w=0.215572, t=0, observables=[1, 1, 0])\n│  │  │  │     └─ (w=0.1671, t=0, observables=[1, 1, 0])\n│  │  │  └─ (w=0.846859, t=10, observables=[9, 25, 16])\n│  │  │     ├─ (w=0.495586, t=6, observables=[3, 5, 2])\n│  │  │     │  ├─ (w=0.495586, t=0, observables=[1, 1, 0])\n│  │  │     │  └─ (w=0.19761, t=0, observables=[1, 1, 0])\n│  │  │     └─ (w=0.846859, t=8, observables=[5, 11, 6])\n│  │  │        ├─ (w=0.846859, t=2, observables=[3, 5, 2])\n│  │  │        │  ├─ (w=0.122918, t=0, observables=[1, 1, 0])\n│  │  │        │  └─ (w=0.846859, t=0, observables=[1, 1, 0])\n│  │  │        └─ (w=0.321122, t=0, observables=[1, 1, 0])\n│  │  └─ (w=0.549756, t=12, observables=[3, 5, 2])\n│  │     ├─ (w=0.216285, t=0, observables=[1, 1, 0])\n│  │     └─ (w=0.549756, t=0, observables=[1, 1, 0])\n│  └─ (w=0.282131, t=0, observables=[1, 1, 0])\n└─ (w=0.219596, t=0, observables=[1, 1, 0])\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskleinbo%2Ftreeprocesses.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskleinbo%2Ftreeprocesses.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskleinbo%2Ftreeprocesses.jl/lists"}