Class: KXI::Math::Matrix

Inherits:
Object
  • Object
show all
Defined in:
lib/kxi/math/matrix.rb

Overview

Represents a matrix

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cols) ⇒ Matrix #initialize(cols, rows) ⇒ Matrix

Instantiates the KXI::Math::Matrix class

Overloads:

  • #initialize(cols) ⇒ Matrix

    Creates a square matrix

    Parameters:

    • cols (Integer)

      Dimension of matrix

  • #initialize(cols, rows) ⇒ Matrix

    Creates a matrix

    Parameters:

    • cols (Integer)

      Number of columns in the matrix

    • rows (Integer)

      Number of rows in the matrix



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 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

Class Method Details

.identity(n) ⇒ KXI::Math::Matrix

Returns a square identity matrix

Parameters:

  • n (Integer)

    Dimension of matrix

Returns:



10
11
12
# 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

Instance Method Details

#*(other) ⇒ KXI::Math::Matrix #*(other) ⇒ KXI::Math::Matrix #*(other) ⇒ KXI::Math::Vector

Multiplies matrix

Overloads:



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# 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

#==(other) ⇒ Boolean

Compares matrix

Parameters:

  • other (void)

    Value to compare to

Returns:

  • (Boolean)

    True if matrix is equivalent to given value; false otherwise



266
267
268
269
270
271
272
273
274
# 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

#columnsInteger

Returns the number of columns

Returns:

  • (Integer)

    Number of columns



22
23
24
# File 'lib/kxi/math/matrix.rb', line 22

def columns
	@cols
end

#determinantNumeric

Computes the determinant of matrix

Returns:

  • (Numeric)

    Determinant of matrix



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# 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

#each {|col, row, val| ... } ⇒ Object

Iterates over each element of matrix

Yields:

  • (col, row, val)

    Iterator function

Yield Parameters:

  • col (Integer)

    Column passed to iterator

  • row (Integer)

    Row passed to iterator

  • val (Numeric)

    Value of matrix at given column and row



209
210
211
212
213
214
215
# 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

#get(col, row) ⇒ Numeric

Gets the value of matrix at given column and row

Parameters:

  • col (Integer)

    Column to get

  • row (Integer)

    Row to get

Returns:

  • (Numeric)

    Value of matrix at given column and row

Raises:



160
161
162
163
164
# 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

#inverseKXI::Math::Matrix

Computes the inverse of matrix

Returns:



143
144
145
# 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

#row_mult(src, cof) ⇒ Matrix #row_mult(src, cof, dst) ⇒ Matrix

Multiplies a row of matrix with specific coefficient

Overloads:

  • #row_mult(src, cof) ⇒ Matrix

    Multiplies a row by coefficient and adds that to the row

    Parameters:

    • src (Integer)

      Row to multiply

    • cof (Numeric)

      Coefficient to multiply with

    Returns:

    • (Matrix)

      New matrix with multiplied row

    Raises:

  • #row_mult(src, cof, dst) ⇒ Matrix

    Multiplies a row by coefficient and adds that to other row

    Parameters:

    • src (Integer)

      Row to multiply

    • cof (Numeric)

      Coefficient to multiply with

    • dst (Numeric)

      Row to write the results of multiplication

    Returns:

    • (Matrix)

      New matrix with multiplied row

    Raises:



106
107
108
109
110
111
112
# 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

#row_mult(src, cof) ⇒ Matrix #row_mult(src, cof, dst) ⇒ Matrix

Multiplies a row of matrix with specific coefficient

Overloads:

  • #row_mult(src, cof) ⇒ Matrix

    Multiplies a row by coefficient into that row

    Parameters:

    • src (Integer)

      Row to multiply

    • cof (Numeric)

      Coefficient to multiply with

    Returns:

    • (Matrix)

      New matrix with multiplied row

    Raises:

  • #row_mult(src, cof, dst) ⇒ Matrix

    Multiplies a row by coefficient into other row

    Parameters:

    • src (Integer)

      Row to multiply

    • cof (Numeric)

      Coefficient to multiply with

    • dst (Numeric)

      Row to write the results of multiplication

    Returns:

    • (Matrix)

      New matrix with multiplied row

    Raises:

Raises:



82
83
84
85
86
87
88
89
90
# 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

#row_swap(a, b) ⇒ KXI::Math::Matrix

Swaps two rows of the matrix

Parameters:

  • a (Integer)

    First row to swap

  • b (Integer)

    Second row to swap with

Returns:

Raises:



58
59
60
61
62
63
64
65
66
# 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

#rowsInteger

Returns the number of rows

Returns:

  • (Integer)

    Number of rows



16
17
18
# File 'lib/kxi/math/matrix.rb', line 16

def rows
	@rows
end

#set(col, row, val) ⇒ Numeric #set(col, row, val) ⇒ Numeric

Sets the value of vector at specific dimension

Overloads:

  • #set(col, row, val) ⇒ Numeric

    Sets the value of vector at specific dimension

    Parameters:

    • col (Integer)

      Column to set

    • row (Integer)

      Row to set

    • val (Integer)

      Value to set the matrix to

    Returns:

    • (Numeric)

      Value passed to function

    Raises:

  • #set(col, row, val) ⇒ Numeric

    Sets the values of vector to range of values starting from specific dimension

    Parameters:

    • col (Integer)

      Column to set

    • row (Integer)

      Row to set

    • val (Array)

      Values to set the matrix to

    Returns:

    • (Numeric)

      Value passed to function

    Raises:

Raises:



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# 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

#to_s(d = true) ⇒ String

Converts matrix to string

Parameters:

  • d (Boolean) (defaults to: true)

    Determines whether string should be decorated

Returns:

  • (String)

    String representation of matrix



283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# 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

#transposeKXI::Math::Matrix

Returns the transpose of matrix

Returns:



219
220
221
222
223
224
225
# 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