# Class: Vector

Inherits:
Object
• Object
show all
Extended by:
Matrix::ConversionHelper
Includes:
Enumerable, ExceptionForMatrix, Matrix::CoercionHelper
Defined in:
lib/matrix.rb

## Overview

The `Vector` class represents a mathematical vector, which is useful in its own right, and also constitutes a row or column of a Matrix.

## Method Catalogue

To create a Vector:

• Vector.[](*array)

• Vector.elements(array, copy = true)

• Vector.basis(size: n, index: k)

To access elements:

• #[](i)

To enumerate the elements:

• #each2(v)

• #collect2(v)

Properties of vectors:

• #angle_with(v)

• Vector.independent?(*vs)

• #independent?(*vs)

Vector arithmetic:

• #*(x) “is matrix or number”

• #+(v)

• #-(v)

• #/(v)

Vector functions:

• #inner_product(v), dot(v)

• #cross_product(v), cross(v)

• #collect

• #magnitude

• #map

• #map2(v)

• #norm

• #normalize

• #r

• #round

• #size

Conversion to other data types:

• #covector

• #to_a

• #coerce(other)

String representations:

• #to_s

• #inspect

## Defined Under Namespace

Classes: ZeroVectorError

## Class Method Summary collapse

• Creates a Vector from a list of elements.

• Returns a standard basis `n`-vector, where k is the index.

• Creates a vector from an Array.

• Returns `true` iff all of vectors are linearly independent.

## Instance Method Summary collapse

• Multiplies the vector by `x`, where `x` is a number or a matrix.

• Vector subtraction.

• Vector division.

• Returns `true` iff the two vectors have the same elements in the same order.

• #[](i) ⇒ Object (also: #element, #component)

Returns element number `i` (starting at zero) of the vector.

• #[]=(i, v) ⇒ Object (also: #set_element, #set_component)
• Returns an angle with another vector.

• Returns a copy of the vector.

• The coerce method provides support for Ruby type coercion.

• #collect(&block) ⇒ Object (also: #map)

Like Array#collect.

