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.
# Matrix[ [25, 93], [-1, 66] ]
# => 25 93
# -1 66
# # => 25 93
# # -1 66
#
def Matrix.[](*rows)
rows(rows, false)
@ -84,8 +84,8 @@ class Matrix
# of the matrix. If the optional argument +copy+ is false, use the given
# arrays as the internal structure of the matrix without copying.
# Matrix.rows([[25, 93], [-1, 66]])
# => 25 93
# -1 66
# # => 25 93
# # -1 66
#
def Matrix.rows(rows, copy = true)
rows = convert_to_array(rows, copy)
@ -102,8 +102,8 @@ class Matrix
#
# Creates a matrix using +columns+ as an array of column vectors.
# Matrix.columns([[25, 93], [-1, 66]])
# => 25 -1
# 93 66
# # => 25 -1
# # 93 66
#
def Matrix.columns(columns)
rows(columns, false).transpose
@ -116,9 +116,9 @@ class Matrix
# Returns an enumerator if no block is given.
#
# 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 }
# => a 3x3 matrix with random elements
# # => a 3x3 matrix with random elements
#
def Matrix.build(row_count, column_count = 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+.
# Matrix.diagonal(9, 5, -3)
# => 9 0 0
# 0 5 0
# 0 0 -3
# # => 9 0 0
# # 0 5 0
# # 0 0 -3
#
def Matrix.diagonal(*values)
size = values.size
@ -155,8 +155,8 @@ class Matrix
# Creates an +n+ by +n+ diagonal matrix where each diagonal element is
# +value+.
# Matrix.scalar(2, 5)
# => 5 0
# 0 5
# # => 5 0
# # 0 5
#
def Matrix.scalar(n, value)
diagonal(*Array.new(n, value))
@ -165,8 +165,8 @@ class Matrix
#
# Creates an +n+ by +n+ identity matrix.
# Matrix.identity(2)
# => 1 0
# 0 1
# # => 1 0
# # 0 1
#
def Matrix.identity(n)
scalar(n, 1)
@ -179,8 +179,8 @@ class Matrix
#
# Creates a zero matrix.
# Matrix.zero(2)
# => 0 0
# 0 0
# # => 0 0
# # 0 0
#
def Matrix.zero(row_count, column_count = row_count)
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
# +row+.
# Matrix.row_vector([4,5,6])
# => 4 5 6
# # => 4 5 6
#
def Matrix.row_vector(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
# in +column+.
# Matrix.column_vector([4,5,6])
# => 4
# 5
# 6
# # => 4
# # 5
# # 6
#
def Matrix.column_vector(column)
column = convert_to_array(column)
@ -217,12 +217,12 @@ class Matrix
#
# m = Matrix.empty(2, 0)
# m == Matrix[ [], [] ]
# => true
# # => true
# n = Matrix.empty(0, 3)
# n == Matrix.columns([ [], [], [] ])
# => true
# # => true
# 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)
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
end
# :call-seq:
# Matrix.combine(*matrices) { |*elements| ... }
#
# Create a matrix by combining matrices entrywise, using the given block
#
@ -301,12 +303,21 @@ class Matrix
new rows, x.column_count
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)
Matrix.combine(self, *matrices, &block)
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)
# 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
# * :upper: yields only elements on or above the diagonal
# Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
# => 1 4
# 9 16
# # => 1 4
# # 9 16
#
def collect(which = :all, &block) # :yield: e
return to_enum(:collect, which) unless block_given?
@ -537,9 +548,9 @@ class Matrix
# * :strict_upper: yields only elements above the diagonal
# * :upper: yields only elements on or above the diagonal
#
# Matrix[ [1,2], [3,4] ].each { |e| puts e }
# # => prints the numbers 1 to 4
# Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
# Matrix[ [1,2], [3,4] ].each { |e| puts e }
# # => prints the numbers 1 to 4
# Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
#
def each(which = :all, &block) # :yield: e
return to_enum :each, which unless block_given?
@ -688,8 +699,8 @@ class Matrix
# * row_range, col_range
#
# Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
# => 9 0 0
# 0 5 0
# # => 9 0 0
# # 0 5 0
#
# Like Array#[], negative indices count backward from the end of the
# 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.
#
# Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
# => 9 0 0
# 0 0 0
# 0 0 4
# # => 9 0 0
# # 0 0 0
# # 0 0 4
#
def first_minor(row, column)
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).
#
# Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
# => -108
# # => -108
#
def cofactor(row, column)
raise RuntimeError, "cofactor of empty matrix is not defined" if empty?
@ -775,8 +786,8 @@ class Matrix
# Returns the adjugate of the matrix.
#
# Matrix[ [7,6],[3,9] ].adjugate
# => 9 -6
# -3 7
# # => 9 -6
# # -3 7
#
def adjugate
raise ErrDimensionMismatch unless square?
@ -789,10 +800,10 @@ class Matrix
# Returns the Laplace expansion along given row or column.
#
# Matrix[[7,6], [3,9]].laplace_expansion(column: 1)
# => 45
# # => 45
#
# 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)
@ -1039,8 +1050,8 @@ class Matrix
#
# Matrix multiplication.
# Matrix[[2,4], [6,8]] * Matrix.identity(2)
# => 2 4
# 6 8
# # => 2 4
# # 6 8
#
def *(m) # m is matrix or vector or number
case(m)
@ -1072,8 +1083,8 @@ class Matrix
#
# Matrix addition.
# Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
# => 6 0
# -4 12
# # => 6 0
# # -4 12
#
def +(m)
case m
@ -1099,8 +1110,8 @@ class Matrix
#
# Matrix subtraction.
# Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
# => -8 2
# 8 1
# # => -8 2
# # 8 1
#
def -(m)
case m
@ -1126,8 +1137,8 @@ class Matrix
#
# Matrix division (multiplication by the inverse).
# Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
# => -7 1
# -3 -6
# # => -7 1
# # -3 -6
#
def /(other)
case other
@ -1146,8 +1157,8 @@ class Matrix
#
# Hadamard product
# Matrix[[1,2], [3,4]].hadamard_product(Matrix[[1,2], [3,2]])
# => 1 4
# 9 8
# # => 1 4
# # 9 8
#
def hadamard_product(m)
combine(m){|a, b| a * b}
@ -1157,8 +1168,8 @@ class Matrix
#
# Returns the inverse of the matrix.
# Matrix[[-1, -1], [0, -1]].inverse
# => -1 1
# 0 -1
# # => -1 1
# # 0 -1
#
def inverse
raise ErrDimensionMismatch unless square?
@ -1216,8 +1227,8 @@ class Matrix
# Non integer exponents will be handled by diagonalizing the matrix.
#
# Matrix[[7,6], [3,9]] ** 2
# => 67 96
# 48 99
# # => 67 96
# # 48 99
#
def **(other)
case other
@ -1246,6 +1257,11 @@ class Matrix
self
end
# Unary matrix negation.
#
# -Matrix[[1,5], [4,2]]
# # => -1 -5
# # -4 -2
def -@
collect {|e| -e }
end
@ -1269,7 +1285,7 @@ class Matrix
# Consider using exact types like Rational or BigDecimal instead.
#
# Matrix[[7,6], [3,9]].determinant
# => 45
# # => 45
#
def determinant
raise ErrDimensionMismatch unless square?
@ -1377,7 +1393,7 @@ class Matrix
# Consider using exact types like Rational or BigDecimal instead.
#
# Matrix[[7,6], [3,9]].rank
# => 2
# # => 2
#
def rank
# 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.
# Matrix[[7,6], [3,9]].trace
# => 16
# # => 16
#
def trace
raise ErrDimensionMismatch unless square?
@ -1438,12 +1454,12 @@ class Matrix
#
# Returns the transpose of the matrix.
# Matrix[[1,2], [3,4], [5,6]]
# => 1 2
# 3 4
# 5 6
# # => 1 2
# # 3 4
# # 5 6
# Matrix[[1,2], [3,4], [5,6]].transpose
# => 1 3 5
# 2 4 6
# # => 1 3 5
# # 2 4 6
#
def transpose
return self.class.empty(column_count, 0) if row_count.zero?
@ -1502,11 +1518,11 @@ class Matrix
#
# Returns the conjugate of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
# => 1+2i i 0
# 1 2 3
# # => 1+2i i 0
# # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].conjugate
# => 1-2i -i 0
# 1 2 3
# # => 1-2i -i 0
# # 1 2 3
#
def conjugate
collect(&:conjugate)
@ -1516,11 +1532,11 @@ class Matrix
#
# Returns the imaginary part of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
# => 1+2i i 0
# 1 2 3
# # => 1+2i i 0
# # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
# => 2i i 0
# 0 0 0
# # => 2i i 0
# # 0 0 0
#
def imaginary
collect(&:imaginary)
@ -1530,11 +1546,11 @@ class Matrix
#
# Returns the real part of the matrix.
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
# => 1+2i i 0
# 1 2 3
# # => 1+2i i 0
# # 1 2 3
# Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real
# => 1 0 0
# 1 2 3
# # => 1 0 0
# # 1 2 3
#
def real
collect(&:real)
@ -1544,7 +1560,7 @@ class Matrix
# Returns an array containing matrices corresponding to the real and imaginary
# 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
[real, imag]
@ -1605,7 +1621,7 @@ class Matrix
# Deprecated.
#
# Use map(&:to_f)
# Use <code>map(&:to_f)</code>
def elements_to_f
warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1
map(&:to_f)
@ -1613,7 +1629,7 @@ class Matrix
# Deprecated.
#
# Use map(&:to_i)
# Use <code>map(&:to_i)</code>
def elements_to_i
warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1
map(&:to_i)
@ -1621,7 +1637,7 @@ class Matrix
# Deprecated.
#
# Use map(&:to_r)
# Use <code>map(&:to_r)</code>
def elements_to_r
warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1
map(&:to_r)
@ -1857,8 +1873,8 @@ end
# * #-@
#
# Vector functions:
# * #inner_product(v), dot(v)
# * #cross_product(v), cross(v)
# * #inner_product(v), #dot(v)
# * #cross_product(v), #cross(v)
# * #collect
# * #collect!
# * #magnitude
@ -1923,7 +1939,7 @@ class Vector
#
# Return a zero vector.
#
# Vector.zero(3) => Vector[0, 0, 0]
# Vector.zero(3) # => Vector[0, 0, 0]
#
def Vector.zero(size)
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.
#
# Vector.independent?(Vector[1,0], Vector[0,1])
# => true
# # => true
#
# Vector.independent?(Vector[1,2], Vector[2,4])
# => false
# # => false
#
def Vector.independent?(*vs)
vs.each do |v|
@ -2072,10 +2088,10 @@ class Vector
# Returns +true+ iff all of vectors are linearly independent.
#
# Vector[1,0].independent?(Vector[0,1])
# => true
# # => true
#
# Vector[1,2].independent?(Vector[2,4])
# => false
# # => false
#
def independent?(*vs)
self.class.independent?(self, *vs)
@ -2212,7 +2228,7 @@ class Vector
#
# 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)
raise ErrDimensionMismatch if size != v.size
@ -2227,7 +2243,7 @@ class Vector
#
# 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
# to the arguments.
@ -2282,7 +2298,7 @@ class 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
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.
# v = Vector[5,8,2].normalize
# # => Vector[0.5184758473652127, 0.8295613557843402, 0.20739033894608505]
# v.norm => 1.0
# v.norm # => 1.0
#
def normalize
n = magnitude