Class: NamedVector

Inherits:
Object
  • Object
show all
Defined in:
lib/named_vector.rb

Overview

Vectors with named dimensions. Infinite dimensional objects with simple vector calculus operations defined.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*dims) ⇒ NamedVector

creates a new named vector

Parameters:

  • dims (Hash<String,Fixnum>, Hash<Symbol,Fixnum>, Array<String>, Array<Symbol>)

    the dimensions to initialize the vectors with, either as a hash of assignments or simply the names of the dimensions.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/named_vector.rb', line 12

def initialize(*dims)
	@vector = Hash.new
	@keys   = Set.new
	if dims && dims.first
		case dims.first
		when Hash
			hash = dims.first
			hash.keys.each {|d| modify_dimension(d, hash[d])}
		when String, Symbol, Fixnum
			@keys = Set.new(dims.map {|i| i.to_s})
			dims.each {|d| new_dimension(d)}
		end
	else
		@keys = []
	end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(mid, *args) ⇒ Object (private)

:nodoc:



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/named_vector.rb', line 99

def method_missing(mid, *args) # :nodoc:
	mname = mid.id2name
	len = args.length
	if mname.chomp!('=')
		if len != 1
			raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
		end
		modify_dimension(mname, args[0])
	elsif len == 0
		@vector.fetch(mname,0.0)
	else
		raise NoMethodError, "undefined method `#{mid}' for #{self}", caller(1)
	end
end

Instance Attribute Details

#keysObject (readonly) Also known as: dimensions

Returns the value of attribute keys.



7
8
9
# File 'lib/named_vector.rb', line 7

def keys
  @keys
end

Class Method Details

.add_dimension_iterator(obj) ⇒ Object

adds a dimension iterator (iterate through the keys) to a Hash or NamedVector

Parameters:

  • obj (Hash, NamedVector)

    the object to add the method to.



47
48
49
50
51
52
53
# File 'lib/named_vector.rb', line 47

def self.add_dimension_iterator(obj)
	obj.define_singleton_method(:each_dimension) do |&block|
		self.keys.each do |key|
			block.call(key)
		end
	end
end

.dot_product(a, b) ⇒ Object

Perform a dot product with another vector

Parameters:

  • a (Hash, NamedVector)

    the vector or scalar to multiply this vector with.

  • b (Hash, NamedVector)

    the vector or scalar to multiply this vector with.



64
65
66
67
68
69
70
71
72
# File 'lib/named_vector.rb', line 64

def self.dot_product(a, b)
	sum    = 0.0
	if a.keys.length < b.keys.length
		a.each_dimension {|i| sum+=a[i]*b[i]}
	else
		b.each_dimension {|i| sum+=b[i]*a[i]}
	end
	sum
end

.from_mongo(doc) ⇒ Object

Mongo retrieval

Parameters:

  • doc (BSON::OrderedHash)

    the mongo document to retrieve the vector from.



150
151
152
153
154
155
156
# File 'lib/named_vector.rb', line 150

def self.from_mongo(doc)
	hash = {}
	doc["keys"].each_with_index do |k, index|
		hash[k] = doc["dimensions"][index]
	end
	self.new hash
end

Instance Method Details

#*(value) ⇒ Object

Perform a dot product with another vector

Parameters:

  • value (Hash, Fixnum, Float, NamedVector)

    the vector or scalar to multiply this vector with. Scalar multiplication is destructive.



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/named_vector.rb', line 31

def *(value)
	case value
	when Fixnum, Float  #scalar multiplication product
		each_dimension {|i| @vector[i] = self[i]*value}
	when NamedVector #dot product
		NamedVector.dot_product(self, value)
	when Hash #dot product
		NamedVector.add_dimension_iterator(value)
		NamedVector.dot_product(self,value)
	else
		raise TypeError, "#{value.class} cannot be coerced to NamedVector."
	end
end

#[](key) ⇒ Object

fetches the value at the dimension specified

Parameters:

  • key (Symbol, String)

    the dimension requested



83
84
85
# File 'lib/named_vector.rb', line 83

def [](key)
	@vector.fetch(key.to_s,0.0)
end

#[]=(key, value) ⇒ Object

assigns a value at the dimension specified

Parameters:

  • key (Symbol, String)

    the dimension requested

  • value (Fixnum, Float)

    the assignment for this dimension



95
96
97
# File 'lib/named_vector.rb', line 95

def []=(key,value)
	modify_dimension(key,value)
end

#dot_product(value) ⇒ Object

Perform a dot product with another vector

Parameters:

  • value (Hash, NamedVector)

    the vector to multiply this vector with.



57
58
59
# File 'lib/named_vector.rb', line 57

def dot_product(value)
	NamedVector.dot_product(self, value)
end

#each_dimensionObject

iterates through each dimension of a vector



75
76
77
78
79
# File 'lib/named_vector.rb', line 75

def each_dimension
	@keys.each do |key|
		yield(key)
	end
end

#normObject

the Euclidean norm of a vector



133
134
135
# File 'lib/named_vector.rb', line 133

def norm
	Math.sqrt(squared_norm)
end

#normalizeObject

normalizes the vector destructively.



138
139
140
141
# File 'lib/named_vector.rb', line 138

def normalize
	current_norm = norm
	if current_norm > 0 then self*(1.0/current_norm) end
end

#squared_normObject

the squared Euclidean norm of a vector



126
127
128
129
130
# File 'lib/named_vector.rb', line 126

def squared_norm
	norm    = 0.0
	each_dimension {|i| norm+=self[i]**2}
	norm
end

#to_mongoObject

Mongo conversion



144
145
146
# File 'lib/named_vector.rb', line 144

def to_mongo
	{"keys"=> @keys, "dimensions"=> @keys.map {|i| self[i]}}
end