diff options
author | marcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-10-03 03:44:20 +0000 |
---|---|---|
committer | marcandre <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-10-03 03:44:20 +0000 |
commit | 5b46b07bf363da57d53394e58e4bccf69ef78865 (patch) | |
tree | 787ab0d0ea19ad89d723520a6e5f41a844f5d2c2 /lib | |
parent | f59098d1182f08594078bc458820c8ab8c972c46 (diff) |
* lib/matrix.rb: Add hstack & vstack methods.
Based on a patch by creasywuqiong. [Fix GH-344]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47769 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r-- | lib/matrix.rb | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/matrix.rb b/lib/matrix.rb index 45c24d1275..81834ab898 100644 --- a/lib/matrix.rb +++ b/lib/matrix.rb @@ -45,6 +45,8 @@ end # * Matrix.zero(n) # * Matrix.row_vector(row) # * Matrix.column_vector(column) +# * Matrix.hstack(*matrices) +# * Matrix.vstack(*matrices) # # To access Matrix elements/columns/rows/submatrices/properties: # * #[](i, j) @@ -90,12 +92,14 @@ end # Matrix functions: # * #determinant # * #det +# * #hstack(*matrices) # * #rank # * #round # * #trace # * #tr # * #transpose # * #t +# * #vstack(*matrices) # # Matrix decompositions: # * #eigen @@ -296,6 +300,51 @@ class Matrix end # + # Create a matrix by stacking matrices vertically + # + # x = Matrix[[1, 2], [3, 4]] + # y = Matrix[[5, 6], [7, 8]] + # Matrix.vstack(x, y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]] + # + def Matrix.vstack(x, *matrices) + raise TypeError, "Expected a Matrix, got a #{x.class}" unless x.is_a?(Matrix) + result = x.send(:rows).map(&:dup) + matrices.each do |m| + raise TypeError, "Expected a Matrix, got a #{m.class}" unless m.is_a?(Matrix) + if m.column_count != x.column_count + raise ErrDimensionMismatch, "The given matrices must have #{x.column_count} columns, but one has #{m.column_count}" + end + result.concat(m.send(:rows)) + end + new result, x.column_count + end + + + # + # Create a matrix by stacking matrices horizontally + # + # x = Matrix[[1, 2], [3, 4]] + # y = Matrix[[5, 6], [7, 8]] + # Matrix.hstack(x, y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]] + # + def Matrix.hstack(x, *matrices) + raise TypeError, "Expected a Matrix, got a #{x.class}" unless x.is_a?(Matrix) + result = x.send(:rows).map(&:dup) + total_column_count = x.column_count + matrices.each do |m| + raise TypeError, "Expected a Matrix, got a #{m.class}" unless m.is_a?(Matrix) + if m.row_count != x.row_count + raise ErrDimensionMismatch, "The given matrices must have #{x.row_count} rows, but one has #{m.row_count}" + end + result.each_with_index do |row, i| + row.concat m.send(:rows)[i] + end + total_column_count += m.column_count + end + new result, total_column_count + end + + # # Matrix.new is private; use Matrix.rows, columns, [], etc... to create. # def initialize(rows, column_count = rows[0].size) @@ -1143,6 +1192,18 @@ class Matrix alias det_e determinant_e # + # Returns a new matrix resulting by stacking horizontally + # the receiver with the given matrices + # + # x = Matrix[[1, 2], [3, 4]] + # y = Matrix[[5, 6], [7, 8]] + # x.hstack(y) # => Matrix[[1, 2, 5, 6], [3, 4, 7, 8]] + # + def hstack(*matrices) + self.class.hstack(self, *matrices) + end + + # # Returns the rank of the matrix. # Beware that using Float values can yield erroneous results # because of their lack of precision. @@ -1223,6 +1284,18 @@ class Matrix end alias t transpose + # + # Returns a new matrix resulting by stacking vertically + # the receiver with the given matrices + # + # x = Matrix[[1, 2], [3, 4]] + # y = Matrix[[5, 6], [7, 8]] + # x.vstack(y) # => Matrix[[1, 2], [3, 4], [5, 6], [7, 8]] + # + def vstack(*matrices) + self.class.vstack(self, *matrices) + end + #-- # DECOMPOSITIONS -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #++ |