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 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
- gem 'borel'
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
- ### Classes of Intervals
107
+ Generic Intervals
108
+ -----------------
109
+
110
+ You may use any **Comparable** class:
106
111
 
107
- You may use any comparable class
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 or 4
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 **open** and **closed**intervals
131
- * Complement and Minus operations have limited support for
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
@@ -1,3 +1,6 @@
1
1
  require 'borel/interval'
2
+
3
+ require 'borel/array'
2
4
  require 'borel/range'
3
5
  require 'borel/numeric'
6
+ require 'borel/nil_class'
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def to_interval
3
+ Interval[*self]
4
+ end
5
+ end
@@ -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{|x|
28
+ array.map(&:components).flatten.sort_by(&:inf).each do |x|
29
29
  if x.sup < x.inf
30
- # skip it
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 construction
45
- map{|x| x.extrema.uniq}
40
+ def union(other)
41
+ Interval.union(other.to_interval, self)
46
42
  end
47
43
 
48
- def simple?
49
- false
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 inspect
53
- "Interval" + construction.inspect
49
+ def complement
50
+ map{|x| x.to_interval.map(&:complement).reduce(:intersect)}.
51
+ flatten.reduce(:union)
54
52
  end
55
53
 
56
- def to_s
57
- inspect
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
- self.components == other.components
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 degenerate?
81
- all? {|x| x.degenerate?}
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 |(other)
105
- self.union other.to_interval
79
+ def degenerate?
80
+ all? &:degenerate?
106
81
  end
107
82
 
108
- [[:&, :intersect]].each do |op, meth|
109
- define_method(op) {|other|
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
- [[:~, :complement]].each do |op, meth|
115
- define_method(op) {
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
- [[:-, :minus]].each do |op, meth|
121
- define_method(op) {|other|
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 each
138
- yield(self)
139
- self
95
+ def inf
96
+ first.inf
140
97
  end
141
98
 
142
- def components
143
- [self]
99
+ def sup
100
+ last.sup
144
101
  end
145
102
 
146
- def initialize (a, b = a)
147
- if (a.respond_to?(:nan?) && a.nan? ) || (b.respond_to?(:nan?) && b.nan?)
148
- @inf, @sup = -Infinity, Infinity
103
+ def hull
104
+ if empty?
105
+ Interval[]
149
106
  else
150
- @inf, @sup = a, b
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
- def minus (other)
168
- self & ~other
169
- end
170
-
171
- def construction
172
- extrema.uniq
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
- class Interval::Multiple < Interval
193
- attr :components
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,17 @@
1
+ class Interval::Multiple < Interval
2
+ attr :components
3
+
4
+ def initialize(array)
5
+ @components = array
6
+ freeze
7
+ end
8
+
9
+ def each
10
+ components.each{|o| yield(o)}
11
+ self
12
+ end
13
+
14
+ def simple?
15
+ false
16
+ end
17
+ end
@@ -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
@@ -1,6 +1,6 @@
1
1
  module Borel
2
2
  MAJOR = 0
3
- MINOR = 2
3
+ MINOR = 3
4
4
  TINY = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join('.')
@@ -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.2.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-02-24 00:00:00.000000000 Z
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.10
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: