首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Matrix

Parent:ObjectIncluded modules:Enumerable

Matrix类表示一个数学矩阵。它提供了创建矩阵的方法,以算术和代数方式对它们进行操作,并确定它们的数学属性(迹,秩,反,行列式)。

方法目录

创建一个矩阵:

  • Matrix
  • ::[]
  • ::rows(rows, copy = true)
  • ::columns
  • ::build(row_count, #column_count, &block)
  • ::diagonal
  • ::scalar(n, value)
  • ::identity
  • ::unit
  • Matrix.I(n)
  • ::zero
  • ::row_vector
  • ::column_vector
  • ::empty(row_count, #column_count)
  • ::hstack
  • ::vstack

To access Matrix elements/columns/rows/submatrices/properties:

  • [](i, j)
  • row_count (row_size)
  • column_count (column_size)
  • row(i)
  • column(j)
  • collect
  • map
  • each
  • each_with_index
  • find_index
  • minor(*param)
  • first_minor(row, column)
  • cofactor(row, column)
  • adjugate
  • laplace_expansion(row_or_column: num)
  • cofactor_expansion(row_or_column: num)

矩阵的属性:

  • diagonal?
  • empty?
  • hermitian?
  • lower_triangular?
  • normal?
  • orthogonal?
  • permutation?
  • real?
  • regular?
  • singular?
  • square?
  • symmetric?
  • unitary?
  • upper_triangular?
  • zero?Matrix arithmetic:
  • #*(m)
  • #+(m)
  • #-(m)
  • #/(m)
  • inverse
  • inv
  • #**
  • #+@
  • #-@

矩阵功能:

  • determinant
  • det
  • hstack(*matrices)
  • rank
  • round
  • trace
  • tr
  • transpose
  • t
  • vstack(*matrices)

矩阵分解:

  • eigen
  • eigensystem
  • lup
  • lup_decomposition

复杂的算术:

  • conj
  • conjugate
  • imag
  • imaginary
  • real
  • rect
  • rectangularConversion to other data types:
  • coerce(other)
  • row_vectors
  • column_vectors
  • to_aString representations:
  • to_s
  • inspects

常量

SELECTORS

属性

column_count [R]

返回列数。

column_size [R]

返回列数。

行[R]

实例创作

insp

I(n)

Alias for: identity

[](*rows)

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

Matrix[ [25, 93], [-1, 66] ] => 25 93 -1 66

代码语言:javascript
复制
               # File matrix.rb, line 49
def Matrix.[](*rows)
  rows(rows, false)
end

build(row_count, column_count = row_count)

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

代码语言:javascript
复制
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
代码语言:javascript
复制
               # File matrix.rb, line 94
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

代码语言:javascript
复制
Matrix.column_vector([4,5,6])
  => 4
     5
     6
代码语言:javascript
复制
               # File matrix.rb, line 180
def Matrix.column_vector(column)
  column = convert_to_array(column)
  new [column].transpose, 1
end

columns(columns)

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

代码语言:javascript
复制
Matrix.columns([[25, 93], [-1, 66]])
   =>  25 -1
       93 66
代码语言:javascript
复制
               # File matrix.rb, line 79
def Matrix.columns(columns)
  rows(columns, false).transpose
end

combine(*matrices)

使用给定的块,通过逐列组合矩阵创建矩阵

代码语言:javascript
复制
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]]
代码语言:javascript
复制
               # File matrix.rb, line 257
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|
    Matrix.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

代码语言:javascript
复制
Matrix.diagonal(9, 5, -3)
  =>  9  0  0
      0  5  0
      0  0 -3
代码语言:javascript
复制
               # File matrix.rb, line 114
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_countx的空矩阵column_count。至少有一个row_countcolumn_count必须是0。

代码语言:javascript
复制
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]]

hstack(x, *matrices)

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

代码语言:javascript
复制
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]]
代码语言:javascript
复制
               # File matrix.rb, line 233
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通过n身份矩阵创建。

代码语言:javascript
复制
Matrix.identity(2)
  => 1 0
     0 1
代码语言:javascript
复制
               # File matrix.rb, line 142
def Matrix.identity(n)
  scalar(n, 1)
end

还有别名: unit, I

new(rows, column_count = rows[0].size)

::new 是私人的; 使用 ::rows, columns, [], etc… 来创建。

代码语言:javascript
复制
               # File matrix.rb, line 282
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

代码语言:javascript
复制
Matrix.row_vector([4,5,6])
  => 4 5 6
