Spec-Zone.ru › Ruby 2.5

класс Matrix

Родитель:
Объект
Включенные модули:
Enumerable

Класс Matrix представляет собой математическую матрицу. Он предоставляет методы для создания матриц, выполнения арифметических и алгебраических операций с ними, а также определения их математических свойств, таких как след, ранг, обратная матрица, определитель или собственная система.

Константы

SELECTORS

Атрибуты

column_count[R]

Возвращает количество столбцов.

column_size[R]

Возвращает количество столбцов.

rows[R]

создание экземпляров

Публичные методы класса

I(n)
Псевдоним для: identity
[](*rows) Показать исходный код
# File lib/matrix.rb, line 49
def Matrix.[](*rows)
  rows(rows, false)
end

Создаёт матрицу, где каждый аргумент — строка.

Matrix[ [25, 93], [-1, 66] ]
   =>  25 93
       -1 66
build(row_count, column_count = row_count) { |i, j| ... } Показать исходный код
# File lib/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

Создаёт матрицу размером row_count х 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
column_vector(column) Показать исходный код
# File lib/matrix.rb, line 180
def Matrix.column_vector(column)
  column = convert_to_array(column)
  new [column].transpose, 1
end

Создаёт матрицу с одним столбцом, где значения этого столбца заданы в column.

Matrix.column_vector([4,5,6])
  => 4
     5
     6
columns(columns) Показать исходный код
# File lib/matrix.rb, line 79
def Matrix.columns(columns)
  rows(columns, false).transpose
end

Создаёт матрицу, используя columns в качестве массива столбцов.

Matrix.columns([[25, 93], [-1, 66]])
   =>  25 -1
       93 66
combine(*matrices) { |map{|m| m}| ... } Показать исходный код
# File lib/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

Создаёт матрицу путём объединения матриц по элементно, используя переданный блок.

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]]
diagonal(*values) Показать исходный код
# File lib/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

Создаёт матрицу, где диагональные элементы состоят из values.

Matrix.diagonal(9, 5, -3)
  =>  9  0  0
      0  5  0
      0  0 -3
empty(row_count = 0, column_count = 0) Показать исходный код
# File lib/matrix.rb, line 198
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

Создаёт пустую матрицу размером row_count х column_count. По крайней мере, один из row_count или column_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]]
hstack(x, *matrices) Показать исходный код
# File lib/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

Создаёт матрицу путём горизонтального объединения матриц.

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]]
identity(n) Показать исходный код
# File lib/matrix.rb, line 142
def Matrix.identity(n)
  scalar(n, 1)
end

Создаёт единичную матрицу размером n х n.

Matrix.identity(2)
  => 1 0
     0 1
Также алиас для: unit, I
new(rows, column_count = rows[0].size) Показать исходный код
# File lib/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

::new — это приватный метод; используйте ::rows, columns, [], и т. д. для создания.

row_vector(row) Показать исходный код
# File lib/matrix.rb, line 167
def Matrix.row_vector(row)
  row = convert_to_array(row)
  new [row]
end

Создаёт матрицу с одной строкой, где значения этой строки заданы в row.

Matrix.row_vector([4,5,6])
  => 4 5 6
rows(rows, copy = true) Показать исходный код
# File lib/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

Создаёт матрицу, где rows — массив массивов, каждый из которых — строка матрицы. Если необязательный аргумент copy равен false, используйте заданные массивы в качестве внутренней структуры матрицы без копирования.

Matrix.rows([[25, 93], [-1, 66]])
   =>  25 93
       -1 66
scalar(n, value) Показать исходный код
# File lib/matrix.rb, line 132
def Matrix.scalar(n, value)
  diagonal(*Array.new(n, value))
end

Создаёт n х n диагональную матрицу, где каждый диагональный элемент равен value.

Matrix.scalar(2, 5)
  => 5 0
     0 5
unit(n)
Псевдоним для: identity
vstack(x, *matrices) Показать исходный код
# File lib/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

Создаёт матрицу путём вертикального объединения матриц.

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]]
zero(row_count, column_count = row_count) Показать исходный код
# File lib/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

Создаёт нулевую матрицу.

Matrix.zero(2)
  => 0 0
     0 0

Методы экземпляра public

