class Matrix

Matrix 类表示一个数学矩阵。它提供了创建矩阵、对其进行算术和代数运算以及确定其数学属性(如迹、秩、逆、行列式或特征系统)的方法。

常量

SELECTORS
VERSION

属性

column_count[R]

返回列数。

column_size[R]

返回列数。

rows[R]

实例创建

公共类方法

I(n)
别名:identity
[](*rows) 点击切换源码

创建一个矩阵,其中每个参数都是一行。

Matrix[ [25, 93], [-1, 66] ]
#   =>  25 93
#       -1 66
# File matrix-0.4.2/lib/matrix.rb, line 78
def Matrix.[](*rows)
  rows(rows, false)
end
build(row_count, column_count = row_count) { |i, j| ... } 点击切换源码

创建一个大小为 row_count x column_count 的矩阵。它通过调用给定的块来填充值,传递当前行和列。如果没有给定块,则返回一个枚举器。

m = Matrix.build(2, 4) {|row, col| col - row }
#  => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
m = Matrix.build(3) { rand }
#  => a 3x3 matrix with random elements
# File matrix-0.4.2/lib/matrix.rb, line 123
def Matrix.build(row_count, column_count = row_count)
  row_count = CoercionHelper.coerce_to_int(row_count)
  column_count = CoercionHelper.coerce_to_int(column_count)
  raise ArgumentError if row_count < 0 || column_count < 0
  return to_enum :build, row_count, column_count unless block_given?
  rows = Array.new(row_count) do |i|
    Array.new(column_count) do |j|
      yield i, j
    end
  end
  new rows, column_count
end
column_vector(column) 点击切换源码

创建一个单列矩阵,其中该列的值如 column 中给定的那样。

Matrix.column_vector([4,5,6])
#  => 4
#     5
#     6
# File matrix-0.4.2/lib/matrix.rb, line 209
def Matrix.column_vector(column)
  column = convert_to_array(column)
  new [column].transpose, 1
end
columns(columns) 点击切换源码

使用 columns 作为列向量数组创建一个矩阵。

Matrix.columns([[25, 93], [-1, 66]])
#   =>  25 -1
#       93 66
# File matrix-0.4.2/lib/matrix.rb, line 108
def Matrix.columns(columns)
  rows(columns, false).transpose
end
combine(*matrices) { |*elements| ... } 点击切换源码

通过使用给定的块逐元素组合矩阵来创建矩阵

x = Matrix[[6, 6], [4, 4]]
y = Matrix[[1, 2], [3, 4]]
Matrix.combine(x, y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
# File matrix-0.4.2/lib/matrix.rb, line 288
def Matrix.combine(*matrices)
  return to_enum(__method__, *matrices) unless block_given?

  return Matrix.empty if matrices.empty?
  matrices.map!(&CoercionHelper.method(:coerce_to_matrix))
  x = matrices.first
  matrices.each do |m|
    raise ErrDimensionMismatch unless x.row_count == m.row_count && x.column_count == m.column_count
  end

  rows = Array.new(x.row_count) do |i|
    Array.new(x.column_count) do |j|
      yield matrices.map{|m| m[i,j]}
    end
  end
  new rows, x.column_count
end
diagonal(*values) 点击切换源码

创建一个矩阵,其中对角线元素由 values 组成。

Matrix.diagonal(9, 5, -3)
#  =>  9  0  0
#      0  5  0
#      0  0 -3
# File matrix-0.4.2/lib/matrix.rb, line 143
def Matrix.diagonal(*values)
  size = values.size
  return Matrix.empty if size == 0
  rows = Array.new(size) {|j|
    row = Array.new(size, 0)
    row[j] = values[j]
    row
  }
  new rows
end
empty(row_count = 0, column_count = 0) 点击切换源码

创建一个 row_count x column_count 的空矩阵。 row_countcolumn_count 中至少有一个必须为 0。

m = Matrix.empty(2, 0)
m == Matrix[ [], [] ]
#  => true
n = Matrix.empty(0, 3)
n == Matrix.columns([ [], [], [] ])
#  => true
m * n
#  => Matrix[[0, 0, 0], [0, 0, 0]]
# File matrix-0.4.2/lib/matrix.rb, line 227
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, "Negative size" if column_count < 0 || row_count < 0

  new([[]]*row_count, column_count)
end
hstack(x, *matrices) 点击切换源码

通过水平堆叠矩阵来创建矩阵

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
Matrix.hstack(x, y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]]
# File matrix-0.4.2/lib/matrix.rb, line 262
def Matrix.hstack(x, *matrices)
  x = CoercionHelper.coerce_to_matrix(x)
  result = x.send(:rows).map(&:dup)
  total_column_count = x.column_count
  matrices.each do |m|
    m = CoercionHelper.coerce_to_matrix(m)
    if m.row_count != x.row_count
      raise ErrDimensionMismatch, "The given matrices must have #{x.row_count} rows, but one has #{m.row_count}"
    end
    result.each_with_index do |row, i|
      row.concat m.send(:rows)[i]
    end
    total_column_count += m.column_count
  end
  new result, total_column_count
end
identity(n) 点击切换源码

创建一个 n x n 的单位矩阵。

Matrix.identity(2)
#  => 1 0
#     0 1
# File matrix-0.4.2/lib/matrix.rb, line 171
def Matrix.identity(n)
  scalar(n, 1)
end
也别名为:unit, I
new(rows, column_count = rows[0].size) 点击切换源码

Matrix.new 是私有的;使用 ::rows, ::columns, ::[] 等来创建。

# File matrix-0.4.2/lib/matrix.rb, line 322
def initialize(rows, column_count = rows[0].size)
  # No checking is done at this point. rows must be an Array of Arrays.
  # column_count must be the size of the first row, if there is one,
  # otherwise it *must* be specified and can be any integer >= 0
  @rows = rows
  @column_count = column_count
end
row_vector(row) 点击切换源码

创建一个单行矩阵,其中该行的值如 row 中给定的那样。

Matrix.row_vector([4,5,6])
#  => 4 5 6
# File matrix-0.4.2/lib/matrix.rb, line 196
def Matrix.row_vector(row)
  row = convert_to_array(row)
  new [row]