代码语言:javascript
复制
               # File matrix.rb, line 167
def Matrix.row_vector(row)
  row = convert_to_array(row)
  new [row]
end

rows(rows, copy = true)

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

代码语言:javascript
复制
Matrix.rows([[25, 93], [-1, 66]])
   =>  25 93
       -1 66
代码语言:javascript
复制
               # File matrix.rb, line 61
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通过n每个对角元素所在的对角矩阵创建value

代码语言:javascript
复制
Matrix.scalar(2, 5)
  => 5 0
     0 5
代码语言:javascript
复制
               # File matrix.rb, line 132
def Matrix.scalar(n, value)
  diagonal(*Array.new(n, value))
end

unit(n)

还有别名: identity

vstack(x, *matrices)

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

代码语言:javascript
复制
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]]
代码语言:javascript
复制
               # File matrix.rb, line 212
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)

创建一个零矩阵。

代码语言:javascript
复制
Matrix.zero(2)
  => 0 0
     0 0
代码语言:javascript
复制
               # File matrix.rb, line 156
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)

矩阵乘法。

代码语言:javascript
复制
Matrix[[2,4], [6,8]] * Matrix.identity(2)
  => 2 4
     6 8
代码语言:javascript
复制
               # File matrix.rb, line 879
def *(m) # m is matrix or vector or number
  case(m)
  when Numeric
    rows = @rows.collect {|row|
      row.collect {|e| e * m }
    }
    return new_matrix rows, column_count
  when Vector
    m = self.class.column_vector(m)
    r = self * m
    return r.column(0)
  when Matrix
    Matrix.Raise ErrDimensionMismatch if column_count != m.row_count

    rows = Array.new(row_count) {|i|
      Array.new(m.column_count) {|j|
        (0 ... column_count).inject(0) do |vij, k|
          vij + self[i, k] * m[k, j]
        end
      }
    }
    return new_matrix rows, m.column_count
  else
    return apply_through_coercion(m, __method__)
  end
end

**(other)

矩阵求幂。相当于将矩阵本身乘以N次。非整数指数将通过矩阵对角化来处理。

代码语言:javascript
复制
Matrix[[7,6], [3,9]] ** 2
  => 67 96
     48 99
代码语言:javascript
复制
               # File matrix.rb, line 1057
def **(other)
  case other
  when Integer
    x = self
    if other <= 0
      x = self.inverse
      return self.class.identity(self.column_count) if other == 0
      other = -other
    end
    z = nil
    loop do
      z = z ? z * x : x if other[0] == 1
      return z if (other >>= 1).zero?
      x *= x
    end
  when Numeric
    v, d, v_inv = eigensystem
    v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** other}) * v_inv
  else
    Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class
  end
end

+(m)

矩阵加法。

代码语言:javascript
复制
Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
  =>  6  0
     -4 12
代码语言:javascript
复制
               # File matrix.rb, line 912
def +(m)
  case m
  when Numeric
    Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class
  when Vector
    m = self.class.column_vector(m)
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  Matrix.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

+@()

代码语言:javascript
复制
               # File matrix.rb, line 1080
def +@
  self
end

-(m)

矩阵相减。

代码语言:javascript
复制
Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
  => -8  2
      8  1
代码语言:javascript
复制
               # File matrix.rb, line 939
def -(m)
  case m
  when Numeric
    Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class
  when Vector
    m = self.class.column_vector(m)
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  Matrix.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

-@()

代码语言:javascript
复制
               # File matrix.rb, line 1084
def -@
  collect {|e| -e }
end

/(other)

矩阵分割(乘以逆)。

代码语言:javascript
复制
Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
  => -7  1
     -3 -6
代码语言:javascript
复制
               # File matrix.rb, line 966
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)

返回true当且仅当两个矩阵包含等于元件。

代码语言:javascript
复制
               # File matrix.rb, line 841
def ==(other)
  return false unless Matrix === other &&
                      column_count == other.column_count # necessary for empty matrices
  rows == other.rows
end

[](i, j)click to toggle source

返回矩阵的元素(ij)。那是:行i,列j

代码语言:javascript
复制
               # File matrix.rb, line 298
def [](i, j)
  @rows.fetch(i){return nil}[j]
end

另外别名为 element, component

adjugate()

返回矩阵的辅助对象。

代码语言:javascript
复制
Matrix[ [7,6],[3,9] ].adjugate
  => 9 -6
     -3 7
代码语言:javascript
复制
               # File matrix.rb, line 627