*(m) Показать исходный код
# File lib/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

Умножение матриц.

Matrix[[2,4], [6,8]] * Matrix.identity(2)
  => 2 4
     6 8
**(other) Показать исходный код
# File lib/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

Возведение матрицы в степень. Эквивалентно умножению матрицы на себя N раз. Для нецелых показателей степени матрица будет диагонализована.

Matrix[[7,6], [3,9]] ** 2
  => 67 96
     48 99
+(m) Показать исходный код
# File lib/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

Сложение матриц.

Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
  =>  6  0
     -4 12
+@() Показать исходный код
# File lib/matrix.rb, line 1080
def +@
  self
end
-(m) Показать исходный код
# File lib/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

Вычитание матриц.

Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
  => -8  2
      8  1
-@() Показать исходный код
# File lib/matrix.rb, line 1084
def -@
  collect {|e| -e }
end
/(other) Показать исходный код
# File lib/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

Деление матриц (умножение на обратную матрицу).

Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
  => -7  1
     -3 -6
==(other) Показать исходный код
# File lib/matrix.rb, line 841
def ==(other)
  return false unless Matrix === other &&
                      column_count == other.column_count # necessary for empty matrices
  rows == other.rows
end

Возвращает true, если и только если две матрицы содержат одинаковые элементы.

[](i, j) Показать исходный код
# File lib/matrix.rb, line 298
def [](i, j)
  @rows.fetch(i){return nil}[j]
end

Возвращает элемент (i, j) матрицы. То есть: строка i, столбец j.

Также алиасируется как: element, component
adjugate() Показать исходный код
# File lib/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

Возвращает присоединённую матрицу.

Matrix[ [7,6],[3,9] ].adjugate
  => 9 -6
     -3 7
clone() Показать исходный код
# File lib/matrix.rb, line 858
def clone
  new_matrix @rows.map(&:dup), column_count
end

Возвращает копию матрицы, чтобы содержимое каждой не ссылалось на идентичные объекты. Для этого нет хорошей причины, так как матрицы неизменяемы.

coerce(other) Показать исходный код
# File lib/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

Метод coerce предоставляет поддержку приведения типов в Ruby. Этот механизм приведения используется Ruby для обработки операций с числами разных типов: он предназначен для поиска совместимого общего типа между двумя операндами оператора. См. также Numeric#coerce.

cofactor(row, column) Показать исходный код
# File lib/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

Возвращает алгебраическое дополнение (row, column), которое получается умножением первого минора на (-1)**(row + column).

Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
  => -108
cofactor_expansion(row: nil, column: nil)
Псевдоним для: laplace_expansion
collect() { |e| ... } Показать исходный код
# File lib/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

Возвращает матрицу, которая является результатом итерации заданного блока по всем элементам матрицы.

Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
  => 1  4
     9 16
Также алиасируется как: map
column(j) { |e| ... } Показать исходный код
# File lib/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

Возвращает вектор-столбец номер j матрицы в виде вектора (начиная с 0, как в массиве). При указании блока элементы этого вектора итерируются.

column_vectors() Показать исходный код
# File lib/matrix.rb, line 1415
def column_vectors
  Array.new(column_count) {|i|
    column(i)
  }
end

Возвращает массив векторов-столбцов матрицы. См. вектор.

combine(*matrices, &block) Показать исходный код
# File lib/matrix.rb, line 275
def combine(*matrices, &block)
  Matrix.combine(self, *matrices, &block)
end
component(i, j)
Псевдоним для: []
conj()
Псевдоним для: conjugate
conjugate() Показать исходный код
# File lib/matrix.rb, line 1340
def conjugate
  collect(&:conjugate)
end

Возвращает сопряжённую матрицу.

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
Также алиасируется как: conj
det()
Псевдоним для: determinant
det_e()
Псевдоним для: determinant_e
determinant() Показать исходный код
# File lib/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

Возвращает определитель матрицы.

Обратите внимание, что использование значений типа Float может привести к ошибочным результатам из-за отсутствия точности. Вместо этого рассмотрите использование точных типов, таких как Rational или BigDecimal.

Matrix[[7,6], [3,9]].determinant
  => 45
