borel 0.2.0 → 0.3.0
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.
- data/README.md +27 -9
- data/lib/borel.rb +3 -0
- data/lib/borel/array.rb +5 -0
- data/lib/borel/interval.rb +45 -129
- data/lib/borel/interval_multiple.rb +17 -0
- data/lib/borel/interval_simple.rb +53 -0
- data/lib/borel/version.rb +1 -1
- data/spec/array_spec.rb +18 -0
- metadata +8 -3
data/README.md
CHANGED
@@ -15,13 +15,15 @@ Borelian sets are formed by enumerable union, intersection or
|
|
15
15
|
Install
|
16
16
|
-------
|
17
17
|
|
18
|
-
You may install it traditionally, for interactive sessions:
|
18
|
+
You may install it traditionally, tipically for interactive sessions:
|
19
19
|
|
20
|
-
gem install borel
|
20
|
+
$ gem install borel
|
21
21
|
|
22
22
|
Or just put this somewhere on your application's `Gemfile`
|
23
23
|
|
24
|
-
|
24
|
+
```ruby
|
25
|
+
gem 'borel'
|
26
|
+
```
|
25
27
|
|
26
28
|
Usage
|
27
29
|
-----
|
@@ -102,15 +104,29 @@ __minus__ and __-__
|
|
102
104
|
Interval[0,5] - Interval[-1,3] # -> Interval[3,5]
|
103
105
|
```
|
104
106
|
|
105
|
-
|
107
|
+
Generic Intervals
|
108
|
+
-----------------
|
109
|
+
|
110
|
+
You may use any **Comparable** class:
|
106
111
|
|
107
|
-
|
112
|
+
* String
|
108
113
|
|
109
114
|
```ruby
|
110
115
|
Interval['a','c'] ^ Interval['b','d'] # -> Interval['b','c']
|
111
116
|
Interval['a','c'] | Interval['b','d'] # -> Interval['a','d']
|
112
117
|
```
|
113
118
|
|
119
|
+
* Time
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
def t(seconds)
|
123
|
+
Time.now + seconds
|
124
|
+
end
|
125
|
+
|
126
|
+
Interval[t(1),t(5)] ^ Interval[t(3),t(7)] # -> Interval[t(3),t(5)]
|
127
|
+
Interval[t(1),t(2)] | Interval[t(3),t(4)] # -> Interval[[t(1),t(2)],[t(3),t(4)]]
|
128
|
+
```
|
129
|
+
|
114
130
|
Math Extensions
|
115
131
|
---------------
|
116
132
|
|
@@ -118,8 +134,10 @@ By requiring `borel/math_extensions` you are provided with some natural
|
|
118
134
|
math-related interval methods:
|
119
135
|
|
120
136
|
```ruby
|
137
|
+
require 'borel/math_extensions'
|
138
|
+
|
121
139
|
Interval[1,5].rand # -> Random.new.rand 1..5
|
122
|
-
Interval[1,5].width # -> 5-1
|
140
|
+
Interval[1,5].width # -> 5-1, only for simple intervals
|
123
141
|
```
|
124
142
|
|
125
143
|
It's supported only for Numeric Comparable and arithmetic supported classes
|
@@ -127,9 +145,9 @@ It's supported only for Numeric Comparable and arithmetic supported classes
|
|
127
145
|
Remarks
|
128
146
|
-------
|
129
147
|
|
130
|
-
* There is no distinction between
|
131
|
-
*
|
132
|
-
non numeric-comparable classes
|
148
|
+
* There is no distinction between _open_ and _closed_ intervals
|
149
|
+
* _complement_ and _minus_ operations, and also _Math Extensions_ have limited
|
150
|
+
support for non numeric-comparable classes
|
133
151
|
|
134
152
|
License
|
135
153
|
-------
|
data/lib/borel.rb
CHANGED
data/lib/borel/array.rb
ADDED
data/lib/borel/interval.rb
CHANGED
@@ -25,180 +25,96 @@ class Interval
|
|
25
25
|
|
26
26
|
def Interval.union(*array)
|
27
27
|
l = []
|
28
|
-
array.map(&:components).flatten.sort_by(&:inf).each
|
28
|
+
array.map(&:components).flatten.sort_by(&:inf).each do |x|
|
29
29
|
if x.sup < x.inf
|
30
|
-
|
30
|
+
next
|
31
31
|
elsif l.empty? || x.inf > l.last.sup
|
32
32
|
l <<= x
|
33
33
|
elsif x.sup > l.last.sup
|
34
34
|
l[-1] = Simple.new(l.last.inf, x.sup)
|
35
35
|
end
|
36
|
-
}
|
37
|
-
if l.size == 1
|
38
|
-
l.first
|
39
|
-
else
|
40
|
-
Multiple.new(l)
|
41
36
|
end
|
37
|
+
if l.size == 1 then l.first else Multiple.new(l) end
|
42
38
|
end
|
43
39
|
|
44
|
-
def
|
45
|
-
|
40
|
+
def union(other)
|
41
|
+
Interval.union(other.to_interval, self)
|
46
42
|
end
|
47
43
|
|
48
|
-
def
|
49
|
-
|
44
|
+
def intersect(other)
|
45
|
+
other.to_interval.map{|y| map{|x| x.intersect(y)}}.
|
46
|
+
flatten.reduce(:union) || Interval[]
|
50
47
|
end
|
51
48
|
|
52
|
-
def
|
53
|
-
|
49
|
+
def complement
|
50
|
+
map{|x| x.to_interval.map(&:complement).reduce(:intersect)}.
|
51
|
+
flatten.reduce(:union)
|
54
52
|
end
|
55
53
|
|
56
|
-
def
|
57
|
-
|
54
|
+
def minus(other)
|
55
|
+
if other.empty?
|
56
|
+
self
|
57
|
+
else
|
58
|
+
map{|x| other.to_interval.map{|y| x.minus(y)}.reduce(:intersect)}.
|
59
|
+
flatten.reduce(:union) || Interval[]
|
60
|
+
end
|
58
61
|
end
|
59
62
|
|
60
63
|
def ==(other)
|
61
|
-
|
64
|
+
construction == other.construction
|
62
65
|
end
|
63
66
|
|
64
67
|
def include?(x)
|
65
68
|
any?{|i| i.include? x}
|
66
69
|
end
|
67
70
|
|
68
|
-
def to_interval
|
69
|
-
self
|
70
|
-
end
|
71
|
-
|
72
|
-
def coerce(other)
|
73
|
-
[other.to_interval, self]
|
74
|
-
end
|
75
|
-
|
76
71
|
def empty?
|
77
72
|
components.empty?
|
78
73
|
end
|
79
74
|
|
80
|
-
def
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
def hull
|
85
|
-
if empty?
|
86
|
-
Interval[]
|
87
|
-
else
|
88
|
-
Interval[components.first.inf, components.last.sup]
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def union(other)
|
93
|
-
Interval.union(other.to_interval, self)
|
94
|
-
end
|
95
|
-
|
96
|
-
def +(other)
|
97
|
-
self | other
|
98
|
-
end
|
99
|
-
|
100
|
-
def ^(other)
|
101
|
-
self & other
|
75
|
+
def construction
|
76
|
+
map &:construction
|
102
77
|
end
|
103
78
|
|
104
|
-
def
|
105
|
-
|
79
|
+
def degenerate?
|
80
|
+
all? &:degenerate?
|
106
81
|
end
|
107
82
|
|
108
|
-
|
109
|
-
|
110
|
-
(other.to_interval.map{|y| map{|x| x.send(meth,y)}}.flatten).reduce(:|) || Interval[]
|
111
|
-
}
|
83
|
+
def to_interval
|
84
|
+
self
|
112
85
|
end
|
113
86
|
|
114
|
-
|
115
|
-
|
116
|
-
map{|x| x.to_interval.map(&meth).reduce(:&)}.flatten.reduce(:|)
|
117
|
-
}
|
87
|
+
def inspect
|
88
|
+
"Interval" + construction.inspect
|
118
89
|
end
|
119
90
|
|
120
|
-
|
121
|
-
|
122
|
-
if other.empty?
|
123
|
-
self
|
124
|
-
else
|
125
|
-
map{|x| other.to_interval.map{|y| x.send(meth,y)}.reduce(:&)}.flatten.reduce(:|) || Interval[]
|
126
|
-
end
|
127
|
-
}
|
91
|
+
def to_s
|
92
|
+
inspect
|
128
93
|
end
|
129
|
-
end
|
130
|
-
|
131
|
-
class Interval::Simple < Interval
|
132
|
-
include Enumerable
|
133
|
-
|
134
|
-
attr :inf
|
135
|
-
attr :sup
|
136
94
|
|
137
|
-
def
|
138
|
-
|
139
|
-
self
|
95
|
+
def inf
|
96
|
+
first.inf
|
140
97
|
end
|
141
98
|
|
142
|
-
def
|
143
|
-
|
99
|
+
def sup
|
100
|
+
last.sup
|
144
101
|
end
|
145
102
|
|
146
|
-
def
|
147
|
-
if
|
148
|
-
|
103
|
+
def hull
|
104
|
+
if empty?
|
105
|
+
Interval[]
|
149
106
|
else
|
150
|
-
|
107
|
+
Interval[inf, sup]
|
151
108
|
end
|
152
|
-
freeze
|
153
|
-
end
|
154
|
-
|
155
|
-
def ==(other)
|
156
|
-
[inf, sup] == [other.inf, other.sup]
|
157
|
-
end
|
158
|
-
|
159
|
-
def intersect(other)
|
160
|
-
Interval[[inf, other.inf].max, [sup, other.sup].min]
|
161
|
-
end
|
162
|
-
|
163
|
-
def complement
|
164
|
-
Interval[-Infinity,inf] | Interval[sup,Infinity]
|
165
109
|
end
|
166
110
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
end
|
174
|
-
|
175
|
-
def simple?
|
176
|
-
true
|
177
|
-
end
|
178
|
-
|
179
|
-
def include?(x)
|
180
|
-
inf <= x && x <= sup
|
181
|
-
end
|
182
|
-
|
183
|
-
def extrema
|
184
|
-
[inf, sup]
|
185
|
-
end
|
186
|
-
|
187
|
-
def degenerate?
|
188
|
-
inf == sup
|
189
|
-
end
|
111
|
+
alias_method :+, :union
|
112
|
+
alias_method :|, :union
|
113
|
+
alias_method :&, :intersect
|
114
|
+
alias_method :^, :intersect
|
115
|
+
alias_method :~, :complement
|
116
|
+
alias_method :-, :minus
|
190
117
|
end
|
191
118
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
def initialize(array)
|
196
|
-
@components = array
|
197
|
-
freeze
|
198
|
-
end
|
199
|
-
|
200
|
-
def each
|
201
|
-
components.each{|o| yield(o)}
|
202
|
-
self
|
203
|
-
end
|
204
|
-
end
|
119
|
+
require 'borel/interval_multiple'
|
120
|
+
require 'borel/interval_simple'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class Interval::Simple < Interval
|
2
|
+
attr :inf, :sup
|
3
|
+
|
4
|
+
def initialize (a, b = a)
|
5
|
+
if (a.respond_to?(:nan?) && a.nan?) || (b.respond_to?(:nan?) && b.nan?)
|
6
|
+
@inf, @sup = -Infinity, Infinity
|
7
|
+
else
|
8
|
+
@inf, @sup = a, b
|
9
|
+
end
|
10
|
+
freeze
|
11
|
+
end
|
12
|
+
|
13
|
+
def each
|
14
|
+
yield(self)
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def intersect(other)
|
19
|
+
Interval[[inf, other.inf].max, [sup, other.sup].min]
|
20
|
+
end
|
21
|
+
|
22
|
+
def complement
|
23
|
+
Interval[[-Infinity, inf], [sup, Infinity]]
|
24
|
+
end
|
25
|
+
|
26
|
+
def minus(other)
|
27
|
+
other.complement.intersect self
|
28
|
+
end
|
29
|
+
|
30
|
+
def components
|
31
|
+
[self]
|
32
|
+
end
|
33
|
+
|
34
|
+
def extrema
|
35
|
+
[inf, sup]
|
36
|
+
end
|
37
|
+
|
38
|
+
def construction
|
39
|
+
extrema.uniq
|
40
|
+
end
|
41
|
+
|
42
|
+
def include?(x)
|
43
|
+
inf <= x && x <= sup
|
44
|
+
end
|
45
|
+
|
46
|
+
def degenerate?
|
47
|
+
inf == sup
|
48
|
+
end
|
49
|
+
|
50
|
+
def simple?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
end
|
data/lib/borel/version.rb
CHANGED
data/spec/array_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'borel/interval'
|
2
|
+
require 'borel/array.rb'
|
3
|
+
|
4
|
+
describe Array do
|
5
|
+
context "#to_interval" do
|
6
|
+
specify "[] -> Interval[]" do
|
7
|
+
[].to_interval.should eq Interval[]
|
8
|
+
end
|
9
|
+
|
10
|
+
specify "[1,2] -> Interval[1,2]" do
|
11
|
+
[1,2].to_interval.should eq Interval[1,2]
|
12
|
+
end
|
13
|
+
|
14
|
+
specify "[[1,2],[3,4]] -> Interval[[1,2],[3,4]]" do
|
15
|
+
[[1,2],[3,4]].to_interval.should eq Interval[[1,2],[3,4]]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: borel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-09 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'Borel sets are made of enumerable union and intersection of
|
15
15
|
|
@@ -31,8 +31,11 @@ files:
|
|
31
31
|
- Rakefile
|
32
32
|
- borel.gemspec
|
33
33
|
- lib/borel.rb
|
34
|
+
- lib/borel/array.rb
|
34
35
|
- lib/borel/errors.rb
|
35
36
|
- lib/borel/interval.rb
|
37
|
+
- lib/borel/interval_multiple.rb
|
38
|
+
- lib/borel/interval_simple.rb
|
36
39
|
- lib/borel/math_extensions.rb
|
37
40
|
- lib/borel/math_extensions/interval_arithmetic.rb
|
38
41
|
- lib/borel/math_extensions/randomizable.rb
|
@@ -40,6 +43,7 @@ files:
|
|
40
43
|
- lib/borel/numeric.rb
|
41
44
|
- lib/borel/range.rb
|
42
45
|
- lib/borel/version.rb
|
46
|
+
- spec/array_spec.rb
|
43
47
|
- spec/interval_spec.rb
|
44
48
|
- spec/math_extensions/interval_arithmetic_spec.rb
|
45
49
|
- spec/math_extensions/randomizable_spec.rb
|
@@ -69,8 +73,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
73
|
version: 1.3.6
|
70
74
|
requirements: []
|
71
75
|
rubyforge_project: borel
|
72
|
-
rubygems_version: 1.8.
|
76
|
+
rubygems_version: 1.8.17
|
73
77
|
signing_key:
|
74
78
|
specification_version: 3
|
75
79
|
summary: Generic ordered set's operations
|
76
80
|
test_files: []
|
81
|
+
has_rdoc:
|