matrix 0.1.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76ae31753ed23d3cb449505dc8d64407f502f80723f5253f329e0d24309d6f04
4
- data.tar.gz: d79a3bd3a4ec37ce78f77c67c3b67820c1b11ff38ac867494eaab1ee4f9a7296
3
+ metadata.gz: bb141efd74292651e0289eb99780e5fdc476e5bf124a1038f6240939c629a2bf
4
+ data.tar.gz: 0e2f47d4f48c2986e4a4cc71973040b9b4a44f1e4c17a0f2319d46316ec742c0
5
5
  SHA512:
6
- metadata.gz: 53a78680becf3477e688d561a8494496a6c1aae69397087795129e422d16fdb0eb7282445de27a0143828a9989590b5a72a2694d6bf2436ca7e0bb79dcb0fec2
7
- data.tar.gz: b792b1ca5924a9b603a18a5fc7735b8e3b94ab2f795aadb1ba73e7e8012df086898f2fdeaceb9411ffc6b66e8cf1ff27c5b1ed4084c07485a389c6d9bb21fa2b
6
+ metadata.gz: 86c8960e1d3878711dc34b4af96ae95a4e0a2c765ab3fd1b63cf1e868ccd6b89cbdbbf4821744202c8ad834f7b65bd7b15642383156cac78d767351085ea4997
7
+ data.tar.gz: e1f5cf5fbdfb027d80afb774c3c89ef8ea837f2c1711ee91ac4689154a24588bfa21f74f2e47a71e5be698512c0023e4649ff1dc64d9feb0fbfcefe250874694
data/lib/matrix.rb CHANGED
@@ -12,17 +12,44 @@
12
12
  # Original Documentation:: Gavin Sinclair (sourced from <i>Ruby in a Nutshell</i> (Matsumoto, O'Reilly))
13
13
  ##
14
14
 
15
- require "e2mmap"
15
+ require_relative "matrix/version"
16
16
 
17
17
  module ExceptionForMatrix # :nodoc:
18
- extend Exception2MessageMapper
19
- def_e2message(TypeError, "wrong argument type %s (expected %s)")
20
- def_e2message(ArgumentError, "Wrong # of arguments(%d for %d)")
21
-
22
- def_exception("ErrDimensionMismatch", "\#{self.name} dimension mismatch")
23
- def_exception("ErrNotRegular", "Not Regular Matrix")
24
- def_exception("ErrOperationNotDefined", "Operation(%s) can\\'t be defined: %s op %s")
25
- def_exception("ErrOperationNotImplemented", "Sorry, Operation(%s) not implemented: %s op %s")
18
+ class ErrDimensionMismatch < StandardError
19
+ def initialize(val = nil)
20
+ if val
21
+ super(val)
22
+ else
23
+ super("Dimension mismatch")
24
+ end
25
+ end
26
+ end
27
+
28
+ class ErrNotRegular < StandardError
29
+ def initialize(val = nil)
30
+ if val
31
+ super(val)
32
+ else
33
+ super("Not Regular Matrix")
34
+ end
35
+ end
36
+ end
37
+
38
+ class ErrOperationNotDefined < StandardError
39
+ def initialize(vals)
40
+ if vals.is_a?(Array)
41
+ super("Operation(#{vals[0]}) can't be defined: #{vals[1]} op #{vals[2]}")
42
+ else
43
+ super(vals)
44
+ end
45
+ end
46
+ end
47
+
48
+ class ErrOperationNotImplemented < StandardError
49
+ def initialize(vals)
50
+ super("Sorry, Operation(#{vals[0]}) not implemented: #{vals[1]} op #{vals[2]}")
51
+ end
52
+ end
26
53
  end
27
54
 
28
55
  #
@@ -45,8 +72,8 @@ class Matrix
45
72
  #
46
73
  # Creates a matrix where each argument is a row.
47
74
  # Matrix[ [25, 93], [-1, 66] ]
48
- # => 25 93
49
- # -1 66
75
+ # # => 25 93
76
+ # # -1 66
50
77
  #
51
78
  def Matrix.[](*rows)
52
79
  rows(rows, false)
@@ -57,8 +84,8 @@ class Matrix
57
84
  # of the matrix. If the optional argument +copy+ is false, use the given
58
85
  # arrays as the internal structure of the matrix without copying.
59
86
  # Matrix.rows([[25, 93], [-1, 66]])
60
- # => 25 93
61
- # -1 66
87
+ # # => 25 93
88
+ # # -1 66
62
89
  #
63
90
  def Matrix.rows(rows, copy = true)
64
91
  rows = convert_to_array(rows, copy)
@@ -75,8 +102,8 @@ class Matrix
75
102
  #
76
103
  # Creates a matrix using +columns+ as an array of column vectors.
77
104
  # Matrix.columns([[25, 93], [-1, 66]])
78
- # => 25 -1
79
- # 93 66
105
+ # # => 25 -1
106
+ # # 93 66
80
107
  #
81
108
  def Matrix.columns(columns)
82
109
  rows(columns, false).transpose
@@ -89,9 +116,9 @@ class Matrix
89
116
  # Returns an enumerator if no block is given.
90
117
  #
91
118
  # m = Matrix.build(2, 4) {|row, col| col - row }
92
- # => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
119
+ # # => Matrix[[0, 1, 2, 3], [-1, 0, 1, 2]]
93
120
  # m = Matrix.build(3) { rand }
94
- # => a 3x3 matrix with random elements
121
+ # # => a 3x3 matrix with random elements
95
122
  #
96
123
  def Matrix.build(row_count, column_count = row_count)
97
124
  row_count = CoercionHelper.coerce_to_int(row_count)
@@ -109,9 +136,9 @@ class Matrix
109
136
  #
110
137
  # Creates a matrix where the diagonal elements are composed of +values+.
111
138
  # Matrix.diagonal(9, 5, -3)
112
- # => 9 0 0
113
- # 0 5 0
114
- # 0 0 -3
139
+ # # => 9 0 0
140
+ # # 0 5 0
141
+ # # 0 0 -3
115
142
  #
116
143
  def Matrix.diagonal(*values)
117
144
  size = values.size
@@ -128,8 +155,8 @@ class Matrix
128
155
  # Creates an +n+ by +n+ diagonal matrix where each diagonal element is
129
156
  # +value+.
130
157
  # Matrix.scalar(2, 5)
131
- # => 5 0
132
- # 0 5
158
+ # # => 5 0
159
+ # # 0 5
133
160
  #
