class Matrix
Public Class Methods
Creates a matrix where the diagonal elements are composed of values.
# File lib/matrix_gem/matrix.rb, line 37 def diagonal(*nums) raise ArgumentError, "Matrix values can't be nil" if nums.include? nil size = nums.length matrix_values = [] Array.new(size) { |i| Array.new(size) do |j| if i == j matrix_values << nums[i] else matrix_values << 0 end end } Matrix.new(size, size, *(matrix_values)) end
Creates an n by n identity matrix.
# File lib/matrix_gem/matrix.rb, line 53 def identity(n) Matrix.new n, n end
# File lib/matrix_gem/matrix.rb, line 12 def initialize(rows, cols, *nums) if rows < 1 || cols < 1 raise MatrixArgumentError, "Rows and Columns should be positive numbers!" elsif ((cols.is_a? Float) || (rows.is_a? Float)) raise MatrixArgumentError, "Dimension of matrix can't be floating point number" elsif nums.length == 0 @matrix = identity rows elsif rows * cols == nums.length @matrix = matrix_with_values nums, cols else raise MatrixArgumentError, "Wrong number of arguments (#{2 + nums.length} for #{2 + rows * cols})" end @matrix end
Creates an n by n zero matrix.
# File lib/matrix_gem/matrix.rb, line 31 def zero(n) values = Array.new(n*n, 0) Matrix.new n, n, *(values) end
Public Instance Methods
Matrix
multiplication.
# File lib/matrix_gem/matrix.rb, line 77 def *(matrix) case(matrix) when Numeric new_matrix_values = [] self.each { |x| new_matrix_values << x * matrix } Matrix.new self.m, self.n, *(new_matrix_values) when Matrix multiply_validation self, matrix rows = Array.new(self.m) { |i| Array.new(matrix.n) { |j| (0 ... self.n).inject(0) do |vij, k| vij + self[i, k] * matrix[k, j] end } } values = [] rows.each{ |x| x.each { |y| values << y} } Matrix.new self.m, matrix.n, *(values) end end
Matrix
exponentiation. Equivalent to multiplying the matrix by itself N times.
# File lib/matrix_gem/matrix.rb, line 272 def **(n) raise MatrixArgumentError if !(n.is_a? Integer) matrix = Matrix.identity(self.m) n.times { |_| matrix *= self } if self.square? matrix end
Return the sum of two matrices in new matrix Raises an error if matrices dimension mismatch.
# File lib/matrix_gem/matrix.rb, line 60 def +(matrix) sum_validation(self, matrix) values = self.zip(matrix).map{ |i| i.inject(:+) } Matrix.new self.m, self.n, *(values) end
Return the difference of two matrices in new matrix. Raises an error if matrices dimension mismatch.
# File lib/matrix_gem/matrix.rb, line 69 def -(matrix) sum_validation(self, matrix) values = self.zip(matrix).map{|i| i.inject(:-)} Matrix.new self.m, self.n, *(values) end
Matrix
division (multiplication by the inverse).
# File lib/matrix_gem/matrix.rb, line 99 def /(matrix) case matrix when Numeric new_matrix_values = [] self.each { |x| new_matrix_values << x / matrix.to_f } Matrix.new self.m, self.n, *(new_matrix_values) when Matrix self * matrix.inversed end end
Returns true if and only if the two matrices contain equal elements.
# File lib/matrix_gem/matrix.rb, line 160 def ==(matrix) (0..self.m-1).each do |i| (0..self.n-1).each do |j| return false if self[i][j] != matrix[i][j] end end true end
Returns element (i,j) of the matrix. That is: row i, column j. If only i is given return row. That is: row with index i.
# File lib/matrix_gem/matrix.rb, line 112 def [](i, j = nil) if j == nil @matrix[i] else @matrix[i][j] end end
Set element (i,j) of the matrix. That is: row i, column j. Set row i of the matrix if j is not given. That is: column j. Also aliased as set_element
# File lib/matrix_gem/matrix.rb, line 123 def []=(i, j = nil, val) if j == nil raise ErrDimensionMismatch if val.length != self.m @matrix[i] = val elsif (i < self.m && j < self.n) @matrix[i][j] = val end end
Returns the determinant of the matrix. Also alised as determinant()
# File lib/matrix_gem/matrix.rb, line 171 def det is_square_validation self _this = copy(self) c = 1 new_matrix = nil size = _this.n (0..size - 2).each do |i| (i + 1..size -1).each do |j| if _this[i][i] == 0 (i+1..size-1).each do |k| if _this[k,i] != 0 swap_rows(_this, k, i) c *= -1 end end end if _this[i,i] == 0 return 0 end new_matrix = cauchy_method(_this, i, j, -_this[j,i]/_this[i,i].to_f) end end det = 1 (0..size-1).each do |i| det *= new_matrix[i][i] end det *= c det.round end
Each method.
# File lib/matrix_gem/matrix.rb, line 151 def each @matrix.each do |sub_arr| sub_arr.each do |value| yield value end end end
Chanege matrix to its inversed.
# File lib/matrix_gem/matrix.rb, line 254 def inverse elements = [] self.inversed.each{ |x| elements << x} @matrix = elements.each_slice(@matrix[0].length).to_a self end
Returns new matrix witch is the inverse of the matrix.
# File lib/matrix_gem/matrix.rb, line 209 def inversed is_square_validation self raise ErrZeroDeterminant if self.det == 0 _this = copy(self) c = 1 e = Matrix.new _this.m, _this.n size = _this.m (0..size-2).each do |i| (i+1..size-1).each do |j| if _this[i, i] == 0 (i..size-2).each do |k| if _this[k, i] != 0 swap_rows(_this, k, i) swap_rows(e, k, i) c *= -1 end end end return 0 if _this[i, i] == 0 cauchy_method(e, i, j, -_this[j, i]/_this[i, i].to_f) cauchy_method(_this, i, j, -_this[j, i]/_this[i, i].to_f) end end (0..size-2).each do |i| (i+1..size-1).each do |j| cauchy_method(e, size-i-1, size-j-1, -_this[size-j-1, size-i-1]/_this[size-i-1, size-i-1]) cauchy_method(_this, size-i-1, size-j-1, -_this[size-j-1, size-i-1]/_this[size-i-1, size-i-1]) end end (0..size-1).each do |i| e.set_row i, multiply_row(e, i, 1/_this[i,i]) _this.set_row i, multiply_row(_this, i, 1/_this[i,i]) end Matrix.new self.m, self.m, *(e) end
Returns a section of the matrix. The parameters are: row_range, col_range
# File lib/matrix_gem/matrix.rb, line 281 def minor(*param) row_range, col_range = param from_row = row_range.first form_row += self.m if from_row < 0 to_row = row_range.end to_row += self.m 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 += self.n if from_col < 0 to_col = col_range.end to_col += self.n if from_col < 0 to_col += 1 unless col_range.exclude_end? size_col = to_col - from_col return nil if from_row > row_count || from_col > column_count || from_row < 0 || from_col < 0 rows = @matrix[from_row, size_row].collect{ |row| row[from_col, size_col] } values = [] rows.each{ |row| row.each {|val| values << val } } Matrix.new [self.m - from_row, size_row].min, [self.n - from_col, size_col].min, *(values) end
To stirng method.
# File lib/matrix_gem/matrix.rb, line 262 def to_str a = "Matrix\n" + @matrix.map do |row| "[" + row.map do |e| e.to_s end.join(" ") + "]" end.join(",\n") puts a end
Transpose the matrix. Also aliased as t().
# File lib/matrix_gem/matrix.rb, line 142 def transpose elements = [] @matrix.to_a.transpose.map{ |x| x.map{ |y| elements << y } } @matrix = elements.each_slice(@matrix[0].length).to_a self end
Return a new matrix which is the transposition of the given one.
# File lib/matrix_gem/matrix.rb, line 134 def transposed elements = [] @matrix.to_a.transpose.map{ |x| x.map{ |y| elements << y } } Matrix.new self.m, self.n, *(elements) end
Private Instance Methods
Multiply the first row elements with multiplier and sum it with second row elements. Used to make matrix in triangular form.
# File lib/matrix_gem/matrix.rb, line 322 def cauchy_method(_this, row1_index, row2_index, multiplier) _this.row(row2_index).each_with_index do |row_element, i| _this.row(row2_index)[i] += _this[row1_index][i] * multiplier end _this end
Return new instance of Matrix
with same values.
# File lib/matrix_gem/matrix.rb, line 313 def copy(_this) values = [] _this.each{ |row| values << row } copy = Matrix.new _this.m, _this.n, *(values) end
Make Identity matrix.
# File lib/matrix_gem/matrix.rb, line 346 def identity(dimension) id_matrix = [] dimension.times do |x| id_matrix[x] = [] dimension.times do |y| if x == y id_matrix[x][y] = 1 else id_matrix[x][y] = 0 end end end return id_matrix end
Check if matrix rows are equals to its columns.
# File lib/matrix_gem/matrix.rb, line 335 def is_square_validation(_this) raise NoSquareMatrix if _this.m != _this.n end
Format values.
# File lib/matrix_gem/matrix.rb, line 367 def matrix_with_values(values, col_length) matrixNums = values.each_slice(col_length).to_a end
Multiplication of matrix row with number.
# File lib/matrix_gem/matrix.rb, line 362 def multiply_row(matrix, index, number) matrix = matrix.row(index).map{ |n| n * number } end
Check if caller matrix columns are equal to other matrix rows.
# File lib/matrix_gem/matrix.rb, line 330 def multiply_validation(_this, matrix) raise ErrDimensionMismatch if _this.col_size != matrix.row_size end
Check if matrices have same dimensions.
# File lib/matrix_gem/matrix.rb, line 340 def sum_validation(_this, matrix) raise ErrOperationNotDefine if !matrix.is_a? Matrix raise ErrDimensionMismatch if matrix.m != _this.m || matrix.n != _this.n end
Swap to matrix rows.
# File lib/matrix_gem/matrix.rb, line 308 def swap_rows(_this, row1_index, row2_index) _this[row1_index], _this[row2_index] = _this[row2_index], _this[row1_index] end