borel 0.3.2 → 0.3.3

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/Gemfile CHANGED
@@ -3,6 +3,7 @@ source "http://www.rubygems.org"
3
3
  gemspec
4
4
 
5
5
  group :development do
6
+ gem 'yard', '~> 0.7.5'
6
7
  gem 'rspec', '~> 2.8.0'
7
8
  gem 'guard', '~> 1.0.0'
8
9
  end
data/Guardfile CHANGED
@@ -3,4 +3,3 @@ guard 'rspec', :version => 2 do
3
3
  watch(%r{^lib/borel/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
4
  watch('spec/spec_helper.rb') { "spec" }
5
5
  end
6
-
@@ -7,12 +7,12 @@ Gem::Specification.new do |s|
7
7
  s.authors = ["Amadeus Folego"]
8
8
  s.email = ["amadeusfolego@gmail.com"]
9
9
  s.homepage = "http://github.com/badosu/borel"
10
- s.summary = "Generic ordered set's operations"
10
+ s.summary = "Interval operation on Comparable classes"
11
11
  s.description = "Borel sets are made of enumerable union and intersection of
12
- intervals. Borel performs regular operations on any interval of any
12
+ intervals. Borel performs regular operations on intervals of any
13
13
  Comparable class."
14
14
  s.rubyforge_project = s.name
15
- s.required_ruby_version = ">= 1.9.3"
15
+ s.required_ruby_version = ">= 1.9.2"
16
16
  s.required_rubygems_version = ">= 1.3.6"
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.require_path = 'lib'
@@ -1,4 +1,8 @@
1
+ # Extends {#to_interval} for the {Array} class
1
2
  class Array
3
+
4
+ # Initializes an interval with the calling array as argument
5
+ # @return [Interval]
2
6
  def to_interval
3
7
  Interval[*self]
4
8
  end
@@ -1,4 +1,5 @@
1
1
  module Borel
2
+ # Raised when an interval is not properly initialized
2
3
  class Construction < ArgumentError
3
4
  def initialize(array)
4
5
  super(
@@ -8,24 +9,30 @@ module Borel
8
9
  end
9
10
  end
10
11
 
12
+ # Raised when a non-degenerate interval calls a method supported only for
13
+ # degenerate intervals
11
14
  class NonDegenerate < ArgumentError
12
15
  def initialize(i)
13
16
  super("#{i.inspect} is not degenerate.")
14
17
  end
15
18
  end
16
19
 
20
+ # Raised when a non simple interval calls a method supported only for simple
21
+ # intervals
17
22
  class NonSimple < ArgumentError
18
23
  def initialize(i)
19
24
  super("#{i.inspect} is not simple.")
20
25
  end
21
26
  end
22
27
 
28
+ # Raised when a method is not supported for empty intervals
23
29
  class EmptyInterval < ArgumentError
24
30
  def initialize
25
31
  super("The interval is empty.")
26
32
  end
27
33
  end
28
34
 
35
+ # Raised when the {Range#to_interval} is not called properly
29
36
  class OpenRight < ArgumentError
30
37
  def initialize(range)
31
38
  super(
@@ -1,10 +1,13 @@
1
1
  require 'borel/errors'
2
2
 
3
+ # Exposes infinity for initializing unbounded intervals
3
4
  Infinity = 1/0.0
4
5
 
6
+ # Retains all non-specific Interval logic
5
7
  class Interval
6
8
  include Enumerable
7
9
 
10
+ # @return [Interval]
8
11
  def self.[](*array)
9
12
  union(*
10
13
  if array.empty?
@@ -22,39 +25,45 @@ class Interval
22
25
  raise
23
26
  end
24
27
 
28
+ # @return [Interval]
25
29
  def self.union(*array)
26
- l = []
27
- array.map(&:components).flatten.sort_by(&:inf).each do |x|
28
- if x.sup < x.inf
30
+ intervals = []
31
+ array.map(&:components).flatten.sort_by(&:inf).each do |component|
32
+ if component.sup < component.inf
29
33
  next
30
- elsif l.empty? || x.inf > l.last.sup
31
- l <<= x
32
- elsif x.sup > l.last.sup
33
- l[-1] = Simple.new(l.last.inf, x.sup)
34
+ elsif intervals.empty? || component.inf > intervals.last.sup
35
+ intervals <<= component
36
+ elsif component.sup > intervals.last.sup
37
+ intervals[-1] = Simple.new(intervals.last.inf, component.sup)
34
38
  end
35
39
  end
36
- if l.size == 1 then l.first else Multiple.new(l) end
40
+ intervals.size == 1 ? intervals.first : Multiple.new(intervals)
37
41
  end
38
42
 
43
+ # @return [Interval]
39
44
  def union(other)
40
45
  Interval.union(other.to_interval, self)
41
46
  end
42
47
 
48
+ # @return [Interval]
43
49
  def intersect(other)
44
50
  other.to_interval.map{|y| map{|x| x.intersect(y)}}.
45
51
  flatten.reduce(:union) || Interval[]
46
52
  end
47
53
 
54
+ # @return [Interval]
48
55
  def complement
49
56
  map{|x| x.to_interval.map(&:complement).reduce(:intersect)}.
50
57
  flatten.reduce(:union)
51
58
  end
52
59
 
60
+ # @return [Interval]
53
61
  def intersect(other)
54
62
  other.to_interval.map{|y| map{|x| x.intersect(y)}}.
55
63
  flatten.reduce(:union) || Interval[]
56
64
  end
57
65
 
66
+ # @return [Interval]
58
67
  def minus(other)
59
68
  if other.empty?
60
69
  self
@@ -64,32 +73,34 @@ class Interval
64
73
  end
65
74
  end
66
75
 
76
+ # @return [Boolean]
67
77
  def ==(other)
68
78
  construction == other.construction
69
79
  end
70
80
 
81
+ # @return [Boolean]
71
82
  def empty?
72
83
  components.empty?
73
84
  end
74
85
 
86
+ # @return [Interval]
75
87
  def to_interval
76
88
  self
77
89
  end
78
90
 
91
+ # @return [String]
79
92
  def inspect
80
93
  "Interval" + construction.inspect
81
94
  end
82
95
 
96
+ # @return [String]
83
97
  def to_s
84
98
  inspect
85
99
  end
86
100
 
101
+ # @return [Interval]
87
102
  def hull
88
- if empty?
89
- Interval[]
90
- else
91
- Interval[inf, sup]
92
- end
103
+ if empty? then Interval[] else Interval[inf, sup] end
93
104
  end
94
105
 
95
106
  alias_method :+, :union
@@ -1,36 +1,45 @@
1
+ # Retains the logic specific for intervals with multiple components
1
2
  class Interval::Multiple < Interval
2
3
  attr :components
3
4
 
5
+ # @return [Interval]
4
6
  def initialize(array)
5
7
  @components = array
6
8
  freeze
7
9
  end
8
10
 
11
+ # @return [Interval]
9
12
  def each
10
13
  components.each{|o| yield(o)}
11
14
  self
12
15
  end
13
16
 
17
+ # @return [Object]
14
18
  def inf
15
19
  components.first.inf
16
20
  end
17
21
 
22
+ # @return [Object]
18
23
  def sup
19
24
  components.last.sup
20
25
  end
21
26
 
27
+ # @return [Array]
22
28
  def construction
23
29
  map &:construction
24
30
  end
25
31
 
32
+ # @return [Boolean]
26
33
  def include?(x)
27
34
  any?{|i| i.include? x}
28
35
  end
29
36
 
37
+ # @return [Boolean]
30
38
  def degenerate?
31
39
  all? &:degenerate?
32
40
  end
33
41
 
42
+ # @return [Boolean]
34
43
  def simple?
35
44
  false
36
45
  end
@@ -1,5 +1,8 @@
1
+ # Retains the logic specific for intervals with a single component
2
+ # in the form [inf,sup]
1
3
  class Interval::Simple < Interval
2
- attr :inf, :sup
4
+ attr :inf
5
+ attr :sup
3
6
 
4
7
  def initialize (a, b = a)
5
8
  if (a.respond_to?(:nan?) && a.nan?) || (b.respond_to?(:nan?) && b.nan?)
@@ -10,43 +13,53 @@ class Interval::Simple < Interval
10
13
  freeze
11
14
  end
12
15
 
16
+ # @return [Simple]
13
17
  def each
14
18
  yield(self)
15
19
  self
16
20
  end
17
21
 
22
+ # @return [Interval]
18
23
  def intersect(other)
19
24
  Interval[[inf, other.inf].max, [sup, other.sup].min]
20
25
  end
21
26
 
27
+ # @return [Interval::Multiple]
22
28
  def complement
23
29
  Interval[[-Infinity, inf], [sup, Infinity]]
24
30
  end
25
31
 
32
+ # @return [Interval]
26
33
  def minus(other)
27
34
  other.complement.intersect self
28
35
  end
29
36
 
37
+ # @return [Array<Interval>]
30
38
  def components
31
39
  [self]
32
40
  end
33
41
 
42
+ # @return [Array]
34
43
  def extrema
35
44
  [inf, sup]
36
45
  end
37
46
 
47
+ # @return [Array]
38
48
  def construction
39
49
  extrema.uniq
40
50
  end
41
51
 
52
+ # @return [Boolean]
42
53
  def include?(x)
43
54
  inf <= x && x <= sup
44
55
  end
45
56
 
57
+ # @return [Boolean]
46
58
  def degenerate?
47
59
  inf == sup
48
60
  end
49
61
 
62
+ # @return [Boolean]
50
63
  def simple?
51
64
  true
52
65
  end
@@ -1,10 +1,12 @@
1
1
  require 'borel'
2
2
 
3
3
  module Borel
4
+ # Includes numeric intervals related methods
4
5
  module IntervalArithmetic
6
+ # @return [Number] the width of the interval
5
7
  def width
6
- raise NonSimple, self unless self.respond_to?(:simple?) and self.simple?
7
- self.extrema.last - self.extrema.first
8
+ raise NonSimple, self unless respond_to?(:simple?) and simple?
9
+ extrema.last - extrema.first
8
10
  end
9
11
 
10
12
  Interval.send(:include, self)
@@ -1,16 +1,18 @@
1
1
  require 'borel/math_extensions/interval_arithmetic'
2
2
 
3
3
  module Borel
4
+ # Includes methods for picking random elements on intervals
4
5
  module Randomizable
6
+ # @return [Object] a random element of the interval
5
7
  def rand
6
- raise EmptyInterval if self.respond_to?(:empty?) and self.empty?
8
+ raise EmptyInterval if respond_to?(:empty?) and empty?
7
9
 
8
- if self.simple?
9
- Random.new.rand Range.new *self.extrema
10
+ if simple?
11
+ Random.new.rand Range.new *extrema
10
12
  else
11
- total_weight = self.map(&:width).reduce(:+)
13
+ total_weight = map(&:width).reduce(:+)
12
14
  selected_weight = Random.new.rand 0..total_weight
13
- rand_interval = self.find{|c| (selected_weight -= c.width) <= 0}
15
+ rand_interval = find{|c| (selected_weight -= c.width) <= 0}
14
16
  Random.new.rand Range.new *rand_interval.extrema
15
17
  end
16
18
  end
@@ -1,4 +1,8 @@
1
+ # Extends {#to_interval} for the {Array} class
1
2
  class NilClass
3
+
4
+ # Initializes an empty interval
5
+ # @return [Interval]
2
6
  def to_interval
3
7
  Interval[]
4
8
  end
@@ -1,4 +1,7 @@
1
+ # Extends {#to_interval} for the {Numeric} class
1
2
  class Numeric
3
+ # Initializes an interval with the calling number as the only point
4
+ # @return [Interval]
2
5
  def to_interval
3
6
  Interval[self]
4
7
  end
@@ -1,4 +1,7 @@
1
+ # Extends {#to_interval} for the {Array} class
1
2
  class Range
3
+
4
+ # @return [Interval]
2
5
  def to_interval
3
6
  Interval[first,
4
7
  if exclude_end?
@@ -1,10 +1,17 @@
1
+ # Namespace for all interval related classes
1
2
  module Borel
3
+ # Major version number
2
4
  MAJOR = 0
5
+ # Minor version number
3
6
  MINOR = 3
4
- TINY = 2
7
+ # Tiny version number
8
+ TINY = 3
5
9
 
10
+ # Joins the version numbers
6
11
  VERSION = [MAJOR, MINOR, TINY].join('.')
7
12
 
13
+ # Returns {VERSION}
14
+ # @return [String]
8
15
  def self.version
9
16
  VERSION
10
17
  end
@@ -1,6 +1,4 @@
1
1
  require 'rspec/core/rake_task'
2
2
 
3
3
  desc "Run specifications"
4
- RSpec::Core::RakeTask.new {|r|
5
- r.rspec_opts = %w(--format documentation)
6
- }
4
+ RSpec::Core::RakeTask.new
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.3.2
4
+ version: 0.3.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-09 00:00:00.000000000 Z
12
+ date: 2012-04-13 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'Borel sets are made of enumerable union and intersection of
15
15
 
16
- intervals. Borel performs regular operations on any interval of any
16
+ intervals. Borel performs regular operations on intervals of any
17
17
 
18
18
  Comparable class.'
19
19
  email:
@@ -23,7 +23,6 @@ extensions: []
23
23
  extra_rdoc_files: []
24
24
  files:
25
25
  - .gitignore
26
- - .rspec
27
26
  - Gemfile
28
27
  - Guardfile
29
28
  - LICENSE
@@ -65,7 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
64
  requirements:
66
65
  - - ! '>='
67
66
  - !ruby/object:Gem::Version
68
- version: 1.9.3
67
+ version: 1.9.2
69
68
  required_rubygems_version: !ruby/object:Gem::Requirement
70
69
  none: false
71
70
  requirements:
@@ -74,9 +73,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
73
  version: 1.3.6
75
74
  requirements: []
76
75
  rubyforge_project: borel
77
- rubygems_version: 1.8.17
76
+ rubygems_version: 1.8.21
78
77
  signing_key:
79
78
  specification_version: 3
80
- summary: Generic ordered set's operations
79
+ summary: Interval operation on Comparable classes
81
80
  test_files: []
82
81
  has_rdoc:
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --colour