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 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: