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:
parent
f5ddbba9a2
commit
c925cc01c5
1 changed files with 105 additions and 89 deletions
194
lib/matrix.rb
194
lib/matrix.rb
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue