class KXI::Math::Matrix
Represents a matrix
Public Class Methods
Returns a square identity matrix @param [Integer] n Dimension of matrix @return [KXI::Math::Matrix] Square identity matrix of given dimension
# File lib/kxi/math/matrix.rb, line 10 def self.identity(n) return KXI::Math::Matrix.new(n, n) { |c, r| c == r ? 1 : 0 } end
Instantiates the {KXI::Math::Matrix} class @overload initialize(cols)
Creates a square matrix @param [Integer] cols Dimension of matrix
@overload initialize(cols, rows)
Creates a matrix @param [Integer] cols Number of columns in the matrix @param [Integer] rows Number of rows in the matrix
# File lib/kxi/math/matrix.rb, line 34 def initialize(cols, rows = nil) rows = cols if rows == nil @data = [] cols.times do |i| if block_given? @data[i] = [] rows.times do |j| v = yield(i, j) raise(KXI::Exceptions::InvalidTypeException.new(v.type, Numeric)) unless v.is_a?(Numeric) @data[i].push(v) end else @data[i] = [0.0] * rows end end @cols = cols @rows = rows end
Public Instance Methods
Multiplies matrix @overload *(other)
Scales matrix @param [Numeric] other Scalar to multiply with @raise [KXI::Exceptions::InvalidTypeException] When value is of invalid type @return [KXI::Math::Matrix] Scaled matrix
@overload *(other)
Multiplies matrix by another matrix @param [KXI::Math::Matrix] other Right-side matrix to multiply with @raise [KXI::Exceptions::InvalidTypeException] When value is of invalid type @return [KXI::Math::Matrix] Multiplied matrix
@overload *(other)
Multiplies matrix by vector @param [KXI::Math::Vector] other Vector to multiply with @raise [KXI::Exceptions::InvalidTypeException] When value is of invalid type @return [KXI::Math::Vector] Result of multiplication
# File lib/kxi/math/matrix.rb, line 243 def *(other) if other.is_a?(Numeric) return KXI::Math::Matrix.new(@cols, @rows) { |c, r| other * get(c, r) } elsif other.is_a?(KXI::Math::Matrix) return KXI::Math::Matrix.new(other.columns, @rows) do |c, r| sum = 0 @cols.times { |i| sum += get(i, r) * other.get(c, i) } next sum end elsif other.is_a?(KXI::Math::Vector) return KXI::Math::Vector.new(@rows) do |d| sum = 0 @cols.times { |c| sum += get(c, d) * other[c] } next sum end else raise(KXI::Exceptions::InvalidTypeException.new(other.class, Numeric, KXI::Math::Matrix, KXI::Math::Vector)) end end
Compares matrix @param [void] other Value to compare to @return [Boolean] True if matrix is equivalent to given value; false otherwise
# File lib/kxi/math/matrix.rb, line 266 def ==(other) return false unless other.is_a?(KXI::Math::Matrix) return false if @cols != other.columns or @row != other.rows @cols.times do |col| @rows.times do |row| return false if get(col, row) != other.get(col, row) end end end
Returns the number of columns @return [Integer] Number of columns
# File lib/kxi/math/matrix.rb, line 22 def columns @cols end
Computes the determinant of matrix @return [Numeric] Determinant of matrix
# File lib/kxi/math/matrix.rb, line 120 def determinant return get(0, 0) * get(1, 1) - get(1, 0) * get(0, 1) if @cols == 2 ci = 0 cz = 0 @cols.times do |col| zeros = 0 @rows.times { |row| zeros += 1 if get(col, row) == 0 } if zeros > cz ci = col cz = zeros end end ret = 0 @rows.times do |row| if get(ci, row) != 0 ret += sign(ci, row) * get(ci, row) * sub(ci, row).determinant end end return ret end
Iterates over each element of matrix @yield [col, row, val] Iterator function @yieldparam [Integer] col Column passed to iterator @yieldparam [Integer] row Row passed to iterator @yieldparam [Numeric] val Value of matrix at given column and row
# File lib/kxi/math/matrix.rb, line 209 def each @cols.times do |col| @rows.times do |row| yield(col, row, @data[col][row]) end end end
Gets the value of matrix at given column and row @param [Integer] col Column to get @param [Integer] row Row to get @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @return [Numeric] Value of matrix at given column and row
# File lib/kxi/math/matrix.rb, line 160 def get(col, row) raise(KXI::Exceptions::OutOfRangeException.new(col, 0, @cols - 1)) if col < 0 or col >= @cols raise(KXI::Exceptions::OutOfRangeException.new(row, 0, @rows - 1)) if row < 0 or row >= @rows return @data[col][row] end
Computes the inverse of matrix @return [KXI::Math::Matrix] Inverse matrix
# File lib/kxi/math/matrix.rb, line 143 def inverse return (KXI::Math::Matrix.new(@cols, @rows) { |c, r| sign(c, r) * sub(c, r).determinant }).transpose * (1 / determinant) end
Multiplies a row of matrix with specific coefficient @overload row_mult
(src, cof)
Multiplies a row by coefficient and adds that to the row @param [Integer] src Row to multiply @param [Numeric] cof Coefficient to multiply with @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @return [Matrix] New matrix with multiplied row
@overload row_mult
(src, cof, dst)
Multiplies a row by coefficient and adds that to other row @param [Integer] src Row to multiply @param [Numeric] cof Coefficient to multiply with @param [Numeric] dst Row to write the results of multiplication @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @return [Matrix] New matrix with multiplied row
# File lib/kxi/math/matrix.rb, line 106 def row_mult(src, cof, dst = nil) dst = src if dst == nil return KXI::Math::Matrix.new(@cols, @rows) do |c, r| next get(c, r) + cof * get(c, src) if r == dst get(c, r) end end
Multiplies a row of matrix with specific coefficient @overload row_mult
(src, cof)
Multiplies a row by coefficient into that row @param [Integer] src Row to multiply @param [Numeric] cof Coefficient to multiply with @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @return [Matrix] New matrix with multiplied row
@overload row_mult
(src, cof, dst)
Multiplies a row by coefficient into other row @param [Integer] src Row to multiply @param [Numeric] cof Coefficient to multiply with @param [Numeric] dst Row to write the results of multiplication @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @return [Matrix] New matrix with multiplied row
# File lib/kxi/math/matrix.rb, line 82 def row_mult!(src, cof, dst = nil) dst = src if dst == nil raise(KXI::Exceptions::OutOfRangeException.new(src, 0, @rows - 1)) if src < 0 or src >= @rows raise(KXI::Exceptions::OutOfRangeException.new(dst, 0, @rows - 1)) if dst < 0 or dst >= @rows return KXI::Math::Matrix.new(@cols, @rows) do |c, r| next cof * get(c, src) if r == dst get(c, r) end end
Swaps two rows of the matrix @param [Integer] a First row to swap @param [Integer] b Second row to swap with @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @return [KXI::Math::Matrix] New matrix with swapped rows
# File lib/kxi/math/matrix.rb, line 58 def row_swap(a, b) raise(KXI::Exceptions::OutOfRangeException.new(a, 0, @rows - 1)) if a < 0 or a >= @rows raise(KXI::Exceptions::OutOfRangeException.new(b, 0, @rows - 1)) if b < 0 or b >= @rows return KXI::Math::Matrix.new(@cols, @rows) do |c, r| next get(c, b) if r == a next get(c, a) if r == b get(c, r) end end
Returns the number of rows @return [Integer] Number of rows
# File lib/kxi/math/matrix.rb, line 16 def rows @rows end
Sets the value of vector at specific dimension @overload set(col, row, val)
Sets the value of vector at specific dimension @param [Integer] col Column to set @param [Integer] row Row to set @param [Integer] val Value to set the matrix to @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @raise [KXI::Exceptions::InvalidTypeException] When value has invalid type @return [Numeric] Value passed to function
@overload set(col, row, val)
Sets the values of vector to range of values starting from specific dimension @param [Integer] col Column to set @param [Integer] row Row to set @param [Array] val Values to set the matrix to @raise [KXI::Exceptions::OutOfRangeException] When one of arguments is out of range @raise [KXI::Exceptions::InvalidTypeException] When value has invalid type @return [Numeric] Value passed to function
# File lib/kxi/math/matrix.rb, line 183 def set(col, row, value) raise(KXI::Exceptions::OutOfRangeException.new(col, 0, @cols - 1)) if col < 0 or col >= @cols raise(KXI::Exceptions::OutOfRangeException.new(row, 0, @rows - 1)) if row < 0 or row >= @rows if value.is_a?(Array) i = 0 while i + col < @cols and i < value.length j = 0 while j + row < @rows and j < value[i].length @data[col + i][row + j] = value[i][j].to_f j += 1 end i += 1 end elsif value.is_a?(Numeric) @data[col][row] = value.to_f else raise(KXI::Exceptions::InvalidTypeException.new(value.type, Numeric, Array)) end return value end
Converts matrix to string @param [Boolean] d Determines whether string should be decorated @return [String] String representation of matrix
# File lib/kxi/math/matrix.rb, line 283 def to_s(d = true) ret = '' just = [0] * @cols each { |c, r, v| d = str(v).length; just[c] = d if d > just[c] } @rows.times do |row| ret += $/ unless row == 0 ret += '|' if d @cols.times do |col| ret += ' ' unless col == 0 ret += str(get(col, row)).rjust(just[col], ' ') end ret += '|' if d end return ret end
Returns the transpose of matrix @return [KXI::Math::Matrix] Transposed matrix
# File lib/kxi/math/matrix.rb, line 219 def transpose ret = KXI::Math::Matrix.new(@rows, @cols) each do |col, row, value| ret.set(row, col, value) end return ret end
Private Instance Methods
# File lib/kxi/math/matrix.rb, line 114 def sign(col, row) return ((col % 2 == 0) == (row % 2 == 0)) ? 1 : -1 end
# File lib/kxi/math/matrix.rb, line 276 def str(num) return (num == num.to_i ? num.to_i : num).to_s end
# File lib/kxi/math/matrix.rb, line 147 def sub(col, row) return KXI::Math::Matrix.new(@cols - 1, @rows - 1) do |c, r| c = c + 1 if c >= col r = r + 1 if r >= row next get(c, r) end end