• Collects (as in Enumerable#collect) over the elements of this vector and `v` in conjunction.

• Creates a single-row matrix from this vector.

• #cross_product(*vs) ⇒ Object (also: #cross)

Returns the cross product of this vector with the others.

• Iterate over the elements of this vector.

• Iterate over the elements of this vector and `v` in conjunction.

• Returns a hash-code for the vector.

• Returns `true` iff all of vectors are linearly independent.

• constructor

Vector.new is private; use Vector[] or Vector.elements to create.

• #inner_product(v) ⇒ Object (also: #dot)

Returns the inner product of this vector with the other.

• Overrides Object#inspect.

• #magnitude ⇒ Object (also: #r, #norm)

Returns the modulus (Pythagorean distance) of the vector.

• Like Vector#collect2, but returns a Vector instead of an Array.

• Returns a new vector with the same direction but with norm 1.

• Returns a vector with entries rounded to the given precision (see Float#round).

• Returns the number of elements in the vector.

• Returns the elements of the vector in an array.

• Overrides Object#to_s.

## Constructor Details

### #initialize(array) ⇒ Vector

Vector.new is private; use Vector[] or Vector.elements to create.

 ``` 1774 1775 1776 1777``` ```# File 'lib/matrix.rb', line 1774 def initialize(array) # No checking is done at this point. @elements = array end```

## Class Method Details

### .[](*array) ⇒ Object

Creates a Vector from a list of elements.

``````Vector[7, 4, ...]
``````
 ``` 1746 1747 1748``` ```# File 'lib/matrix.rb', line 1746 def Vector.[](*array) new convert_to_array(array, false) end```

### .basis(size:, index:) ⇒ Object

Returns a standard basis `n`-vector, where k is the index.

``````Vector.basis(size:, index:) # => Vector[0, 1, 0]
``````

Raises:

• (ArgumentError)
 ``` 1763 1764 1765 1766 1767 1768 1769``` ```# File 'lib/matrix.rb', line 1763 def Vector.basis(size:, index:) raise ArgumentError, "invalid size (#{size} for 1..)" if size < 1 raise ArgumentError, "invalid index (#{index} for 0...#{size})" unless 0 <= index && index < size array = Array.new(size, 0) array[index] = 1 new convert_to_array(array, false) end```

### .elements(array, copy = true) ⇒ Object

Creates a vector from an Array. The optional second argument specifies whether the array itself or a copy is used internally.

 ``` 1754 1755 1756``` ```# File 'lib/matrix.rb', line 1754 def Vector.elements(array, copy = true) new convert_to_array(array, copy) end```

### .independent?(*vs) ⇒ Boolean

Returns `true` iff all of vectors are linearly independent.

``````Vector.independent?(Vector[1,0], Vector[0,1])
=> true

Vector.independent?(Vector[1,2], Vector[2,4])
=> false
``````

Returns:

• (Boolean)
 ``` 1863 1864 1865 1866 1867 1868 1869 1870``` ```# File 'lib/matrix.rb', line 1863 def Vector.independent?(*vs) vs.each do |v| raise TypeError, "expected Vector, got #{v.class}" unless v.is_a?(Vector) Vector.Raise ErrDimensionMismatch unless v.size == vs.first.size end return false if vs.count > vs.first.size Matrix[*vs].rank.eql?(vs.count) end```

## Instance Method Details

### #*(x) ⇒ Object

Multiplies the vector by `x`, where `x` is a number or a matrix.

 ``` 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935``` ```# File 'lib/matrix.rb', line 1923 def *(x) case x when Numeric els = @elements.collect{|e| e * x} self.class.elements(els, false) when Matrix Matrix.column_vector(self) * x when Vector Vector.Raise ErrOperationNotDefined, "*", self.class, x.class else apply_through_coercion(x, __method__) end end```

### #+(v) ⇒ Object

 ``` 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953``` ```# File 'lib/matrix.rb', line 1940 def +(v) case v when Vector Vector.Raise ErrDimensionMismatch if size != v.size els = collect2(v) {|v1, v2| v1 + v2 } self.class.elements(els, false) when Matrix Matrix.column_vector(self) + v else apply_through_coercion(v, __method__) end end```

### #[email protected] ⇒ Object

 ``` 1988 1989 1990``` ```# File 'lib/matrix.rb', line 1988 def [email protected] self end```

### #-(v) ⇒ Object

Vector subtraction.

 ``` 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971``` ```# File 'lib/matrix.rb', line 1958 def -(v) case v when Vector Vector.Raise ErrDimensionMismatch if size != v.size els = collect2(v) {|v1, v2| v1 - v2 } self.class.elements(els, false) when Matrix Matrix.column_vector(self) - v else apply_through_coercion(v, __method__) end end```

### #[email protected] ⇒ Object

 ``` 1992 1993 1994``` ```# File 'lib/matrix.rb', line 1992 def [email protected] collect {|e| -e } end```

### #/(x) ⇒ Object

Vector division.

 ``` 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986``` ```# File 'lib/matrix.rb', line 1976 def /(x) case x when Numeric els = @elements.collect{|e| e / x} self.class.elements(els, false) when Matrix, Vector Vector.Raise ErrOperationNotDefined, "/", self.class, x.class else apply_through_coercion(x, __method__) end end```

### #==(other) ⇒ Object

Returns `true` iff the two vectors have the same elements in the same order.

 ``` 1892 1893 1894 1895``` ```# File 'lib/matrix.rb', line 1892 def ==(other) return false unless Vector === other @elements == other.elements end```

### #[](i) ⇒ ObjectAlso known as: element, component

Returns element number `i` (starting at zero) of the vector.

 ``` 1784 1785 1786``` ```# File 'lib/matrix.rb', line 1784 def [](i) @elements[i] end```

### #[]=(i, v) ⇒ ObjectAlso known as: set_element, set_component

 ``` 1790 1791 1792``` ```# File 'lib/matrix.rb', line 1790 def []=(i, v) @elements[i]= v end```

### #angle_with(v) ⇒ Object

Returns an angle with another vector. Result is within the [0…Math::PI].

``````Vector[1,0].angle_with(Vector[0,1])
# => Math::PI / 2
``````

Raises:

• (TypeError)
 ``` 2097 2098 2099 2100 2101 2102 2103 2104``` ```# File 'lib/matrix.rb', line 2097 def angle_with(v) raise TypeError, "Expected a Vector, got a #{v.class}" unless v.is_a?(Vector) Vector.Raise ErrDimensionMismatch if size != v.size prod = magnitude * v.magnitude raise ZeroVectorError, "Can't get angle of zero vector" if prod == 0 Math.acos( inner_product(v) / prod ) end```

### #clone ⇒ Object

Returns a copy of the vector.

 ``` 1905 1906 1907``` ```# File 'lib/matrix.rb', line 1905 def clone self.class.elements(@elements) end```

### #coerce(other) ⇒ Object

The coerce method provides support for Ruby type coercion. This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator. See also Numeric#coerce.

 ``` 2146 2147 2148 2149 2150 2151 2152 2153``` ```# File 'lib/matrix.rb', line 2146 def coerce(other) case other when Numeric return Matrix::Scalar.new(other), self else raise TypeError, "#{self.class} can't be coerced into #{other.class}" end end```

### #collect(&block) ⇒ ObjectAlso known as: map

Like Array#collect.

 ``` 2052 2053 2054 2055 2056``` ```# File 'lib/matrix.rb', line 2052 def collect(&block) # :yield: e return to_enum(:collect) unless block_given? els = @elements.collect(&block) self.class.elements(els, false) end```

### #collect2(v) ⇒ Object

Collects (as in Enumerable#collect) over the elements of this vector and `v` in conjunction.

Raises:

• (TypeError)
 ``` 1841 1842 1843 1844 1845 1846 1847 1848``` ```# File 'lib/matrix.rb', line 1841 def collect2(v) # :yield: e1, e2 raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer) Vector.Raise ErrDimensionMismatch if size != v.size return to_enum(:collect2, v) unless block_given? Array.new(size) do |i| yield @elements[i], v[i] end end```

### #covector ⇒ Object

Creates a single-row matrix from this vector.

 ``` 2113 2114 2115``` ```# File 'lib/matrix.rb', line 2113 def covector Matrix.row_vector(self) end```

### #cross_product(*vs) ⇒ ObjectAlso known as: cross

Returns the cross product of this vector with the others.

``````Vector[1, 0, 0].cross_product Vector[0, 1, 0]   => Vector[0, 0, 1]
``````

It is generalized to other dimensions to return a vector perpendicular to the arguments.

``````Vector[1, 2].cross_product # => Vector[-2, 1]
Vector[1, 0, 0, 0].cross_product(
Vector[0, 1, 0, 0],
Vector[0, 0, 1, 0]
)  #=> Vector[0, 0, 0, 1]
``````

Raises:

• (ErrOperationNotDefined)
 ``` 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046``` ```# File 'lib/matrix.rb', line 2027 def cross_product(*vs) raise ErrOperationNotDefined, "cross product is not defined on vectors of dimension #{size}" unless size >= 2 raise ArgumentError, "wrong number of arguments (#{vs.size} for #{size - 2})" unless vs.size == size - 2 vs.each do |v| raise TypeError, "expected Vector, got #{v.class}" unless v.is_a? Vector Vector.Raise ErrDimensionMismatch unless v.size == size end case size when 2 Vector[-@elements[1], @elements[0]] when 3 v = vs[0] Vector[ v[2]*@elements[1] - v[1]*@elements[2], v[0]*@elements[2] - v[2]*@elements[0], v[1]*@elements[0] - v[0]*@elements[1] ] else rows = self, *vs, Array.new(size) {|i| Vector.basis(size: size, index: i) } Matrix.rows(rows).laplace_expansion(row: size - 1) end end```

### #each(&block) ⇒ Object

Iterate over the elements of this vector

 ``` 1818 1819 1820 1821 1822``` ```# File 'lib/matrix.rb', line 1818 def each(&block) return to_enum(:each) unless block_given? @elements.each(&block) self end```

### #each2(v) ⇒ Object

Iterate over the elements of this vector and `v` in conjunction.

Raises:

• (TypeError)
 ``` 1827 1828 1829 1830 1831 1832 1833 1834 1835``` ```# File 'lib/matrix.rb', line 1827 def each2(v) # :yield: e1, e2 raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer) Vector.Raise ErrDimensionMismatch if size != v.size return to_enum(:each2, v) unless block_given? size.times do |i| yield @elements[i], v[i] end self end```

### #elements_to_f ⇒ Object

 ``` 2124 2125 2126 2127``` ```# File 'lib/matrix.rb', line 2124 def elements_to_f warn "#{caller(1)[0]}: warning: Vector#elements_to_f is deprecated" map(&:to_f) end```

### #elements_to_i ⇒ Object

 ``` 2129 2130 2131 2132``` ```# File 'lib/matrix.rb', line 2129 def elements_to_i warn "#{caller(1)[0]}: warning: Vector#elements_to_i is deprecated" map(&:to_i) end```

### #elements_to_r ⇒ Object

 ``` 2134 2135 2136 2137``` ```# File 'lib/matrix.rb', line 2134 def elements_to_r warn "#{caller(1)[0]}: warning: Vector#elements_to_r is deprecated" map(&:to_r) end```

### #eql?(other) ⇒ Boolean

Returns:

• (Boolean)
 ``` 1897 1898 1899 1900``` ```# File 'lib/matrix.rb', line 1897 def eql?(other) return false unless Vector === other @elements.eql? other.elements end```

### #hash ⇒ Object

Returns a hash-code for the vector.

 ``` 1912 1913 1914``` ```# File 'lib/matrix.rb', line 1912 def hash @elements.hash end```

### #independent?(*vs) ⇒ Boolean

Returns `true` iff all of vectors are linearly independent.

``````Vector[1,0].independent?(Vector[0,1])
=> true

Vector[1,2].independent?(Vector[2,4])
=> false
``````

Returns:

• (Boolean)
 ``` 1881 1882 1883``` ```# File 'lib/matrix.rb', line 1881 def independent?(*vs) self.class.independent?(self, *vs) end```

### #inner_product(v) ⇒ ObjectAlso known as: dot

Returns the inner product of this vector with the other.

``````Vector[4,7].inner_product Vector[10,1]  => 47
``````
 ``` 2004 2005 2006 2007 2008 2009 2010 2011 2012``` ```# File 'lib/matrix.rb', line 2004 def inner_product(v) Vector.Raise ErrDimensionMismatch if size != v.size p = 0 each2(v) {|v1, v2| p += v1 * v2.conj } p end```

### #inspect ⇒ Object

Overrides Object#inspect

 ``` 2169 2170 2171``` ```# File 'lib/matrix.rb', line 2169 def inspect "Vector" + @elements.inspect end```

### #magnitude ⇒ ObjectAlso known as: r, norm

Returns the modulus (Pythagorean distance) of the vector.

``````Vector[5,8,2].r => 9.643650761
``````
 ``` 2063 2064 2065``` ```# File 'lib/matrix.rb', line 2063 def magnitude Math.sqrt(@elements.inject(0) {|v, e| v + e.abs2}) end```

### #map2(v, &block) ⇒ Object

Like Vector#collect2, but returns a Vector instead of an Array.

 ``` 2072 2073 2074 2075 2076``` ```# File 'lib/matrix.rb', line 2072 def map2(v, &block) # :yield: e1, e2 return to_enum(:map2, v) unless block_given? els = collect2(v, &block) self.class.elements(els, false) end```

### #normalize ⇒ Object

Returns a new vector with the same direction but with norm 1.

``````v = Vector[5,8,2].normalize
# => Vector[0.5184758473652127, 0.8295613557843402, 0.20739033894608505]
v.norm => 1.0
``````

Raises:

 ``` 2086 2087 2088 2089 2090``` ```# File 'lib/matrix.rb', line 2086 def normalize n = magnitude raise ZeroVectorError, "Zero vectors can not be normalized" if n == 0 self / n end```

### #round(ndigits = 0) ⇒ Object

Returns a vector with entries rounded to the given precision (see Float#round)

 ``` 1800 1801 1802``` ```# File 'lib/matrix.rb', line 1800 def round(ndigits=0) map{|e| e.round(ndigits)} end```

### #size ⇒ Object

Returns the number of elements in the vector.

 ``` 1807 1808 1809``` ```# File 'lib/matrix.rb', line 1807 def size @elements.size end```

### #to_a ⇒ Object

Returns the elements of the vector in an array.

 ``` 2120 2121 2122``` ```# File 'lib/matrix.rb', line 2120 def to_a @elements.dup end```

### #to_s ⇒ Object

Overrides Object#to_s

 ``` 2162 2163 2164``` ```# File 'lib/matrix.rb', line 2162 def to_s "Vector[" + @elements.join(", ") + "]" end```