View Source Interval (Interval v0.1.1)

An interval represents the points between two endpoints.

The interval can be empty. The empty interval is never contained in any other interval, and contains itself no points.

It can also be left and/or right unbounded, in which case it contains all points in the unbounded direction. A fully unbounded interval contains all other intervals, except the empty interval.

Link to this section Summary

Types

t()

The Interval struct, representing all points between two endpoints.

Functions

Is the interval a adjacent to b, to the left of b.

Is the interval a adjacent to b, to the right of b.

Does a contain b?

Is the interval empty?

Is the interval left-inclusive?

Is the interval right-inclusive?

Compute the intersection between a and b.

Create a new unbounded interval

Normalize an Interval struct

Does a overlap with b?

Create a new Interval containing a single point.

Is a strictly left of b.

Is a strictly right of b.

Check if the interval is left-unbounded.

Check if the interval is right-unbounded.

Computes the union of a and b.

Link to this section Types

@type t() :: %Interval{
  left: :empty | :unbounded | Interval.Endpoint.t(),
  right: :empty | :unbounded | Interval.Endpoint.t()
}

The Interval struct, representing all points between two endpoints.

The struct has two fields: left and right, representing the left (lower) and right (upper) points in the interval.

The endpoints are stored as an Interval.Endpoint.t/0 or the atom :unbounded.

A special case exists for the empty interval, which is represented by both left and right being set to the atom :empty

Link to this section Functions

@spec adjacent_left_of?(t(), t()) :: boolean()

Is the interval a adjacent to b, to the left of b.

a is adjacent to b left of b, if a and b do not overlap, and there are no points between a.right and b.left.

a: [---)
b:     [---)
r: true

a: [---]
b:     [---]
r: false (overlaps)

a: (---)
b:        (---)
r: false (points exist between a.right and b.left)

examples

Examples

iex> adjacent_left_of?(new(left: 1, right: 2), new(left: 2, right: 3))
true

iex> adjacent_left_of?(new(left: 1, right: 3), new(left: 2, right: 4))
false

iex> adjacent_left_of?(new(left: 3, right: 4), new(left: 1, right: 2))
false

iex> adjacent_left_of?(new(right: 2, bounds: "[]"), new(left: 3))
true
Link to this function

adjacent_right_of?(a, b)

View Source
@spec adjacent_right_of?(t(), t()) :: boolean()

Is the interval a adjacent to b, to the right of b.

a is adjacent to b right of b, if a and b do not overlap, and there are no points between a.left and b.right.

a:     [---)
b: [---)
r: true

a:     [---)
b: [---]
r: false (overlaps)

a:        (---)
b: (---)
r: false (points exist between a.left and b.right)

examples

Examples

iex> adjacent_right_of?(new(left: 2, right: 3), new(left: 1, right: 2))
true

iex> adjacent_right_of?(new(left: 1, right: 3), new(left: 2, right: 4))
false

iex> adjacent_right_of?(new(left: 1, right: 2), new(left: 3, right: 4))
false

iex> adjacent_right_of?(new(left: 3), new(right: 2, bounds: "]"))
true
@spec contains?(t(), t()) :: boolean()

Does a contain b?

a contains b of all points in b is also in a.

For an interval a to contain an interval b, all points in b must be contained in a:

a: [-------]
b:   [---]
r: true

a: [---]
b: [---]
r: true

a: [---]
b: (---)
r: true

a: (---)
b: [---]
r: false

a:   [---]
b: [-------]
r: false

This means that a.left is less than b.left (or unbounded), and a.right is greater than b.right (or unbounded)

If a and b's point match, then b is "in" a if a and b share bound types.

E.g. if a.left and b.left matches, then a contains b if both a and b's left is inclusive or exclusive.

If either of b endpoints are unbounded, then a only contains b if the corresponding endpoint in a is also unbounded.

examples

Examples

iex> contains?(new(left: 1, right: 2), new(left: 1, right: 2))
true

iex> contains?(new(left: 1, right: 3), new(left: 2, right: 3))
true

iex> contains?(new(left: 2, right: 3), new(left: 1, right: 4))
false

iex> contains?(new(left: 1, right: 3), new(left: 1, right: 2))
true

iex> contains?(new(left: 1, right: 2, bounds: "()"), new(left: 1, right: 3))
false

iex> contains?(new(right: 1), new(left: 0, right: 1))
true

Is the interval empty?

An empty interval is an interval that represents no points. Any interval interval containing no points is considered empty.

examples

Examples

iex> empty?(new(left: 0, right: 0))
true

iex> empty?(single(1.0))
false

iex> empty?(new(left: 1, right: 2))
false
Link to this function

from_endpoints(left, right)

View Source
Link to this function

inclusive_left?(interval)

View Source

Is the interval left-inclusive?

The interval is left-inclusive if the left endpoint value is included in the interval.

Note

Discrete intervals (like integers and dates) are always normalized to be left-inclusive right-exclusive ([)) which this function reflects.

iex> inclusive_left?(new(left: 1.0, right: 2.0, bounds: "[]"))
true

iex> inclusive_left?(new(left: 1.0, right: 2.0, bounds: "[)"))
true

iex> inclusive_left?(new(left: 1.0, right: 2.0, bounds: "()"))
false
Link to this function