134
161
  def Matrix.scalar(n, value)
135
162
  diagonal(*Array.new(n, value))
@@ -138,8 +165,8 @@ class Matrix
138
165
  #
139
166
  # Creates an +n+ by +n+ identity matrix.
140
167
  # Matrix.identity(2)
141
- # => 1 0
142
- # 0 1
168
+ # # => 1 0
169
+ # # 0 1
143
170
  #
144
171
  def Matrix.identity(n)
145
172
  scalar(n, 1)
@@ -152,8 +179,8 @@ class Matrix
152
179
  #
153
180
  # Creates a zero matrix.
154
181
  # Matrix.zero(2)
155
- # => 0 0
156
- # 0 0
182
+ # # => 0 0
183
+ # # 0 0
157
184
  #
158
185
  def Matrix.zero(row_count, column_count = row_count)
159
186
  rows = Array.new(row_count){Array.new(column_count, 0)}
@@ -164,7 +191,7 @@ class Matrix
164
191
  # Creates a single-row matrix where the values of that row are as given in
165
192
  # +row+.
166
193
  # Matrix.row_vector([4,5,6])
167
- # => 4 5 6
194
+ # # => 4 5 6
168
195
  #
169
196
  def Matrix.row_vector(row)
170
197
  row = convert_to_array(row)
@@ -175,9 +202,9 @@ class Matrix
175
202
  # Creates a single-column matrix where the values of that column are as given
176
203
  # in +column+.
177
204
  # Matrix.column_vector([4,5,6])
178
- # => 4
179
- # 5
180
- # 6
205
+ # # => 4
206
+ # # 5
207
+ # # 6
181
208
  #
182
209
  def Matrix.column_vector(column)
183
210
  column = convert_to_array(column)
@@ -190,12 +217,12 @@ class Matrix
190
217
  #
191
218
  # m = Matrix.empty(2, 0)
192
219
  # m == Matrix[ [], [] ]
193
- # => true
220
+ # # => true
194
221
  # n = Matrix.empty(0, 3)
195
222
  # n == Matrix.columns([ [], [], [] ])
196
- # => true
223
+ # # => true
197
224
  # m * n
198
- # => Matrix[[0, 0, 0], [0, 0, 0]]
225
+ # # => Matrix[[0, 0, 0], [0, 0, 0]]
199
226
  #
200
227
  def Matrix.empty(row_count = 0, column_count = 0)
201
228
  raise ArgumentError, "One size must be 0" if column_count != 0 && row_count != 0
@@ -249,6 +276,8 @@ class Matrix
249
276
  new result, total_column_count
250
277
  end
251
278
 
279
+ # :call-seq:
280
+ # Matrix.combine(*matrices) { |*elements| ... }
252
281
  #
253
282
  # Create a matrix by combining matrices entrywise, using the given block
254
283
  #
@@ -263,7 +292,7 @@ class Matrix
263
292
  matrices.map!(&CoercionHelper.method(:coerce_to_matrix))
264
293
  x = matrices.first
265
294
  matrices.each do |m|
266
- Matrix.Raise ErrDimensionMismatch unless x.row_count == m.row_count && x.column_count == m.column_count
295
+ raise ErrDimensionMismatch unless x.row_count == m.row_count && x.column_count == m.column_count
267
296
  end
268
297
 
269
298
  rows = Array.new(x.row_count) do |i|
@@ -274,12 +303,21 @@ class Matrix
274
303
  new rows, x.column_count
275
304
  end
276
305
 
306
+ # :call-seq:
307
+ # combine(*other_matrices) { |*elements| ... }
308
+ #
309
+ # Creates new matrix by combining with <i>other_matrices</i> entrywise,
310
+ # using the given block.
311
+ #
312
+ # x = Matrix[[6, 6], [4, 4]]
313
+ # y = Matrix[[1, 2], [3, 4]]
314
+ # x.combine(y) {|a, b| a - b} # => Matrix[[5, 4], [1, 0]]
277
315
  def combine(*matrices, &block)
278
316
  Matrix.combine(self, *matrices, &block)
279
317
  end
280
318
 
281
319
  #
282
- # Matrix.new is private; use Matrix.rows, columns, [], etc... to create.
320
+ # Matrix.new is private; use ::rows, ::columns, ::[], etc... to create.
283
321
  #
284
322
  def initialize(rows, column_count = rows[0].size)
285
323
  # No checking is done at this point. rows must be an Array of Arrays.
@@ -341,7 +379,7 @@ class Matrix
341
379
  end
342
380
 
343
381
  private def set_value(row, col, value)
344
- raise ErrDimensionMismatch, "Expected a a value, got a #{value.class}" if value.respond_to?(:to_matrix)
382
+ raise ErrDimensionMismatch, "Expected a value, got a #{value.class}" if value.respond_to?(:to_matrix)
345
383
 
346
384
  @rows[row][col] = value
347
385
  end
@@ -372,12 +410,12 @@ class Matrix
372
410
 
373
411
  private def set_row_range(row_range, col, value)
374
412
  if value.is_a?(Vector)
375
- Matrix.Raise ErrDimensionMismatch unless row_range.size == value.size
413
+ raise ErrDimensionMismatch unless row_range.size == value.size
376
414
  set_column_vector(row_range, col, value)
377
415
  elsif value.is_a?(Matrix)
378
- Matrix.Raise ErrDimensionMismatch unless value.column_count == 1
416
+ raise ErrDimensionMismatch unless value.column_count == 1
379
417
  value = value.column(0)
380
- Matrix.Raise ErrDimensionMismatch unless row_range.size == value.size
418
+ raise ErrDimensionMismatch unless row_range.size == value.size
381
419
  set_column_vector(row_range, col, value)
382
420
  else
383
421
  @rows[row_range].each{|e| e[col] = value }
@@ -395,12 +433,12 @@ class Matrix
395
433
  value = if value.is_a?(Vector)
396
434
  value.to_a
397
435
  elsif value.is_a?(Matrix)
398
- Matrix.Raise ErrDimensionMismatch unless value.row_count == 1
436
+ raise ErrDimensionMismatch unless value.row_count == 1
399
437
  value.row(0).to_a
400
438
  else
401
439
  Array.new(col_range.size, value)
402
440
  end
403
- Matrix.Raise ErrDimensionMismatch unless col_range.size == value.size
441
+ raise ErrDimensionMismatch unless col_range.size == value.size
404
442
  @rows[row][col_range] = value