def adjugate
  Matrix.Raise ErrDimensionMismatch unless square?
  Matrix.build(row_count, column_count) do |row, column|
    cofactor(column, row)
  end
end

clone()

返回矩阵的一个副本,以便每个元素的内容不引用相同的对象。由于矩阵是不可变的,因此不应该有这么做的理由。

代码语言:javascript
复制
               # File matrix.rb, line 858
def clone
  new_matrix @rows.map(&:dup), column_count
end

coerce(other)

胁迫方法为Ruby类型强制提供支持。Ruby使用这种强制机制来处理混合类型的数字操作:它旨在找到操作符的两个操作数之间的兼容通用类型。另请参阅Numeric#coerce。

代码语言:javascript
复制
               # File matrix.rb, line 1394
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)

返回通过将第一个小数乘以(-1)**(row + column)获得的(行,列)辅助因子。

代码语言:javascript
复制
Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
  => -108
代码语言:javascript
复制
               # File matrix.rb, line 612
def cofactor(row, column)
  raise RuntimeError, "cofactor of empty matrix is not defined" if empty?
  Matrix.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)

别名为:laplace_expansion

collect()

返回一个矩阵,该矩阵是矩阵中所有元素的给定块迭代的结果。

代码语言:javascript
复制
Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
  => 1  4
     9 16
代码语言:javascript
复制
               # File matrix.rb, line 366
def collect(&block) # :yield: e
  return to_enum(:collect) unless block_given?
  rows = @rows.collect{|row| row.collect(&block)}
  new_matrix rows, column_count
end

另外别名为: map

column(j)

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

代码语言:javascript
复制
               # File matrix.rb, line 343
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()

返回矩阵的列向量数组。请参阅矢量

代码语言:javascript
复制
               # File matrix.rb, line 1415
def column_vectors
  Array.new(column_count) {|i|
    column(i)
  }
end

combine(*matrices, &block)

代码语言:javascript
复制
               # File matrix.rb, line 275
def combine(*matrices, &block)
  Matrix.combine(self, *matrices, &block)
end

component(i, j)

别名: []

conj()

别名: conjugate

conjugate()

返回矩阵的共轭。

代码语言:javascript
复制
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
代码语言:javascript
复制
               # File matrix.rb, line 1340
def conjugate
  collect(&:conjugate)
end

另外别名为conj

det()

别名: determinant

det_e()

别名: determinant_e

determinant()

返回矩阵的行列式。

请注意,使用Float值会因为精度不够而产生错误的结果。考虑使用类似Rational或BigDecimal的确切类型。

代码语言:javascript
复制
Matrix[[7,6], [3,9]].determinant
  => 45
代码语言:javascript
复制
  # File matrix.rb, line 1102
def determinant
  Matrix.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()

deprecated; use #determinant

代码语言:javascript
复制
               # File matrix.rb, line 1184
def determinant_e
  warn "Matrix#determinant_e is deprecated; use #determinant", uplevel: 1
  determinant
end

别名:det_e

diagonal?()

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

代码语言:javascript
复制
               # File matrix.rb, line 673
def diagonal?
  Matrix.Raise ErrDimensionMismatch unless square?
  each(:off_diagonal).all?(&:zero?)
end

each(which = :all)

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

  • :all(默认):产生所有元素
  • :diagonal:仅产生对角线上的元素
  • :off_diagonal:产生除对角线外的所有元素
  • :lower:仅产生对角线上或下方的元素
  • :strict_lower:只产生对角线以下的元素
  • :strict_upper:只产生对角线以上的元素
  • :upper:只产生对角线上的元素

Matrix[ 1,2, 3,4 ].each { |e| puts e }

Matrix[ 1,2, 3,4 ].each(:strict_lower).to_a # => 3

代码语言:javascript
复制
# File lib/matrix.rb, line 462
def each(which = :all) # :yield: e
  return to_enum :each, which unless block_given?
  last = column_count - 1
  case which
  when :all
    block = Proc.new
    @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| ... } Show source

与每个元素相同,除了元素之外,还包括行索引和列索引

代码语言:javascript
复制
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
代码语言:javascript
复制
# File lib/matrix.rb, line 523
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()

别名r: eigensystem

eigensystem() Show source

返回矩阵的Eigensystem; 见EigenvalueDecomposition

代码语言:javascript
复制
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
代码语言:javascript
复制
# File lib/matrix.rb, line 1369
def eigensystem
  EigenvalueDecomposition.new(self)
end

别名: eigen