inclusive_right?(interval)

View Source

Is the interval right-inclusive?

The interval is right-inclusive if the right endpoint value is included in the interval.

Note

Discrete intervals (like integers and dates) are always normalized to be left-inclusive right-exclusive ([)) which this function reflects.

iex> inclusive_right?(new(left: 1.0, right: 2.0, bounds: "[]"))
true

iex> inclusive_right?(new(left: 1.0, right: 2.0, bounds: "[)"))
false

iex> inclusive_right?(new(left: 1.0, right: 2.0, bounds: "()"))
false

Compute the intersection between a and b.

The intersection contains all of the points that are both in a and b.

If either a or b are empty, the returned interval will be empty.

a: [----]
b:    [----]
r:    [-]

a: (----)
b:    (----)
r:    (-)

a: [----)
b:    [----)
r:    [-)

examples

Examples:

Discrete:

a: [----)
b:    [----)
c:    [-)

iex> intersection(new(left: 1, right: 3), new(left: 2, right: 4))
new(left: 2, right: 3)

Continuous:

a: [----)
b:    [----)
c:    [-)

iex> intersection(new(left: 1.0, right: 3.0), new(left: 2.0, right: 4.0))
new(left: 2.0, right: 3.0)

a: (----)
b:    (----)
c:    (-)

iex> intersection(
...>   new(left: 1.0, right: 3.0, bounds: "()"),
...>   new(left: 2.0, right: 4.0, bounds: "()")
...> )
new(left: 2.0, right: 3.0, bounds: "()")

Create a new unbounded interval

Normalize an Interval struct

@spec overlaps?(t(), t()) :: boolean()

Does a overlap with b?

a overlaps with b if any point in a is also in b.

a: [---)
b:   [---)
r: true

a: [---)
b:     [---)
r: false

a: [---]
b:     [---]
r: true

a: (---)
b:     (---)
r: false

a: [---)
b:        [---)
r: false

examples

Examples

[--a--)
    [--b--)

iex> overlaps?(new(left: 1, right: 3), new(left: 2, right: 4))
true


[--a--)
      [--b--)

iex> overlaps?(new(left: 1, right: 3), new(left: 3, right: 5))
false


[--a--]
      [--b--]

iex> overlaps?(new(left: 1, right: 3), new(left: 2, right: 4))
true


(--a--)
      (--b--)

iex> overlaps?(new(left: 1, right: 3), new(left: 3, right: 5))
false


[--a--)
         [--b--)

iex> overlaps?(new(left: 1, right: 2), new(left: 3, right: 4))
false

Create a new Interval containing a single point.

@spec strictly_left_of?(t(), t()) :: boolean()

Is a strictly left of b.

a is strictly left of b if no point in a is in b, and all points in a is left (<) of all points in b.

examples

Examples

a: [---)
b:     [---)
r: true

a: [---)
b:        [---)
r: true

a: [---)
b:    [---)
r: false (overlaps)

iex> strictly_left_of?(new(left: 1, right: 2), new(left: 3, right: 4))
true

iex> strictly_left_of?(new(left: 1, right: 3), new(left: 2, right: 4))
false

iex> strictly_left_of?(new(left: 3, right: 4), new(left: 1, right: 2))
false
Link to this function

strictly_right_of?(a, b)

View Source
@spec strictly_right_of?(t(), t()) :: boolean()

Is a strictly right of b.

a is strictly right of b if no point in a is in b, and all points in a is right (>) of all points in b.

examples

Examples

a:     [---)
b: [---)
r: true

a:        [---)
b: [---)
r: true

a:    [---)
b: [---)
r: false (overlaps)

iex> strictly_right_of?(new(left: 1, right: 2), new(left: 3, right: 4))
false

iex> strictly_right_of?(new(left: 1, right: 3), new(left: 2, right: 4))
false

iex> strictly_right_of?(new(left: 3, right: 4), new(left: 1, right: 2))
true
Link to this function

unbounded_left?(interval)

View Source

Check if the interval is left-unbounded.

The interval is left-unbounded if all points left of the right bound is included in this interval.

examples

Examples

iex> unbounded_left?(new())
true

iex> unbounded_left?(new(right: 2))
true

iex> unbounded_left?(new(left: 1, right: 2))
false
Link to this function

unbounded_right?(interval)

View Source

Check if the interval is right-unbounded.

The interval is right-unbounded if all points right of the left bound is included in this interval.

examples

Examples

iex> unbounded_right?(new(right: 1))
false

iex> unbounded_right?(new())
true

iex> unbounded_right?(new(left: 1))
true

Computes the union of a and b.

The union contains all of the points that are either in a or b.

If either a or b are empty, the returned interval will be empty.

a: [---)
b:   [---)
r: [-----)

examples

Examples

[--A--)
    [--B--)
[----C----)

iex> union(new(left: 1, right: 3), new(left: 2, right: 4))
new(left: 1, right: 4)


[-A-)
    [-B-)
[---C---)

iex> union(new(left: 1, right: 2), new(left: 2, right: 3))
new(left: 1, right: 3)

iex> union(new(left: 1, right: 2), new(left: 3, right: 4))
new(left: 0, right: 0)