borel 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|