Также алиасируется как: det
determinant_e() Показать исходный код
# File lib/matrix.rb, line 1184
def determinant_e
  warn "Matrix#determinant_e is deprecated; use #determinant", uplevel: 1
  determinant
end

устарело; используйте #determinant

Также алиасируется как: det_e
diagonal?() Показать исходный код
# File lib/matrix.rb, line 673
def diagonal?
  Matrix.Raise ErrDimensionMismatch unless square?
  each(:off_diagonal).all?(&:zero?)
end

Возвращает true, если это диагональная матрица. Вызовет ошибку, если матрица не квадратная.

END_OF_DOCUMENT_MARKER
each(which = :all) { |e| ... } Показать исходный код
# File lib/matrix.rb, line 389
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

Возвращает все элементы матрицы, начиная с элементов первой строки, или возвращает перечислитель Enumerator, если блок не задан. Элементы могут быть ограничены передачей аргумента:

  • :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]

each_with_index(which = :all) { |e, row, column| ... } Показать исходный код
# File lib/matrix.rb, line 450
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

Аналогично 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
eigen()
Псевдоним для: eigensystem
eigensystem() Показать исходный код
# File lib/matrix.rb, line 1307
def eigensystem
  EigenvalueDecomposition.new(self)
end

Возвращает систему собственных значений матрицы; см. 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
Также псевдоним для: eigen
element(i, j)
Псевдоним для: []
elements_to_f() Показать исходный код
# File lib/matrix.rb, line 1435
def elements_to_f
  warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1
  map(&:to_f)
end
elements_to_i() Показать исходный код
# File lib/matrix.rb, line 1440
def elements_to_i
  warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1
  map(&:to_i)
end
elements_to_r() Показать исходный код
# File lib/matrix.rb, line 1445
def elements_to_r
  warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1
  map(&:to_r)
end
empty?() Показать исходный код
# File lib/matrix.rb, line 682
def empty?
  column_count == 0 || row_count == 0
end

Возвращает true , если эта матрица пустая, т.е. если число строк или число столбцов равно 0.

entrywise_product(m)
Псевдоним для: hadamard_product
eql?(other) Показать исходный код
# File lib/matrix.rb, line 847
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) Показать исходный код
# File lib/matrix.rb, line 585
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

Возвращает подматрицу, полученную путём удаления указанной строки и столбца.

Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
  => 9 0 0
     0 0 0
     0 0 4
hadamard_product(m) Показать исходный код
# File lib/matrix.rb, line 986
def hadamard_product(m)
  combine(m){|a, b| a * b}
end

Произведение Адамара

Matrix[[1,2], [3,4]].hadamard_product(Matrix[[1,2], [3,2]])
  => 1  4
     9  8
Также псевдоним для: entrywise_product
hash() Показать исходный код
# File lib/matrix.rb, line 865
def hash
  @rows.hash
end

Возвращает хэш-код для матрицы.

hermitian?() Показать исходный код
# File lib/matrix.rb, line 690
def hermitian?
  Matrix.Raise ErrDimensionMismatch unless square?
  each_with_index(:upper).all? do |e, row, col|
    e == rows[col][row].conj
  end
end

Возвращает true , если это эрмитова матрица. Вызывает ошибку, если матрица не квадратная.

hstack(*matrices) Показать исходный код
# File lib/matrix.rb, line 1198
def hstack(*matrices)
  self.class.hstack(self, *matrices)
end

Возвращает новую матрицу, полученную горизонтальной укладкой матрицы-приёмника вместе с заданными матрицами

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.hstack(y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]]
imag()
Псевдоним для: imaginary
imaginary() Показать исходный код
# File lib/matrix.rb, line 1354
def imaginary
  collect(&:imaginary)
end

Возвращает мнимую часть матрицы.

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
Также псевдоним для: imag
index(value, selector = :all) → [row, column] Показать исходный код
index(selector = :all){ block } → [row, column]
index(selector = :all) → an_enumerator
# File lib/matrix.rb, line 513
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

Метод index специализирован для возвращения индекса в формате [строка, столбец]. Он также принимает необязательный selector аргумент, см. each для подробностей.