end
rows(rows, copy = true) 点击切换源码

创建一个矩阵,其中 rows 是一个数组的数组,每个数组都是矩阵的一行。如果可选参数 copy 为 false,则使用给定的数组作为矩阵的内部结构,而不进行复制。

Matrix.rows([[25, 93], [-1, 66]])
#   =>  25 93
#       -1 66
# File matrix-0.4.2/lib/matrix.rb, line 90
def Matrix.rows(rows, copy = true)
  rows = convert_to_array(rows, copy)
  rows.map! do |row|
    convert_to_array(row, copy)
  end
  size = (rows[0] || []).size
  rows.each do |row|
    raise ErrDimensionMismatch, "row size differs (#{row.size} should be #{size})" unless row.size == size
  end
  new rows, size
end
scalar(n, value) 点击切换源码

创建一个 n x n 的对角矩阵,其中每个对角线元素都是 value

Matrix.scalar(2, 5)
#  => 5 0
#     0 5
# File matrix-0.4.2/lib/matrix.rb, line 161
def Matrix.scalar(n, value)
  diagonal(*Array.new(n, value))
end
unit(n)
别名:identity
vstack(x, *matrices) 点击切换源码

通过垂直堆叠矩阵来创建矩阵

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
Matrix.vstack(x, y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]]
# File matrix-0.4.2/lib/matrix.rb, line 241
def Matrix.vstack(x, *matrices)
  x = CoercionHelper.coerce_to_matrix(x)
  result = x.send(:rows).map(&:dup)
  matrices.each do |m|
    m = CoercionHelper.coerce_to_matrix(m)
    if m.column_count != x.column_count
      raise ErrDimensionMismatch, "The given matrices must have #{x.column_count} columns, but one has #{m.column_count}"
    end
    result.concat(m.send(:rows))
  end
  new result, x.column_count
end
zero(row_count, column_count = row_count) 点击切换源码

创建一个零矩阵。

Matrix.zero(2)
#  => 0 0
#     0 0
# File matrix-0.4.2/lib/matrix.rb, line 185
def Matrix.zero(row_count, column_count = row_count)
  rows = Array.new(row_count){Array.new(column_count, 0)}
  new rows, column_count
end

公共实例方法

*(m) 点击切换源码

Matrix 乘法。

Matrix[[2,4], [6,8]] * Matrix.identity(2)
#  => 2 4
#     6 8
# File matrix-0.4.2/lib/matrix.rb, line 1058
def *(m) # m is matrix or vector or number
  case(m)
  when Numeric
    new_rows = @rows.collect {|row|
      row.collect {|e| e * m }
    }
    return new_matrix new_rows, column_count
  when Vector
    m = self.class.column_vector(m)
    r = self * m
    return r.column(0)
  when Matrix
    raise ErrDimensionMismatch if column_count != m.row_count
    m_rows = m.rows
    new_rows = rows.map do |row_i|
      Array.new(m.column_count) do |j|
        vij = 0
        column_count.times do |k|
          vij += row_i[k] * m_rows[k][j]
        end
        vij
      end
    end
    return new_matrix new_rows, m.column_count
  else
    return apply_through_coercion(m, __method__)
  end
end
**(exp) 点击切换源码

Matrix 指数运算。等效于将矩阵自乘 N 次。非整数指数将通过对矩阵进行对角化来处理。

Matrix[[7,6], [3,9]] ** 2
#  => 67 96
#     48 99
# File matrix-0.4.2/lib/matrix.rb, line 1237
def **(exp)
  case exp
  when Integer
    case
    when exp == 0
      raise ErrDimensionMismatch unless square?
      self.class.identity(column_count)
    when exp < 0
      inverse.power_int(-exp)
    else
      power_int(exp)
    end
  when Numeric
    v, d, v_inv = eigensystem
    v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** exp}) * v_inv
  else
    raise ErrOperationNotDefined, ["**", self.class, exp.class]
  end
end
+(m) 点击切换源码

Matrix 加法。

Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
#  =>  6  0
#     -4 12
# File matrix-0.4.2/lib/matrix.rb, line 1093
def +(m)
  case m
  when Numeric
    raise ErrOperationNotDefined, ["+", self.class, m.class]
  when Vector
    m = self.class.column_vector(m)
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count

  rows = Array.new(row_count) {|i|
    Array.new(column_count) {|j|
      self[i, j] + m[i, j]
    }
  }
  new_matrix rows, column_count
end
+@() 点击切换源码
# File matrix-0.4.2/lib/matrix.rb, line 1283
def +@
  self
end
-(m) 点击切换源码

Matrix 减法。

Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
#  => -8  2
#      8  1
# File matrix-0.4.2/lib/matrix.rb, line 1120
def -(m)
  case m
  when Numeric
    raise ErrOperationNotDefined, ["-", self.class, m.class]
  when Vector
    m = self.class.column_vector(m)
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count

  rows = Array.new(row_count) {|i|
    Array.new(column_count) {|j|
      self[i, j] - m[i, j]
    }
  }
  new_matrix rows, column_count
end
-@() 点击切换源码

一元矩阵取负。

-Matrix[[1,5], [4,2]]
# => -1 -5
#    -4 -2
# File matrix-0.4.2/lib/matrix.rb, line 1292
def -@
  collect {|e| -e }
end
/(other) 点击切换源码

Matrix 除法(乘以逆矩阵)。

Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
#  => -7  1
#     -3 -6
# File matrix-0.4.2/lib/matrix.rb, line 1147
def /(other)
  case other
  when Numeric
    rows = @rows.collect {|row|
      row.collect {|e| e / other }
    }
    return new_matrix rows, column_count
  when Matrix
    return self * other.inverse
  else
    return apply_through_coercion(other, __method__)
  end
end
==(other) 点击切换源码

返回两个矩阵是否包含相等的元素。

# File matrix-0.4.2/lib/matrix.rb, line 1021
def ==(other)
  return false unless Matrix === other &&
                      column_count == other.column_count # necessary for empty matrices
  rows == other.rows
end
[](i, j) 点击切换源码

返回矩阵的元素(i, j)。即:第 i 行,第 j 列。

