matrix 0.1.0 → 0.4.2

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.
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)