405
443
  end
406
444
 
@@ -464,8 +502,8 @@ class Matrix
464
502
  # * :strict_upper: yields only elements above the diagonal
465
503
  # * :upper: yields only elements on or above the diagonal
466
504
  # Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
467
- # => 1 4
468
- # 9 16
505
+ # # => 1 4
506
+ # # 9 16
469
507
  #
470
508
  def collect(which = :all, &block) # :yield: e
471
509
  return to_enum(:collect, which) unless block_given?
@@ -494,7 +532,8 @@ class Matrix
494
532
  alias map! collect!
495
533
 
496
534
  def freeze
497
- @rows.freeze
535
+ @rows.each(&:freeze).freeze
536
+
498
537
  super
499
538
  end
500
539
 
@@ -510,16 +549,15 @@ class Matrix
510
549
  # * :strict_upper: yields only elements above the diagonal
511
550
  # * :upper: yields only elements on or above the diagonal
512
551
  #
513
- # Matrix[ [1,2], [3,4] ].each { |e| puts e }
514
- # # => prints the numbers 1 to 4
515
- # Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
552
+ # Matrix[ [1,2], [3,4] ].each { |e| puts e }
553
+ # # => prints the numbers 1 to 4
554
+ # Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
516
555
  #
517
- def each(which = :all) # :yield: e
556
+ def each(which = :all, &block) # :yield: e
518
557
  return to_enum :each, which unless block_given?
519
558
  last = column_count - 1
520
559
  case which
521
560
  when :all
522
- block = Proc.new
523
561
  @rows.each do |row|
524
562
  row.each(&block)
525
563
  end
@@ -662,8 +700,8 @@ class Matrix
662
700
  # * row_range, col_range
663
701
  #
664
702
  # Matrix.diagonal(9, 5, -3).minor(0..1, 0..2)
665
- # => 9 0 0
666
- # 0 5 0
703
+ # # => 9 0 0
704
+ # # 0 5 0
667
705
  #
668
706
  # Like Array#[], negative indices count backward from the end of the
669
707
  # row or column (-1 is the last element). Returns nil if the starting
@@ -706,9 +744,9 @@ class Matrix
706
744
  # Returns the submatrix obtained by deleting the specified row and column.
707
745
  #
708
746
  # Matrix.diagonal(9, 5, -3, 4).first_minor(1, 2)
709
- # => 9 0 0
710
- # 0 0 0
711
- # 0 0 4
747
+ # # => 9 0 0
748
+ # # 0 0 0
749
+ # # 0 0 4
712
750
  #
713
751
  def first_minor(row, column)
714
752
  raise RuntimeError, "first_minor of empty matrix is not defined" if empty?
@@ -735,11 +773,11 @@ class Matrix
735
773
  # the first minor by (-1)**(row + column).
736
774
  #
737
775
  # Matrix.diagonal(9, 5, -3, 4).cofactor(1, 1)
738
- # => -108
776
+ # # => -108
739
777
  #
740
778
  def cofactor(row, column)
741
779
  raise RuntimeError, "cofactor of empty matrix is not defined" if empty?
742
- Matrix.Raise ErrDimensionMismatch unless square?
780
+ raise ErrDimensionMismatch unless square?
743
781
 
744
782
  det_of_minor = first_minor(row, column).determinant
745
783
  det_of_minor * (-1) ** (row + column)
@@ -749,11 +787,11 @@ class Matrix
749
787
  # Returns the adjugate of the matrix.
750
788
  #
751
789
  # Matrix[ [7,6],[3,9] ].adjugate
752
- # => 9 -6
753
- # -3 7
790
+ # # => 9 -6
791
+ # # -3 7
754
792
  #
755
793
  def adjugate
756
- Matrix.Raise ErrDimensionMismatch unless square?
794
+ raise ErrDimensionMismatch unless square?
757
795
  Matrix.build(row_count, column_count) do |row, column|
758
796
  cofactor(column, row)
759
797
  end
@@ -763,10 +801,10 @@ class Matrix
763
801
  # Returns the Laplace expansion along given row or column.
764
802
  #
765
803
  # Matrix[[7,6], [3,9]].laplace_expansion(column: 1)
766
- # => 45
804
+ # # => 45
767
805
  #
768
806
  # Matrix[[Vector[1, 0], Vector[0, 1]], [2, 3]].laplace_expansion(row: 0)
769
- # => Vector[3, -2]
807
+ # # => Vector[3, -2]
770
808
  #
771
809
  #
772
810
  def laplace_expansion(row: nil, column: nil)
@@ -776,7 +814,7 @@ class Matrix
776
814
  raise ArgumentError, "exactly one the row or column arguments must be specified"
777
815
  end
778
816
 
779
- Matrix.Raise ErrDimensionMismatch unless square?
817
+ raise ErrDimensionMismatch unless square?
780
818
  raise RuntimeError, "laplace_expansion of empty matrix is not defined" if empty?
781
819
 
782
820
  unless 0 <= num && num < row_count
@@ -799,7 +837,7 @@ class Matrix
799
837
  # Raises an error if matrix is not square.
800
838
  #
801
839
  def diagonal?
802
- Matrix.Raise ErrDimensionMismatch unless square?
840
+ raise ErrDimensionMismatch unless square?
803
841
  each(:off_diagonal).all?(&:zero?)
804
842
  end
805
843
 
@@ -816,7 +854,7 @@ class Matrix
816
854
  # Raises an error if matrix is not square.
817
855
  #
818
856
  def hermitian?
819
- Matrix.Raise ErrDimensionMismatch unless square?
857
+ raise ErrDimensionMismatch unless square?
820
858
  each_with_index(:upper).all? do |e, row, col|
821
859
  e == rows[col][row].conj
822
860
  end
@@ -834,7 +872,7 @@ class Matrix
834
872
  # Raises an error if matrix is not square.
835
873
  #
836
874
  def normal?
837
- Matrix.Raise ErrDimensionMismatch unless square?
875
+ raise ErrDimensionMismatch unless square?
838
876
  rows.each_with_index do |row_i, i|
839
877
  rows.each_with_index do |row_j, j|
840
878
  s = 0
@@ -852,12 +890,13 @@ class Matrix
852
890
  # Raises an error if matrix is not square.
853
891
  #
854
892
  def orthogonal?