# File matrix-0.4.2/lib/matrix.rb, line 337
def [](i, j)
  @rows.fetch(i){return nil}[j]
end
也别名为:element, component
matrix[range, range] = matrix/element 点击切换源码
matrix[range, integer] = vector/column_matrix/element
matrix[integer, range] = vector/row_matrix/element
matrix[integer, integer] = element

设置矩阵的一个或多个元素。

# File matrix-0.4.2/lib/matrix.rb, line 351
def []=(i, j, v)
  raise FrozenError, "can't modify frozen Matrix" if frozen?
  rows = check_range(i, :row) or row = check_int(i, :row)
  columns = check_range(j, :column) or column = check_int(j, :column)
  if rows && columns
    set_row_and_col_range(rows, columns, v)
  elsif rows
    set_row_range(rows, column, v)
  elsif columns
    set_col_range(row, columns, v)
  else
    set_value(row, column, v)
  end
end
也别名为:set_element, set_component
abs() 点击切换源码

返回逐元素的绝对值

# File matrix-0.4.2/lib/matrix.rb, line 1299
def abs
  collect(&:abs)
end
adjoint() 点击切换源码

返回矩阵的伴随矩阵。

Matrix[ [i,1],[2,-i] ].adjoint
#  => -i 2
#      1 i
# File matrix-0.4.2/lib/matrix.rb, line 1595
def adjoint
  conjugate.transpose
end
adjugate() 点击切换源码

返回矩阵的伴随矩阵。

Matrix[ [7,6],[3,9] ].adjugate
#  => 9 -6
#     -3 7
# File matrix-0.4.2/lib/matrix.rb, line 793
def adjugate
  raise ErrDimensionMismatch unless square?
  Matrix.build(row_count, column_count) do |row, column|
    cofactor(column, row)
  end
end
antisymmetric?() 点击切换源码

如果这是一个反对称矩阵,则返回 true。如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 973
def antisymmetric?
  raise ErrDimensionMismatch unless square?
  each_with_index(:upper) do |e, row, col|
    return false unless e == -rows[col][row]
  end
  true
end
也别名为:skew_symmetric?
coerce(other) 点击切换源码

coerce 方法为 Ruby 类型强制转换提供支持。 Ruby 使用此强制转换机制来处理混合类型的数值运算:它旨在查找运算符的两个操作数之间兼容的公共类型。另请参阅 Numeric#coerce。

# File matrix-0.4.2/lib/matrix.rb, line 1648
def coerce(other)
  case other
  when Numeric
    return Scalar.new(other), self
  else
    raise TypeError, "#{self.class} can't be coerced into #{other.class}"
  end
end
cofactor(row, column) 点击切换源码

返回 (row, column) 的余因子,它是通过将第一主子式乘以 (-1)**(row + column) 获得的。

Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
#  => -108
# File matrix-0.4.2/lib/matrix.rb, line 778
def cofactor(row, column)
  raise RuntimeError, "cofactor of empty matrix is not defined" if empty?
  raise ErrDimensionMismatch unless square?

  det_of_minor = first_minor(row, column).determinant
  det_of_minor * (-1) ** (row + column)
end
cofactor_expansion(row: nil, column: nil)
collect(which = :all) { |e| ... } 点击切换源码

返回一个矩阵,该矩阵是对矩阵的所有元素迭代给定块的结果。可以通过传递参数来限制元素

  • :all(默认):产生所有元素

  • :diagonal:仅产生对角线上的元素

  • :off_diagonal:产生除对角线上的所有元素

  • :lower:仅产生对角线或之下的元素

  • :strict_lower:仅产生对角线以下的元素

  • :strict_upper:仅产生对角线以上的元素

  • :upper:仅产生对角线或以上的元素 Matrix[ [1,2], [3,4] ].collect { |e| e**2 } # => 1 4 # 9 16

# File matrix-0.4.2/lib/matrix.rb, line 508
def collect(which = :all, &block) # :yield: e
  return to_enum(:collect, which) unless block_given?
  dup.collect!(which, &block)
end
也别名为:map
collect!(which = :all) { |e| ... } 点击切换源码

对矩阵的每个元素调用给定的块,用该块返回的值替换该元素。可以通过传递参数来限制元素

  • :all(默认):产生所有元素

  • :diagonal:仅产生对角线上的元素

  • :off_diagonal:产生除对角线上的所有元素

  • :lower:仅产生对角线或之下的元素

  • :strict_lower:仅产生对角线以下的元素

  • :strict_upper:仅产生对角线以上的元素

  • :upper:仅产生对角线或以上的元素

# File matrix-0.4.2/lib/matrix.rb, line 526
def collect!(which = :all)
  return to_enum(:collect!, which) unless block_given?
  raise FrozenError, "can't modify frozen Matrix" if frozen?
  each_with_index(which){ |e, row_index, col_index| @rows[row_index][col_index] = yield e }
end
也别名为:map!
column(j) { |e| ... } 点击切换源码

将矩阵的第 j 列作为 Vector 返回(从 0 开始,如数组)。当给定一个块时,该向量的元素将被迭代。

# File matrix-0.4.2/lib/matrix.rb, line 477
def column(j) # :yield: e
  if block_given?
    return self if j >= column_count || j < -column_count
    row_count.times do |i|
      yield @rows[i][j]
    end
    self
  else
    return nil if j >= column_count || j < -column_count
    col = Array.new(row_count) {|i|
      @rows[i][j]
    }
    Vector.elements(col, false)
  end
end
column_vectors() 点击切换源码

返回矩阵的列向量数组。参见 Vector

# File matrix-0.4.2/lib/matrix.rb, line 1669
def column_vectors
  Array.new(column_count) {|i|
    column(i)
  }
end
combine(*other_matrices) { |*elements| ... } 点击切换源码

通过使用给定的块与 other_matrices 逐元素组合来创建新矩阵。

