rubysl-matrix 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/lib/matrix.rb +1 -0
  9. data/lib/rubysl/matrix.rb +2 -0
  10. data/lib/rubysl/matrix/matrix.rb +1537 -0
  11. data/lib/rubysl/matrix/version.rb +5 -0
  12. data/rubysl-matrix.gemspec +27 -0
  13. data/spec/I_spec.rb +5 -0
  14. data/spec/build_spec.rb +75 -0
  15. data/spec/clone_spec.rb +26 -0
  16. data/spec/coerce_spec.rb +11 -0
  17. data/spec/collect_spec.rb +5 -0
  18. data/spec/column_size_spec.rb +14 -0
  19. data/spec/column_spec.rb +36 -0
  20. data/spec/column_vector_spec.rb +36 -0
  21. data/spec/column_vectors_spec.rb +25 -0
  22. data/spec/columns_spec.rb +45 -0
  23. data/spec/conj_spec.rb +7 -0
  24. data/spec/conjugate_spec.rb +7 -0
  25. data/spec/constructor_spec.rb +68 -0
  26. data/spec/det_spec.rb +6 -0
  27. data/spec/determinant_spec.rb +6 -0
  28. data/spec/diagonal_spec.rb +73 -0
  29. data/spec/divide_spec.rb +60 -0
  30. data/spec/each_spec.rb +77 -0
  31. data/spec/each_with_index_spec.rb +84 -0
  32. data/spec/eigenvalue_decomposition/eigenvalue_matrix_spec.rb +10 -0
  33. data/spec/eigenvalue_decomposition/eigenvalues_spec.rb +23 -0
  34. data/spec/eigenvalue_decomposition/eigenvector_matrix_spec.rb +23 -0
  35. data/spec/eigenvalue_decomposition/eigenvectors_spec.rb +25 -0
  36. data/spec/eigenvalue_decomposition/initialize_spec.rb +27 -0
  37. data/spec/eigenvalue_decomposition/to_a_spec.rb +19 -0
  38. data/spec/element_reference_spec.rb +24 -0
  39. data/spec/empty_spec.rb +69 -0
  40. data/spec/eql_spec.rb +12 -0
  41. data/spec/equal_value_spec.rb +10 -0
  42. data/spec/exponent_spec.rb +66 -0
  43. data/spec/find_index_spec.rb +147 -0
  44. data/spec/fixtures/classes.rb +7 -0
  45. data/spec/hash_spec.rb +14 -0
  46. data/spec/hermitian_spec.rb +37 -0
  47. data/spec/identity_spec.rb +5 -0
  48. data/spec/imag_spec.rb +7 -0
  49. data/spec/imaginary_spec.rb +7 -0
  50. data/spec/inspect_spec.rb +30 -0
  51. data/spec/inv_spec.rb +6 -0
  52. data/spec/inverse_from_spec.rb +5 -0
  53. data/spec/inverse_spec.rb +6 -0
  54. data/spec/lower_triangular_spec.rb +25 -0
  55. data/spec/lup_decomposition/determinant_spec.rb +24 -0
  56. data/spec/lup_decomposition/initialize_spec.rb +14 -0
  57. data/spec/lup_decomposition/l_spec.rb +19 -0
  58. data/spec/lup_decomposition/p_spec.rb +19 -0
  59. data/spec/lup_decomposition/solve_spec.rb +54 -0
  60. data/spec/lup_decomposition/to_a_spec.rb +36 -0
  61. data/spec/lup_decomposition/u_spec.rb +19 -0
  62. data/spec/map_spec.rb +5 -0
  63. data/spec/minor_spec.rb +90 -0
  64. data/spec/minus_spec.rb +45 -0
  65. data/spec/multiply_spec.rb +73 -0
  66. data/spec/new_spec.rb +7 -0
  67. data/spec/normal_spec.rb +27 -0
  68. data/spec/orthogonal_spec.rb +27 -0
  69. data/spec/permutation_spec.rb +33 -0
  70. data/spec/plus_spec.rb +45 -0
  71. data/spec/rank_spec.rb +24 -0
  72. data/spec/real_spec.rb +45 -0
  73. data/spec/rect_spec.rb +7 -0
  74. data/spec/rectangular_spec.rb +7 -0
  75. data/spec/regular_spec.rb +34 -0
  76. data/spec/round_spec.rb +24 -0
  77. data/spec/row_size_spec.rb +12 -0
  78. data/spec/row_spec.rb +37 -0
  79. data/spec/row_vector_spec.rb +33 -0
  80. data/spec/row_vectors_spec.rb +25 -0
  81. data/spec/rows_spec.rb +40 -0
  82. data/spec/scalar/Fail_spec.rb +5 -0
  83. data/spec/scalar/Raise_spec.rb +5 -0
  84. data/spec/scalar/divide_spec.rb +5 -0
  85. data/spec/scalar/exponent_spec.rb +5 -0
  86. data/spec/scalar/included_spec.rb +5 -0
  87. data/spec/scalar/initialize_spec.rb +5 -0
  88. data/spec/scalar/minus_spec.rb +5 -0
  89. data/spec/scalar/multiply_spec.rb +5 -0
  90. data/spec/scalar/plus_spec.rb +5 -0
  91. data/spec/scalar_spec.rb +66 -0
  92. data/spec/shared/collect.rb +29 -0
  93. data/spec/shared/conjugate.rb +21 -0
  94. data/spec/shared/determinant.rb +53 -0
  95. data/spec/shared/equal_value.rb +35 -0
  96. data/spec/shared/identity.rb +21 -0
  97. data/spec/shared/imaginary.rb +22 -0
  98. data/spec/shared/inverse.rb +42 -0
  99. data/spec/shared/rectangular.rb +20 -0
  100. data/spec/shared/trace.rb +14 -0
  101. data/spec/shared/transpose.rb +23 -0
  102. data/spec/singular_spec.rb +34 -0
  103. data/spec/spec_helper.rb +35 -0
  104. data/spec/square_spec.rb +29 -0
  105. data/spec/symmetric_spec.rb +30 -0
  106. data/spec/t_spec.rb +5 -0
  107. data/spec/to_a_spec.rb +5 -0
  108. data/spec/to_s_spec.rb +5 -0
  109. data/spec/tr_spec.rb +6 -0
  110. data/spec/trace_spec.rb +6 -0
  111. data/spec/transpose_spec.rb +5 -0
  112. data/spec/unit_spec.rb +5 -0
  113. data/spec/unitary_spec.rb +29 -0
  114. data/spec/upper_triangular_spec.rb +26 -0
  115. data/spec/vector/cross_product_spec.rb +25 -0
  116. data/spec/vector/each2_spec.rb +52 -0
  117. data/spec/vector/eql_spec.rb +17 -0
  118. data/spec/vector/inner_product_spec.rb +25 -0
  119. data/spec/vector/normalize_spec.rb +19 -0
  120. data/spec/zero_spec.rb +55 -0
  121. metadata +341 -0
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../shared/equal_value', __FILE__)
2
+ require 'matrix'
3
+
4
+ describe "Matrix#eql?" do
5
+ it_behaves_like(:equal, :eql?)
6
+
7
+ ruby_bug("[ruby-dev:36298]", "1.8.7") do
8
+ it "returns false if some elements are == but not eql?" do
9
+ Matrix[[1, 2],[3, 4]].eql?(Matrix[[1, 2],[3, 4.0]]).should be_false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../shared/equal_value', __FILE__)
2
+ require 'matrix'
3
+
4
+ describe "Matrix#==" do
5
+ it_behaves_like(:equal, :==)
6
+
7
+ it "returns true if some elements are == but not eql?" do
8
+ Matrix[[1, 2],[3, 4]].should == Matrix[[1, 2],[3, 4.0]]
9
+ end
10
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path('../fixtures/classes', __FILE__)
2
+ require 'matrix'
3
+
4
+ describe "Matrix#**" do
5
+
6
+ describe "given an integer _n_" do
7
+ it "multiples the Matrix by itself _n_ times" do
8
+ m = Matrix[ [7,6], [3,9] ]
9
+ (m ** 1).should == m
10
+ (m ** 2).should == Matrix[ [67, 96], [48,99] ]
11
+ (m ** 2).should == m * m
12
+ (m ** 3).should == m * m * m
13
+ (m ** 4).should == m * m * m * m
14
+ (m ** 5).should == m * m * m * m * m
15
+ end
16
+
17
+ it "raises a ErrDimensionMismatch for non square matrices" do
18
+ m = Matrix[ [1, 1], [1, 2], [2, 3]]
19
+ lambda { m ** 3 }.should raise_error(Matrix::ErrDimensionMismatch)
20
+ lambda { m ** 0 }.should raise_error(Matrix::ErrDimensionMismatch)
21
+ end
22
+
23
+ describe "that is <= 0" do
24
+ it "returns the inverse of **(-n)" do
25
+ m = Matrix[ [1, 1], [1, 2] ]
26
+ (m ** -2).should == Matrix[ [5, -3], [-3, 2]]
27
+ (m ** -4).should == (m.inverse ** 4)
28
+ end
29
+
30
+ it "raises a ErrDimensionMismatch for irregular matrices" do
31
+ m = Matrix[ [1, 1], [1, 1] ]
32
+ lambda { m ** -2 }.should raise_error(Matrix::ErrNotRegular)
33
+ lambda { m ** 0 }.should raise_error(Matrix::ErrNotRegular)
34
+ end
35
+ end
36
+ end
37
+
38
+ ruby_version_is "" ... "1.9.1" do
39
+ it "raises a ErrOperationNotDefined exception for powers that aren't Integers" do
40
+ lambda {Matrix[ [1,2], [8,2] ] ** 2.5}.should \
41
+ raise_error(Matrix::ErrOperationNotDefined)
42
+ end
43
+ end
44
+
45
+ ruby_version_is "1.9.1" ... "1.9.3" do
46
+ it "raises a ErrOperationNotImplemented exception for powers that aren't Integers" do
47
+ lambda {Matrix[ [1,2], [8,2] ] ** 2.5}.should \
48
+ raise_error(Matrix::ErrOperationNotImplemented)
49
+ end
50
+ end
51
+
52
+ ruby_version_is "1.9.3" do
53
+ it "returns the power for non integer powers" do
54
+ a = Matrix[[5, 4], [4, 5]]
55
+ ((a ** 0.5) ** 2).round(8).should == a
56
+ a = Matrix[[7, 10], [15, 22]]
57
+ ((a ** 0.25) ** 4).round(8).should == a
58
+ end
59
+ end
60
+
61
+ describe "for a subclass of Matrix" do
62
+ it "returns an instance of that subclass" do
63
+ (MatrixSub.ins ** 1).should be_an_instance_of(MatrixSub)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,147 @@
1
+ require 'matrix'
2
+
3
+ ruby_version_is "1.9.3" do
4
+ describe "Matrix#find_index without any argument" do
5
+ before :all do
6
+ @m = Matrix[ [1, 2, 3, 4], [5, 6, 7, 8] ]
7
+ end
8
+
9
+ it "returns an Enumerator when called without a block" do
10
+ enum = @m.find_index
11
+ enum.should be_an_instance_of(enumerator_class)
12
+ enum.to_a.should == [1, 2, 3, 4, 5, 6, 7, 8]
13
+ end
14
+
15
+ it "returns nil if the block is always false" do
16
+ @m.find_index{false}.should be_nil
17
+ end
18
+
19
+ it "returns the first index for which the block is true" do
20
+ @m.find_index{|x| x >= 3}.should == [0, 2]
21
+ end
22
+ end
23
+
24
+ describe "Matrix#find_index with a subselection argument" do
25
+ before :all do
26
+ @tests = [
27
+ [ Matrix[ [1, 2, 3, 4], [5, 6, 7, 8] ], {
28
+ :diagonal => [1, 6] ,
29
+ :off_diagonal => [2, 3, 4, 5, 7, 8],
30
+ :lower => [1, 5, 6] ,
31
+ :strict_lower => [5] ,
32
+ :strict_upper => [2, 3, 4, 7, 8] ,
33
+ :upper => [1, 2, 3, 4, 6, 7, 8] ,
34
+ }
35
+ ],
36
+ [ Matrix[ [1, 2], [3, 4], [5, 6], [7, 8] ], {
37
+ :diagonal => [1, 4] ,
38
+ :off_diagonal => [2, 3, 5, 6, 7, 8],
39
+ :lower => [1, 3, 4, 5, 6, 7, 8] ,
40
+ :strict_lower => [3, 5, 6, 7, 8] ,
41
+ :strict_upper => [2] ,
42
+ :upper => [1, 2, 4] ,
43
+ }
44
+ ]]
45
+ end
46
+
47
+ describe "and no generic argument" do
48
+ it "returns an Enumerator when called without a block" do
49
+ @tests.each do |matrix, h|
50
+ h.each do |selector, result|
51
+ matrix.find_index(selector).should be_an_instance_of(enumerator_class)
52
+ end
53
+ end
54
+ end
55
+
56
+ it "yields the rights elements" do
57
+ @tests.each do |matrix, h|
58
+ h.each do |selector, result|
59
+ matrix.find_index(selector).to_a.should == result
60
+ end
61
+ end
62
+ end
63
+
64
+ it "returns the first index for which the block returns true" do
65
+ @tests.each do |matrix, h|
66
+ h.each do |selector, result|
67
+ cnt = result.size.div 2
68
+ which = result[cnt]
69
+ idx = matrix.find_index(selector){|x| cnt -= 1; x == which}
70
+ matrix[*idx].should == which
71
+ cnt.should == -1
72
+ end
73
+ end
74
+ end
75
+
76
+ it "returns nil if the block is always false" do
77
+ @tests.each do |matrix, h|
78
+ h.each do |selector, result|
79
+ matrix.find_index(selector){ nil }.should == nil
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ describe "and a generic argument" do
87
+ it "ignores a block" do
88
+ @m.find_index(42, :diagonal){raise "oups"}.should == nil
89
+ end
90
+
91
+ it "returns the index of the requested value" do
92
+ @tests.each do |matrix, h|
93
+ h.each do |selector, result|
94
+ cnt = result.size / 2
95
+ which = result[cnt]
96
+ idx = matrix.find_index(which, selector)
97
+ matrix[*idx].should == which
98
+ end
99
+ end
100
+ end
101
+
102
+ it "returns nil if the requested value is not found" do
103
+ @tests.each do |matrix, h|
104
+ h.each do |selector, result|
105
+ matrix.find_index(42, selector).should == nil
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+ describe "Matrix#find_index with only a generic argument" do
114
+ before :all do
115
+ @m = Matrix[ [1, 2, 3, 4], [1, 2, 3, 4] ]
116
+ end
117
+
118
+ it "returns nil if the value is not found" do
119
+ @m.find_index(42).should be_nil
120
+ end
121
+
122
+ it "returns the first index for of the requested value" do
123
+ @m.find_index(3).should == [0, 2]
124
+ end
125
+
126
+ it "ignores a block" do
127
+ @m.find_index(4){raise "oups"}.should == [0, 3]
128
+ end
129
+ end
130
+
131
+ describe "Matrix#find_index with two arguments" do
132
+ it "raises an ArgumentError for an unrecognized last argument" do
133
+ lambda {
134
+ @m.find_index(1, "all"){}
135
+ }.should raise_error(ArgumentError)
136
+ lambda {
137
+ @m.find_index(1, nil){}
138
+ }.should raise_error(ArgumentError)
139
+ lambda {
140
+ @m.find_index(1, :left){}
141
+ }.should raise_error(ArgumentError)
142
+ lambda {
143
+ @m.find_index(:diagonal, 1){}
144
+ }.should raise_error(ArgumentError)
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,7 @@
1
+ require 'matrix'
2
+
3
+ class MatrixSub < Matrix
4
+ def self.ins
5
+ rows([[1, 0], [0, 1]])
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require 'matrix'
2
+
3
+ describe "Matrix#hash" do
4
+
5
+ it "returns a Fixnum" do
6
+ Matrix[ [1,2] ].hash.should be_an_instance_of(Fixnum)
7
+ end
8
+
9
+ it "returns the same value for the same matrix" do
10
+ data = [ [40,5], [2,7] ]
11
+ Matrix[ *data ].hash.should == Matrix[ *data ].hash
12
+ end
13
+
14
+ end
@@ -0,0 +1,37 @@
1
+ require 'matrix'
2
+
3
+ ruby_version_is "1.9.3" do
4
+ describe "Matrix.hermitian?" do
5
+ it "returns true for a hermitian Matrix" do
6
+ Matrix[[1, 2, Complex(0, 3)], [2, 4, 5], [Complex(0, -3), 5, 6]].hermitian?.should be_true
7
+ end
8
+
9
+ it "returns true for a 0x0 empty matrix" do
10
+ Matrix.empty.hermitian?.should be_true
11
+ end
12
+
13
+ it "returns false for an assymetric Matrix" do
14
+ Matrix[[1, 2],[-2, 1]].hermitian?.should be_false
15
+ end
16
+
17
+ it "raises an error for rectangular matrices" do
18
+ [
19
+ Matrix[[0], [0]],
20
+ Matrix[[0, 0]],
21
+ Matrix.empty(0, 2),
22
+ Matrix.empty(2, 0),
23
+ ].each do |rectangual_matrix|
24
+ lambda {
25
+ rectangual_matrix.hermitian?
26
+ }.should raise_error(Matrix::ErrDimensionMismatch)
27
+ end
28
+ end
29
+
30
+ ruby_bug "redmine:6290", "1.9.3" do
31
+ it "returns false for a matrix with complex values on the diagonal" do
32
+ Matrix[[Complex(1,1)]].hermitian?.should be_false
33
+ Matrix[[Complex(1,0)]].hermitian?.should be_true
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path('../shared/identity', __FILE__)
2
+
3
+ describe "Matrix.identity" do
4
+ it_behaves_like(:matrix_identity, :identity)
5
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../shared/imaginary', __FILE__)
2
+
3
+ ruby_version_is "1.9" do
4
+ describe "Matrix#imag" do
5
+ it_behaves_like(:matrix_imaginary, :imag)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../shared/imaginary', __FILE__)
2
+
3
+ ruby_version_is "1.9" do
4
+ describe "Matrix#imaginary" do
5
+ it_behaves_like(:matrix_imaginary, :imaginary)
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../fixtures/classes', __FILE__)
2
+ require 'matrix'
3
+
4
+ describe "Matrix#inspect" do
5
+
6
+ it "returns a stringified representation of the Matrix" do
7
+ Matrix[ [1,2], [2,1] ].inspect.should == "Matrix[[1, 2], [2, 1]]"
8
+ end
9
+
10
+ ruby_bug "redmine:1532", "1.8.7" do
11
+ it "returns 'Matrix.empty(...)' for empty matrices" do
12
+ Matrix[ [], [], [] ].inspect.should == "Matrix.empty(3, 0)"
13
+ Matrix.columns([ [], [], [] ]).inspect.should == "Matrix.empty(0, 3)"
14
+ end
15
+ end
16
+
17
+ it "calls inspect on its contents" do
18
+ obj = mock("some_value")
19
+ obj.should_receive(:inspect).and_return("some_value")
20
+ Matrix[ [1, 2], [3, obj] ].inspect.should == "Matrix[[1, 2], [3, some_value]]"
21
+ end
22
+
23
+ ruby_bug "redmine #5307", "1.9.3" do
24
+ describe "for a subclass of Matrix" do
25
+ it "returns a string using the subclass' name" do
26
+ MatrixSub.ins.inspect.should == "MatrixSub[[1, 0], [0, 1]]"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require File.expand_path('../shared/inverse', __FILE__)
3
+
4
+ describe "Matrix#inv" do
5
+ it_behaves_like(:inverse, :inv)
6
+ end
@@ -0,0 +1,5 @@
1
+ require 'matrix'
2
+
3
+ describe "Matrix#inverse_from" do
4
+ it "needs to be reviewed for spec completeness"
5
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require File.expand_path('../shared/inverse', __FILE__)
3
+
4
+ describe "Matrix#inverse" do
5
+ it_behaves_like(:inverse, :inverse)
6
+ end
@@ -0,0 +1,25 @@
1
+ require 'matrix'
2
+
3
+ ruby_version_is "1.9.3" do
4
+ describe "Matrix.lower_triangular?" do
5
+ it "returns true for a square lower triangular Matrix" do
6
+ Matrix[[1, 0, 0], [1, 2, 0], [1, 2, 3]].lower_triangular?.should be_true
7
+ Matrix.diagonal([1, 2, 3]).lower_triangular?.should be_true
8
+ Matrix[[1, 0], [1, 2], [1, 2], [1, 2]].lower_triangular?.should be_true
9
+ Matrix[[1, 0, 0, 0], [1, 2, 0, 0]].lower_triangular?.should be_true
10
+ end
11
+
12
+ it "returns true for an empty Matrix" do
13
+ Matrix.empty(3, 0).lower_triangular?.should be_true
14
+ Matrix.empty(0, 3).lower_triangular?.should be_true
15
+ Matrix.empty(0, 0).lower_triangular?.should be_true
16
+ end
17
+
18
+ it "returns false for a non lower triangular square Matrix" do
19
+ Matrix[[0, 1], [0, 0]].lower_triangular?.should be_false
20
+ Matrix[[1, 2, 3], [1, 2, 3], [1, 2, 3]].lower_triangular?.should be_false
21
+ Matrix[[0, 1], [0, 0], [0, 0], [0, 0]].lower_triangular?.should be_false
22
+ Matrix[[0, 0, 0, 1], [0, 0, 0, 0]].lower_triangular?.should be_false
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ require 'matrix'
2
+
3
+ ruby_version_is "1.9.3" do
4
+ describe "Matrix::LUPDecomposition#determinant" do
5
+ it "returns the determinant when the matrix is square" do
6
+ a = Matrix[[7, 8, 9], [14, 46, 51], [28, 82, 163]]
7
+ a.lup.determinant.should == 15120 # == a.determinant
8
+ end
9
+
10
+ ruby_bug "#7620", "1.9.3" do
11
+ it "raises an error for rectangular matrices" do
12
+ [
13
+ Matrix[[7, 8, 9], [14, 46, 51]],
14
+ Matrix[[7, 8], [14, 46], [28, 82]],
15
+ ].each do |m|
16
+ lup = m.lup
17
+ lambda {
18
+ lup.determinant
19
+ }.should raise_error(Matrix::ErrDimensionMismatch)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'matrix'
2
+
3
+ ruby_version_is "1.9.3" do
4
+ describe "Matrix::LUPDecomposition#initialize" do
5
+ it "raises an error if argument is not a matrix" do
6
+ lambda {
7
+ Matrix::LUPDecomposition.new([[]])
8
+ }.should raise_error(TypeError)
9
+ lambda {
10
+ Matrix::LUPDecomposition.new(42)
11
+ }.should raise_error(TypeError)
12
+ end
13
+ end
14
+ end