lazytree


Namelazytree JSON
Version 0.3.4 PyPI version JSON
download
home_pagehttps://github.com/mvcisback/pyLazyTree
SummaryPython library for manipulating infinite trees.
upload_time2024-01-23 07:07:23
maintainer
docs_urlNone
authorMarcell Vazquez-Chanlatte
requires_python>=3.6,<4.0
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Lazy Tree

[![Build Status](https://cloud.drone.io/api/badges/mvcisback/pyLazyTree/status.svg)](https://cloud.drone.io/mvcisback/pyLazyTree)
[![codecov](https://codecov.io/gh/mvcisback/DiscreteSignals/branch/master/graph/badge.svg)](https://codecov.io/gh/mvcisback/pyLazyTree)
[![PyPI version](https://badge.fury.io/py/lazytree.svg)](https://badge.fury.io/py/lazytree)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->
**Table of Contents**

- [Installation](#installation)
- [Usage](#usage)

<!-- markdown-toc end -->


# Installation

If you just need to use `lazytree`, you can just run:

`$ pip install lazytree`

For developers, note that this project uses the
[poetry](https://poetry.eustace.io/) python package/dependency
management tool. Please familarize yourself with it and then
run:

`$ poetry install`

# Usage

A `LazyTree` is a triple, `(root, child_map, view)` where `root : A`
and a child map, `child_map`, which maps `a` to a (finite) list of
children `child_map : A -> List[A]` define the tree's structure and
`view : A -> B` defines what the tree represents. The default view is
the identity map, `lambda x: x`.

This structure is useful for modeling infinite (or really large) trees
where only a finite number of nodes need to be accessed. For example,
the following Binary tree represents the recursive subdivision of the
interval [0, 1].

```python
from lazytree import LazyTree

def split(itvl):
    lo, hi = itvl
    mid = lo + (hi - lo)/2
    return (lo, mid), (mid, hi)

tree = LazyTree(
    root=(0, 1),  # Initial Itvl
    child_map=split  # Itvl -> [Itvl]
)
```

Conceptually a `LazyTree` object can be thought of as containing the pieces of data.

1. The `root` of the tree.
2. The data represented by the `root`, accessed via the `view` method.
3. The child subtrees - computed using `child_map` and accessed through the `.children` attribute.

For example, in our interval example, each node corresponds to an interval of `(0, 1)` and has two child subtrees.

```python
# View the current root.
assert tree.view() == tree.root

subtrees = tree.children
assert len(subtrees) == 2
```

Often, for each node in a tree, one is interested in computing a particular function. This can be done using the `map` and `view` methods. For example, below `map` each interval in the tree to it's size. This results in a new `LazyTree` object.

```python
tree2 = tree.map(lambda itvl: itvl[1] - itvl[0])  # Change view to itvl size.
assert tree2.view() == 1

# Access the root's subtrees
subtrees = tree2.children
assert len(subtrees) == 2
assert subtrees[0].root == (0, 0.5)
assert subtrees[0].view() == 0.5
```

Travesals of a `LazyTree` object are also implemented. For example,

```python
# Breadth First Search through tree.
## Note: calls .view() before returning. 
itvls = tree.bfs()  # returns a generator.
sizes = tree2.bfs()  # returns a generator.

assert next(itvls) == (0, 1)
assert next(sizes) == 1

assert next(itvls) == (0, 0.5)
assert next(sizes) == 0.5

assert next(itvls) == (0.5, 1)
assert next(sizes) == 0.5

# Cost guided traversal.
## Note: Smaller means higher priority.
sizes = tree2.cost_guided_refinement(cost=lambda x: x)
assert next(sizes)  == 1  # (0, 1)
assert next(sizes)  == 0.5  # (0, 0.5)
assert next(sizes)  == 0.25  # (0, 0.25)

# Iterative Deepening Depth First Traversal
sizes = tree2.iddfs(max_depth=3)  # returns a generator.
assert list(sizes) == [1, 0.5, 0.5, 0.25, 0.25, 0.25, 0.25, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125]

# Note, you can reset the current view.
tree3 = tree2.with_identity_view()
assert tree3.view() == tree.view()
```

Finally, one can "prune" away subtrees by labeling them as leaf nodes using the `prune` method. If you are sure that the resulting tree is finite (either due to pruning or the provided `child_map`) then one can compute the leaves of the tree.

```python
# Prune subtrees with a root of size less than 0.1.
tree4 = tree2.prune(isleaf=lambda s: s < 0.2)
sizes = tree.bfs()
assert all(s > 0.001 for s in sizes)  # Note that sizes is now finite.



# Compute leafs of tree. Careful! Could be infinite!
assert all(s == 0.125 for s in tree4.leaves())
assert len(list(tree4.leaves())) == 8
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mvcisback/pyLazyTree",
    "name": "lazytree",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "Marcell Vazquez-Chanlatte",
    "author_email": "marcell.vc@eecs.berkeley.edu",
    "download_url": "https://files.pythonhosted.org/packages/41/9c/f45816d4c4da03eb12d4da72aa8e5d682ba755d113c45de445639f157cad/lazytree-0.3.4.tar.gz",
    "platform": null,
    "description": "# Lazy Tree\n\n[![Build Status](https://cloud.drone.io/api/badges/mvcisback/pyLazyTree/status.svg)](https://cloud.drone.io/mvcisback/pyLazyTree)\n[![codecov](https://codecov.io/gh/mvcisback/DiscreteSignals/branch/master/graph/badge.svg)](https://codecov.io/gh/mvcisback/pyLazyTree)\n[![PyPI version](https://badge.fury.io/py/lazytree.svg)](https://badge.fury.io/py/lazytree)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->\n**Table of Contents**\n\n- [Installation](#installation)\n- [Usage](#usage)\n\n<!-- markdown-toc end -->\n\n\n# Installation\n\nIf you just need to use `lazytree`, you can just run:\n\n`$ pip install lazytree`\n\nFor developers, note that this project uses the\n[poetry](https://poetry.eustace.io/) python package/dependency\nmanagement tool. Please familarize yourself with it and then\nrun:\n\n`$ poetry install`\n\n# Usage\n\nA `LazyTree` is a triple, `(root, child_map, view)` where `root : A`\nand a child map, `child_map`, which maps `a` to a (finite) list of\nchildren `child_map : A -> List[A]` define the tree's structure and\n`view : A -> B` defines what the tree represents. The default view is\nthe identity map, `lambda x: x`.\n\nThis structure is useful for modeling infinite (or really large) trees\nwhere only a finite number of nodes need to be accessed. For example,\nthe following Binary tree represents the recursive subdivision of the\ninterval [0, 1].\n\n```python\nfrom lazytree import LazyTree\n\ndef split(itvl):\n    lo, hi = itvl\n    mid = lo + (hi - lo)/2\n    return (lo, mid), (mid, hi)\n\ntree = LazyTree(\n    root=(0, 1),  # Initial Itvl\n    child_map=split  # Itvl -> [Itvl]\n)\n```\n\nConceptually a `LazyTree` object can be thought of as containing the pieces of data.\n\n1. The `root` of the tree.\n2. The data represented by the `root`, accessed via the `view` method.\n3. The child subtrees - computed using `child_map` and accessed through the `.children` attribute.\n\nFor example, in our interval example, each node corresponds to an interval of `(0, 1)` and has two child subtrees.\n\n```python\n# View the current root.\nassert tree.view() == tree.root\n\nsubtrees = tree.children\nassert len(subtrees) == 2\n```\n\nOften, for each node in a tree, one is interested in computing a particular function. This can be done using the `map` and `view` methods. For example, below `map` each interval in the tree to it's size. This results in a new `LazyTree` object.\n\n```python\ntree2 = tree.map(lambda itvl: itvl[1] - itvl[0])  # Change view to itvl size.\nassert tree2.view() == 1\n\n# Access the root's subtrees\nsubtrees = tree2.children\nassert len(subtrees) == 2\nassert subtrees[0].root == (0, 0.5)\nassert subtrees[0].view() == 0.5\n```\n\nTravesals of a `LazyTree` object are also implemented. For example,\n\n```python\n# Breadth First Search through tree.\n## Note: calls .view() before returning. \nitvls = tree.bfs()  # returns a generator.\nsizes = tree2.bfs()  # returns a generator.\n\nassert next(itvls) == (0, 1)\nassert next(sizes) == 1\n\nassert next(itvls) == (0, 0.5)\nassert next(sizes) == 0.5\n\nassert next(itvls) == (0.5, 1)\nassert next(sizes) == 0.5\n\n# Cost guided traversal.\n## Note: Smaller means higher priority.\nsizes = tree2.cost_guided_refinement(cost=lambda x: x)\nassert next(sizes)  == 1  # (0, 1)\nassert next(sizes)  == 0.5  # (0, 0.5)\nassert next(sizes)  == 0.25  # (0, 0.25)\n\n# Iterative Deepening Depth First Traversal\nsizes = tree2.iddfs(max_depth=3)  # returns a generator.\nassert list(sizes) == [1, 0.5, 0.5, 0.25, 0.25, 0.25, 0.25, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125]\n\n# Note, you can reset the current view.\ntree3 = tree2.with_identity_view()\nassert tree3.view() == tree.view()\n```\n\nFinally, one can \"prune\" away subtrees by labeling them as leaf nodes using the `prune` method. If you are sure that the resulting tree is finite (either due to pruning or the provided `child_map`) then one can compute the leaves of the tree.\n\n```python\n# Prune subtrees with a root of size less than 0.1.\ntree4 = tree2.prune(isleaf=lambda s: s < 0.2)\nsizes = tree.bfs()\nassert all(s > 0.001 for s in sizes)  # Note that sizes is now finite.\n\n\n\n# Compute leafs of tree. Careful! Could be infinite!\nassert all(s == 0.125 for s in tree4.leaves())\nassert len(list(tree4.leaves())) == 8\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python library for manipulating infinite trees.",
    "version": "0.3.4",
    "project_urls": {
        "Homepage": "https://github.com/mvcisback/pyLazyTree",
        "Repository": "https://github.com/mvcisback/pyLazyTree"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "42878d989292d3202019c134d75e2808ee069c7729b78750ac76cf2e36f9f968",
                "md5": "04ba8bfaa0b32ced4aa19b878c5e6d50",
                "sha256": "a3d9ee2a0d70dda85ddb8807624e8b28848ce5eb7391fe058b0ce4c01a01f0da"
            },
            "downloads": -1,
            "filename": "lazytree-0.3.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "04ba8bfaa0b32ced4aa19b878c5e6d50",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6,<4.0",
            "size": 5641,
            "upload_time": "2024-01-23T07:07:22",
            "upload_time_iso_8601": "2024-01-23T07:07:22.553376Z",
            "url": "https://files.pythonhosted.org/packages/42/87/8d989292d3202019c134d75e2808ee069c7729b78750ac76cf2e36f9f968/lazytree-0.3.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "419cf45816d4c4da03eb12d4da72aa8e5d682ba755d113c45de445639f157cad",
                "md5": "293d8f8b70a37fc63dfcc66bcd615937",
                "sha256": "8998673043d4be464913eea59f18f3e9cd5e996ce8042ba97433ff38165b397b"
            },
            "downloads": -1,
            "filename": "lazytree-0.3.4.tar.gz",
            "has_sig": false,
            "md5_digest": "293d8f8b70a37fc63dfcc66bcd615937",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6,<4.0",
            "size": 4712,
            "upload_time": "2024-01-23T07:07:23",
            "upload_time_iso_8601": "2024-01-23T07:07:23.783669Z",
            "url": "https://files.pythonhosted.org/packages/41/9c/f45816d4c4da03eb12d4da72aa8e5d682ba755d113c45de445639f157cad/lazytree-0.3.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-23 07:07:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mvcisback",
    "github_project": "pyLazyTree",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "lazytree"
}
        
Elapsed time: 0.17968s