Matrix[ [1,2], [3,4] ].index(&:even?) # => [0, 1]
Matrix[ [1,1], [1,1] ].index(1, :strict_lower) # => [1, 0]
Также псевдоним для: find_index
inspect() Показать исходный код
# File lib/matrix.rb, line 1470
def inspect
  if empty?
    "#{self.class}.empty(#{row_count}, #{column_count})"
  else
    "#{self.class}#{@rows.inspect}"
  end
end

Переопределяет Object#inspect

inv()
Псевдоним для: inverse
inverse() Показать исходный код
# File lib/matrix.rb, line 997
def inverse
  Matrix.Raise ErrDimensionMismatch unless square?
  self.class.I(row_count).send(:inverse_from, self)
end

Возвращает обратную матрицу.

Matrix[[-1, -1], [0, -1]].inverse
  => -1  1
      0 -1
Также псевдоним для: inv
laplace_expansion(row: nil, column: nil) Показать исходный код
# File lib/matrix.rb, line 644
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

Возвращает разложение Лапласа по заданной строке или столбцу.

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]
Также псевдоним для: cofactor_expansion
lower_triangular?() Показать исходный код
# File lib/matrix.rb, line 700
def lower_triangular?
  each(:strict_upper).all?(&:zero?)
end

Возвращает true , если это нижняя треугольная матрица.

lup() Показать исходный код
# File lib/matrix.rb, line 1322
def lup
  LUPDecomposition.new(self)
end

Возвращает LU-разложение матрицы; см. 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)]
Также используется как: lup_decomposition
lup_decomposition()
Псевдоним для: lup
map()
Псевдоним для: collect
minor(*param) Показать исходный код
# File lib/matrix.rb, line 544
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

Возвращает фрагмент матрицы. Параметры могут быть:

  • начальная_строка, кол-во_строк, начальный_столбец, кол-во_столбцов; ИЛИ

  • диапазон_строк, диапазон_столбцов

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

Аналогично Array#[], отрицательные индексы считаются от конца строки или столбца (-1 — последний элемент). Возвращает nil, если начальная строка или столбец больше #row_count или #column_count соответственно.

normal?() Показать исходный код
# File lib/matrix.rb, line 708
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

Возвращает true, если это нормальная матрица. Вызывает ошибку, если матрица не квадратная.

orthogonal?() Показать исходный код
# File lib/matrix.rb, line 726
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

Возвращает true, если это ортогональная матрица. Вызывает ошибку, если матрица не квадратная.

permutation?() Показать исходный код
# File lib/matrix.rb, line 744
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

Возвращает true, если это перестановки матрица. Вызывает ошибку, если матрица не квадратная.

rank() Показать исходный код
# File lib/matrix.rb, line 1211
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

Возвращает ранг матрицы. Имейте в виду, что использование значений Float может привести к ошибочным результатам из-за их недостаточной точности. Вместо этого следует использовать точные типы, такие как Rational или BigDecimal.

Matrix[[7,6], [3,9]].rank
  => 2
rank_e() Показать исходный код
# File lib/matrix.rb, line 1242
def rank_e
  warn "Matrix#rank_e is deprecated; use #rank", uplevel: 1
  rank
end

устаревшее; используйте #rank

real() Показать исходный код
# File lib/matrix.rb, line 1368
def real
  collect(&:real)
end

Возвращает вещественную часть матрицы.

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
real?() Показать исходный код
# File lib/matrix.rb, line 765
def real?
  all?(&:real?)
end

Возвращает true, если все элементы матрицы вещественные.

rect() Показать исходный код
# File lib/matrix.rb, line 1378
def rect
  [real, imag]
end

Возвращает массив, содержащий матрицы, соответствующие действительной и мнимой частям матрицы

m.rect == [m.real, m.imag] # ==> true для всех матриц m

Также используется как: rectangular
rectangular()
Псевдоним для: rect
regular?() Показать исходный код
# File lib/matrix.rb, line 772
def regular?
  not singular?
end

Возвращает true, если это правильная (т.е. невырожденная) матрица.

round(ndigits=0) Показать исходный код
# File lib/matrix.rb, line 1250
def round(ndigits=0)
  map{|e| e.round(ndigits)}
end

