summaryrefslogtreecommitdiff
path: root/test/matrix
diff options
context:
space:
mode:
authormarcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-02 17:52:51 +0000
committermarcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-02 17:52:51 +0000
commiteda970cfe231797fcf19d14a8dce3a9b49880708 (patch)
tree3f60576debd5ccce402a34453ea24aab98e8c8e7 /test/matrix
parentb9d42af0f28f7957c5a086a86175a0739d251c73 (diff)
lib/matrix.rb: Make Matrix & Vector mutable. Add #[]=, #map!.
Adapted from patch by Grzegorz Jakubiak. [#14151] [Fix GH-1769] [Fix GH-1905] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65507 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/matrix')
-rw-r--r--test/matrix/test_matrix.rb141
-rw-r--r--test/matrix/test_vector.rb102
2 files changed, 242 insertions, 1 deletions
diff --git a/test/matrix/test_matrix.rb b/test/matrix/test_matrix.rb
index d40e0c0430..3ecb9d2f8b 100644
--- a/test/matrix/test_matrix.rb
+++ b/test/matrix/test_matrix.rb
@@ -283,7 +283,18 @@ class TestMatrix < Test::Unit::TestCase
end
def test_collect
- assert_equal(Matrix[[1, 4, 9], [16, 25, 36]], @m1.collect {|x| x ** 2 })
+ m1 = Matrix.zero(2,2)
+ m2 = Matrix.build(3,4){|row, col| 1}
+
+ assert_equal(Matrix[[5, 5, 5, 5], [5, 5, 5, 5], [5, 5, 5, 5]], m2.collect{|e| e * 5})
+ assert_equal(Matrix[[7, 0],[0, 7]], m1.collect(:diagonal){|e| e + 7})
+ assert_equal(Matrix[[0, 5],[5, 0]], m1.collect(:off_diagonal){|e| e + 5})
+ assert_equal(Matrix[[8, 1, 1, 1], [8, 8, 1, 1], [8, 8, 8, 1]], m2.collect(:lower){|e| e + 7})
+ assert_equal(Matrix[[1, 1, 1, 1], [-11, 1, 1, 1], [-11, -11, 1, 1]], m2.collect(:strict_lower){|e| e - 12})
+ assert_equal(Matrix[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], m2.collect(:strict_upper){|e| e ** 2})
+ assert_equal(Matrix[[-1, -1, -1, -1], [1, -1, -1, -1], [1, 1, -1, -1]], m2.collect(:upper){|e| -e})
+ assert_raise(ArgumentError) {m1.collect(:test){|e| e + 7}}
+ assert_not_equal(m2, m2.collect {|e| e * 2 })
end
def test_minor
@@ -623,6 +634,134 @@ class TestMatrix < Test::Unit::TestCase
assert_equal Matrix.empty(0,3), Matrix.combine(Matrix.empty(0,3), Matrix.empty(0,3)) { raise }
end
+ def test_set_element
+ src = Matrix[
+ [1, 2, 3, 4],
+ [5, 6, 7, 8],
+ [9, 10, 11, 12],
+ ]
+ rows = {
+ range: [1..2, 1...3, 1..-1, -2..2, 1.., 1..., -2.., -2...],
+ int: [2, -1],
+ invalid: [-4, 4, -4..2, 2..-4, 0...0, 2..0, -4..],
+ }
+ columns = {
+ range: [2..3, 2...4, 2..-1, -2..3, 2.., 2..., -2..., -2..],
+ int: [3, -1],
+ invalid: [-5, 5, -5..2, 2..-5, 0...0, -5..],
+ }
+ values = {
+ element: 42,
+ matrix: Matrix[[20, 21], [22, 23]],
+ vector: Vector[30, 31],
+ row: Matrix[[60, 61]],
+ column: Matrix[[50], [51]],
+ mismatched_matrix: Matrix.identity(3),
+ mismatched_vector: Vector[0, 1, 2, 3],
+ }
+ solutions = {
+ [:int, :int] => {
+ element: Matrix[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 42]],
+ },
+ [:range , :int] => {
+ element: Matrix[[1, 2, 3, 4], [5, 6, 7, 42], [9, 10, 11, 42]],
+ column: Matrix[[1, 2, 3, 4], [5, 6, 7, 50], [9, 10, 11, 51]],
+ vector: Matrix[[1, 2, 3, 4], [5, 6, 7, 30], [9, 10, 11, 31]],
+ },
+ [:int, :range] => {
+ element: Matrix[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 42, 42]],
+ row: Matrix[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 60, 61]],
+ vector: Matrix[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 30, 31]],
+ },
+ [:range , :range] => {
+ element: Matrix[[1, 2, 3, 4], [5, 6, 42, 42], [9, 10, 42, 42]],
+ matrix: Matrix[[1, 2, 3, 4], [5, 6, 20, 21], [9, 10, 22, 23]],
+ },
+ }
+ solutions.default = Hash.new(IndexError)
+
+ rows.each do |row_style, row_arguments|
+ row_arguments.each do |row_argument|
+ columns.each do |column_style, column_arguments|
+ column_arguments.each do |column_argument|
+ values.each do |value_type, value|
+ expected = solutions[[row_style, column_style]][value_type] || Matrix::ErrDimensionMismatch
+
+ result = src.clone
+ begin
+ result[row_argument, column_argument] = value
+ assert_equal expected, result,
+ "m[#{row_argument.inspect}][#{column_argument.inspect}] = #{value.inspect} failed"
+ rescue Exception => e
+ raise if e.class != expected
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def test_map!
+ m1 = Matrix.zero(2,2)
+ m2 = Matrix.build(3,4){|row, col| 1}
+ m3 = Matrix.zero(3,5).freeze
+ m4 = Matrix.empty.freeze
+
+ assert_equal Matrix[[5, 5, 5, 5], [5, 5, 5, 5], [5, 5, 5, 5]], m2.map!{|e| e * 5}
+ assert_equal Matrix[[7, 0],[0, 7]], m1.map!(:diagonal){|e| e + 7}
+ assert_equal Matrix[[7, 5],[5, 7]], m1.map!(:off_diagonal){|e| e + 5}
+ assert_equal Matrix[[12, 5, 5, 5], [12, 12, 5, 5], [12, 12, 12, 5]], m2.map!(:lower){|e| e + 7}
+ assert_equal Matrix[[12, 5, 5, 5], [0, 12, 5, 5], [0, 0, 12, 5]], m2.map!(:strict_lower){|e| e - 12}
+ assert_equal Matrix[[12, 25, 25, 25], [0, 12, 25, 25], [0, 0, 12, 25]], m2.map!(:strict_upper){|e| e ** 2}
+ assert_equal Matrix[[-12, -25, -25, -25], [0, -12, -25, -25], [0, 0, -12, -25]], m2.map!(:upper){|e| -e}
+ assert_equal m1, m1.map!{|e| e ** 2 }
+ assert_equal m2, m2.map!(:lower){ |e| e - 3 }
+ assert_raise(ArgumentError) {m1.map!(:test){|e| e + 7}}
+ assert_raise(FrozenError) { m3.map!{|e| e * 2} }
+ assert_raise(FrozenError) { m4.map!{} }
+ end
+
+ def test_freeze
+ m = Matrix[[1, 2, 3],[4, 5, 6]]
+ f = m.freeze
+ assert_equal true, f.frozen?
+ assert m.equal?(f)
+ assert m.equal?(f.freeze)
+ assert_raise(FrozenError){ m[0, 1] = 56 }
+ assert_equal m.dup, m
+ end
+
+ def test_clone
+ a = Matrix[[4]]
+ def a.foo
+ 42
+ end
+
+ m = a.clone
+ m[0, 0] = 2
+ assert_equal a, m * 2
+ assert_equal 42, m.foo
+
+ a.freeze
+ m = a.clone
+ assert m.frozen?
+ assert_equal 42, m.foo
+ end
+
+ def test_dup
+ a = Matrix[[4]]
+ def a.foo
+ 42
+ end
+ a.freeze
+
+ m = a.dup
+ m[0, 0] = 2
+ assert_equal a, m * 2
+ assert !m.respond_to?(:foo)
+ end
+
def test_eigenvalues_and_eigenvectors_symmetric
m = Matrix[
[8, 1],
diff --git a/test/matrix/test_vector.rb b/test/matrix/test_vector.rb
index 631b4d809a..8b771efee3 100644
--- a/test/matrix/test_vector.rb
+++ b/test/matrix/test_vector.rb
@@ -27,6 +27,108 @@ class TestVector < Test::Unit::TestCase
assert_raise(ArgumentError) { Vector.basis(index: 3) }
end
+ def test_get_element
+ assert_equal(@v1[0..], [1, 2, 3])
+ assert_equal(@v1[0..1], [1, 2])
+ assert_equal(@v1[2], 3)
+ assert_equal(@v1[4], nil)
+ end
+
+ def test_set_element
+
+ assert_block do
+ v = Vector[5, 6, 7, 8, 9]
+ v[1..2] = Vector[1, 2]
+ v == Vector[5, 1, 2, 8, 9]
+ end
+
+ assert_block do
+ v = Vector[6, 7, 8]
+ v[1..2] = Matrix[[1, 3]]
+ v == Vector[6, 1, 3]
+ end
+
+ assert_block do
+ v = Vector[1, 2, 3, 4, 5, 6]
+ v[0..2] = 8
+ v == Vector[8, 8, 8, 4, 5, 6]
+ end
+
+ assert_block do
+ v = Vector[1, 3, 4, 5]
+ v[2] = 5
+ v == Vector[1, 3, 5, 5]
+ end
+
+ assert_block do
+ v = Vector[2, 3, 5]
+ v[-2] = 13
+ v == Vector[2, 13, 5]
+ end
+
+ assert_block do
+ v = Vector[4, 8, 9, 11, 30]
+ v[1..-2] = Vector[1, 2, 3]
+ v == Vector[4, 1, 2, 3, 30]
+ end
+
+ assert_raise(IndexError) {Vector[1, 3, 4, 5][5..6] = 17}
+ assert_raise(IndexError) {Vector[1, 3, 4, 5][6] = 17}
+ assert_raise(Matrix::ErrDimensionMismatch) {Vector[1, 3, 4, 5][0..2] = Matrix[[1], [2], [3]]}
+ assert_raise(ArgumentError) {Vector[1, 2, 3, 4, 5, 6][0..2] = Vector[1, 2, 3, 4, 5, 6]}
+ assert_raise(FrozenError) { Vector[7, 8, 9].freeze[0..1] = 5}
+ end
+
+ def test_map!
+ v1 = Vector[1, 2, 3]
+ v2 = Vector[1, 3, 5].freeze
+ v3 = Vector[].freeze
+ assert_equal Vector[1, 4, 9], v1.map!{|e| e ** 2}
+ assert_equal v1, v1.map!{|e| e - 8}
+ assert_raise(FrozenError) { v2.map!{|e| e + 2 }}
+ assert_raise(FrozenError){ v3.map!{} }
+ end
+
+ def test_freeze
+ v = Vector[1,2,3]
+ f = v.freeze
+ assert_equal true, f.frozen?
+ assert v.equal?(f)
+ assert v.equal?(f.freeze)
+ assert_raise(FrozenError){ v[1] = 56 }
+ assert_equal v.dup, v
+ end
+
+ def test_clone
+ a = Vector[4]
+ def a.foo
+ 42
+ end
+
+ v = a.clone
+ v[0] = 2
+ assert_equal a, v * 2
+ assert_equal 42, v.foo
+
+ a.freeze
+ v = a.clone
+ assert v.frozen?
+ assert_equal 42, v.foo
+ end
+
+ def test_dup
+ a = Vector[4]
+ def a.foo
+ 42
+ end
+ a.freeze
+
+ v = a.dup
+ v[0] = 2
+ assert_equal a, v * 2
+ assert !v.respond_to?(:foo)
+ end
+
def test_identity
assert_same @v1, @v1
assert_not_same @v1, @v2