diff --git a/lib/matrix/matrix.rb b/lib/matrix/matrix.rb index 250e054..20d902e 100644 --- a/lib/matrix/matrix.rb +++ b/lib/matrix/matrix.rb @@ -112,61 +112,17 @@ def self.convert(matrix) fast_matrix end - # + # # Yields all elements of the matrix, starting with those of the first row # # Matrix[ [1,2], [3,4] ].each { |e| puts e } # # => prints the numbers 1 to 4 - def each(which = :all) # :yield: e - return to_enum :each, which unless block_given? - case which - when :all - (0...row_count).each do |i| - (0...column_count).each do |j| - yield self[i, j] - end - end - when :diagonal - (0...[row_count, column_count].min).each do |i| - yield self[i, i] - end - when :off_diagonal - (0...row_count).each do |i| - (0...column_count).each do |j| - if i != j - yield self[i, j] - end - end - end - when :lower - (0...row_count).each do |i| - (0..[i,column_count-1].min).each do |j| - yield self[i, j] - end - end - when :strict_lower - (1...row_count).each do |i| - (0...[i,column_count].min).each do |j| - yield self[i, j] - end - end - when :strict_upper - (0...row_count).each do |i| - (i+1...column_count).each do |j| - yield self[i, j] - end - end - when :upper - (0...row_count).each do |i| - (i...column_count).each do |j| - yield self[i, j] - end - end - else - raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper" - end - self + def each(which = :all) # :yield: e + return to_enum :each, which unless block_given? + + each_with_index(which){ |elem, _, _| yield elem} end + # # Same as #each, but the row index and column index in addition to the element # @@ -179,17 +135,85 @@ def each(which = :all) # :yield: e # # 3 at 1, 0 # # 4 at 1, 1 # - def each_with_index - raise NotSupportedError unless block_given? + def each_with_index(which = :all) # :yield: e, row, column + return to_enum :each_with_index, which unless block_given? + case which + when :all + each_all{|i, j| yield self[i, j], i, j} + when :diagonal + each_diagonal{|i, j| yield self[i, j], i, j} + when :off_diagonal + each_off_diagonal{|i, j| yield self[i, j], i, j} + when :lower + each_lower{|i, j| yield self[i, j], i, j} + when :strict_lower + each_strict_lower{|i, j| yield self[i, j], i, j} + when :strict_upper + each_strict_upper{|i, j| yield self[i, j], i, j} + when :upper + each_upper{|i, j| yield self[i, j], i, j} + else + raise ArgumentError, "expected #{which.inspect} to be one of :all, :diagonal, :off_diagonal, :lower, :strict_lower, :strict_upper or :upper" + end + self + end + def each_all(&block) (0...row_count).each do |i| (0...column_count).each do |j| - yield self[i, j], i, j + block[i,j] end end - self end + def each_diagonal(&block) + (0...[row_count, column_count].min).each do |i| + block[i, i] + end + end + + def each_off_diagonal(&block) + (0...row_count).each do |i| + (0...column_count).each do |j| + if i != j + block[i, j] + end + end + end + end + + def each_lower(&block) + (0...row_count).each do |i| + (0..[i,column_count-1].min).each do |j| + block[i, j] + end + end + end + + def each_strict_lower(&block) + (1...row_count).each do |i| + (0...[i,column_count].min).each do |j| + block[i, j] + end + end + end + + def each_strict_upper(&block) + (0...row_count).each do |i| + (i+1...column_count).each do |j| + block[i, j] + end + end + end + + def each_upper(&block) + (0...row_count).each do |i| + (i...column_count).each do |j| + block[i, j] + end + end + end + # don't use (Issue#1) def each_with_index! (0...row_count).each do |i| diff --git a/test/matrix/matrix_test.rb b/test/matrix/matrix_test.rb index 357aa9a..d5d0a0a 100644 --- a/test/matrix/matrix_test.rb +++ b/test/matrix/matrix_test.rb @@ -259,6 +259,121 @@ def test_each_strict_upper_rec2 assert_equal [2, 3, 6], m.each(:strict_upper).to_a end + def test_each_wi_all_sq + m = Matrix[[1, 2], [3, 4]] + assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 1, 0], [4.0, 1, 1]], m.each_with_index(:all).to_a + end + + def test_each_wi_all_rec1 + m = Matrix[[1, 2], [3, 4], [5, 6]] + assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 1, 0], [4.0, 1, 1], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:all).to_a + end + + def test_each_wi_all_rec2 + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 0, 2], [4.0, 1, 0], [5.0, 1, 1], [6.0, 1, 2]], m.each_with_index(:all).to_a + end + + def test_each_wi_diagonal_sq + m = Matrix[[1, 2], [3, 4]] + assert_equal [[1.0, 0, 0], [4.0, 1, 1]], m.each_with_index(:diagonal).to_a + end + + def test_each_wi_diagonal_rec1 + m = Matrix[[1, 2], [3, 4], [5, 6]] + assert_equal [[1.0, 0, 0], [4.0, 1, 1]], m.each_with_index(:diagonal).to_a + end + + def test_each_wi_diagonal_rec2 + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_equal [[1.0, 0, 0], [5.0, 1, 1]], m.each_with_index(:diagonal).to_a + end + + def test_each_wi_off_diagonal_sq + m = Matrix[[1, 2], [3, 4]] + assert_equal [[2.0, 0, 1], [3.0, 1, 0]], m.each_with_index(:off_diagonal).to_a + end + + def test_each_wi_off_diagonal_rec1 + m = Matrix[[1, 2], [3, 4], [5, 6]] + assert_equal [[2.0, 0, 1], [3.0, 1, 0], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:off_diagonal).to_a + end + + def test_each_wi_off_diagonal_rec2 + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_equal [[2.0, 0, 1], [3.0, 0, 2], [4.0, 1, 0], [6.0, 1, 2]], m.each_with_index(:off_diagonal).to_a + end + + def test_each_wi_lower_sq + m = Matrix[[1, 2], [3, 4]] + assert_equal [[1.0, 0, 0], [3.0, 1, 0], [4.0, 1, 1]], m.each_with_index(:lower).to_a + end + + def test_each_wi_lower_rec1 + m = Matrix[[1, 2], [3, 4], [5, 6]] + assert_equal [[1.0, 0, 0], [3.0, 1, 0], [4.0, 1, 1], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:lower).to_a + end + + def test_each_wi_lower_rec2 + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_equal [[1.0, 0, 0], [4.0, 1, 0], [5.0, 1, 1]], m.each_with_index(:lower).to_a + end + + def test_each_wi_strict_lower_sq + m = Matrix[[1, 2], [3, 4]] + assert_equal [[3.0, 1, 0]], m.each_with_index(:strict_lower).to_a + end + + def test_each_wi_strict_lower_rec1 + m = Matrix[[1, 2], [3, 4], [5, 6]] + assert_equal [[3.0, 1, 0], [5.0, 2, 0], [6.0, 2, 1]], m.each_with_index(:strict_lower).to_a + end + + def test_each_wi_strict_lower_rec2 + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_equal [[4.0, 1, 0]], m.each_with_index(:strict_lower).to_a + end + + def test_each_wi_upper_sq + m = Matrix[[1, 2], [3, 4]] + assert_equal [[1.0, 0, 0], [2.0, 0, 1], [4.0, 1, 1]], m.each_with_index(:upper).to_a + end + + def test_each_wi_upper_rec1 + m = Matrix[[1, 2], [3, 4], [5, 6]] + assert_equal [[1.0, 0, 0], [2.0, 0, 1], [4.0, 1, 1]], m.each_with_index(:upper).to_a + end + + def test_each_wi_upper_rec2 + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_equal [[1.0, 0, 0], [2.0, 0, 1], [3.0, 0, 2], [5.0, 1, 1], [6.0, 1, 2]], m.each_with_index(:upper).to_a + end + + def test_each_wi_strict_upper_sq + m = Matrix[[1, 2], [3, 4]] + assert_equal [[2.0, 0, 1]], m.each_with_index(:strict_upper).to_a + end + + def test_each_wi_strict_upper_rec1 + m = Matrix[[1, 2], [3, 4], [5, 6]] + assert_equal [[2.0, 0, 1]], m.each_with_index(:strict_upper).to_a + end + + def test_each_wi_strict_upper_rec2 + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_equal [[2.0, 0, 1], [3.0, 0, 2], [6.0, 1, 2]], m.each_with_index(:strict_upper).to_a + end + + def test_each_argument_error + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_raises (ArgumentError){ m.each(:al).to_a } + end + + def test_each_wi_argument_error + m = Matrix[[1, 2, 3], [4, 5, 6]] + assert_raises (ArgumentError){ m.each_with_index(:al).to_a } + end + def test_greater m1 = Matrix[[1, 2, 3], [3, 2, 1]] m2 = Matrix[[2, 3, 6], [4, 4, 4]]