Возвращает матрицу с элементами, округлёнными до заданной точности (см. Float#round)

row(i) { |e| ... } Показать исходный код
# File lib/matrix.rb, line 329
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

Возвращает вектор строки с номером i матрицы в виде Vector (начинается с 0, как и массив). При указании блока элементы этого вектора итерируются.

row_count() Показать исходный код
# File lib/matrix.rb, line 314
def row_count
  @rows.size
end

Возвращает количество строк.

Также используется как: row_size
row_size()
Псевдоним для: row_count
row_vectors() Показать исходный код
# File lib/matrix.rb, line 1406
def row_vectors
  Array.new(row_count) {|i|
    row(i)
  }
end

Возвращает массив векторов строк матрицы. См. Vector.

singular?() Показать исходный код
# File lib/matrix.rb, line 779
def singular?
  determinant == 0
end

Возвращает true, если это вырожденная матрица.

square?() Показать исходный код
# File lib/matrix.rb, line 786
def square?
  column_count == row_count
end

Возвращает true, если это квадратная матрица.

symmetric?() Показать исходный код
# File lib/matrix.rb, line 794
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

Возвращает true, если это симметричная матрица. Вызывает ошибку, если матрица не квадратная.

t()
Псевдоним для: transpose
to_a() Показать исходный код
# File lib/matrix.rb, line 1431
def to_a
  @rows.collect(&:dup)
end

Возвращает массив массивов, описывающих строки матрицы.

to_matrix() Показать исходный код
# File lib/matrix.rb, line 1424
def to_matrix
  self
end

Явное преобразование в Matrix. Возвращает self

to_s() Показать исходный код
# File lib/matrix.rb, line 1457
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

Переопределяет Object#to_s

tr()
Псевдоним для: trace
trace() Показать исходный код
# File lib/matrix.rb, line 1259
def trace
  Matrix.Raise ErrDimensionMismatch unless square?
  (0...column_count).inject(0) do |tr, i|
    tr + @rows[i][i]
  end
end

Возвращает след (сумму диагональных элементов) матрицы.

Matrix[[7,6], [3,9]].trace
  => 16
Также алиасируется как: tr
transpose() Показать исходный код
# File lib/matrix.rb, line 1277
def transpose
  return self.class.empty(column_count, 0) if row_count.zero?
  new_matrix @rows.transpose, row_count
end

Возвращает транспонированную матрицу.

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
Также алиасируется как: t
unitary?() Показать исходный код
# File lib/matrix.rb, line 806
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

Возвращает true, если это унитарная матрица. Вызывает ошибку, если матрица не квадратная.

upper_triangular?() Показать исходный код
# File lib/matrix.rb, line 823
def upper_triangular?
  each(:strict_lower).all?(&:zero?)
end

Возвращает true, если это верхняя треугольная матрица.

vstack(*matrices) Показать исходный код
# File lib/matrix.rb, line 1291
def vstack(*matrices)
  self.class.vstack(self, *matrices)
end

Возвращает новую матрицу, полученную путем вертикального объединения текущей матрицы с заданными матрицами.

x = Matrix[[1, 2], [3, 4]]
y = Matrix[[5, 6], [7, 8]]
x.vstack(y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]]
zero?() Показать исходный код
# File lib/matrix.rb, line 830
def zero?
  all?(&:zero?)
end

Возвращает true, если это матрица, содержащая только нулевые элементы.

Приватные методы экземпляра

[]=(i, j, v) Показать исходный код
# File lib/matrix.rb, line 304
def []=(i, j, v)
  @rows[i][j] = v
end
Также алиасируется как: set_element, set_component
determinant_bareiss() Показать исходный код
# File lib/matrix.rb, line 1153
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

Приватный. Используйте #determinant

Возвращает определитель матрицы, используя алгоритм Гаусса с устранением Барейса для целочисленных матриц. Он имеет тот же порядок вычислительной сложности O(n^3), что и стандартное исключение Гаусса. Промежуточные результаты без дробей и с меньшей сложностью. Матрица целых чисел будет иметь, таким образом, промежуточные результаты, которые также являются целыми числами, с меньшими bignums (если таковые имеются), в то время как матрица Float обычно будет иметь промежуточные результаты с лучшей точностью.

set_component(i, j, v)
Псевдоним для: []=
set_element(i, j, v)
Псевдоним для: []=

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API