367
388
# Yields all elements of the matrix, starting with those of the first row,
368
# or returns an Enumerator is no block given
389
# or returns an Enumerator is no block given.
390
# Elements can be restricted by passing an argument:
391
# * :all (default): yields all elements
392
# * :diagonal: yields only elements on the diagonal
393
# * :off_diagonal: yields all elements except on the diagonal
394
# * :lower: yields only elements on or below the diagonal
395
# * :strict_lower: yields only elements below the diagonal
396
# * :strict_upper: yields only elements above the diagonal
397
# * :upper: yields only elements on or above the diagonal
369
399
# Matrix[ [1,2], [3,4] ].each { |e| puts e }
370
400
# # => prints the numbers 1 to 4
401
# Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
372
def each(&block) # :yield: e
373
return to_enum(:each) unless block_given?
403
def each(which = :all) # :yield: e
404
return to_enum :each, which unless block_given?
405
last = column_size - 1
413
@rows.each_with_index do |row, row_index|
414
yield row.fetch(row_index){return self}
417
@rows.each_with_index do |row, row_index|
418
column_size.times do |col_index|
419
yield row[col_index] unless row_index == col_index
423
@rows.each_with_index do |row, row_index|
424
0.upto([row_index, last].min) do |col_index|
429
@rows.each_with_index do |row, row_index|
430
[row_index, column_size].min.times do |col_index|
435
@rows.each_with_index do |row, row_index|
436
(row_index+1).upto(last) do |col_index|
441
@rows.each_with_index do |row, row_index|
442
row_index.upto(last) do |col_index|
447
Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
381
# Yields all elements of the matrix, starting with those of the first row,
382
# along with the row index and column index,
383
# or returns an Enumerator is no block given
453
# Same as #each, but the row index and column index in addition to the element
384
455
# Matrix[ [1,2], [3,4] ].each_with_index do |e, row, col|
385
456
# puts "#{e} at #{row}, #{col}"
392
def each_with_index(&block) # :yield: e, row, column
393
return to_enum(:each_with_index) unless block_given?
394
@rows.each_with_index do |row, row_index|
395
row.each_with_index do |e, col_index|
396
yield e, row_index, col_index
464
def each_with_index(which = :all) # :yield: e, row, column
465
return to_enum :each_with_index, which unless block_given?
466
last = column_size - 1
469
@rows.each_with_index do |row, row_index|
470
row.each_with_index do |e, col_index|
471
yield e, row_index, col_index
475
@rows.each_with_index do |row, row_index|
476
yield row.fetch(row_index){return self}, row_index, row_index
479
@rows.each_with_index do |row, row_index|
480
column_size.times do |col_index|
481
yield row[col_index], row_index, col_index unless row_index == col_index
485
@rows.each_with_index do |row, row_index|
486
0.upto([row_index, last].min) do |col_index|
487
yield row[col_index], row_index, col_index
491
@rows.each_with_index do |row, row_index|
492
[row_index, column_size].min.times do |col_index|
493
yield row[col_index], row_index, col_index
497
@rows.each_with_index do |row, row_index|
498
(row_index+1).upto(last) do |col_index|
499
yield row[col_index], row_index, col_index
503
@rows.each_with_index do |row, row_index|
504
row_index.upto(last) do |col_index|
505
yield row[col_index], row_index, col_index
509
Matrix.Raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper"
514
SELECTORS = {all: true, diagonal: true, off_diagonal: true, lower: true, strict_lower: true, strict_upper: true, upper: true}.freeze
517
# index(value, selector = :all) -> [row, column]
518
# index(selector = :all){ block } -> [row, column]
519
# index(selector = :all) -> an_enumerator
521
# The index method is specialized to return the index as [row, column]
522
# It also accepts an optional +selector+ argument, see #each for details.
524
# Matrix[ [1,2], [3,4] ].index(&:even?) # => [0, 1]
525
# Matrix[ [1,1], [1,1] ].index(1, :strict_lower) # => [1, 0]
528
raise ArgumentError, "wrong number of arguments(#{args.size} for 0-2)" if args.size > 2
529
which = (args.size == 2 || SELECTORS.include?(args.last)) ? args.pop : :all
530
return to_enum :find_index, which, *args unless block_given? || args.size == 1
533
each_with_index(which) do |e, row_index, col_index|
534
return row_index, col_index if e == value
537
each_with_index(which) do |e, row_index, col_index|
538
return row_index, col_index if yield e
543
alias_method :find_index, :index
403
545
# Returns a section of the matrix. The parameters are either:
404
546
# * start_row, nrows, start_col, ncols; OR
612
# Returns +true+ is this is an hermitian matrix.
613
# Raises an error if matrix is not square.
616
Matrix.Raise ErrDimensionMismatch unless square?
617
each_with_index(:strict_upper).all? do |e, row, col|
618
e == rows[col][row].conj
623
# Returns +true+ is this is a lower triangular matrix.
625
def lower_triangular?
626
each(:strict_upper).all?(&:zero?)
630
# Returns +true+ is this is a normal matrix.
631
# Raises an error if matrix is not square.
634
Matrix.Raise ErrDimensionMismatch unless square?
635
rows.each_with_index do |row_i, i|
636
rows.each_with_index do |row_j, j|
638
rows.each_with_index do |row_k, k|
639
s += row_i[k] * row_j[k].conj - row_k[i].conj * row_k[j]
641
return false unless s == 0
648
# Returns +true+ is this is an orthogonal matrix
649
# Raises an error if matrix is not square.
652
Matrix.Raise ErrDimensionMismatch unless square?
653
rows.each_with_index do |row, i|
654
column_size.times do |j|
656
row_size.times do |k|
657
s += row[k] * rows[k][j]
659
return false unless s == (i == j ? 1 : 0)
666
# Returns +true+ is this is a permutation matrix
667
# Raises an error if matrix is not square.
670
Matrix.Raise ErrDimensionMismatch unless square?
671
cols = Array.new(column_size)
672
rows.each_with_index do |row, i|
674
row.each_with_index do |e, j|
676
return false if found || cols[j]
677
found = cols[j] = true
682
return false unless found
461
688
# Returns +true+ if all entries of the matrix are real.