855
- Matrix.Raise ErrDimensionMismatch unless square?
856
- rows.each_with_index do |row, i|
857
- column_count.times do |j|
893
+ raise ErrDimensionMismatch unless square?
894
+
895
+ rows.each_with_index do |row_i, i|
896
+ rows.each_with_index do |row_j, j|
858
897
  s = 0
859
898
  row_count.times do |k|
860
- s += row[k] * rows[k][j]
899
+ s += row_i[k] * row_j[k]
861
900
  end
862
901
  return false unless s == (i == j ? 1 : 0)
863
902
  end
@@ -870,7 +909,7 @@ class Matrix
870
909
  # Raises an error if matrix is not square.
871
910
  #
872
911
  def permutation?
873
- Matrix.Raise ErrDimensionMismatch unless square?
912
+ raise ErrDimensionMismatch unless square?
874
913
  cols = Array.new(column_count)
875
914
  rows.each_with_index do |row, i|
876
915
  found = false
@@ -920,7 +959,7 @@ class Matrix
920
959
  # Raises an error if matrix is not square.
921
960
  #
922
961
  def symmetric?
923
- Matrix.Raise ErrDimensionMismatch unless square?
962
+ raise ErrDimensionMismatch unless square?
924
963
  each_with_index(:strict_upper) do |e, row, col|
925
964
  return false if e != rows[col][row]
926
965
  end
@@ -932,7 +971,7 @@ class Matrix
932
971
  # Raises an error if matrix is not square.
933
972
  #
934
973
  def antisymmetric?
935
- Matrix.Raise ErrDimensionMismatch unless square?
974
+ raise ErrDimensionMismatch unless square?
936
975
  each_with_index(:upper) do |e, row, col|
937
976
  return false unless e == -rows[col][row]
938
977
  end
@@ -945,12 +984,12 @@ class Matrix
945
984
  # Raises an error if matrix is not square.
946
985
  #
947
986
  def unitary?
948
- Matrix.Raise ErrDimensionMismatch unless square?
949
- rows.each_with_index do |row, i|
950
- column_count.times do |j|
987
+ raise ErrDimensionMismatch unless square?
988
+ rows.each_with_index do |row_i, i|
989
+ rows.each_with_index do |row_j, j|
951
990
  s = 0
952
991
  row_count.times do |k|
953
- s += row[k].conj * rows[k][j]
992
+ s += row_i[k].conj * row_j[k]
954
993
  end
955
994
  return false unless s == (i == j ? 1 : 0)
956
995
  end
@@ -977,7 +1016,7 @@ class Matrix
977
1016
  #++
978
1017
 
979
1018
  #
980
- # Returns +true+ if and only if the two matrices contain equal elements.
1019
+ # Returns whether the two matrices contain equal elements.
981
1020
  #
982
1021
  def ==(other)
983
1022
  return false unless Matrix === other &&
@@ -1013,31 +1052,33 @@ class Matrix
1013
1052
  #
1014
1053
  # Matrix multiplication.
1015
1054
  # Matrix[[2,4], [6,8]] * Matrix.identity(2)
1016
- # => 2 4
1017
- # 6 8
1055
+ # # => 2 4
1056
+ # # 6 8
1018
1057
  #
1019
1058
  def *(m) # m is matrix or vector or number
1020
1059
  case(m)
1021
1060
  when Numeric
