interval_notation 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/TODO.md +5 -1
- data/interval_notation.gemspec +1 -0
- data/lib/interval_notation/basic_intervals.rb +11 -0
- data/lib/interval_notation/combiners.rb +47 -1
- data/lib/interval_notation/interval_set.rb +2 -2
- data/lib/interval_notation/operations.rb +3 -46
- data/lib/interval_notation/version.rb +1 -1
- data/lib/interval_notation.rb +10 -2
- data/spec/interval_notation_spec.rb +7 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48b23bd79ddea327e0d8da11597e387ef1df690a
|
4
|
+
data.tar.gz: 6911357f55445730fcf793991412b74830ac510f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca29426c646771b4cc577d64d2ce15d5856daf22f84bba9aa8b2be2912f047881041d8ef92926bb31989e6101de8f8935f6a1b13bd3dbedd9a94478b1cb57100
|
7
|
+
data.tar.gz: 1c7571f48cf241d8e8876070e1a9417421cb145b1aa3bf1e9289d90bb7de8b5fb27bf1f3af9163e9675fd45fe6d4307e9b34095984fed8c6d9bf64baf843ce9f
|
data/TODO.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
1
|
* Write benchmarks
|
2
|
-
* Optimize `#closure
|
2
|
+
* Optimize `#closure`, `#complement`
|
3
3
|
* Visualization in console and in IRuby (how to scale into 80-symbol or 1200px screen); SVG; TeX formatters
|
4
|
+
* Remove old git history related to mTOR project
|
5
|
+
* What about working with simgle intervals (their, length, relations etc)?
|
6
|
+
* (?) Make it possible to use intervals with non-numeric objects to be possible to use math expressions as interval boundaries
|
7
|
+
* May be we should check that boundary is an actual number, not a NaN
|
data/interval_notation.gemspec
CHANGED
@@ -38,6 +38,9 @@ module IntervalNotation
|
|
38
38
|
def from_finite?; from.to_f.finite?; end
|
39
39
|
def to_finite?; to.to_f.finite?; end
|
40
40
|
def finite?; from_finite? && to_finite?; end
|
41
|
+
def from_infinite?; from.to_f.infinite?; end
|
42
|
+
def to_infinite?; to.to_f.infinite?; end
|
43
|
+
def infinite?; from_infinite? || to_infinite?; end
|
41
44
|
|
42
45
|
def from_to_s; from_finite? ? from : MINUS_INFINITY_SYMBOL; end
|
43
46
|
def to_to_s; to_finite? ? to : PLUS_INFINITY_SYMBOL; end
|
@@ -85,6 +88,7 @@ module IntervalNotation
|
|
85
88
|
def include_to?; true; end
|
86
89
|
|
87
90
|
def to_finite?; true; end
|
91
|
+
def to_infinite?; false; end
|
88
92
|
def to_to_s; to; end
|
89
93
|
|
90
94
|
def closure
|
@@ -116,6 +120,7 @@ module IntervalNotation
|
|
116
120
|
def include_to?; false; end
|
117
121
|
|
118
122
|
def from_finite?; true; end
|
123
|
+
def from_infinite?; false; end
|
119
124
|
def from_to_s; from; end
|
120
125
|
|
121
126
|
def closure
|
@@ -149,6 +154,9 @@ module IntervalNotation
|
|
149
154
|
def from_finite?; true; end
|
150
155
|
def to_finite?; true; end
|
151
156
|
def finite?; true; end
|
157
|
+
def from_infinite?; false; end
|
158
|
+
def to_infinite?; false; end
|
159
|
+
def infinite?; false; end
|
152
160
|
def from_to_s; from; end
|
153
161
|
def to_to_s; to; end
|
154
162
|
|
@@ -177,6 +185,9 @@ module IntervalNotation
|
|
177
185
|
def from_finite?; true; end
|
178
186
|
def to_finite?; true; end
|
179
187
|
def finite?; true; end
|
188
|
+
def from_infinite?; false; end
|
189
|
+
def to_infinite?; false; end
|
190
|
+
def infinite?; false; end
|
180
191
|
|
181
192
|
def length; 0; end
|
182
193
|
def to_s; "{#{@value}}"; end
|
@@ -4,7 +4,10 @@ module IntervalNotation
|
|
4
4
|
# Combiner is an internal helper class for combining interval sets using sweep line.
|
5
5
|
# It starts moving from -∞ to +∞ and keep which intervals are crossed by sweep line.
|
6
6
|
# Class helps to effectively recalculate number of crossed intervals without rechecking
|
7
|
-
# all intervals each time, and dramatically reduces speed of operations on large number of intervals
|
7
|
+
# all intervals each time, and dramatically reduces speed of operations on large number of intervals.
|
8
|
+
#
|
9
|
+
# Usage example:
|
10
|
+
# UnionCombiner.new(3).combine([interval_1, interval_2, interval_3])
|
8
11
|
class Combiner
|
9
12
|
attr_reader :num_interval_sets
|
10
13
|
attr_reader :previous_state
|
@@ -15,6 +18,49 @@ module IntervalNotation
|
|
15
18
|
@num_intervals_inside = 0 # number of intervals, we are inside (for efficiency)
|
16
19
|
end
|
17
20
|
|
21
|
+
# Combines intervals according on an information given by #state/#include_last_point functions
|
22
|
+
# which tell whether current section or point should be included to a new interval.
|
23
|
+
def combine(interval_sets)
|
24
|
+
points = interval_sets.each_with_index.flat_map{|interval_set, interval_set_index|
|
25
|
+
interval_set.intervals.flat_map{|interval|
|
26
|
+
interval.interval_boundaries(interval_set_index)
|
27
|
+
}
|
28
|
+
}.sort_by(&:value)
|
29
|
+
|
30
|
+
intervals = []
|
31
|
+
|
32
|
+
incl_from = nil
|
33
|
+
from = nil
|
34
|
+
|
35
|
+
points.chunk(&:value).each do |point_value, points_on_place|
|
36
|
+
pass(points_on_place)
|
37
|
+
|
38
|
+
if previous_state
|
39
|
+
if state
|
40
|
+
unless include_last_point
|
41
|
+
intervals << BasicIntervals.interval_by_boundary_inclusion(incl_from, from, false, point_value)
|
42
|
+
incl_from = false
|
43
|
+
from = point_value
|
44
|
+
end
|
45
|
+
else
|
46
|
+
to = point_value
|
47
|
+
incl_to = include_last_point
|
48
|
+
intervals << BasicIntervals.interval_by_boundary_inclusion(incl_from, from, incl_to, to)
|
49
|
+
from = nil # easier to find an error (but not necessary code)
|
50
|
+
incl_from = nil # ditto
|
51
|
+
end
|
52
|
+
else
|
53
|
+
if state
|
54
|
+
from = point_value
|
55
|
+
incl_from = include_last_point
|
56
|
+
else
|
57
|
+
intervals << BasicIntervals::Point.new(point_value) if include_last_point
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
IntervalSet.new_unsafe(intervals)
|
62
|
+
end
|
63
|
+
|
18
64
|
# When sweep line pass several interval boundaries, +#pass+ should get all those points at once
|
19
65
|
# and update status of crossing sweep line.
|
20
66
|
# It also stores previous state, because it's actively used downstream.
|
@@ -220,12 +220,12 @@ module IntervalNotation
|
|
220
220
|
|
221
221
|
# Difference between an interval set and another interval set +other+. Alias: +-+
|
222
222
|
def subtract(other)
|
223
|
-
|
223
|
+
SubtractCombiner.new.combine([self, other])
|
224
224
|
end
|
225
225
|
|
226
226
|
# Symmetric difference between an interval set and another interval set +other+. Alias: +^+
|
227
227
|
def symmetric_difference(other)
|
228
|
-
|
228
|
+
SymmetricDifferenceCombiner.new.combine([self, other])
|
229
229
|
end
|
230
230
|
|
231
231
|
# Complement of an interval set in R. Alias: +~+
|
@@ -4,59 +4,16 @@ require_relative 'combiners'
|
|
4
4
|
|
5
5
|
module IntervalNotation
|
6
6
|
module Operations
|
7
|
-
# Internal method which combines intervals according to an algorithm given by a combiner.
|
8
|
-
# Combiner tells whether current section or point should be included to a new interval.
|
9
|
-
def combine(interval_sets, combiner)
|
10
|
-
points = interval_sets.each_with_index.flat_map{|interval_set, interval_set_index|
|
11
|
-
interval_set.intervals.flat_map{|interval|
|
12
|
-
interval.interval_boundaries(interval_set_index)
|
13
|
-
}
|
14
|
-
}.sort_by(&:value)
|
15
|
-
|
16
|
-
intervals = []
|
17
|
-
|
18
|
-
incl_from = nil
|
19
|
-
from = nil
|
20
|
-
|
21
|
-
points.chunk(&:value).each do |point_value, points_on_place|
|
22
|
-
combiner.pass(points_on_place)
|
23
|
-
|
24
|
-
if combiner.previous_state
|
25
|
-
if combiner.state
|
26
|
-
unless combiner.include_last_point
|
27
|
-
intervals << BasicIntervals.interval_by_boundary_inclusion(incl_from, from, false, point_value)
|
28
|
-
incl_from = false
|
29
|
-
from = point_value
|
30
|
-
end
|
31
|
-
else
|
32
|
-
to = point_value
|
33
|
-
incl_to = combiner.include_last_point
|
34
|
-
intervals << BasicIntervals.interval_by_boundary_inclusion(incl_from, from, incl_to, to)
|
35
|
-
from = nil # easier to find an error (but not necessary code)
|
36
|
-
incl_from = nil # ditto
|
37
|
-
end
|
38
|
-
else
|
39
|
-
if combiner.state
|
40
|
-
from = point_value
|
41
|
-
incl_from = combiner.include_last_point
|
42
|
-
else
|
43
|
-
intervals << BasicIntervals::Point.new(point_value) if combiner.include_last_point
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
IntervalSet.new_unsafe(intervals)
|
48
|
-
end
|
49
|
-
|
50
7
|
# Union of multiple intervals.
|
51
8
|
def union(intervals)
|
52
|
-
|
9
|
+
UnionCombiner.new(intervals.size).combine(intervals)
|
53
10
|
end
|
54
11
|
|
55
12
|
# Intersection of multiple intervals
|
56
13
|
def intersection(intervals)
|
57
|
-
|
14
|
+
IntersectCombiner.new(intervals.size).combine(intervals)
|
58
15
|
end
|
59
16
|
|
60
|
-
module_function :
|
17
|
+
module_function :union, :intersection
|
61
18
|
end
|
62
19
|
end
|
data/lib/interval_notation.rb
CHANGED
@@ -38,7 +38,11 @@ module IntervalNotation
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def cc(from, to)
|
41
|
-
|
41
|
+
if from != to
|
42
|
+
IntervalSet.new_unsafe( [BasicIntervals::ClosedClosedInterval.new(from, to)] )
|
43
|
+
else
|
44
|
+
IntervalSet.new_unsafe( [BasicIntervals::Point.new(from)] )
|
45
|
+
end
|
42
46
|
end
|
43
47
|
|
44
48
|
def pt(value)
|
@@ -86,7 +90,11 @@ module IntervalNotation
|
|
86
90
|
end
|
87
91
|
|
88
92
|
def closed_closed(from, to)
|
89
|
-
|
93
|
+
if from != to
|
94
|
+
IntervalSet.new_unsafe( [BasicIntervals::ClosedClosedInterval.new(from, to)] )
|
95
|
+
else
|
96
|
+
IntervalSet.new_unsafe( [BasicIntervals::Point.new(from)] )
|
97
|
+
end
|
90
98
|
end
|
91
99
|
|
92
100
|
def point(value)
|
@@ -59,6 +59,13 @@ describe IntervalNotation do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
describe 'closed_closed helper' do
|
63
|
+
specify 'closed_closed(x,x) returns point(x)' do
|
64
|
+
expect(cc(3,3)).to eq(pt(3))
|
65
|
+
expect(IntervalNotation::Syntax::Long.closed_closed(3,3)).to eq(IntervalNotation::Syntax::Long.point(3))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
62
69
|
describe '.to_s' do
|
63
70
|
{
|
64
71
|
Empty => '∅',
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interval_notation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Vorontsov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.1.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.1.0
|
41
55
|
description: interval_notation provides methods to create intervals with open or closed
|
42
56
|
boundaries or singular points, unite and intersect them, check inclusion into an
|
43
57
|
interval and so on.
|
@@ -85,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
99
|
version: '0'
|
86
100
|
requirements: []
|
87
101
|
rubyforge_project:
|
88
|
-
rubygems_version: 2.4.
|
102
|
+
rubygems_version: 2.4.6
|
89
103
|
signing_key:
|
90
104
|
specification_version: 4
|
91
105
|
summary: interval_notation allows one to work with 1D-intervals.
|