tomstuart-vector_space 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -2,3 +2,109 @@ VectorSpace
2
2
  ===========
3
3
 
4
4
  A Ruby library for treating multidimensional values as elements of a vector space.
5
+
6
+ Examples
7
+ --------
8
+
9
+ A simple vector space:
10
+
11
+ class Round < VectorSpace::SimpleVector
12
+ has_dimension :hoegaarden
13
+ has_dimension :franziskaner
14
+ has_dimension :fruli
15
+ has_dimension :water
16
+ end
17
+
18
+ >> Round.new
19
+ => 0 and 0 and 0 and 0
20
+
21
+ >> Round.new :hoegaarden => 5, :fruli => 3
22
+ => 5 and 0 and 3 and 0
23
+
24
+ With custom descriptions:
25
+
26
+ class Round < VectorSpace::SimpleVector
27
+ has_dimension :hoegaarden, :describe => lambda { |n| "#{n} Hoegaardens" unless n.zero? }
28
+ has_dimension :franziskaner, :describe => lambda { |n| "#{n} Franziskaners" unless n.zero? }
29
+ has_dimension :fruli, :describe => lambda { |n| "#{n} Frülis" unless n.zero? }
30
+ has_dimension :water, :describe => lambda { |n| "#{n} waters" unless n.zero? }
31
+ has_zero_description 'no drinks'
32
+ end
33
+
34
+ >> Round.new
35
+ => no drinks
36
+
37
+ >> Round.new :hoegaarden => 5, :fruli => 3
38
+ => 5 Hoegaardens and 3 Frülis
39
+
40
+ >> Round.new(:hoegaarden => 2, :franziskaner => 3) + Round.new(:water => 2, :fruli => 2, :hoegaarden => 1)
41
+ => 3 Hoegaardens and 3 Franziskaners and 2 Frülis and 2 waters
42
+
43
+ >> (Round.new(:hoegaarden => 2, :franziskaner => 3) * 2) - Round.new(:hoegaarden => 1)
44
+ => 3 Hoegaardens and 6 Franziskaners
45
+
46
+ An indexed family of vector spaces with custom descriptions:
47
+
48
+ class Cocktail < VectorSpace::SimpleIndexedVector
49
+ indexed_by :units
50
+ has_dimension :gin, :describe => lambda { |units, n| "#{n}#{units} gin" unless n.zero? }
51
+ has_dimension :vermouth, :describe => lambda { |units, n| "#{n}#{units} vermouth" unless n.zero? }
52
+ has_dimension :whisky, :describe => lambda { |units, n| "#{n}#{units} whisky" unless n.zero? }
53
+ has_dimension :vodka, :describe => lambda { |units, n| "#{n}#{units} vodka" unless n.zero? }
54
+ has_dimension :kahlua, :describe => lambda { |units, n| "#{n}#{units} Kahlúa" unless n.zero? }
55
+ has_dimension :cream, :describe => lambda { |units, n| "#{n}#{units} cream" unless n.zero? }
56
+ end
57
+
58
+ >> martini = Cocktail.new :units => :cl, :gin => 5.5, :vermouth => 1.5
59
+ => 5.5cl gin and 1.5cl vermouth
60
+
61
+ >> manhattan = Cocktail.new :units => :cl, :whisky => 5, :vermouth => 2
62
+ => 2cl vermouth and 5cl whisky
63
+
64
+ >> white_russian = Cocktail.new :units => :oz, :vodka => 2, :kahlua => 1, :cream => 1.5
65
+ => 2oz vodka and 1oz Kahlúa and 1.5oz cream
66
+
67
+ >> martini * 2
68
+ => 11cl gin and 3cl vermouth
69
+
70
+ >> martini + manhattan
71
+ => 5.5cl gin and 3.5cl vermouth and 5cl whisky
72
+
73
+ >> martini + white_russian
74
+ ArgumentError: can't add 5.5cl gin and 1.5cl vermouth to 2oz vodka and 1oz Kahlúa and 1.5oz cream
75
+
76
+ A real (one-dimensional) example:
77
+
78
+ class Money < VectorSpace::SimpleIndexedVector
79
+ indexed_by :currency, :default => Currency::GBP
80
+ has_dimension :cents,
81
+ :coerce => lambda { |n| n.round }, # or just :coerce => :round if you have Symbol#to_proc
82
+ :describe => lambda { |currency, cents| "#{currency.symbol}#{cents / 100}.#{sprintf('%02d', cents % 100)}" }
83
+ end
84
+
85
+ >> a = Money.new(:currency => Currency::GBP, :cents => 9900)
86
+ => £99.00
87
+
88
+ >> b = Money.new(:currency => Currency::GBP, :cents => 1500)
89
+ => £15.00
90
+
91
+ >> a < b
92
+ => false
93
+
94
+ >> a > b
95
+ => true
96
+
97
+ >> a + b
98
+ => £114.00
99
+
100
+ >> c = Money.new(:currency => Currency::USD, :cents => 99)
101
+ => $0.99
102
+
103
+ >> a < c
104
+ => false
105
+
106
+ >> c < a
107
+ => false
108
+
109
+ >> a + c
110
+ ArgumentError: can't add $0.99 to £99.00
@@ -25,20 +25,9 @@ module VectorSpace
25
25
  self + (-vector)
26
26
  end
27
27
 
28
- def /(divisor)
29
- if divisor.zero?
30
- raise ZeroDivisionError
31
- else
32
- if divisor.is_a?(Numeric)
33
- # Scalar division (by multiplication)
34
- self * (1.0 / divisor)
35
- elsif compatible_with?(divisor)
36
- # Vector division
37
- map_values(dimensions.reject { |dimension| divisor.project(dimension).zero? }, divisor) { |a, b| a / b }.min
38
- else
39
- raise ArgumentError, "can't divide #{self.inspect} by #{divisor.inspect}"
40
- end
41
- end
28
+ # Scalar division (by multiplication)
29
+ def /(n)
30
+ self * (1.0 / n)
42
31
  end
43
32
  end
44
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tomstuart-vector_space
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Stuart
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-08 00:00:00 -07:00
12
+ date: 2009-07-09 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15