1022
- rows = @rows.collect {|row|
1061
+ new_rows = @rows.collect {|row|
1023
1062
  row.collect {|e| e * m }
1024
1063
  }
1025
- return new_matrix rows, column_count
1064
+ return new_matrix new_rows, column_count
1026
1065
  when Vector
1027
1066
  m = self.class.column_vector(m)
1028
1067
  r = self * m
1029
1068
  return r.column(0)
1030
1069
  when Matrix
1031
- Matrix.Raise ErrDimensionMismatch if column_count != m.row_count
1032
-
1033
- rows = Array.new(row_count) {|i|
1034
- Array.new(m.column_count) {|j|
1035
- (0 ... column_count).inject(0) do |vij, k|
1036
- vij + self[i, k] * m[k, j]
1070
+ raise ErrDimensionMismatch if column_count != m.row_count
1071
+ m_rows = m.rows
1072
+ new_rows = rows.map do |row_i|
1073
+ Array.new(m.column_count) do |j|
1074
+ vij = 0
1075
+ column_count.times do |k|
1076
+ vij += row_i[k] * m_rows[k][j]
1037
1077
  end
1038
- }
1039
- }
1040
- return new_matrix rows, m.column_count
1078
+ vij
1079
+ end
1080
+ end
1081
+ return new_matrix new_rows, m.column_count
1041
1082
  else
1042
1083
  return apply_through_coercion(m, __method__)
1043
1084
  end
@@ -1046,13 +1087,13 @@ class Matrix
1046
1087
  #
1047
1088
  # Matrix addition.
1048
1089
  # Matrix.scalar(2,5) + Matrix[[1,0], [-4,7]]
1049
- # => 6 0
1050
- # -4 12
1090
+ # # => 6 0
1091
+ # # -4 12
1051
1092
  #
1052
1093
  def +(m)
1053
1094
  case m
1054
1095
  when Numeric
1055
- Matrix.Raise ErrOperationNotDefined, "+", self.class, m.class
1096
+ raise ErrOperationNotDefined, ["+", self.class, m.class]
1056
1097
  when Vector
1057
1098
  m = self.class.column_vector(m)
1058
1099
  when Matrix
@@ -1060,7 +1101,7 @@ class Matrix
1060
1101
  return apply_through_coercion(m, __method__)
1061
1102
  end
1062
1103
 
1063
- Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
1104
+ raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
1064
1105
 
1065
1106
  rows = Array.new(row_count) {|i|
1066
1107
  Array.new(column_count) {|j|
@@ -1073,13 +1114,13 @@ class Matrix
1073
1114
  #
1074
1115
  # Matrix subtraction.
1075
1116
  # Matrix[[1,5], [4,2]] - Matrix[[9,3], [-4,1]]
1076
- # => -8 2
1077
- # 8 1
1117
+ # # => -8 2
1118
+ # # 8 1
1078
1119
  #
1079
1120
  def -(m)
1080
1121
  case m
1081
1122
  when Numeric
1082
- Matrix.Raise ErrOperationNotDefined, "-", self.class, m.class
1123
+ raise ErrOperationNotDefined, ["-", self.class, m.class]
1083
1124
  when Vector
1084
1125
  m = self.class.column_vector(m)
1085
1126
  when Matrix
@@ -1087,7 +1128,7 @@ class Matrix
1087
1128
  return apply_through_coercion(m, __method__)
1088
1129
  end
1089
1130
 
1090
- Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
1131
+ raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count
1091
1132
 
1092
1133
  rows = Array.new(row_count) {|i|
1093
1134
  Array.new(column_count) {|j|
@@ -1100,8 +1141,8 @@ class Matrix
1100
1141
  #
1101
1142
  # Matrix division (multiplication by the inverse).
1102
1143
  # Matrix[[7,6], [3,9]] / Matrix[[2,9], [3,1]]
1103
- # => -7 1
1104
- # -3 -6
1144
+ # # => -7 1
1145
+ # # -3 -6
1105
1146
  #
1106
1147
  def /(other)
1107
1148
  case other
@@ -1120,8 +1161,8 @@ class Matrix
1120
1161
  #
1121
1162
  # Hadamard product
1122
1163
  # Matrix[[1,2], [3,4]].hadamard_product(Matrix[[1,2], [3,2]])
1123
- # => 1 4
1124
- # 9 8
1164
+ # # => 1 4
1165
+ # # 9 8
1125
1166
  #
1126
1167
  def hadamard_product(m)
1127
1168
  combine(m){|a, b| a * b}
@@ -1131,11 +1172,11 @@ class Matrix
1131
1172
  #
1132
1173
  # Returns the inverse of the matrix.
1133
1174
  # Matrix[[-1, -1], [0, -1]].inverse
1134
- # => -1 1
1135
- # 0 -1
1175
+ # # => -1 1
1176
+ # # 0 -1
1136
1177
  #
1137
1178
  def inverse
1138
- Matrix.Raise ErrDimensionMismatch unless square?
1179
+ raise ErrDimensionMismatch unless square?
1139
1180
  self.class.I(row_count).send(:inverse_from, self)
1140
1181
  end
1141
1182
  alias_method :inv, :inverse
@@ -1154,7 +1195,7 @@ class Matrix
1154
1195
  akk = v
1155
1196
  end
1156
1197
  end
1157
- Matrix.Raise ErrNotRegular if akk == 0
1198
+ raise ErrNotRegular if akk == 0
1158
1199
  if i != k
1159
1200
  a[i], a[k] = a[k], a[i]
1160
1201
  @rows[i], @rows[k] = @rows[k], @rows[i]
@@ -1190,29 +1231,52 @@ class Matrix
1190
1231
  # Non integer exponents will be handled by diagonalizing the matrix.
1191
1232
  #
1192
1233
  # Matrix[[7,6], [3,9]] ** 2
1193
- # => 67 96
1194
- # 48 99
1234
+ # # => 67 96
1235
+ # # 48 99
1195
1236
  #
1196
- def **(other)
1197
- case other
1237
+ def **(exp)
1238
+ case exp
1198
1239
  when Integer
1199
- x = self
1200
- if other <= 0
1201
- x = self.inverse
1202
- return self.class.identity(self.column_count) if other == 0
1203
- other = -other
1204
- end
1205
- z = nil
1206
- loop do
1207
- z = z ? z * x : x if other[0] == 1
1208
- return z if (other >>= 1).zero?
1209
- x *= x
1240
+ case
1241
+ when exp == 0
1242
+ raise ErrDimensionMismatch unless square?
1243
+ self.class.identity(column_count)
1244
+ when exp < 0
1245
+ inverse.power_int(-exp)
1246
+ else
1247
+ power_int(exp)
1210
1248
  end
1211
1249
  when Numeric
1212
1250
  v, d, v_inv = eigensystem
1213
- v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** other}) * v_inv
1251
+ v * self.class.diagonal(*d.each(:diagonal).map{|e| e ** exp}) * v_inv
1252
+ else
1253
+ raise ErrOperationNotDefined, ["**", self.class, exp.class]
1254
+ end
1255
+ end
1256
+
1257
+ protected def power_int(exp)
1258
+ # assumes `exp` is an Integer > 0
1259
+ #
1260
+ # Previous algorithm:
1261
+ # build M**2, M**4 = (M**2)**2, M**8, ... and multiplying those you need
1262
+ # e.g. M**0b1011 = M**11 = M * M**2 * M**8
1263
+ # ^ ^
1264
+ # (highlighted the 2 out of 5 multiplications involving `M * x`)
1265
+ #
1266
+ # Current algorithm has same number of multiplications but with lower exponents:
1267
+ # M**11 = M * (M * M**4)**2
1268
+ # ^ ^ ^
1269
+ # (highlighted the 3 out of 5 multiplications involving `M * x`)
1270
+ #
1271
+ # This should be faster for all (non nil-potent) matrices.
1272
+ case
1273
+ when exp == 1
1274
+ self
1275
+ when exp.odd?
1276
+ self * power_int(exp - 1)
1214
1277
  else
1215
- Matrix.Raise ErrOperationNotDefined, "**", self.class, other.class
1278
+ sqrt = power_int(exp / 2)
1279
+ sqrt * sqrt
1216
1280
  end
1217
1281
  end
1218
1282
 
@@ -1220,10 +1284,22 @@ class Matrix
1220
1284
  self
1221
1285
  end
1222
1286
 
1287
+ # Unary matrix negation.
1288
+ #
1289
+ # -Matrix[[1,5], [4,2]]
1290
+ # # => -1 -5
1291
+ # # -4 -2
1223
1292
  def -@
1224
1293
  collect {|e| -e }
1225
1294
  end
1226
1295
 
1296
+ #
1297
+ # Returns the absolute value elementwise
1298
+ #
1299
+ def abs
1300
+ collect(&:abs)
1301
+ end
1302
+
1227
1303
  #--
1228
1304
  # MATRIX FUNCTIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
1229
1305
  #++
@@ -1236,10 +1312,10 @@ class Matrix
1236
1312
  # Consider using exact types like Rational or BigDecimal instead.
1237
1313
  #
1238
1314
  # Matrix[[7,6], [3,9]].determinant
1239
- # => 45
1315
+ # # => 45
1240
1316
  #
1241
1317
  def determinant
1242
- Matrix.Raise ErrDimensionMismatch unless square?
1318
+ raise ErrDimensionMismatch unless square?
1243
1319
  m = @rows
1244
1320
  case row_count
1245
1321
  # Up to 4x4, give result using Laplacian expansion by minors.
@@ -1344,7 +1420,7 @@ class Matrix
1344
1420
  # Consider using exact types like Rational or BigDecimal instead.
1345
1421
  #
1346
1422
  # Matrix[[7,6], [3,9]].rank
1347
- # => 2
1423
+ # # => 2
1348
1424
  #
1349
1425
  def rank
1350
1426
  # We currently use Bareiss' multistep integer-preserving gaussian elimination
@@ -1382,6 +1458,35 @@ class Matrix
1382
1458
  rank
1383
1459
  end
1384
1460
 
1461
+ #
1462
+ # Returns a new matrix with rotated elements.
1463
+ # The argument specifies the rotation (defaults to `:clockwise`):
1464
+ # * :clockwise, 1, -3, etc.: "turn right" - first row becomes last column
1465
+ # * :half_turn, 2, -2, etc.: first row becomes last row, elements in reverse order
1466
+ # * :counter_clockwise, -1, 3: "turn left" - first row becomes first column
1467
+ # (but with elements in reverse order)
1468
+ #
1469
+ # m = Matrix[ [1, 2], [3, 4] ]
1470
+ # r = m.rotate_entries(:clockwise)
1471
+ # # => Matrix[[3, 1], [4, 2]]
1472
+ #
1473
+ def rotate_entries(rotation = :clockwise)
1474
+ rotation %= 4 if rotation.respond_to? :to_int
1475
+
1476
+ case rotation
1477
+ when 0
1478
+ dup
1479
+ when 1, :clockwise
1480
+ new_matrix @rows.transpose.each(&:reverse!), row_count
1481
+ when 2, :half_turn
1482
+ new_matrix @rows.map(&:reverse).reverse!, column_count
1483
+ when 3, :counter_clockwise
1484
+ new_matrix @rows.transpose.reverse!, row_count
1485
+ else
1486
+ raise ArgumentError, "expected #{rotation.inspect} to be one of :clockwise, :counter_clockwise, :half_turn or an integer"
1487
+ end
1488
+ end
1489
+
1385
1490
  # Returns a matrix with entries rounded to the given precision
1386
1491
  # (see Float#round)
1387
1492
  #
@@ -1392,10 +1497,10 @@ class Matrix
1392
1497
  #
1393
1498
  # Returns the trace (sum of diagonal elements) of the matrix.
1394
1499
  # Matrix[[7,6], [3,9]].trace
1395
- # => 16
1500
+ # # => 16
1396
1501
  #
1397
1502
  def trace
1398
- Matrix.Raise ErrDimensionMismatch unless square?
1503
+ raise ErrDimensionMismatch unless square?
1399
1504
  (0...column_count).inject(0) do |tr, i|
1400
1505
  tr + @rows[i][i]
1401
1506
  end
@@ -1405,12 +1510,12 @@ class Matrix
1405
1510
  #
1406
1511
  # Returns the transpose of the matrix.
1407
1512
  # Matrix[[1,2], [3,4], [5,6]]
1408
- # => 1 2
1409
- # 3 4
1410
- # 5 6
1513
+ # # => 1 2
1514
+ # # 3 4
1515
+ # # 5 6
1411
1516
  # Matrix[[1,2], [3,4], [5,6]].transpose
1412
- # => 1 3 5
1413
- # 2 4 6
1517
+ # # => 1 3 5
1518
+ # # 2 4 6
1414
1519
  #
1415
1520
  def transpose
1416
1521
  return self.class.empty(column_count, 0) if row_count.zero?
@@ -1469,25 +1574,36 @@ class Matrix
1469
1574
  #
1470
1575
  # Returns the conjugate of the matrix.
1471
1576
  # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
1472
- # => 1+2i i 0
1473
- # 1 2 3
1577
+ # # => 1+2i i 0
1578
+ # # 1 2 3
1474
1579
  # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].conjugate
1475
- # => 1-2i -i 0
1476
- # 1 2 3
1580
+ # # => 1-2i -i 0
1581
+ # # 1 2 3
1477
1582
  #
1478
1583
  def conjugate
1479
1584
  collect(&:conjugate)
1480
1585
  end
1481
1586
  alias_method :conj, :conjugate
1482
1587
 
1588
+ #
1589
+ # Returns the adjoint of the matrix.
1590
+ #
1591
+ # Matrix[ [i,1],[2,-i] ].adjoint
1592
+ # # => -i 2
1593
+ # # 1 i
1594
+ #
1595
+ def adjoint
1596
+ conjugate.transpose
1597
+ end
1598
+
1483
1599
  #
1484
1600
  # Returns the imaginary part of the matrix.
1485
1601
  # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
1486
- # => 1+2i i 0
1487
- # 1 2 3
1602
+ # # => 1+2i i 0
1603
+ # # 1 2 3
1488
1604
  # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].imaginary
1489
- # => 2i i 0
1490
- # 0 0 0
1605
+ # # => 2i i 0
1606
+ # # 0 0 0
1491
1607
  #
1492
1608
  def imaginary
1493
1609
  collect(&:imaginary)
@@ -1497,11 +1613,11 @@ class Matrix
1497
1613
  #
1498
1614
  # Returns the real part of the matrix.
1499
1615
  # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]]
1500
- # => 1+2i i 0
1501
- # 1 2 3
1616
+ # # => 1+2i i 0
1617
+ # # 1 2 3
1502
1618
  # Matrix[[Complex(1,2), Complex(0,1), 0], [1, 2, 3]].real
1503
- # => 1 0 0
1504
- # 1 2 3
1619
+ # # => 1 0 0
1620
+ # # 1 2 3
1505
1621
  #
1506
1622
  def real
1507
1623
  collect(&:real)
@@ -1511,7 +1627,7 @@ class Matrix
1511
1627
  # Returns an array containing matrices corresponding to the real and imaginary
1512
1628
  # parts of the matrix
1513
1629
  #
1514
- # m.rect == [m.real, m.imag] # ==> true for all matrices m
1630
+ # m.rect == [m.real, m.imag] # ==> true for all matrices m
1515
1631
  #
1516
1632
  def rect
1517
1633
  [real, imag]
@@ -1572,7 +1688,7 @@ class Matrix
1572
1688
 
1573
1689
  # Deprecated.
1574
1690
  #
1575
- # Use map(&:to_f)
1691
+ # Use <code>map(&:to_f)</code>
1576
1692
  def elements_to_f
1577
1693
  warn "Matrix#elements_to_f is deprecated, use map(&:to_f)", uplevel: 1
1578
1694
  map(&:to_f)
@@ -1580,7 +1696,7 @@ class Matrix
1580
1696
 
1581
1697
  # Deprecated.
1582
1698
  #
1583
- # Use map(&:to_i)
1699
+ # Use <code>map(&:to_i)</code>
1584
1700
  def elements_to_i
1585
1701
  warn "Matrix#elements_to_i is deprecated, use map(&:to_i)", uplevel: 1
1586
1702
  map(&:to_i)
@@ -1588,7 +1704,7 @@ class Matrix
1588
1704
 
1589
1705
  # Deprecated.
1590
1706
  #
1591
- # Use map(&:to_r)
1707
+ # Use <code>map(&:to_r)</code>
1592
1708
  def elements_to_r
1593
1709
  warn "Matrix#elements_to_r is deprecated, use map(&:to_r)", uplevel: 1
1594
1710
  map(&:to_r)
@@ -1728,7 +1844,7 @@ class Matrix
1728
1844
  when Numeric
1729
1845
  Scalar.new(@value + other)
1730
1846
  when Vector, Matrix
1731
- Scalar.Raise ErrOperationNotDefined, "+", @value.class, other.class
1847
+ raise ErrOperationNotDefined, ["+", @value.class, other.class]
1732
1848
  else
1733
1849
  apply_through_coercion(other, __method__)
1734
1850
  end
@@ -1739,7 +1855,7 @@ class Matrix
1739
1855
  when Numeric
1740
1856
  Scalar.new(@value - other)
1741
1857
  when Vector, Matrix
1742
- Scalar.Raise ErrOperationNotDefined, "-", @value.class, other.class
1858
+ raise ErrOperationNotDefined, ["-", @value.class, other.class]
1743
1859
  else
1744
1860
  apply_through_coercion(other, __method__)
1745
1861
  end
@@ -1761,7 +1877,7 @@ class Matrix
1761
1877
  when Numeric
1762
1878
  Scalar.new(@value / other)
1763
1879
  when Vector
1764
- Scalar.Raise ErrOperationNotDefined, "/", @value.class, other.class
1880
+ raise ErrOperationNotDefined, ["/", @value.class, other.class]
1765
1881
  when Matrix
1766
1882
  self * other.inverse
1767
1883
  else
@@ -1774,10 +1890,10 @@ class Matrix
1774
1890
  when Numeric
1775
1891
  Scalar.new(@value ** other)
1776
1892
  when Vector
1777
- Scalar.Raise ErrOperationNotDefined, "**", @value.class, other.class
1893
+ raise ErrOperationNotDefined, ["**", @value.class, other.class]
1778
1894
  when Matrix
1779
1895
  #other.powered_by(self)
1780
- Scalar.Raise ErrOperationNotImplemented, "**", @value.class, other.class
1896
+ raise ErrOperationNotImplemented, ["**", @value.class, other.class]
1781
1897
  else
1782
1898
  apply_through_coercion(other, __method__)
1783
1899
  end
@@ -1824,8 +1940,8 @@ end
1824
1940
  # * #-@
1825
1941
  #
1826
1942
  # Vector functions:
1827
- # * #inner_product(v), dot(v)
1828
- # * #cross_product(v), cross(v)
1943
+ # * #inner_product(v), #dot(v)
1944
+ # * #cross_product(v), #cross(v)
1829
1945
  # * #collect
1830
1946
  # * #collect!
1831
1947
  # * #magnitude
@@ -1890,7 +2006,7 @@ class Vector
1890
2006
  #
1891
2007
  # Return a zero vector.
1892
2008
  #
1893
- # Vector.zero(3) => Vector[0, 0, 0]
2009
+ # Vector.zero(3) # => Vector[0, 0, 0]
1894
2010
  #
1895
2011
  def Vector.zero(size)
1896
2012
  raise ArgumentError, "invalid size (#{size} for 0..)" if size < 0
@@ -1953,7 +2069,7 @@ class Vector
1953
2069
  raise ArgumentError, "vector to be set has wrong size" unless range.size == value.size
1954
2070
  @elements[range] = value.elements
1955
2071
  elsif value.is_a?(Matrix)
1956
- Matrix.Raise ErrDimensionMismatch unless value.row_count == 1
2072
+ raise ErrDimensionMismatch unless value.row_count == 1
1957
2073
  @elements[range] = value.row(0).elements
1958
2074
  else
1959
2075
  @elements[range] = Array.new(range.size, value)
@@ -1992,7 +2108,7 @@ class Vector
1992
2108
  #
1993
2109
  def each2(v) # :yield: e1, e2
1994
2110
  raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer)
1995
- Vector.Raise ErrDimensionMismatch if size != v.size
2111
+ raise ErrDimensionMismatch if size != v.size
1996
2112
  return to_enum(:each2, v) unless block_given?
1997
2113
  size.times do |i|
1998
2114
  yield @elements[i], v[i]
@@ -2006,7 +2122,7 @@ class Vector
2006
2122
  #
2007
2123
  def collect2(v) # :yield: e1, e2
2008
2124
  raise TypeError, "Integer is not like Vector" if v.kind_of?(Integer)
2009
- Vector.Raise ErrDimensionMismatch if size != v.size
2125
+ raise ErrDimensionMismatch if size != v.size
2010
2126
  return to_enum(:collect2, v) unless block_given?
2011
2127
  Array.new(size) do |i|
2012
2128
  yield @elements[i], v[i]
@@ -2018,43 +2134,46 @@ class Vector
2018
2134
  #++
2019
2135
 
2020
2136
  #
2021
- # Returns +true+ iff all of vectors are linearly independent.
2137
+ # Returns whether all of vectors are linearly independent.
2022
2138
  #
2023
2139
  # Vector.independent?(Vector[1,0], Vector[0,1])
2024
- # => true
2140
+ # # => true
2025
2141
  #
2026
2142
  # Vector.independent?(Vector[1,2], Vector[2,4])
2027
- # => false
2143
+ # # => false
2028
2144
  #
2029
2145
  def Vector.independent?(*vs)
2030
2146
  vs.each do |v|
2031
2147
  raise TypeError, "expected Vector, got #{v.class}" unless v.is_a?(Vector)
2032
- Vector.Raise ErrDimensionMismatch unless v.size == vs.first.size
2148
+ raise ErrDimensionMismatch unless v.size == vs.first.size
2033
2149
  end
2034
2150
  return false if vs.count > vs.first.size
2035
2151
  Matrix[*vs].rank.eql?(vs.count)
2036
2152
  end
2037
2153
 
2038
2154
  #
2039
- # Returns +true+ iff all of vectors are linearly independent.
2155
+ # Returns whether all of vectors are linearly independent.
2040
2156
  #
2041
2157
  # Vector[1,0].independent?(Vector[0,1])
2042
- # => true
2158
+ # # => true
2043
2159
  #
2044
2160
  # Vector[1,2].independent?(Vector[2,4])
2045
- # => false
2161
+ # # => false
2046
2162
  #
2047
2163
  def independent?(*vs)
2048
2164
  self.class.independent?(self, *vs)
2049
2165
  end
2050
2166
 
2051
2167
  #
2052
- # Returns +true+ iff all elements are zero.
2168
+ # Returns whether all elements are zero.
2053
2169
  #
2054
2170
  def zero?
2055
2171
  all?(&:zero?)
2056
2172
  end
2057
2173
 
2174
+ #
2175
+ # Makes the matrix frozen and Ractor-shareable
2176
+ #
2058
2177
  def freeze
2059
2178
  @elements.freeze
2060
2179
  super
@@ -2074,7 +2193,7 @@ class Vector
2074
2193
  #++
2075
2194
 
2076
2195
  #
2077
- # Returns +true+ iff the two vectors have the same elements in the same order.
2196
+ # Returns whether the two vectors have the same elements in the same order.
2078
2197
  #
2079
2198
  def ==(other)
2080
2199
  return false unless Vector === other
@@ -2108,7 +2227,7 @@ class Vector
2108
2227
  when Matrix
2109
2228
  Matrix.column_vector(self) * x
2110
2229
  when Vector
2111
- Vector.Raise ErrOperationNotDefined, "*", self.class, x.class
2230
+ raise ErrOperationNotDefined, ["*", self.class, x.class]
2112
2231
  else
2113
2232
  apply_through_coercion(x, __method__)
2114
2233
  end
@@ -2120,7 +2239,7 @@ class Vector
2120
2239
  def +(v)
2121
2240
  case v
2122
2241
  when Vector
2123
- Vector.Raise ErrDimensionMismatch if size != v.size
2242
+ raise ErrDimensionMismatch if size != v.size
2124
2243
  els = collect2(v) {|v1, v2|
2125
2244
  v1 + v2
2126
2245
  }
@@ -2138,7 +2257,7 @@ class Vector
2138
2257
  def -(v)
2139
2258
  case v
2140
2259
  when Vector
2141
- Vector.Raise ErrDimensionMismatch if size != v.size
2260
+ raise ErrDimensionMismatch if size != v.size
2142
2261
  els = collect2(v) {|v1, v2|
2143
2262
  v1 - v2
2144
2263
  }
@@ -2159,7 +2278,7 @@ class Vector
2159
2278
  els = @elements.collect{|e| e / x}
2160
2279
  self.class.elements(els, false)
2161
2280
  when Matrix, Vector
2162
- Vector.Raise ErrOperationNotDefined, "/", self.class, x.class
2281
+ raise ErrOperationNotDefined, ["/", self.class, x.class]
2163
2282
  else
2164
2283
  apply_through_coercion(x, __method__)
2165
2284
  end
@@ -2179,10 +2298,10 @@ class Vector
2179
2298
 
2180
2299
  #
2181
2300
  # Returns the inner product of this vector with the other.
2182
- # Vector[4,7].inner_product Vector[10,1] => 47
2301
+ # Vector[4,7].inner_product Vector[10,1] # => 47
2183
2302
  #
2184
2303
  def inner_product(v)
2185
- Vector.Raise ErrDimensionMismatch if size != v.size
2304
+ raise ErrDimensionMismatch if size != v.size
2186
2305
 
2187
2306
  p = 0
2188
2307
  each2(v) {|v1, v2|
@@ -2194,7 +2313,7 @@ class Vector
2194
2313
 
2195
2314
  #
2196
2315
  # Returns the cross product of this vector with the others.
2197
- # Vector[1, 0, 0].cross_product Vector[0, 1, 0] => Vector[0, 0, 1]
2316
+ # Vector[1, 0, 0].cross_product Vector[0, 1, 0] # => Vector[0, 0, 1]
2198
2317
  #
2199
2318
  # It is generalized to other dimensions to return a vector perpendicular
2200
2319
  # to the arguments.
@@ -2209,7 +2328,7 @@ class Vector
2209
2328
  raise ArgumentError, "wrong number of arguments (#{vs.size} for #{size - 2})" unless vs.size == size - 2
2210
2329
  vs.each do |v|
2211
2330
  raise TypeError, "expected Vector, got #{v.class}" unless v.is_a? Vector
2212
- Vector.Raise ErrDimensionMismatch unless v.size == size
2331
+ raise ErrDimensionMismatch unless v.size == size
2213
2332
  end
2214
2333
  case size
2215
2334
  when 2
@@ -2249,7 +2368,7 @@ class Vector
2249
2368
 
2250
2369
  #
2251
2370
  # Returns the modulus (Pythagorean distance) of the vector.
2252
- # Vector[5,8,2].r => 9.643650761
2371
+ # Vector[5,8,2].r # => 9.643650761
2253
2372
  #
2254
2373
  def magnitude
2255
2374
  Math.sqrt(@elements.inject(0) {|v, e| v + e.abs2})
@@ -2272,7 +2391,7 @@ class Vector
2272
2391
  # Returns a new vector with the same direction but with norm 1.
2273
2392
  # v = Vector[5,8,2].normalize
2274
2393
  # # => Vector[0.5184758473652127, 0.8295613557843402, 0.20739033894608505]
2275
- # v.norm => 1.0
2394
+ # v.norm # => 1.0
2276
2395
  #
2277
2396
  def normalize
2278
2397
  n = magnitude
@@ -2287,7 +2406,7 @@ class Vector
2287
2406
  #
2288
2407
  def angle_with(v)
2289
2408
  raise TypeError, "Expected a Vector, got a #{v.class}" unless v.is_a?(Vector)
2290
- Vector.Raise ErrDimensionMismatch if size != v.size
2409
+ raise ErrDimensionMismatch if size != v.size
2291
2410
  prod = magnitude * v.magnitude
2292
2411
  raise ZeroVectorError, "Can't get angle of zero vector" if prod == 0
2293
2412
  dot = inner_product(v)