Compute Monotone Threshold Surfaces and compute distances between surfaces.

# mvcisback/monotone-bipartition

Switch branches/tags
Nothing to show

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

## Files

Failed to load latest commit information.
Type
Name
Commit time

# Monotone Bipartitions

This library enable manipulating and comparing implicitly defined monotone bipartitions on the unit box. Namely, the user provides a threshold oracle: `oracle : [0, 1]^n -> bool` with the constraint that for any two points in the unit box, `x, y in [0, 1]^n` if `x <= y` coordinate-wise, then `oracle(x) <= oracle(y)` , where `False <= True`. An example is given below:

Compute Monotone Threshold Surfaces and compute distances between surfaces.

The basis of the implemented algorithm to approximate the bipartition using black box access to `oracle` was orignally given by Oded Maler in Learning Monotone Partitions of Partially-Ordered Domains.

# Installation

If you just need to use `monotone-partition`, you can just run:

`\$ pip install monotone-bipartition`

For developers, note that this project uses the poetry python package/dependency management tool. Please familarize yourself with it and then run:

`\$ poetry install`

# Usage

```import monotone_bipartition as mbp

partition1 = mbp.from_threshold(
func=lambda x: x[0] >= 0.5,
dim=2,
)  # type: mbp.BiPartition

assert partition1.dim == 2

# Approximate the boundary using a collection of rectangles.
recs = partition1.approx(tol=1e-3)  # List of rectangles.

## Rectangles are defined as the product of intervals.
## I.e, each interval is the projection of the rectangle
## on a given axis of the unit box.
print(recs[0].intervals)  # (Interval(bot=0.49999237060546875, top=0.5), Interval(bot=0.0, top=1)

# Support labeling point using boundary.
# Useful for testing equiv to `oracle` or
# if calling `oracle` is very expensive.

assert partition1.label((0.8, 0))
assert not partition1.label((0.3, 0.3))```

## Comparing partitions

It is often useful to compare boundaries. (See https://github.com/mvcisback/LogicalLens for a usecase).

```d11 = partition1.dist(partition1, tol=1e-1)  # Returns an Interval
assert 0 in d12
print(d11.center)  # 0.029

partition2 = mbp.from_threshold(
func=lambda x: x[1] >= 0.6,
dim=2,
)  # type: mbp.BiPartition

d12 = partition1.dist(partition2, tol=1e-1)  # Returns an Interval
assert 0.6 in d12
print(d12.center)  # 0.5726

# TODO: implement partial ordering. Check if lower sets are subsets of each other.
partition3 = mbp.from_threshold(func=lambda x: x[1] >= 0.7, dim=2)
assert partition3 >= partition2
assert not (partition1 >= partition3)  # Incomparable since they intersect.```

## Find particular points on the boundary

Sometimes, it is useful to find particular points on the threshold boundary. For example, the following two works leverage such "projections" to learn classifiers for the data that induces the partitions. (Again, see https://github.com/mvcisback/LogicalLens).

```# Find the point that intersects the line running
# between the origin and (0.2, 0.2).
rec = partition1.project((0.2, 0.2))  # Approximation of intersection point.
assert rec.shortest_edge < 1e-3
x = rec.center  # Can use the center of the rectangle as the projected point.

## This value is approx (0.5, 0.5)
assert abs(max(x[0] - 0.5, x[1] - 0.5)) < 1e-3

# Find the point that lexicographically maximizes the 0-axis
# and then miniminizes the 1-axis.
order = [(1, True), (0, False)]  # List of axis index and should_max tuples.
rec = partition1.project(order, lexicographic=True)
assert rec.shortest_edge < 1e-3
x = rec.center  # Can use the center of the rectangle as the projected point.

## This value is approx (0.5, 1)
assert abs(max(x[0] - 0.5, x[1] - 1)) < 1e-3```

## Intersection Strategy

By default, the `find_threshold` function uses a binary search along the diagonal (with a fixed relative tolerance) to find asub-division point. This can be overridden using the `find_intersect` argument. For example, below we change the binary search tolerance to `1e-2`.

```from typing import Tuple

from monotone_bipartition.rectangles import Rec
from monotone_bipartition.search import binsearch, SearchResultType

def find_intersect(domain: Rec, oracle) -> Tuple[SearchResultType, Rec]:
"""Returns a rectangle within the domain containing the boundary.

This rectangle will be used to update the boundary approximation
during subdivision.
"""
# eps is the relative tolerance.
result_type, rec = binsearch(domain, oracle, eps=1e-2)
return result_type, rec

partition1 = mbp.from_threshold(
func=lambda x: x[0] >= 0.5,
dim=2,
find_intersect=find_intersect,
)  # type: mbp.BiPartition```

Compute Monotone Threshold Surfaces and compute distances between surfaces.

## Releases 2

Initial Release Latest
Jan 19, 2019

## Packages 0

No packages published

•
•
•