element(i, j)

别名: []

elements_to_f() Show source

代码语言:javascript
复制
# File lib/matrix.rb, line 1490
def elements_to_f
  warn "#{caller(1)[0]}: warning: Matrix#elements_to_f is deprecated, use map(&:to_f)"
  map(&:to_f)
end

elements_to_i() Show source

代码语言:javascript
复制
# File lib/matrix.rb, line 1495
def elements_to_i
  warn "#{caller(1)[0]}: warning: Matrix#elements_to_i is deprecated, use map(&:to_i)"
  map(&:to_i)
end

elements_to_r() Show source

代码语言:javascript
复制
# File lib/matrix.rb, line 1500
def elements_to_r
  warn "#{caller(1)[0]}: warning: Matrix#elements_to_r is deprecated, use map(&:to_r)"
  map(&:to_r)
end

empty?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 755
def empty?
  column_count == 0 || row_count == 0
end

eql?(other) Show source

代码语言:javascript
复制
# File lib/matrix.rb, line 920
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) Show source

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

代码语言:javascript
复制
Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
  => 9 0 0
     0 0 0
     0 0 4
代码语言:javascript
复制
# File lib/matrix.rb, line 658
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

hash() Show source

返回矩阵的散列码。

代码语言:javascript
复制
# File lib/matrix.rb, line 938
def hash
  @rows.hash
end

hermitian?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 763
def hermitian?
  Matrix.Raise ErrDimensionMismatch unless square?
  each_with_index(:upper).all? do |e, row, col|
    e == rows[col][row].conj
  end
end

hstack(*matrices) Show source

返回一个新的矩阵,通过水平叠加给定矩阵的接收器

代码语言:javascript
复制
x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.hstack(y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]]
代码语言:javascript
复制
# File lib/matrix.rb, line 1260
def hstack(*matrices)
  self.class.hstack(self, *matrices)
end

imag()

别名: imaginary

imaginary() Show source

返回矩阵的虚部。

代码语言:javascript
复制
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
代码语言:javascript
复制
# File lib/matrix.rb, line 1416
def imaginary
  collect(&:imaginary)
end

别名: imag

index(value, selector = :all) → row, column()

index(selector = :all){ block } → row, column

index(selector = :all) → an_enumerator

index方法专用于将索引作为行,列返回。它还接受可选的选择器参数,请参阅每个参数以获取详细信息。

代码语言:javascript
复制
Matrix[ [1,2], [3,4] ].index(&:even?) # => [0, 1]
Matrix[ [1,1], [1,1] ].index(1, :strict_lower) # => [1, 0]
代码语言:javascript
复制
# File lib/matrix.rb, line 586
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() Show source

覆盖对象#检查

代码语言:javascript
复制
# File lib/matrix.rb, line 1525
def inspect
  if empty?
    "#{self.class}.empty(#{row_count}, #{column_count})"
  else
    "#{self.class}#{@rows.inspect}"
  end
end

inv()

别名: inverse

inverse() Show source

返回矩阵的逆。

代码语言:javascript
复制
Matrix[[-1, -1], [0, -1]].inverse
  => -1  1
      0 -1
代码语言:javascript
复制
# File lib/matrix.rb, line 1059
def inverse
  Matrix.Raise ErrDimensionMismatch unless square?
  self.class.I(row_count).send(:inverse_from, self)
end

别名: inv

laplace_expansion(row: nil, column: nil) Show source

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

代码语言:javascript
复制
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]
代码语言:javascript
复制
# File lib/matrix.rb, line 717
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

  Matrix.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

别名: cofactor_expansion

lower_triangular?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 773
def lower_triangular?
  each(:strict_upper).all?(&:zero?)
end

lup() Show source

返回矩阵的LUP分解; 见LUPDecomposition

代码语言:javascript
复制
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)]
代码语言:javascript
复制
# File lib/matrix.rb, line 1384
def lup
  LUPDecomposition.new(self)
end

别名: lup_decomposition

lup_decomposition()

别名: lup

map()

别名: collect

minor(*param) Show source

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

  • start_row, nrows, start_col, ncols; OR
  • row_range, col_range
代码语言:javascript
复制
Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
  => 9 0 0
     0 5 0

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

代码语言:javascript
复制
# File lib/matrix.rb, line 617
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?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 781
def normal?
  Matrix.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?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 799
