Class: Matrix
- Inherits:
-
Object
- Object
- Matrix
- Extended by:
- ConversionHelper
- Includes:
- Enumerable, ExceptionForMatrix, CoercionHelper
- Defined in:
- lib/rubysl/matrix/matrix.rb
Overview
The Matrix class represents a mathematical matrix. It provides methods for creating matrices, operating on them arithmetically and algebraically, and determining their mathematical properties (trace, rank, inverse, determinant).
Method Catalogue
To create a matrix:
-
Matrix[*rows] -
Matrix.[](*rows) -
Matrix.rows(rows, copy = true) -
Matrix.columns(columns) -
Matrix.build(row_size, column_size, &block) -
Matrix.diagonal(*values) -
Matrix.scalar(n, value) -
Matrix.identity(n) -
Matrix.unit(n) -
Matrix.I(n) -
Matrix.zero(n) -
Matrix.row_vector(row) -
Matrix.column_vector(column)
To access Matrix elements/columns/rows/submatrices/properties:
-
[](i, j) -
#row_size -
#column_size -
#row(i) -
#column(j) -
#collect -
#map -
#each -
#each_with_index -
#minor(*param)
Properties of a matrix:
-
#empty? -
#real? -
#regular? -
#singular? -
#square?
Matrix arithmetic:
-
*(m) -
+(m) -
-(m) -
#/(m) -
#inverse -
#inv -
**
Matrix functions:
-
#determinant -
#det -
#rank -
#trace -
#tr -
#transpose -
#t
Complex arithmetic:
-
conj -
conjugate -
imag -
imaginary -
real -
rect -
rectangular
Conversion to other data types:
-
#coerce(other) -
#row_vectors -
#column_vectors -
#to_a
String representations:
-
#to_s -
#inspect
Defined Under Namespace
Modules: CoercionHelper, ConversionHelper Classes: Scalar
Instance Attribute Summary collapse
-
#column_size ⇒ Object
readonly
Returns the number of columns.
Class Method Summary collapse
-
.[](*rows) ⇒ Object
Creates a matrix where each argument is a row.
-
.build(row_size, column_size = row_size) ⇒ Object
Creates a matrix of size
row_sizexcolumn_size. -
.column_vector(column) ⇒ Object
Creates a single-column matrix where the values of that column are as given in
column. -
.columns(columns) ⇒ Object
Creates a matrix using
columnsas an array of column vectors. -
.diagonal(*values) ⇒ Object
Creates a matrix where the diagonal elements are composed of
values. -
.empty(row_size = 0, column_size = 0) ⇒ Object
Creates a empty matrix of
row_sizexcolumn_size. -
.identity(n) ⇒ Object
(also: unit, I)
Creates an
nbynidentity matrix. -
.row_vector(row) ⇒ Object
Creates a single-row matrix where the values of that row are as given in
row. -
.rows(rows, copy = true) ⇒ Object
Creates a matrix where
rowsis an array of arrays, each of which is a row of the matrix. -
.scalar(n, value) ⇒ Object
Creates an
nbyndiagonal matrix where each diagonal element isvalue. -
.zero(n) ⇒ Object
Creates an
nbynzero matrix.
Instance Method Summary collapse
-
#*(m) ⇒ Object
Matrix multiplication.
-
#**(other) ⇒ Object
Matrix exponentiation.
-
#+(m) ⇒ Object
Matrix addition.
-
#-(m) ⇒ Object
Matrix subtraction.
-
#/(other) ⇒ Object
Matrix division (multiplication by the inverse).
-
#==(other) ⇒ Object
Returns
trueif and only if the two matrices contain equal elements. -
#[](i, j) ⇒ Object
(also: #element, #component)
Returns element (
i,j) of the matrix. - #[]=(i, j, v) ⇒ Object (also: #set_element, #set_component)
-
#clone ⇒ Object
Returns a clone of the matrix, so that the contents of each do not reference identical objects.
-
#coerce(other) ⇒ Object
The coerce method provides support for Ruby type coercion.
-
#collect(&block) ⇒ Object
(also: #map)
Returns a matrix that is the result of iteration of the given block over all elements of the matrix.
-
#column(j) ⇒ Object
Returns column vector number
jof the matrix as a Vector (starting at 0 like an array). -
#column_vectors ⇒ Object
Returns an array of the column vectors of the matrix.
-
#conjugate ⇒ Object
(also: #conj)
Returns the conjugate of the matrix.
-
#determinant ⇒ Object
(also: #det)
Returns the determinant of the matrix.
-
#determinant_e ⇒ Object
(also: #det_e)
deprecated; use Matrix#determinant.
-
#each(&block) ⇒ Object
Yields all elements of the matrix, starting with those of the first row, or returns an Enumerator is no block given Matrix[ [1,2], [3,4] ].each { |e| puts e } # => prints the numbers 1 to 4.
-
#each_with_index(&block) ⇒ Object
Yields all elements of the matrix, starting with those of the first row, along with the row index and column index, or returns an Enumerator is no block given Matrix[ [1,2], [3,4] ].each_with_index do |e, row, col| puts “#e at ##row, #col” end # => 1 at 0, 0 # => 2 at 0, 1 # => 3 at 1, 0 # => 4 at 1, 1.
- #elements_to_f ⇒ Object
- #elements_to_i ⇒ Object
- #elements_to_r ⇒ Object
-
#empty? ⇒ Boolean
Returns
trueif this is an empty matrix, i.e. - #eql?(other) ⇒ Boolean
-
#hash ⇒ Object
Returns a hash-code for the matrix.
-
#imaginary ⇒ Object
(also: #imag)
Returns the imaginary part of the matrix.
-
#initialize(rows, column_size = rows[0].size) ⇒ Matrix
constructor
Matrix.new is private; use Matrix.rows, columns, [], etc…
-
#inspect ⇒ Object
Overrides Object#inspect.
-
#inverse ⇒ Object
(also: #inv)
Returns the inverse of the matrix.
-
#minor(*param) ⇒ Object
Returns a section of the matrix.
-
#rank ⇒ Object
Returns the rank of the matrix.
-
#rank_e ⇒ Object
deprecated; use Matrix#rank.
-
#real ⇒ Object
Returns the real part of the matrix.
-
#real? ⇒ Boolean
Returns
trueif all entries of the matrix are real. -
#rect ⇒ Object
(also: #rectangular)
Returns an array containing matrices corresponding to the real and imaginary parts of the matrix.
-
#regular? ⇒ Boolean
Returns
trueif this is a regular (i.e. non-singular) matrix. -
#row(i, &block) ⇒ Object
Returns row vector number
iof the matrix as a Vector (starting at 0 like an array). -
#row_size ⇒ Object
Returns the number of rows.
-
#row_vectors ⇒ Object
Returns an array of the row vectors of the matrix.
-
#singular? ⇒ Boolean
Returns
trueis this is a singular matrix. -
#square? ⇒ Boolean
Returns
trueis this is a square matrix. -
#to_a ⇒ Object
Returns an array of arrays that describe the rows of the matrix.
-
#to_s ⇒ Object
Overrides Object#to_s.
-
#trace ⇒ Object
(also: #tr)
Returns the trace (sum of diagonal elements) of the matrix.
-
#transpose ⇒ Object
(also: #t)
Returns the transpose of the matrix.
Methods included from CoercionHelper
Constructor Details
#initialize(rows, column_size = rows[0].size) ⇒ Matrix
Matrix.new is private; use Matrix.rows, columns, [], etc… to create.
277 278 279 280 281 282 283 |
# File 'lib/rubysl/matrix/matrix.rb', line 277 def initialize(rows, column_size = rows[0].size) # No checking is done at this point. rows must be an Array of Arrays. # column_size 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_size = column_size end |
Instance Attribute Details
#column_size ⇒ Object (readonly)
Returns the number of columns.
316 317 318 |
# File 'lib/rubysl/matrix/matrix.rb', line 316 def column_size @column_size end |
Class Method Details
.[](*rows) ⇒ Object
Creates a matrix where each argument is a row.
Matrix[ [25, 93], [-1, 66] ]
=> 25 93
-1 66
120 121 122 |
# File 'lib/rubysl/matrix/matrix.rb', line 120 def Matrix.[](*rows) Matrix.rows(rows, false) end |
.build(row_size, column_size = row_size) ⇒ Object
Creates a matrix of size row_size x column_size. It fills the values by calling the given block, passing the current row and column. Returns an enumerator if no block is given.
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
165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/rubysl/matrix/matrix.rb', line 165 def Matrix.build(row_size, column_size = row_size) row_size = CoercionHelper.coerce_to_int(row_size) column_size = CoercionHelper.coerce_to_int(column_size) raise ArgumentError if row_size < 0 || column_size < 0 return to_enum :build, row_size, column_size unless block_given? rows = row_size.times.map do |i| column_size.times.map do |j| yield i, j end end new rows, column_size end |
.column_vector(column) ⇒ Object
Creates a single-column matrix where the values of that column are as given in column.
Matrix.column_vector([4,5,6])
=> 4
5
6
249 250 251 252 |
# File 'lib/rubysl/matrix/matrix.rb', line 249 def Matrix.column_vector(column) column = convert_to_array(column) new [column].transpose, 1 end |
.columns(columns) ⇒ Object
Creates a matrix using columns as an array of column vectors.
Matrix.columns([[25, 93], [-1, 66]])
=> 25 -1
93 66
150 151 152 |
# File 'lib/rubysl/matrix/matrix.rb', line 150 def Matrix.columns(columns) Matrix.rows(columns, false).transpose end |
.diagonal(*values) ⇒ Object
Creates a matrix where the diagonal elements are composed of values.
Matrix.diagonal(9, 5, -3)
=> 9 0 0
0 5 0
0 0 -3
185 186 187 188 189 190 191 192 193 |
# File 'lib/rubysl/matrix/matrix.rb', line 185 def Matrix.diagonal(*values) size = values.size rows = (0 ... size).collect {|j| row = Array.new(size, 0) row[j] = values[j] row } new rows end |
.empty(row_size = 0, column_size = 0) ⇒ Object
Creates a empty matrix of row_size x column_size. At least one of row_size or column_size must be 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]]
267 268 269 270 271 272 |
# File 'lib/rubysl/matrix/matrix.rb', line 267 def Matrix.empty(row_size = 0, column_size = 0) Matrix.Raise ArgumentError, "One size must be 0" if column_size != 0 && row_size != 0 Matrix.Raise ArgumentError, "Negative size" if column_size < 0 || row_size < 0 new([[]]*row_size, column_size) end |
.identity(n) ⇒ Object Also known as: unit, I
Creates an n by n identity matrix.
Matrix.identity(2)
=> 1 0
0 1
212 213 214 |
# File 'lib/rubysl/matrix/matrix.rb', line 212 def Matrix.identity(n) Matrix.scalar(n, 1) end |
.row_vector(row) ⇒ Object
Creates a single-row matrix where the values of that row are as given in row.
Matrix.row_vector([4,5,6])
=> 4 5 6
236 237 238 239 |
# File 'lib/rubysl/matrix/matrix.rb', line 236 def Matrix.row_vector(row) row = convert_to_array(row) new [row] end |
.rows(rows, copy = true) ⇒ Object
Creates a matrix where rows is an array of arrays, each of which is a row of the matrix. If the optional argument copy is false, use the given arrays as the internal structure of the matrix without copying.
Matrix.rows([[25, 93], [-1, 66]])
=> 25 93
-1 66
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/rubysl/matrix/matrix.rb', line 132 def Matrix.rows(rows, copy = true) rows = convert_to_array(rows) rows.map! do |row| convert_to_array(row, copy) end size = (rows[0] || []).size rows.each do |row| Matrix.Raise ErrDimensionMismatch, "row size differs (#{row.size} should be #{size})" unless row.size == size end new rows, size end |
Instance Method Details
#*(m) ⇒ Object
Matrix multiplication.
Matrix[[2,4], [6,8]] * Matrix.identity(2)
=> 2 4
6 8
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 |
# File 'lib/rubysl/matrix/matrix.rb', line 531 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_size when Vector m = Matrix.column_vector(m) r = self * m return r.column(0) when Matrix Matrix.Raise ErrDimensionMismatch if column_size != m.row_size rows = (0 ... row_size).collect {|i| (0 ... m.column_size).collect {|j| (0 ... column_size).inject(0) do |vij, k| vij + self[i, k] * m[k, j] end } } return new_matrix rows, m.column_size else return apply_through_coercion(m, __method__) end end |
#**(other) ⇒ Object
Matrix exponentiation. Currently implemented for integer powers only. Equivalent to multiplying the matrix by itself N times.
Matrix[[7,6], [3,9]] ** 2
=> 67 96
48 99
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 |
# File 'lib/rubysl/matrix/matrix.rb', line 700 def ** (other) case other when Integer x = self if other <= 0 x = self.inverse return Matrix.identity(self.column_size) 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 else Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class end end |
#+(m) ⇒ Object
Matrix addition.
Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
=> 6 0
-4 12
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
# File 'lib/rubysl/matrix/matrix.rb', line 566 def +(m) case m when Numeric Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class when Vector m = Matrix.column_vector(m) when Matrix else return apply_through_coercion(m, __method__) end Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size rows = (0 ... row_size).collect {|i| (0 ... column_size).collect {|j| self[i, j] + m[i, j] } } new_matrix rows, column_size end |
#-(m) ⇒ Object
Matrix subtraction.
Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
=> -8 2
8 1
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
# File 'lib/rubysl/matrix/matrix.rb', line 593 def -(m) case m when Numeric Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class when Vector m = Matrix.column_vector(m) when Matrix else return apply_through_coercion(m, __method__) end Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size rows = (0 ... row_size).collect {|i| (0 ... column_size).collect {|j| self[i, j] - m[i, j] } } new_matrix rows, column_size end |
#/(other) ⇒ Object
Matrix division (multiplication by the inverse).
Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
=> -7 1
-3 -6
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
# File 'lib/rubysl/matrix/matrix.rb', line 620 def /(other) case other when Numeric rows = @rows.collect {|row| row.collect {|e| e / other } } return new_matrix rows, column_size when Matrix return self * other.inverse else return apply_through_coercion(other, __method__) end end |
#==(other) ⇒ Object
Returns true if and only if the two matrices contain equal elements.
495 496 497 498 |
# File 'lib/rubysl/matrix/matrix.rb', line 495 def ==(other) return false unless Matrix === other rows == other.rows end |
#[](i, j) ⇒ Object Also known as: element, component
Returns element (i,j) of the matrix. That is: row i, column j.
293 294 295 |
# File 'lib/rubysl/matrix/matrix.rb', line 293 def [](i, j) @rows.fetch(i){return nil}[j] end |
#[]=(i, j, v) ⇒ Object Also known as: set_element, set_component
299 300 301 |
# File 'lib/rubysl/matrix/matrix.rb', line 299 def []=(i, j, v) @rows[i][j] = v end |
#clone ⇒ Object
Returns a clone of the matrix, so that the contents of each do not reference identical objects. There should be no good reason to do this since Matrices are immutable.
510 511 512 |
# File 'lib/rubysl/matrix/matrix.rb', line 510 def clone new_matrix @rows.map(&:dup), column_size end |
#coerce(other) ⇒ Object
The coerce method provides support for Ruby type coercion. This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator. See also Numeric#coerce.
965 966 967 968 969 970 971 972 |
# File 'lib/rubysl/matrix/matrix.rb', line 965 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 |
#collect(&block) ⇒ Object Also known as: map
Returns a matrix that is the result of iteration of the given block over all elements of the matrix.
Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
=> 1 4
9 16
359 360 361 362 363 |
# File 'lib/rubysl/matrix/matrix.rb', line 359 def collect(&block) # :yield: e return to_enum(:collect) unless block_given? rows = @rows.collect{|row| row.collect(&block)} new_matrix rows, column_size end |
#column(j) ⇒ Object
Returns column vector number j of the matrix as a Vector (starting at 0 like an array). When a block is given, the elements of that vector are iterated.
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/rubysl/matrix/matrix.rb', line 336 def column(j) # :yield: e if block_given? return self if j >= column_size || j < -column_size row_size.times do |i| yield @rows[i][j] end self else return nil if j >= column_size || j < -column_size col = (0 ... row_size).collect {|i| @rows[i][j] } Vector.elements(col, false) end end |
#column_vectors ⇒ Object
Returns an array of the column vectors of the matrix. See Vector.
986 987 988 989 990 |
# File 'lib/rubysl/matrix/matrix.rb', line 986 def column_vectors (0 ... column_size).collect {|i| column(i) } end |
#conjugate ⇒ Object Also known as: conj
Returns the conjugate of the matrix.
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
911 912 913 |
# File 'lib/rubysl/matrix/matrix.rb', line 911 def conjugate collect(&:conjugate) end |
#determinant ⇒ Object Also known as: det
Returns the determinant of the matrix.
Beware that using Float values can yield erroneous results because of their lack of precision. Consider using exact types like Rational or BigDecimal instead.
Matrix[[7,6], [3,9]].determinant
=> 45
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 |
# File 'lib/rubysl/matrix/matrix.rb', line 734 def determinant Matrix.Raise ErrDimensionMismatch unless square? m = @rows case row_size # 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 end end |
#determinant_e ⇒ Object Also known as: det_e
deprecated; use Matrix#determinant
816 817 818 819 |
# File 'lib/rubysl/matrix/matrix.rb', line 816 def determinant_e warn "#{caller(1)[0]}: warning: Matrix#determinant_e is deprecated; use #determinant" rank end |
#each(&block) ⇒ Object
Yields all elements of the matrix, starting with those of the first row, or returns an Enumerator is no block given
Matrix[ [1,2], [3,4] ].each { |e| puts e }
# => prints the numbers 1 to 4
372 373 374 375 376 377 378 |
# File 'lib/rubysl/matrix/matrix.rb', line 372 def each(&block) # :yield: e return to_enum(:each) unless block_given? @rows.each do |row| row.each(&block) end self end |
#each_with_index(&block) ⇒ Object
Yields all elements of the matrix, starting with those of the first row, along with the row index and column index, or returns an Enumerator is no block given
Matrix[ [1,2], [3,4] ].each_with_index do |e, row, col|
puts "#{e} at #{row}, #{col}"
end
# => 1 at 0, 0
# => 2 at 0, 1
# => 3 at 1, 0
# => 4 at 1, 1
392 393 394 395 396 397 398 399 400 |
# File 'lib/rubysl/matrix/matrix.rb', line 392 def each_with_index(&block) # :yield: e, row, column return to_enum(:each_with_index) unless block_given? @rows.each_with_index do |row, row_index| row.each_with_index do |e, col_index| yield e, row_index, col_index end end self end |
#elements_to_f ⇒ Object
999 1000 1001 1002 |
# File 'lib/rubysl/matrix/matrix.rb', line 999 def elements_to_f warn "#{caller(1)[0]}: warning: Matrix#elements_to_f is deprecated, use map(&:to_f)" map(&:to_f) end |
#elements_to_i ⇒ Object
1004 1005 1006 1007 |
# File 'lib/rubysl/matrix/matrix.rb', line 1004 def elements_to_i warn "#{caller(1)[0]}: warning: Matrix#elements_to_i is deprecated, use map(&:to_i)" map(&:to_i) end |
#elements_to_r ⇒ Object
1009 1010 1011 1012 |
# File 'lib/rubysl/matrix/matrix.rb', line 1009 def elements_to_r warn "#{caller(1)[0]}: warning: Matrix#elements_to_r is deprecated, use map(&:to_r)" map(&:to_r) end |
#empty? ⇒ Boolean
Returns true if this is an empty matrix, i.e. if the number of rows or the number of columns is 0.
456 457 458 |
# File 'lib/rubysl/matrix/matrix.rb', line 456 def empty? column_size == 0 || row_size == 0 end |
#eql?(other) ⇒ Boolean
500 501 502 503 |
# File 'lib/rubysl/matrix/matrix.rb', line 500 def eql?(other) return false unless Matrix === other rows.eql? other.rows end |
#hash ⇒ Object
Returns a hash-code for the matrix.
517 518 519 |
# File 'lib/rubysl/matrix/matrix.rb', line 517 def hash @rows.hash end |
#imaginary ⇒ Object Also known as: imag
Returns the imaginary part of the matrix.
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
925 926 927 |
# File 'lib/rubysl/matrix/matrix.rb', line 925 def imaginary collect(&:imaginary) end |
#inspect ⇒ Object
Overrides Object#inspect
1034 1035 1036 1037 1038 1039 1040 |
# File 'lib/rubysl/matrix/matrix.rb', line 1034 def inspect if empty? "Matrix.empty(#{row_size}, #{column_size})" else "Matrix#{@rows.inspect}" end end |
#inverse ⇒ Object Also known as: inv
Returns the inverse of the matrix.
Matrix[[-1, -1], [0, -1]].inverse
=> -1 1
0 -1
642 643 644 645 |
# File 'lib/rubysl/matrix/matrix.rb', line 642 def inverse Matrix.Raise ErrDimensionMismatch unless square? Matrix.I(row_size).send(:inverse_from, self) end |
#minor(*param) ⇒ Object
Returns a section of the matrix. The parameters are either:
-
start_row, nrows, start_col, ncols; OR
-
row_range, col_range
Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
=> 9 0 0
0 5 0
Like Array#[], negative indices count backward from the end of the row or column (-1 is the last element). Returns nil if the starting row or column is greater than row_size or column_size respectively.
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/rubysl/matrix/matrix.rb', line 415 def minor(*param) case param.size when 2 row_range, col_range = param from_row = row_range.first from_row += row_size if from_row < 0 to_row = row_range.end to_row += row_size 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_size if from_col < 0 to_col = col_range.end to_col += column_size 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_size if from_row < 0 from_col += column_size if from_col < 0 else Matrix.Raise ArgumentError, param.inspect end return nil if from_row > row_size || from_col > column_size || from_row < 0 || from_col < 0 rows = @rows[from_row, size_row].collect{|row| row[from_col, size_col] } new_matrix rows, column_size - from_col end |
#rank ⇒ Object
Returns the rank of the matrix. Beware that using Float values can yield erroneous results because of their lack of precision. Consider using exact types like Rational or BigDecimal instead.
Matrix[[7,6], [3,9]].rank
=> 2
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 |
# File 'lib/rubysl/matrix/matrix.rb', line 831 def rank # We currently use Bareiss' multistep integer-preserving gaussian elimination # (see comments on determinant) a = to_a last_column = column_size - 1 last_row = row_size - 1 rank = 0 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 |
#rank_e ⇒ Object
deprecated; use Matrix#rank
863 864 865 866 |
# File 'lib/rubysl/matrix/matrix.rb', line 863 def rank_e warn "#{caller(1)[0]}: warning: Matrix#rank_e is deprecated; use #rank" rank end |
#real ⇒ Object
Returns the real part of the matrix.
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
939 940 941 |
# File 'lib/rubysl/matrix/matrix.rb', line 939 def real collect(&:real) end |
#real? ⇒ Boolean
Returns true if all entries of the matrix are real.
463 464 465 |
# File 'lib/rubysl/matrix/matrix.rb', line 463 def real? all?(&:real?) end |
#rect ⇒ Object Also known as: rectangular
Returns an array containing matrices corresponding to the real and imaginary parts of the matrix
m.rect == [m.real, m.imag] # ==> true for all matrices m
949 950 951 |
# File 'lib/rubysl/matrix/matrix.rb', line 949 def rect [real, imag] end |
#regular? ⇒ Boolean
Returns true if this is a regular (i.e. non-singular) matrix.
470 471 472 |
# File 'lib/rubysl/matrix/matrix.rb', line 470 def regular? not singular? end |
#row(i, &block) ⇒ Object
Returns row vector number i of the matrix as a Vector (starting at 0 like an array). When a block is given, the elements of that vector are iterated.
322 323 324 325 326 327 328 329 |
# File 'lib/rubysl/matrix/matrix.rb', line 322 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 |
#row_size ⇒ Object
Returns the number of rows.
309 310 311 |
# File 'lib/rubysl/matrix/matrix.rb', line 309 def row_size @rows.size end |
#row_vectors ⇒ Object
Returns an array of the row vectors of the matrix. See Vector.
977 978 979 980 981 |
# File 'lib/rubysl/matrix/matrix.rb', line 977 def row_vectors (0 ... row_size).collect {|i| row(i) } end |
#singular? ⇒ Boolean
Returns true is this is a singular matrix.
477 478 479 |
# File 'lib/rubysl/matrix/matrix.rb', line 477 def singular? determinant == 0 end |
#square? ⇒ Boolean
Returns true is this is a square matrix.
484 485 486 |
# File 'lib/rubysl/matrix/matrix.rb', line 484 def square? column_size == row_size end |
#to_a ⇒ Object
Returns an array of arrays that describe the rows of the matrix.
995 996 997 |
# File 'lib/rubysl/matrix/matrix.rb', line 995 def to_a @rows.collect{|row| row.dup} end |
#to_s ⇒ Object
Overrides Object#to_s
1021 1022 1023 1024 1025 1026 1027 1028 1029 |
# File 'lib/rubysl/matrix/matrix.rb', line 1021 def to_s if empty? "Matrix.empty(#{row_size}, #{column_size})" else "Matrix[" + @rows.collect{|row| "[" + row.collect{|e| e.to_s}.join(", ") + "]" }.join(", ")+"]" end end |
#trace ⇒ Object Also known as: tr
Returns the trace (sum of diagonal elements) of the matrix.
Matrix[[7,6], [3,9]].trace
=> 16
874 875 876 877 878 879 |
# File 'lib/rubysl/matrix/matrix.rb', line 874 def trace Matrix.Raise ErrDimensionMismatch unless square? (0...column_size).inject(0) do |tr, i| tr + @rows[i][i] end end |
#transpose ⇒ Object Also known as: t
Returns the transpose of the matrix.
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
892 893 894 895 |
# File 'lib/rubysl/matrix/matrix.rb', line 892 def transpose return Matrix.empty(column_size, 0) if row_size.zero? new_matrix @rows.transpose, row_size end |