1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby-matrix] Update docs (nicer rendering, undocumented method)

This commit is contained in:
zverok 2019-10-26 12:52:08 +03:00 committed by Marc-Andre Lafortune
parent f5ddbba9a2
commit c925cc01c5

View file

@ -72,8 +72,8 @@ class Matrix
# #
# Creates a matrix where each argument is a row. # Creates a matrix where each argument is a row.
# Matrix[ [25, 93], [-1, 66] ] # Matrix[ [25, 93], [-1, 66] ]
# => 25 93 # # => 25 93
# -1 66 # # -1 66
# #
def Matrix.[](*rows) def Matrix.[](*rows)
rows(rows, false) rows(rows, false)
@ -84,8 +84,8 @@ class Matrix
# of the matrix. If the optional argument +copy+ is false, use the given # of the matrix. If the optional argument +copy+ is false, use the given
# arrays as the internal structure of the matrix without copying. # arrays as the internal structure of the matrix without copying.
# Matrix.rows([[25, 93], [-1, 66]]) # Matrix.rows([[25, 93], [-1, 66]])
# => 25 93 # # => 25 93
# -1 66 # # -1 66
# #
def Matrix.rows(rows, copy = true) def Matrix.rows(rows, copy = true)
rows = convert_to_array(rows, copy) rows = convert_to_array(rows, copy)
@ -102,8 +102,8 @@ class Matrix
# #
# Creates a matrix using +columns+ as an array of column vectors. # Creates a matrix using +columns+ as an array of column vectors.
# Matrix.columns([[25, 93], [-1, 66]]) # Matrix.columns([[25, 93], [-1, 66]])
# => 25 -1 # # => 25 -1
# 93 66 # # 93 66
# #
def Matrix.columns(columns) def Matrix.columns(columns)
rows(columns, false).transpose rows(columns, false).transpose
@ -116,9 +116,9 @@ class Matrix
# Returns an enumerator if no block is given. # Returns an enumerator if no block is given.
# #
# m = Matrix.build(2, 4) {|row, col| col - row } # m = Matrix.build(2, 4) {|row, col| col - row }
# => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]] # # => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
# m = Matrix.build(3) { rand } # m = Matrix.build(3) { rand }
# => a 3x3 matrix with random elements # # => a 3x3 matrix with random elements
# #
def Matrix.build(row_count, column_count = row_count) def Matrix.build(row_count, column_count = row_count)
row_count = CoercionHelper.coerce_to_int(row_count) row_count = CoercionHelper.coerce_to_int(row_count)
@ -136,9 +136,9 @@ class Matrix
# #
# Creates a matrix where the diagonal elements are composed of +values+. # Creates a matrix where the diagonal elements are composed of +values+.
# Matrix.diagonal(9, 5, -3) # Matrix.diagonal(9, 5, -3)
# => 9 0 0 # # => 9 0 0
# 0 5 0 # # 0 5 0
# 0 0 -3 # # 0 0 -3
# #
def Matrix.diagonal(*values) def Matrix.diagonal(*values)
size = values.size size = values.size
@ -155,8 +155,8 @@ class Matrix
# Creates an +n+ by +n+ diagonal matrix where each diagonal element is # Creates an +n+ by +n+ diagonal matrix where each diagonal element is
# +value+. # +value+.
# Matrix.scalar(2, 5) # Matrix.scalar(2, 5)
# => 5 0 # # => 5 0
# 0 5 # # 0 5
# #
def Matrix.scalar(n, value) def Matrix.scalar(n, value)
diagonal(*Array.new(n, value)) diagonal(*Array.new(n, value))
@ -165,8 +165,8 @@ class Matrix
# #
# Creates an +n+ by +n+ identity matrix. # Creates an +n+ by +n+ identity matrix.
# Matrix.identity(2) # Matrix.identity(2)
# => 1 0 # # => 1 0
# 0 1 # # 0 1
# #
def Matrix.identity(n) def Matrix.identity(n)
scalar(n, 1) scalar(n, 1)
@ -179,8 +179,8 @@ class Matrix
# #
# Creates a zero matrix. # Creates a zero matrix.
# Matrix.zero(2) # Matrix.zero(2)
# => 0 0 # # => 0 0
# 0 0 # # 0 0
# #
def Matrix.zero(row_count, column_count = row_count) def Matrix.zero(row_count, column_count = row_count)
rows = Array.new(row_count){Array.new(column_count, 0)} rows = Array.new(row_count){Array.new(column_count, 0)}
@ -191,7 +191,7 @@ class Matrix
# Creates a single-row matrix where the values of that row are as given in # Creates a single-row matrix where the values of that row are as given in
# +row+. # +row+.
# Matrix.row_vector([4,5,6]) # Matrix.row_vector([4,5,6])
# => 4 5 6 # # => 4 5 6
# #
def Matrix.row_vector(row) def Matrix.row_vector(row)
row = convert_to_array(row) row = convert_to_array(row)
@ -202,9 +202,9 @@ class Matrix
# Creates a single-column matrix where the values of that column are as given # Creates a single-column matrix where the values of that column are as given
# in +column+. # in +column+.
# Matrix.column_vector([4,5,6]) # Matrix.column_vector([4,5,6])
# => 4 # # => 4
# 5 # # 5
# 6 # # 6
# #
def Matrix.column_vector(column) def Matrix.column_vector(column)
column = convert_to_array(column) column = convert_to_array(column)
@ -217,12 +217,12 @@ class Matrix
# #
# m = Matrix.empty(2, 0) # m = Matrix.empty(2, 0)
# m == Matrix[ [], [] ] # m == Matrix[ [], [] ]
# => true # # => true
# n = Matrix.empty(0, 3) # n = Matrix.empty(0, 3)
# n == Matrix.columns([ [], [], [] ]) # n == Matrix.columns([ [], [], [] ])
# => true # # => true
# m * n # m * n
# => Matrix[[0, 0, 0], [0, 0, 0]] # # => Matrix[[0, 0, 0], [0, 0, 0]]
# #
def Matrix.empty(row_count = 0, column_count = 0) def Matrix.empty(row_count = 0, column_count = 0)
raise ArgumentError, "One size must be 0" if column_count != 0 && row_count != 0 raise ArgumentError, "One size must be 0" if column_count != 0 && row_count != 0
@ -276,6 +276,8 @@ class Matrix
new result, total_column_count new result, total_column_count
end end
# :call-seq:
# Matrix.combine(*matrices) { |*elements| ... }
# #
# Create a matrix by combining matrices entrywise, using the given block # Create a matrix by combining matrices entrywise, using the given block
# #
@ -301,12 +303,21 @@ class Matrix
new rows, x.column_count new rows, x.column_count
end end
# :call-seq:
# combine(*other_matrices) { |*elements| ... }
#
# Creates new matrix by combining with <i>other_matrices</i> entrywise,
# using the given block.
#
# x = Matrix[[6, 6], [4, 4]]
# y = Matrix[[1, 2], [3, 4]]
# x.combine(y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
def combine(*matrices, &block) def combine(*matrices, &block)
Matrix.combine(self, *matrices, &block) Matrix.combine(self, *matrices, &block)
end end
# #
# Matrix.new is private; use Matrix.rows, columns, [], etc... to create. # Matrix.new is private; use ::rows, ::columns, ::[], etc... to create.
# #
def initialize(rows, column_count = rows[0].size) def initialize(rows, column_count = rows[0].size)
# No checking is done at this point. rows must be an Array of Arrays. # No checking is done at this point. rows must be an Array of Arrays.
@ -491,8 +502,8 @@ class Matrix
# * :strict_upper: yields only elements above the diagonal # * :strict_upper: yields only elements above the diagonal
# * :upper: yields only elements on or above the diagonal # * :upper: yields only elements on or above the diagonal
# Matrix[ [1,2], [3,4] ].collect { |e| e**2 } # Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
# => 1 4 # # => 1 4
# 9 16 # # 9 16
# #
def collect(which = :all, &block) # :yield: e def collect(which = :all, &block) # :yield: e
return to_enum(:collect, which) unless block_given? return to_enum(:collect, which) unless block_given?
@ -537,9 +548,9 @@ class Matrix
# * :strict_upper: yields only elements above the diagonal # * :strict_upper: yields only elements above the diagonal
# * :upper: yields only elements on or above the diagonal # * :upper: yields only elements on or above the diagonal
# #
# Matrix[ [1,2], [3,4] ].each { |e| puts e } # Matrix[ [1,2], [3,4] ].each { |e| puts e }
# # => prints the numbers 1 to 4 # # => prints the numbers 1 to 4
# Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3] # Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
# #
def each(which = :all, &block) # :yield: e def each(which = :all, &block) # :yield: e
return to_enum :each, which unless block_given? return to_enum :each, which unless block_given?
@ -688,8 +699,8 @@ class Matrix
# * row_range, col_range # * row_range, col_range
# #
# Matrix.diagonal(9, 5, -3).minor(0..1, 0..2) # Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
# => 9 0 0 # # => 9 0 0
# 0 5 0 # # 0 5 0
# #
# Like Array#[], negative indices count backward from the end of the # Like Array#[], negative indices count backward from the end of the
# row or column (-1 is the last element). Returns nil if the starting # row or column (-1 is the last element). Returns nil if the starting
@ -732,9 +743,9 @@ class Matrix
# Returns the submatrix obtained by deleting the specified row and column. # Returns the submatrix obtained by deleting the specified row and column.
# #
# Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2) # Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
# => 9 0 0 # # => 9 0 0
# 0 0 0 # # 0 0 0
# 0 0 4 # # 0 0 4
# #
def first_minor(row, column) def first_minor(row, column)
raise RuntimeError, "first_minor of empty matrix is not defined" if empty? raise RuntimeError, "first_minor of empty matrix is not defined" if empty?
@ -761,7 +772,7 @@ class Matrix
# the first minor by (-1)**(row + column). # the first minor by (-1)**(row + column).
# #
# Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1) # Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
# => -108 # # => -108
# #
def cofactor(row, column) def cofactor(row, column)
raise RuntimeError, "cofactor of empty matrix is not defined" if empty? raise RuntimeError, "cofactor of empty matrix is not defined" if empty?
@ -775,8 +786,8 @@ class Matrix
# Returns the adjugate of the matrix. # Returns the adjugate of the matrix.
# #
# Matrix[ [7,6],[3,9] ].adjugate # Matrix[ [7,6],[3,9] ].adjugate
# => 9 -6 # # => 9 -6
# -3 7 # # -3 7
# #
def adjugate def adjugate
raise ErrDimensionMismatch unless square? raise ErrDimensionMismatch unless square?
@ -789,10 +800,10 @@ class Matrix
# Returns the Laplace expansion along given row or column. # Returns the Laplace expansion along given row or column.
# #
# Matrix[[7,6], [3,9]].laplace_expansion(column: 1) # Matrix[[7,6], [3,9]].laplace_expansion(column: 1)
# => 45 # # => 45
# #
# Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0) # Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0)
# => Vector[3, -2] # # => Vector[3, -2]
# #
# #
def laplace_expansion(row: nil, column: nil) def laplace_expansion(row: nil, column: nil)
@ -1039,8 +1050,8 @@ class Matrix
# #
# Matrix multiplication. # Matrix multiplication.
# Matrix[[2,4], [6,8]] * Matrix.identity(2) # Matrix[[2,4], [6,8]] * Matrix.identity(2)
# => 2 4 # # => 2 4
# 6 8 # # 6 8
# #
def *(m) # m is matrix or vector or number def *(m) # m is matrix or vector or number
case(m) case(m)
@ -1072,8 +1083,8 @@ class Matrix
# #
# Matrix addition. # Matrix addition.
# Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]] # Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
# => 6 0 # # => 6 0
# -4 12 # # -4 12
# #
def +(m) def +(m)
case m case m
@ -1099,8 +1110,8 @@ class Matrix
# #
# Matrix subtraction. # Matrix subtraction.
# Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]] # Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
# => -8 2 # # => -8 2
# 8 1 # # 8 1
# #
def -(m) def -(m)
case m case m
@ -1126,8 +1137,8 @@ class Matrix
# #
# Matrix division (multiplication by the inverse). # Matrix division (multiplication by the inverse).
# Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]] # Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
# => -7 1 # # => -7 1
# -3 -6 # # -3 -6
# #
def /(other) def /(other)
case other case other
@ -1146,8 +1157,8 @@ class Matrix
# #
# Hadamard product # Hadamard product
# Matrix[[1,2], [3,4]].hadamard_product(Matrix[[1,2], [3,2]]) # Matrix[[1,2], [3,4]].hadamard_product(Matrix[[1,2], [3,2]])
# => 1 4 # # => 1 4
# 9 8 # # 9 8
# #
def hadamard_product(m) def hadamard_product(m)
combine(m){|a, b| a * b} combine(m){|a, b| a * b}
@ -1157,8 +1168,8 @@ class Matrix
# #
# Returns the inverse of the matrix. # Returns the inverse of the matrix.
# Matrix[[-1, -1], [0, -1]].inverse # Matrix[[-1, -1], [0, -1]].inverse
# => -1 1 # # => -1 1
# 0 -1 # # 0 -1
# #
def inverse def inverse
raise ErrDimensionMismatch unless square? raise ErrDimensionMismatch unless square?
@ -1216,8 +1227,8 @@ class Matrix
# Non integer exponents will be handled by diagonalizing the matrix. # Non integer exponents will be handled by diagonalizing the matrix.
# #
# Matrix[[7,6], [3,9]] ** 2 # Matrix[[7,6], [3,9]] ** 2
# => 67 96 # # => 67 96
# 48 99 # # 48 99
# #
def **(other) def **(other)
case other case other
@ -1246,6 +1257,11 @@ class Matrix
self self
end end
# Unary matrix negation.
#
# -Matrix[[1,5], [4,2]]
# # => -1 -5
# # -4 -2
def -@ def -@
collect {|e| -e } collect {|e| -e }
end end
@ -1269,7 +1285,7 @@ class Matrix
# Consider using exact types like Rational or BigDecimal instead. # Consider using exact types like Rational or BigDecimal instead.
# #
# Matrix[[7,6], [3,9]].determinant # Matrix[[7,6], [3,9]].determinant
# => 45 # # => 45
# #
def determinant def determinant
raise ErrDimensionMismatch unless square? raise ErrDimensionMismatch unless square?
@ -1377,7 +1393,7 @@ class Matrix
# Consider using exact types like Rational or BigDecimal instead. # Consider using exact types like Rational or BigDecimal instead.
# #
# Matrix[[7,6], [3,9]].rank # Matrix[[7,6], [3,9]].rank
# => 2 # # => 2
# #
def rank def rank
# We currently use Bareiss' multistep integer-preserving gaussian elimination # We currently use Bareiss' multistep integer-preserving gaussian elimination
@ -1425,7 +1441,7 @@ class Matrix
# #
# Returns the trace (sum of diagonal elements) of the matrix. # Returns the trace (sum of diagonal elements) of the matrix.
# Matrix[[7,6], [3,9]].trace # Matrix[[7,6], [3,9]].trace
# => 16 # # => 16
# #
def trace def trace
raise ErrDimensionMismatch unless square? raise ErrDimensionMismatch unless square?
@ -1438,12 +1454,12 @@ class Matrix
# #
# Returns the transpose of the matrix. # Returns the transpose of the matrix.
# Matrix[[1,2], [3,4], [5,6]] # Matrix[[1,2], [3,4], [5,6]]
# => 1 2 # # => 1 2
# 3 4 # # 3 4
# 5 6 # # 5 6
# Matrix[[1,2], [3,4], [5,6]].transpose # Matrix[[1,2], [3,4], [5,6]].transpose
# => 1 3 5 # # => 1 3 5
# 2 4 6 # # 2 4 6
# #
def transpose def transpose
return self.class.empty(column_count, 0) if row_count.zero? return self.class.empty(column_count, 0) if row_count.zero?
@ -1502,11 +1518,11 @@ class Matrix
# #
# Returns the conjugate of the matrix. # Returns the conjugate of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]] # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
# => 1+2i i 0 # # => 1+2i i 0
# 1 2 3 # # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].conjugate # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].conjugate
# => 1-2i -i 0 # # => 1-2i -i 0
# 1 2 3 # # 1 2 3
# #
def conjugate def conjugate
collect(&:conjugate) collect(&:conjugate)
@ -1516,11 +1532,11 @@ class Matrix
# #
# Returns the imaginary part of the matrix. # Returns the imaginary part of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]] # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
# => 1+2i i 0 # # => 1+2i i 0
# 1 2 3 # # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
# => 2i i 0 # # => 2i i 0
# 0 0 0 # # 0 0 0
# #
def imaginary def imaginary
collect(&:imaginary) collect(&:imaginary)
@ -1530,11 +1546,11 @@ class Matrix
# #
# Returns the real part of the matrix. # Returns the real part of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]] # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
# => 1+2i i 0 # # => 1+2i i 0
# 1 2 3 # # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real
# => 1 0 0 # # => 1 0 0
# 1 2 3 # # 1 2 3
# #
def real def real
collect(&:real) collect(&:real)
@ -1544,7 +1560,7 @@ class Matrix
# Returns an array containing matrices corresponding to the real and imaginary # Returns an array containing matrices corresponding to the real and imaginary
# parts of the matrix # parts of the matrix
# #
# m.rect == [m.real, m.imag] # ==> true for all matrices m # m.rect == [m.real, m.imag] # ==> true for all matrices m
# #
def rect def rect
[real, imag] [real, imag]
@ -1605,7 +1621,7 @@ class Matrix
# Deprecated. # Deprecated.
# #
# Use map(&:to_f) # Use <code>map(&:to_f)</code>
def elements_to_f def elements_to_f
warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1 warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1
map(&:to_f) map(&:to_f)
@ -1613,7 +1629,7 @@ class Matrix
# Deprecated. # Deprecated.
# #
# Use map(&:to_i) # Use <code>map(&:to_i)</code>
def elements_to_i def elements_to_i
warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1 warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1
map(&:to_i) map(&:to_i)
@ -1621,7 +1637,7 @@ class Matrix
# Deprecated. # Deprecated.
# #
# Use map(&:to_r) # Use <code>map(&:to_r)</code>
def elements_to_r def elements_to_r
warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1 warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1
map(&:to_r) map(&:to_r)
@ -1857,8 +1873,8 @@ end
# * #-@ # * #-@
# #
# Vector functions: # Vector functions:
# * #inner_product(v), dot(v) # * #inner_product(v), #dot(v)
# * #cross_product(v), cross(v) # * #cross_product(v), #cross(v)
# * #collect # * #collect
# * #collect! # * #collect!
# * #magnitude # * #magnitude
@ -1923,7 +1939,7 @@ class Vector
# #
# Return a zero vector. # Return a zero vector.
# #
# Vector.zero(3) => Vector[0, 0, 0] # Vector.zero(3) # => Vector[0, 0, 0]
# #
def Vector.zero(size) def Vector.zero(size)
raise ArgumentError, "invalid size (#{size} for 0..)" if size < 0 raise ArgumentError, "invalid size (#{size} for 0..)" if size < 0
@ -2054,10 +2070,10 @@ class Vector
# Returns +true+ iff all of vectors are linearly independent. # Returns +true+ iff all of vectors are linearly independent.
# #
# Vector.independent?(Vector[1,0], Vector[0,1]) # Vector.independent?(Vector[1,0], Vector[0,1])
# => true # # => true
# #
# Vector.independent?(Vector[1,2], Vector[2,4]) # Vector.independent?(Vector[1,2], Vector[2,4])
# => false # # => false
# #
def Vector.independent?(*vs) def Vector.independent?(*vs)
vs.each do |v| vs.each do |v|
@ -2072,10 +2088,10 @@ class Vector
# Returns +true+ iff all of vectors are linearly independent. # Returns +true+ iff all of vectors are linearly independent.
# #
# Vector[1,0].independent?(Vector[0,1]) # Vector[1,0].independent?(Vector[0,1])
# => true # # => true
# #
# Vector[1,2].independent?(Vector[2,4]) # Vector[1,2].independent?(Vector[2,4])
# => false # # => false
# #
def independent?(*vs) def independent?(*vs)
self.class.independent?(self, *vs) self.class.independent?(self, *vs)
@ -2212,7 +2228,7 @@ class Vector
# #
# Returns the inner product of this vector with the other. # Returns the inner product of this vector with the other.
# Vector[4,7].inner_product Vector[10,1] => 47 # Vector[4,7].inner_product Vector[10,1] # => 47
# #
def inner_product(v) def inner_product(v)
raise ErrDimensionMismatch if size != v.size raise ErrDimensionMismatch if size != v.size
@ -2227,7 +2243,7 @@ class Vector
# #
# Returns the cross product of this vector with the others. # Returns the cross product of this vector with the others.
# Vector[1, 0, 0].cross_product Vector[0, 1, 0] => Vector[0, 0, 1] # 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 # It is generalized to other dimensions to return a vector perpendicular
# to the arguments. # to the arguments.
@ -2282,7 +2298,7 @@ class Vector
# #
# Returns the modulus (Pythagorean distance) of the vector. # Returns the modulus (Pythagorean distance) of the vector.
# Vector[5,8,2].r => 9.643650761 # Vector[5,8,2].r # => 9.643650761
# #
def magnitude def magnitude
Math.sqrt(@elements.inject(0) {|v, e| v + e.abs2}) Math.sqrt(@elements.inject(0) {|v, e| v + e.abs2})
@ -2305,7 +2321,7 @@ class Vector
# Returns a new vector with the same direction but with norm 1. # Returns a new vector with the same direction but with norm 1.
# v = Vector[5,8,2].normalize # v = Vector[5,8,2].normalize
# # => Vector[0.5184758473652127, 0.8295613557843402, 0.20739033894608505] # # => Vector[0.5184758473652127, 0.8295613557843402, 0.20739033894608505]
# v.norm => 1.0 # v.norm # => 1.0
# #
def normalize def normalize
n = magnitude n = magnitude