class Matrix
An extension to the Ruby Matrix
class. @author Michael Imstepf
Public Class Methods
Concatenates two matrices horizontally (resulting in more columns). @param *matrices [Matrix] matrices @return [Matrix] concatenated matrix @raise [ErrDimensionMismatch] if dimensions don't match @raise [TypeError] if matrices are not of type Matrix
or Vector
# File lib/matrix_extensions.rb, line 20 def self.hconcat(*matrices) columns = [] matrices.each do |m| raise TypeError, "#{m.class} is not a Matrix or Vector" unless m.is_a?(Matrix) || m.is_a?(Vector) # convert Vector to Matrix m = self.convert_vector_to_matrix(m, :column) if m.is_a? Vector # check if dimensions match row_count ||= m.row_count Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count # prepare array of columns m.column_vectors.each do |v| columns << v.to_a end end # create new matrix self.columns(columns) end
Matrix
prefilled with ones. @param rows [Integer] number of rows @param columns [Integer] number of columns @return [Matrix] matrix
# File lib/matrix_extensions.rb, line 11 def self.one(rows = 1, columns = 1) Matrix.build(rows, columns) { 1 } end
Concatenates two matrices vertically (resulting in more rows). @param *matrices [Matrix] matrices @return [Matrix] concatenated matrix @raise [ErrDimensionMismatch] if dimensions don't match @raise [TypeError] if matrices are not of type Matrix
or Vector
# File lib/matrix_extensions.rb, line 47 def self.vconcat(*matrices) rows = [] matrices.each do |m| raise TypeError, "#{m.class} is not a Matrix or Vector" unless m.is_a?(Matrix) || m.is_a?(Vector) # convert Vector to Matrix m = self.convert_vector_to_matrix(m, :row) if m.is_a? Vector # check if dimensions match column_count ||= m.column_count Matrix.Raise ErrDimensionMismatch unless column_count == m.column_count # prepare array of columns m.row_vectors.each do |v| rows << v.to_a end end # create new matrix self.rows(rows) end
Private Class Methods
Convert vector to matrix for arithmetic operations. @param vector [Vector] vector @param dimension [Symbol] :row or :column @return [Matrix] matrix @raise [TypeError] if vector ist not of type Vector
# File lib/matrix_extensions.rb, line 232 def self.convert_vector_to_matrix(v, dimension) raise TypeError, "#{v.class} is not a Vector" unless v.is_a? Vector if dimension == :row self.row_vector(v) elsif dimension == :column self.column_vector(v) else raise ArgumentError end end
Public Instance Methods
Element-wise division. @param m [Matrix] matrix @return [Matrix] matrix @raise [ErrDimensionMismatch] if dimensions don't match
# File lib/matrix_extensions.rb, line 132 def element_division(m) case m when Numeric return self./ m when Vector if row_count > column_count # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch) m = self.class.convert_vector_to_matrix(m, :column) else # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch) m = self.class.convert_vector_to_matrix(m, :row) end 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) do |i| Array.new(column_count) do|j| self[i, j] / m[i, j] end end new_matrix rows, column_count end
Element-wise exponentiation. @param m [Matrix] matrix @return [Matrix] matrix @raise [ErrDimensionMismatch] if dimensions don't match
# File lib/matrix_extensions.rb, line 194 def element_exponentiation(m) case m when Numeric # self.** m will break rows = @rows.collect {|row| row.collect {|e| e ** m } } return new_matrix rows, column_count when Vector if row_count > column_count # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch) m = self.class.convert_vector_to_matrix(m, :column) else # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch) m = self.class.convert_vector_to_matrix(m, :row) end 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) do |i| Array.new(column_count) do|j| self[i, j] ** m[i, j] end end new_matrix rows, column_count end
Element-wise multiplication. @param m [Matrix] matrix @return [Matrix] matrix @raise [ErrDimensionMismatch] if dimensions don't match
# File lib/matrix_extensions.rb, line 163 def element_multiplication(m) case m when Numeric return self.* m when Vector if row_count > column_count # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch) m = self.class.convert_vector_to_matrix(m, :column) else # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch) m = self.class.convert_vector_to_matrix(m, :row) end 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) do |i| Array.new(column_count) do|j| self[i, j] * m[i, j] end end new_matrix rows, column_count end
Copies columns. @param number_of_copies [Integer] number of times columns should be copied @return [Matrix] matrix
# File lib/matrix_extensions.rb, line 116 def hcopy(number_of_copies = 1) rows.each do |row| existing_row = row.clone number_of_copies.times do existing_row.each { |v| row << v } end end @column_count += @column_count * number_of_copies self end
Removes trailing columns from a Matrix
(destructive). @param number_of_columns [Integer] number of trailing columns to be removed @return [Matrix] matrix consisting of of dropped columns @raise [ErrDimensionMismatch] if Matrix
does not have enough columns for operation
# File lib/matrix_extensions.rb, line 73 def hpop(number_of_columns = 1) Matrix.Raise ErrDimensionMismatch unless number_of_columns < self.column_count dropped_columns = [] number_of_columns.times do dropped_column = [] @rows.each {|r| dropped_column << r.pop} dropped_columns << dropped_column end @column_count -= number_of_columns Matrix.columns(dropped_columns.reverse) end
Copies rows. @param number_of_copies [Integer] number of times rows should be copied @return [Matrix] matrix
# File lib/matrix_extensions.rb, line 103 def vcopy(number_of_copies = 1) existing_rows = rows.clone number_of_copies.times do existing_rows.each { |row| rows << row } end self end
Removes trailing rows from a Matrix
(destructive). @param number_of_rows [Integer] number of trailing rows to be removed @return [Matrix] matrix consisting of of dropped rows @raise [ErrDimensionMismatch] if Matrix
does not have enough rows for operation
# File lib/matrix_extensions.rb, line 91 def vpop(number_of_rows = 1) Matrix.Raise ErrDimensionMismatch unless number_of_rows < self.row_count dropped_rows = [] number_of_rows.times { dropped_rows << @rows.pop } Matrix.rows(dropped_rows) end