Python Intervals Arithmetic
Project description
Interval arithmetic for Python
Provide interval arithmetic for Python 3.4+.
Features
- Support intervals of any (comparable) objects.
- Closed or open, finite or infinite intervals.
- Union of intervals out of the box.
- Automatic simplification of (union of) intervals.
- Support comparison, intersection, union, complement, difference and containment.
Installation
You can use pip
to install this library:
pip install python-intervals
This will install the latest available version from pypi branch. Prereleases are available from the master branch.
Usage
Assuming this library is imported using import intervals as I
, intervals can be easily created using one of the following functions:
I.open(1, 2)
corresponds to(1,2)
;I.closed(1, 2)
corresponds to[1,2]
;I.openclosed(1, 2)
corresponds to(1,2]
;I.closedopen(1, 2)
corresponds to[1,2)
;I.singleton(1)
corresponds to[1,1]
;I.empty()
corresponds to the empty interval()
.
>>> I.closed(0, 3)
[0,3]
>>> I.openclosed('a', 'z')
('a','z']
>>> I.singleton(2.5)
[2.5]
>>> I.empty()
()
Infinite and semi-infinite intervals are supported using I.inf
and -I.inf
as upper or lower bounds. These two objects support comparison with any other object.
>>> I.openclosed(-I.inf, 0)
(-inf,0]
>>> I.closed(-I.inf, I.inf) # Automatically converted
(-inf,+inf)
>>> I.inf > 'a', I.inf > 0, I.inf > True
(True, True, True)
Intervals created with this library are Interval
instances.
An Interval
object is a disjunction of AtomicInterval
.
An AtomicInterval
represents a single interval (e.g. [1,2])
while an Interval
represents union of intervals (e.g. [1,2] | [3,4]
).
For convenience, Interval
are automatically simplified:
>>> I.closed(0, 2) | I.closed(2, 4)
[0,4]
>>> I.closed(1, 2) | I.closed(3, 4) | I.closed(2, 3)
[1,4]
>>> I.closed(1, 2) | I.openclosed(2, 3) | I.closedopen(5, 5)
[1,3]
Both classes support interval arithmetic:
x.intersection(other)
orx & other
returns the intersection of two intervals.>>> I.closed(0, 2) & I.closed(1, 3) [1,2] >>> I.closed(0, 4) & I.open(2, 3) (2,3) >>> I.closed(0, 2) & I.closed(2, 3) [2] >>> I.closed(0, 2) & I.closed(3, 4) ()
x.union(other)
orx | other
returns the union of two intervals.>>> I.closed(0, 1) | I.closed(1, 2) [0,2] >>> I.closed(0, 1) | I.closed(2, 3) [0,1] | [2,3]
x.complement(other)
or~x
returns the complement of the interval.>>> ~I.closed(0, 1) (-inf,0) | (1,+inf) >>> ~(I.open(-I.inf, 0) | I.open(1, I.inf)) [0,1] >>> ~I.open(-I.inf, I.inf) ()
x.difference(other)
orx - other
returns the difference betweenx
andother
.>>> I.closed(0,2) - I.closed(1,2) [0,1) >>> I.closed(0, 4) - I.closed(1, 2) [0,1) | (2,4]
x == other
checks for interval equality.>>> I.closed(0, 2) == I.closed(0, 1) | I.closed(1, 2) True
x.is_empty()
tests if the interval is empty.>>> I.closed(0, 1).is_empty() False >>> I.closed(0, 0).is_empty() False >>> I.openclosed(0, 0).is_empty() True >>> I.empty().is_empty() True
x.overlaps(other)
test if there is an overlap between two intervals. This method accepts apermissive
parameter which defaults toFalse
. IfTrue
, it considers that [1, 2) and [2, 3] have an overlap on 2 (but not [1, 2) and (2, 3]).>>> I.closed(1, 2).overlaps(I.closed(2, 3)) True >>> I.closed(1, 2).overlaps(I.open(2, 3)) False >>> I.closed(1, 2).overlaps(I.open(2, 3), permissive=True) True
x.contains(other)
orother in x
returns True if given item is contained in the interval. SupportInterval
,AtomicInterval
and arbitrary comparable values.>>> 2 in I.closed(0, 2) True >>> 2 in I.open(0, 2) False >> I.open(0, 1) in I.closed(0, 2) True
Moreover, both Interval
and AtomicInterval
are comparable using ==, !=, <, <=, >
and >=
.
The comparison is based on the full interval, not only on one bound or the other:
>>> I.closed(0, 2) < I.closed(3, 4)
True
>>> I.closed(0, 2) < I.closed(2, 3)
False
>>> I.closed(0, 2) <= I.closed(2, 3)
False
>>> I.closed(0, 2) | I.closed(5, 6) <= I.closed(3, 4)
False
Additionally, an Interval
provides:
x.enclosure()
returns the smallest interval that includes the current one.>>> (I.closed(0, 1) | I.closed(2, 3)).enclosure() [0,3]
x.is_atomic()
evaluates toTrue
if interval is the union of a single (possibly empty) atomic interval.>>> I.closed(0, 2).is_atomic(), (I.closed(0, 1) | I.closed(2, 3)).is_atomic() (True, False)
x.to_atomic()
returns the smallestAtomicInterval
that contains the interval(s). Is equivalent tox.enclosure()
but returns anAtomicInterval
instead of anInterval
object.- Iteration protocol for the underlying set of
AtomicInterval
, sorted by their lower bound value.
The left and right boundaries, and the lower and upper bound of an AtomicInterval
can be respectively accessed with its left
, right
, lower
and upper
attribute.
>>> [(i.left, i.lower, i.upper, i.right) for i in I.open(2, 3) | I.closed(0, 1)]
[(True, 0, 1, True), (False, 2, 3, False)]
Contributions
Contributions are very welcome! Feel free to report bugs or suggest new features using GitHub issues and/or pull requests.
This library was inspired by pyinter.
Licence
LGPLv3 - GNU Lesser General Public License, version 3
Changelog
1.1.0 (2018-04-04)
- Both
AtomicInterval
andInterval
are fully comparable. - Add
singleton(x)
to create a singleton interval [x]. - Add
empty()
to create an empty interval. - Add
Interval.enclosure()
that returns the smallest interval that includes the current one. - Interval simplification is in O(n) instead of O(n*m).
AtomicInterval
in anInterval
are sorted by lower bound.
1.0.4 (2018-04-03)
- All operations of
AtomicInterval
(except overlaps) acceptInterval
. - Raise
TypeError
instead ofValueError
if type is not supported (coherent withNotImplemented
).
1.0.3 (2018-04-03)
- Initial working release on PyPi.
1.0.0 (2018-04-03)
- Initial release.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for python_intervals-1.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d28905afbe05b2ca9686051450a39064168f611c817aff615c8d6af670bb58f8 |
|
MD5 | 0826202814785d236887a66aee234498 |
|
BLAKE2b-256 | 9d98d78713703fe7db791d64086b191fd505920351796b3b2c54c0f039917784 |