x = Matrix[[6, 6], [4, 4]]
y = Matrix[[1, 2], [3, 4]]
x.combine(y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
# File matrix-0.4.2/lib/matrix.rb, line 315
def combine(*matrices, &block)
  Matrix.combine(self, *matrices, &block)
end
component(i, j)
别名:[]
conj()
别名:conjugate
conjugate() 点击切换源码

返回矩阵的共轭矩阵。

Matrix[[Complex(1,2), Complex(0,1), 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
# File matrix-0.4.2/lib/matrix.rb, line 1583
def conjugate
  collect(&:conjugate)
end
也别名为:conj
det()
别名:determinant
det_e()
determinant() 点击以切换源代码

返回矩阵的行列式。

请注意,使用浮点数值可能会因其精度不足而产生错误的结果。 考虑使用精确类型,如 Rational 或 BigDecimal。

Matrix[[7,6], [3,9]].determinant
#  => 45
# File matrix-0.4.2/lib/matrix.rb, line 1317
def determinant
  raise ErrDimensionMismatch unless square?
  m = @rows
  case row_count
    # Up to 4x4, give result using Laplacian expansion by minors.
    # This will typically be faster, as well as giving good results
    # in case of Floats
  when 0
    +1
  when 1
    + m[0][0]
  when 2
    + m[0][0] * m[1][1] - m[0][1] * m[1][0]
  when 3
    m0, m1, m2 = m
    + m0[0] * m1[1] * m2[2] - m0[0] * m1[2] * m2[1] \
    - m0[1] * m1[0] * m2[2] + m0[1] * m1[2] * m2[0] \
    + m0[2] * m1[0] * m2[1] - m0[2] * m1[1] * m2[0]
  when 4
    m0, m1, m2, m3 = m
    + m0[0] * m1[1] * m2[2] * m3[3] - m0[0] * m1[1] * m2[3] * m3[2] \
    - m0[0] * m1[2] * m2[1] * m3[3] + m0[0] * m1[2] * m2[3] * m3[1] \
    + m0[0] * m1[3] * m2[1] * m3[2] - m0[0] * m1[3] * m2[2] * m3[1] \
    - m0[1] * m1[0] * m2[2] * m3[3] + m0[1] * m1[0] * m2[3] * m3[2] \
    + m0[1] * m1[2] * m2[0] * m3[3] - m0[1] * m1[2] * m2[3] * m3[0] \
    - m0[1] * m1[3] * m2[0] * m3[2] + m0[1] * m1[3] * m2[2] * m3[0] \
    + m0[2] * m1[0] * m2[1] * m3[3] - m0[2] * m1[0] * m2[3] * m3[1] \
    - m0[2] * m1[1] * m2[0] * m3[3] + m0[2] * m1[1] * m2[3] * m3[0] \
    + m0[2] * m1[3] * m2[0] * m3[1] - m0[2] * m1[3] * m2[1] * m3[0] \
    - m0[3] * m1[0] * m2[1] * m3[2] + m0[3] * m1[0] * m2[2] * m3[1] \
    + m0[3] * m1[1] * m2[0] * m3[2] - m0[3] * m1[1] * m2[2] * m3[0] \
    - m0[3] * m1[2] * m2[0] * m3[1] + m0[3] * m1[2] * m2[1] * m3[0]
  else
    # For bigger matrices, use an efficient and general algorithm.
    # Currently, we use the Gauss-Bareiss algorithm
    determinant_bareiss
  end
end
别名: det
determinant_e() 点击以切换源代码

已弃用; 请使用 Matrix#determinant

# File matrix-0.4.2/lib/matrix.rb, line 1398
def determinant_e
  warn "Matrix#determinant_e is deprecated; use #determinant", uplevel: 1
  determinant
end
别名: det_e
diagonal?() 点击以切换源代码

如果这是一个对角矩阵,则返回 true。 如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 839
def diagonal?
  raise ErrDimensionMismatch unless square?
  each(:off_diagonal).all?(&:zero?)
end
each(which = :all) { |e| ... } 点击以切换源代码

产生矩阵的所有元素,从第一行的元素开始,如果没有给出块,则返回一个枚举器。 可以通过传递参数来限制元素。

  • :all(默认):产生所有元素

  • :diagonal:仅产生对角线上的元素

  • :off_diagonal:产生除对角线上的所有元素

  • :lower:仅产生对角线或之下的元素

  • :strict_lower:仅产生对角线以下的元素

  • :strict_upper:仅产生对角线以上的元素

  • :upper:仅产生对角线或以上的元素

    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]
    
# File matrix-0.4.2/lib/matrix.rb, line 556
def each(which = :all, &block) # :yield: e
  return to_enum :each, which unless block_given?
  last = column_count - 1
  case which
  when :all
    @rows.each do |row|
      row.each(&block)
    end
  when :diagonal
    @rows.each_with_index do |row, row_index|
      yield row.fetch(row_index){return self}
    end
  when :off_diagonal
    @rows.each_with_index do |row, row_index|
      column_count.times do |col_index|
        yield row[col_index] unless row_index == col_index
      end
    end
  when :lower
    @rows.each_with_index do |row, row_index|
      0.upto([row_index, last].min) do |col_index|
        yield row[col_index]
      end
    end
  when :strict_lower
    @rows.each_with_index do |row, row_index|
      [row_index, column_count].min.times do |col_index|
        yield row[col_index]
      end
    end
  when :strict_upper
    @rows.each_with_index do |row, row_index|
      (row_index+1).upto(last) do |col_index|
        yield row[col_index]
      end
    end
  when :upper
    @rows.each_with_index do |row, row_index|
      row_index.upto(last) do |col_index|
        yield row[col_index]
      end
    end
  else
    raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
  end
  self
end
each_with_index(which = :all) { |e, row, column| ... } 点击以切换源代码

each 相同,但除了元素之外,还包括行索引和列索引。

Matrix[ [1,2], [3,4] ].each_with_index do |e, row, col|
  puts "#{e} at #{row}, #{col}"
end
  # => Prints:
  #    1 at 0, 0
  #    2 at 0, 1
  #    3 at 1, 0
  #    4 at 1, 1
# File matrix-0.4.2/lib/matrix.rb, line 616
def each_with_index(which = :all) # :yield: e, row, column
  return to_enum :each_with_index, which unless block_given?
  last = column_count - 1
  case which
  when :all
    @rows.each_with_index do |row, row_index|
      row.each_with_index do |e, col_index|
        yield e, row_index, col_index
      end
    end
  when :diagonal
    @rows.each_with_index do |row, row_index|
      yield row.fetch(row_index){return self}, row_index, row_index
    end
  when :off_diagonal
    @rows.each_with_index do |row, row_index|
      column_count.times do |col_index|
        yield row[col_index], row_index, col_index unless row_index == col_index
      end
    end
  when :lower
    @rows.each_with_index do |row, row_index|
      0.upto([row_index, last].min) do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  when :strict_lower
    @rows.each_with_index do |row, row_index|
      [row_index, column_count].min.times do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  when :strict_upper
    @rows.each_with_index do |row, row_index|
      (row_index+1).upto(last) do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  when :upper
    @rows.each_with_index do |row, row_index|
      row_index.upto(last) do |col_index|
        yield row[col_index], row_index, col_index
      end
    end
  else
    raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
  end
  self
end
eigen()
别名: eigensystem
eigensystem() 点击以切换源代码

返回矩阵的特征系统;请参阅 EigenvalueDecomposition

m = Matrix[[1, 2], [3, 4]]
v, d, v_inv = m.eigensystem
d.diagonal? # => true
v.inv == v_inv # => true
(v * d * v_inv).round(5) == m # => true
# File matrix-0.4.2/lib/matrix.rb, line 1550
def eigensystem
  EigenvalueDecomposition.new(self)
end
别名: eigen
element(i, j)
别名:[]
elements_to_f() 点击以切换源代码

已弃用。

请使用 map(&:to_f)

# File matrix-0.4.2/lib/matrix.rb, line 1692
def elements_to_f
  warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1
  map(&:to_f)
end
elements_to_i() 点击以切换源代码

已弃用。

请使用 map(&:to_i)

# File matrix-0.4.2/lib/matrix.rb, line 1700
def elements_to_i
  warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1
  map(&:to_i)
end
elements_to_r() 点击以切换源代码

已弃用。

请使用 map(&:to_r)

# File matrix-0.4.2/lib/matrix.rb, line 1708
def elements_to_r
  warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1
  map(&:to_r)
end
empty?() 点击以切换源代码

如果这是一个空矩阵,即行数或列数为 0,则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 848
def empty?
  column_count == 0 || row_count == 0
end
entrywise_product(m)
eql?(other) 点击以切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 1027
def eql?(other)
  return false unless Matrix === other &&
                      column_count == other.column_count # necessary for empty matrices
  rows.eql? other.rows
end
find_index(*args)
别名: index
first_minor(row, column) 点击以切换源代码

返回通过删除指定的行和列获得的子矩阵。

Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
#  => 9 0 0
#     0 0 0
#     0 0 4
# File matrix-0.4.2/lib/matrix.rb, line 751
def first_minor(row, column)
  raise RuntimeError, "first_minor of empty matrix is not defined" if empty?

  unless 0 <= row && row < row_count
    raise ArgumentError, "invalid row (#{row.inspect} for 0..#{row_count - 1})"
  end

  unless 0 <= column && column < column_count
    raise ArgumentError, "invalid column (#{column.inspect} for 0..#{column_count - 1})"
  end

  arrays = to_a
  arrays.delete_at(row)
  arrays.each do |array|
    array.delete_at(column)
  end

  new_matrix arrays, column_count - 1
end
freeze() 点击以切换源代码
调用超类方法
# File matrix-0.4.2/lib/matrix.rb, line 534
def freeze
  @rows.each(&:freeze).freeze

  super
end
hadamard_product(m) 点击以切换源代码

哈达玛积

Matrix[[1,2], [3,4]].hadamard_product(Matrix[[1,2], [3,2]])
#  => 1  4
#     9  8
# File matrix-0.4.2/lib/matrix.rb, line 1167
def hadamard_product(m)
  combine(m){|a, b| a * b}
end
hash() 点击以切换源代码

返回矩阵的哈希码。

# File matrix-0.4.2/lib/matrix.rb, line 1044
def hash
  @rows.hash
end
hermitian?() 点击以切换源代码

如果这是一个埃尔米特矩阵,则返回 true。如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 856
def hermitian?
  raise ErrDimensionMismatch unless square?
  each_with_index(:upper).all? do |e, row, col|
    e == rows[col][row].conj
  end
end
hstack(*matrices) 点击以切换源代码

返回一个新矩阵,该矩阵是通过将接收器与给定的矩阵水平堆叠而形成的。

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.hstack(y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]]
# File matrix-0.4.2/lib/matrix.rb, line 1412
def hstack(*matrices)
  self.class.hstack(self, *matrices)
end
imag()
别名: imaginary
imaginary() 点击以切换源代码

返回矩阵的虚部。

Matrix[[Complex(1,2), Complex(0,1), 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
# File matrix-0.4.2/lib/matrix.rb, line 1608
def imaginary
  collect(&:imaginary)
end
别名: imag
index(value, selector = :all) → [row, column] 点击以切换源代码
index(selector = :all){ block } → [row, column]
index(selector = :all) → an_enumerator

index 方法专门用于以 [row, column] 的形式返回索引。它还接受一个可选的 selector 参数,有关详细信息,请参阅 each

Matrix[ [1,2], [3,4] ].index(&:even?) # => [0, 1]
Matrix[ [1,1], [1,1] ].index(1, :strict_lower) # => [1, 0]
# File matrix-0.4.2/lib/matrix.rb, line 679
def index(*args)
  raise ArgumentError, "wrong number of arguments(#{args.size} for 0-2)" if args.size > 2
  which = (args.size == 2 || SELECTORS.include?(args.last)) ? args.pop : :all
  return to_enum :find_index, which, *args unless block_given? || args.size == 1
  if args.size == 1
    value = args.first
    each_with_index(which) do |e, row_index, col_index|
      return row_index, col_index if e == value
    end
  else
    each_with_index(which) do |e, row_index, col_index|
      return row_index, col_index if yield e
    end
  end
  nil
end
别名: find_index
inspect() 点击以切换源代码

覆盖 Object#inspect

# File matrix-0.4.2/lib/matrix.rb, line 1733
def inspect
  if empty?
    "#{self.class}.empty(#{row_count}, #{column_count})"
  else
    "#{self.class}#{@rows.inspect}"
  end
end
inv()
别名: inverse
inverse() 点击以切换源代码

返回矩阵的逆矩阵。

Matrix[[-1, -1], [0, -1]].inverse
#  => -1  1
#      0 -1
# File matrix-0.4.2/lib/matrix.rb, line 1178
def inverse
  raise ErrDimensionMismatch unless square?
  self.class.I(row_count).send(:inverse_from, self)
end
别名: inv
laplace_expansion(row: nil, column: nil) 点击以切换源代码

返回沿给定行或列的拉普拉斯展开。

Matrix[[7,6], [3,9]].laplace_expansion(column: 1)
# => 45

Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0)
# => Vector[3, -2]
# File matrix-0.4.2/lib/matrix.rb, line 810
def laplace_expansion(row: nil, column: nil)
  num = row || column

  if !num || (row && column)
    raise ArgumentError, "exactly one the row or column arguments must be specified"
  end

  raise ErrDimensionMismatch unless square?
  raise RuntimeError, "laplace_expansion of empty matrix is not defined" if empty?

  unless 0 <= num && num < row_count
    raise ArgumentError, "invalid num (#{num.inspect} for 0..#{row_count - 1})"
  end

  send(row ? :row : :column, num).map.with_index { |e, k|
    e * cofactor(*(row ? [num, k] : [k,num]))
  }.inject(:+)
end
lower_triangular?() 点击以切换源代码

如果这是一个下三角矩阵,则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 866
def lower_triangular?
  each(:strict_upper).all?(&:zero?)
end
lup() 点击以切换源代码

返回矩阵的 LUP 分解;请参阅 LUPDecomposition

a = Matrix[[1, 2], [3, 4]]
l, u, p = a.lup
l.lower_triangular? # => true
u.upper_triangular? # => true
p.permutation?      # => true
l * u == p * a      # => true
a.lup.solve([2, 5]) # => Vector[(1/1), (1/2)]
# File matrix-0.4.2/lib/matrix.rb, line 1565
def lup
  LUPDecomposition.new(self)
end
lup_decomposition()
别名: lup
map(which = :all)
别名: collect
map!(which = :all)
别名: collect!
minor(*param) 点击以切换源代码

返回矩阵的一部分。 参数为:

  • start_row,nrows,start_col,ncols; 或者

  • row_range,col_range

Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
#  => 9 0 0
#     0 5 0

类似于 Array#[],负索引从行或列的末尾向后计数(-1 是最后一个元素)。 如果起始行或列分别大于 row_countcolumn_count,则返回 nil。

# File matrix-0.4.2/lib/matrix.rb, line 710
def minor(*param)
  case param.size
  when 2
    row_range, col_range = param
    from_row = row_range.first
    from_row += row_count if from_row < 0
    to_row = row_range.end
    to_row += row_count if to_row < 0
    to_row += 1 unless row_range.exclude_end?
    size_row = to_row - from_row

    from_col = col_range.first
    from_col += column_count if from_col < 0
    to_col = col_range.end
    to_col += column_count if to_col < 0
    to_col += 1 unless col_range.exclude_end?
    size_col = to_col - from_col
  when 4
    from_row, size_row, from_col, size_col = param
    return nil if size_row < 0 || size_col < 0
    from_row += row_count if from_row < 0
    from_col += column_count if from_col < 0
  else
    raise ArgumentError, param.inspect
  end

  return nil if from_row > row_count || from_col > column_count || from_row < 0 || from_col < 0
  rows = @rows[from_row, size_row].collect{|row|
    row[from_col, size_col]
  }
  new_matrix rows, [column_count - from_col, size_col].min
end
normal?() 点击以切换源代码

如果这是一个正规矩阵,则返回 true。如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 874
def normal?
  raise ErrDimensionMismatch unless square?
  rows.each_with_index do |row_i, i|
    rows.each_with_index do |row_j, j|
      s = 0
      rows.each_with_index do |row_k, k|
        s += row_i[k] * row_j[k].conj - row_k[i].conj * row_k[j]
      end
      return false unless s == 0
    end
  end
  true
end
orthogonal?() 点击以切换源代码

如果这是一个正交矩阵,则返回 true。如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 892
def orthogonal?
  raise ErrDimensionMismatch unless square?

  rows.each_with_index do |row_i, i|
    rows.each_with_index do |row_j, j|
      s = 0
      row_count.times do |k|
        s += row_i[k] * row_j[k]
      end
      return false unless s == (i == j ? 1 : 0)
    end
  end
  true
end
permutation?() 点击以切换源代码

如果这是一个置换矩阵,则返回 true。如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 911
def permutation?
  raise ErrDimensionMismatch unless square?
  cols = Array.new(column_count)
  rows.each_with_index do |row, i|
    found = false
    row.each_with_index do |e, j|
      if e == 1
        return false if found || cols[j]
        found = cols[j] = true
      elsif e != 0
        return false
      end
    end
    return false unless found
  end
  true
end
rank() 点击以切换源代码

返回矩阵的秩。请注意,使用浮点数值可能会因其精度不足而产生错误的结果。考虑使用精确类型,如 Rational 或 BigDecimal。

Matrix[[7,6], [3,9]].rank
#  => 2
# File matrix-0.4.2/lib/matrix.rb, line 1425
def rank
  # We currently use Bareiss' multistep integer-preserving gaussian elimination
  # (see comments on determinant)
  a = to_a
  last_column = column_count - 1
  last_row = row_count - 1
  pivot_row = 0
  previous_pivot = 1
  0.upto(last_column) do |k|
    switch_row = (pivot_row .. last_row).find {|row|
      a[row][k] != 0
    }
    if switch_row
      a[switch_row], a[pivot_row] = a[pivot_row], a[switch_row] unless pivot_row == switch_row
      pivot = a[pivot_row][k]
      (pivot_row+1).upto(last_row) do |i|
         ai = a[i]
         (k+1).upto(last_column) do |j|
           ai[j] =  (pivot * ai[j] - ai[k] * a[pivot_row][j]) / previous_pivot
         end
       end
      pivot_row += 1
      previous_pivot = pivot
    end
  end
  pivot_row
end
rank_e() 点击以切换源代码

已弃用;请使用 Matrix#rank

# File matrix-0.4.2/lib/matrix.rb, line 1456
def rank_e
  warn "Matrix#rank_e is deprecated; use #rank", uplevel: 1
  rank
end
real() 点击以切换源代码

返回矩阵的实部。

Matrix[[Complex(1,2), Complex(0,1), 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
# File matrix-0.4.2/lib/matrix.rb, line 1622
def real
  collect(&:real)
end
real?() 点击以切换源代码

如果矩阵的所有条目都是实数,则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 932
def real?
  all?(&:real?)
end
rect() 点击以切换源代码

返回一个包含与矩阵的实部和虚部相对应的矩阵的数组。

m.rect == [m.real, m.imag]  # ==> true for all matrices m
# File matrix-0.4.2/lib/matrix.rb, line 1632
def rect
  [real, imag]
end
别名: rectangular
rectangular()
别名: rect
regular?() 点击以切换源代码

如果这是一个正则(即非奇异)矩阵,则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 939
def regular?
  not singular?
end
rotate_entries(rotation = :clockwise) 点击以切换源代码

返回一个具有旋转元素的新矩阵。 参数指定旋转(默认为 ‘:clockwise`)

  • :clockwise, 1, -3, 等: “向右转” - 第一行变为最后一列

  • :half_turn, 2, -2, 等: 第一行变为最后一行,元素顺序相反

  • :counter_clockwise, -1, 3: “向左转” - 第一行变为第一列(但元素顺序相反)

    m = Matrix[ [1, 2], [3, 4] ] r = m.rotate_entries(:clockwise) # => Matrix[[3, 1], [4, 2]]

# File matrix-0.4.2/lib/matrix.rb, line 1473
def rotate_entries(rotation = :clockwise)
  rotation %= 4 if rotation.respond_to? :to_int

  case rotation
  when 0
    dup
  when 1, :clockwise
    new_matrix @rows.transpose.each(&:reverse!), row_count
  when 2, :half_turn
    new_matrix @rows.map(&:reverse).reverse!, column_count
  when 3, :counter_clockwise
    new_matrix @rows.transpose.reverse!, row_count
  else
    raise ArgumentError, "expected #{rotation.inspect} to be one of :clockwise, :counter_clockwise, :half_turn or an integer"
  end
end
round(ndigits=0) 点击以切换源代码

返回一个条目四舍五入到给定精度的矩阵(请参阅 Float#round)

# File matrix-0.4.2/lib/matrix.rb, line 1493
def round(ndigits=0)
  map{|e| e.round(ndigits)}
end
row(i) { |e| ... } 点击以切换源代码

将矩阵的第 i 个行向量作为 Vector 返回(像数组一样从 0 开始)。 当给出一个块时,将迭代该向量的元素。

# File matrix-0.4.2/lib/matrix.rb, line 463
def row(i, &block) # :yield: e
  if block_given?
    @rows.fetch(i){return self}.each(&block)
    self
  else
    Vector.elements(@rows.fetch(i){return nil})
  end
end
row_count() 点击以切换源代码

返回行数。

# File matrix-0.4.2/lib/matrix.rb, line 448
def row_count
  @rows.size
end
别名: row_size
row_size()
别名: row_count
row_vectors() 点击以切换源代码

返回矩阵的行向量数组。 请参阅 Vector

# File matrix-0.4.2/lib/matrix.rb, line 1660
def row_vectors
  Array.new(row_count) {|i|
    row(i)
  }
end
singular?() 点击以切换源代码

如果这是一个奇异矩阵,则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 946
def singular?
  determinant == 0
end
skew_symmetric?()
square?() 点击以切换源代码

如果这是一个方阵,则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 953
def square?
  column_count == row_count
end
symmetric?() 点击以切换源代码

如果这是一个对称矩阵,则返回 true。如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 961
def symmetric?
  raise ErrDimensionMismatch unless square?
  each_with_index(:strict_upper) do |e, row, col|
    return false if e != rows[col][row]
  end
  true
end
t()
别名: transpose
to_a() 点击以切换源代码

返回一个描述矩阵行的数组数组。

# File matrix-0.4.2/lib/matrix.rb, line 1685
def to_a
  @rows.collect(&:dup)
end
to_matrix() 点击以切换源代码

显式转换为 Matrix。 返回 self

# File matrix-0.4.2/lib/matrix.rb, line 1678
def to_matrix
  self
end
to_s() 点击以切换源代码

覆盖 Object#to_s

# File matrix-0.4.2/lib/matrix.rb, line 1720
def to_s
  if empty?
    "#{self.class}.empty(#{row_count}, #{column_count})"
  else
    "#{self.class}[" + @rows.collect{|row|
      "[" + row.collect{|e| e.to_s}.join(", ") + "]"
    }.join(", ")+"]"
  end
end
tr()
别名:trace
trace() 点击切换源代码

返回矩阵的迹(对角线元素之和)。

Matrix[[7,6], [3,9]].trace
#  => 16
# File matrix-0.4.2/lib/matrix.rb, line 1502
def trace
  raise ErrDimensionMismatch unless square?
  (0...column_count).inject(0) do |tr, i|
    tr + @rows[i][i]
  end
end
也别名为:tr
transpose() 点击切换源代码

返回矩阵的转置。

Matrix[[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
# File matrix-0.4.2/lib/matrix.rb, line 1520
def transpose
  return self.class.empty(column_count, 0) if row_count.zero?
  new_matrix @rows.transpose, row_count
end
也别名为:t
unitary?() 点击切换源代码

如果这是一个酉矩阵则返回 true。如果矩阵不是方阵,则引发错误。

# File matrix-0.4.2/lib/matrix.rb, line 986
def unitary?
  raise ErrDimensionMismatch unless square?
  rows.each_with_index do |row_i, i|
    rows.each_with_index do |row_j, j|
      s = 0
      row_count.times do |k|
        s += row_i[k].conj * row_j[k]
      end
      return false unless s == (i == j ? 1 : 0)
    end
  end
  true
end
upper_triangular?() 点击切换源代码

如果这是一个上三角矩阵则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 1003
def upper_triangular?
  each(:strict_lower).all?(&:zero?)
end
vstack(*matrices) 点击切换源代码

返回一个新矩阵,该矩阵是通过将接收器与给定的矩阵垂直堆叠而形成的。

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.vstack(y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]]
# File matrix-0.4.2/lib/matrix.rb, line 1534
def vstack(*matrices)
  self.class.vstack(self, *matrices)
end
zero?() 点击切换源代码

如果这是一个仅包含零元素的矩阵,则返回 true

# File matrix-0.4.2/lib/matrix.rb, line 1010
def zero?
  all?(&:zero?)
end

受保护的实例方法

power_int(exp) 点击切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 1257
          def power_int(exp)
  # assumes `exp` is an Integer > 0
  #
  # Previous algorithm:
  #   build M**2, M**4 = (M**2)**2, M**8, ... and multiplying those you need
  #   e.g. M**0b1011 = M**11 = M * M**2 * M**8
  #                              ^  ^
  #   (highlighted the 2 out of 5 multiplications involving `M * x`)
  #
  # Current algorithm has same number of multiplications but with lower exponents:
  #    M**11 = M * (M * M**4)**2
  #              ^    ^  ^
  #   (highlighted the 3 out of 5 multiplications involving `M * x`)
  #
  # This should be faster for all (non nil-potent) matrices.
  case
  when exp == 1
    self
  when exp.odd?
    self * power_int(exp - 1)
  else
    sqrt = power_int(exp / 2)
    sqrt * sqrt
  end
end

私有实例方法

check_int(val, direction) 点击切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 376
        def check_int(val, direction)
  count = direction == :row ? row_count : column_count
  CoercionHelper.check_int(val, count, direction)
end
check_range(val, direction) 点击切换源代码

返回范围或 nil

# File matrix-0.4.2/lib/matrix.rb, line 370
        def check_range(val, direction)
  return unless val.is_a?(Range)
  count = direction == :row ? row_count : column_count
  CoercionHelper.check_range(val, count, direction)
end
determinant_bareiss() 点击切换源代码

私有。请使用 Matrix#determinant

返回矩阵的行列式,使用 Bareiss 的多步整数保留高斯消元法。它与标准高斯消元法具有相同的计算成本阶数 O(n^3)。中间结果是无分数的,并且复杂度较低。因此,整数矩阵的中间结果也将是整数,且具有较小的 bignum(如果有的话),而浮点数矩阵通常具有精度更高的中间结果。

# File matrix-0.4.2/lib/matrix.rb, line 1368
        def determinant_bareiss
  size = row_count
  last = size - 1
  a = to_a
  no_pivot = Proc.new{ return 0 }
  sign = +1
  pivot = 1
  size.times do |k|
    previous_pivot = pivot
    if (pivot = a[k][k]) == 0
      switch = (k+1 ... size).find(no_pivot) {|row|
        a[row][k] != 0
      }
      a[switch], a[k] = a[k], a[switch]
      pivot = a[k][k]
      sign = -sign
    end
    (k+1).upto(last) do |i|
      ai = a[i]
      (k+1).upto(last) do |j|
        ai[j] =  (pivot * ai[j] - ai[k] * a[k][j]) / previous_pivot
      end
    end
  end
  sign * pivot
end
initialize_copy(m) 点击切换源代码

用于 dup 和 clone 调用。

调用超类方法
# File matrix-0.4.2/lib/matrix.rb, line 1036
        def initialize_copy(m)
  super
  @rows = @rows.map(&:dup) unless frozen?
end
set_col_range(row, col_range, value) 点击切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 432
        def set_col_range(row, col_range, value)
  value = if value.is_a?(Vector)
    value.to_a
  elsif value.is_a?(Matrix)
    raise ErrDimensionMismatch unless value.row_count == 1
    value.row(0).to_a
  else
    Array.new(col_range.size, value)
  end
  raise ErrDimensionMismatch unless col_range.size == value.size
  @rows[row][col_range] = value
end
set_column_vector(row_range, col, value) 点击切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 425
        def set_column_vector(row_range, col, value)
  value.each_with_index do |e, index|
    r = row_range.begin + index
    @rows[r][col] = e
  end
end
set_component(i, j, v)
别名:[]=
set_element(i, j, v)
别名:[]=
set_row_and_col_range(row_range, col_range, value) 点击切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 387
        def set_row_and_col_range(row_range, col_range, value)
  if value.is_a?(Matrix)
    if row_range.size != value.row_count || col_range.size != value.column_count
      raise ErrDimensionMismatch, [
        'Expected a Matrix of dimensions',
        "#{row_range.size}x#{col_range.size}",
        'got',
        "#{value.row_count}x#{value.column_count}",
      ].join(' ')
    end
    source = value.instance_variable_get :@rows
    row_range.each_with_index do |row, i|
      @rows[row][col_range] = source[i]
    end
  elsif value.is_a?(Vector)
    raise ErrDimensionMismatch, 'Expected a Matrix or a value, got a Vector'
  else
    value_to_set = Array.new(col_range.size, value)
    row_range.each do |i|
      @rows[i][col_range] = value_to_set
    end
  end
end
set_row_range(row_range, col, value) 点击切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 411
        def set_row_range(row_range, col, value)
  if value.is_a?(Vector)
    raise ErrDimensionMismatch unless row_range.size == value.size
    set_column_vector(row_range, col, value)
  elsif value.is_a?(Matrix)
    raise ErrDimensionMismatch unless value.column_count == 1
    value = value.column(0)
    raise ErrDimensionMismatch unless row_range.size == value.size
    set_column_vector(row_range, col, value)
  else
    @rows[row_range].each{|e| e[col] = value }
  end
end
set_value(row, col, value) 点击切换源代码
# File matrix-0.4.2/lib/matrix.rb, line 381
        def set_value(row, col, value)
  raise ErrDimensionMismatch, "Expected a value, got a #{value.class}" if value.respond_to?(:to_matrix)

  @rows[row][col] = value
end