def orthogonal?
  Matrix.Raise ErrDimensionMismatch unless square?
  rows.each_with_index do |row, i|
    column_count.times do |j|
      s = 0
      row_count.times do |k|
        s += row[k] * rows[k][j]
      end
      return false unless s == (i == j ? 1 : 0)
    end
  end
  true
end

permutation?() Show source

如果这是置换矩阵,则返回true,如果矩阵不是平方,则返回错误。

代码语言:javascript
复制
# File lib/matrix.rb, line 817
def permutation?
  Matrix.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() Show source

返回矩阵的等级。请注意,使用Float值会因为精度不够而产生错误的结果。考虑使用类似Rational或BigDecimal的确切类型。

代码语言:javascript
复制
Matrix[[7,6], [3,9]].rank
  => 2
代码语言:javascript
复制
# File lib/matrix.rb, line 1273
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() Show source

deprecated; use #rank

代码语言:javascript
复制
# File lib/matrix.rb, line 1304
def rank_e
  warn "#{caller(1)[0]}: warning: Matrix#rank_e is deprecated; use #rank"
  rank
end

real() Show source

返回矩阵的实部。

代码语言:javascript
复制
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
代码语言:javascript
复制
# File lib/matrix.rb, line 1430
def real
  collect(&:real)
end

real?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 838
def real?
  all?(&:real?)
end

rect() Show source

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

m.rect == m.real, m.imag # ==> true for all matrices m

代码语言:javascript
复制
# File lib/matrix.rb, line 1440
def rect
  [real, imag]
end

别名: rectangular

rectangular()

别名: rect

regular?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 845
def regular?
  not singular?
end

round(ndigits=0) Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 1312
def round(ndigits=0)
  map{|e| e.round(ndigits)}
end

row(i) { |e| ... } Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 402
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() Show source

返回行数。

代码语言:javascript
复制
# File lib/matrix.rb, line 387
def row_count
  @rows.size
end

另外别名为:row_size

row_size()

别名为:row_count

row_vectors() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 1468
def row_vectors
  Array.new(row_count) {|i|
    row(i)
  }
end

singular?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 852
def singular?
  determinant == 0
end

square?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 859
def square?
  column_count == row_count
end

symmetric?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 867
def symmetric?
  Matrix.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() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 1486
def to_a
  @rows.collect(&:dup)
end

to_s() Show source

Overrides Object#to_s

代码语言:javascript
复制
# File lib/matrix.rb, line 1512
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()

别名r: trace

trace() Show source

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

代码语言:javascript
复制
Matrix[[7,6], [3,9]].trace
  => 16
代码语言:javascript
复制
# File lib/matrix.rb, line 1321
def trace
  Matrix.Raise ErrDimensionMismatch unless square?
  (0...column_count).inject(0) do |tr, i|
    tr + @rows[i][i]
  end
end

别名: tr

transpose() Show source

返回矩阵的转置。

代码语言:javascript
复制
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
代码语言:javascript
复制
# File lib/matrix.rb, line 1339
def transpose
  return self.class.empty(column_count, 0) if row_count.zero?
  new_matrix @rows.transpose, row_count
end

别名: t

unitary?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 879
def unitary?
  Matrix.Raise ErrDimensionMismatch unless square?
  rows.each_with_index do |row, i|
    column_count.times do |j|
      s = 0
      row_count.times do |k|
        s += row[k].conj * rows[k][j]
      end
      return false unless s == (i == j ? 1 : 0)
    end
  end
  true
end

upper_triangular?() Show source

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

代码语言:javascript
复制
# File lib/matrix.rb, line 896
def upper_triangular?
  each(:strict_lower).all?(&:zero?)
end

vstack(*matrices) Show source

通过垂直堆叠给定矩阵的接收器返回一个新矩阵

代码语言:javascript
复制
x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.vstack(y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]]
代码语言:javascript
复制
# File lib/matrix.rb, line 1353
def vstack(*matrices)
  self.class.vstack(self, *matrices)
end

zero?() Show source

如果这是一个只有零元素的矩阵,则返回true

代码语言:javascript
复制
# File lib/matrix.rb, line 903
def zero?
  all?(&:zero?)
end

私有实例方法

[]=(i, j, v) Show source

代码语言:javascript
复制
# File lib/matrix.rb, line 377
def []=(i, j, v)
  @rows[i][j] = v
end

别名: set_element, set_component

determinant_bareiss() Show source

Private. Use #determinant

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

代码语言:javascript
复制
# File lib/matrix.rb, line 1215
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

set_component(i, j, v)

别名: []=

set_element(i, j, v)

别名: []=

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com