Class: Matrix

Inherits:
Object
  • Object
show all
Defined in:
lib/matrix_extensions.rb

Overview

An extension to the Ruby Matrix class.

Author:

  • Michael Imstepf

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.hconcat(*matrices) ⇒ Matrix

Concatenates two matrices horizontally (resulting in more columns).

Parameters:

  • matrices

Returns:

  • concatenated matrix

Raises:

  • if dimensions don’t match

  • if matrices are not of type Matrix or Vector



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/matrix_extensions.rb', line 20

def self.hconcat(*matrices)        
  columns = []
  matrices.each do |m|
    raise TypeError, "#{m.class} is not a Matrix or Vector" unless m.is_a?(Matrix) || m.is_a?(Vector)
    
    # convert Vector to Matrix
    m = self.convert_vector_to_matrix(m, :column) if m.is_a? Vector

    # check if dimensions match
    row_count ||= m.row_count
    Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count
    
    # prepare array of columns
    m.column_vectors.each do |v|
      columns << v.to_a
    end
  end

  # create new matrix
  self.columns(columns)
end

.one(rows = 1, columns = 1) ⇒ Matrix

Matrix prefilled with ones.

Parameters:

  • (defaults to: 1)

    number of rows

  • (defaults to: 1)

    number of columns

Returns:

  • matrix



11
12
13
# File 'lib/matrix_extensions.rb', line 11

def self.one(rows = 1, columns = 1)
  Matrix.build(rows, columns) { 1 }
end

.vconcat(*matrices) ⇒ Matrix

Concatenates two matrices vertically (resulting in more rows).

Parameters:

  • matrices

Returns:

  • concatenated matrix

Raises:

  • if dimensions don’t match

  • if matrices are not of type Matrix or Vector



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/matrix_extensions.rb', line 47

def self.vconcat(*matrices)
  rows = []
  matrices.each do |m|
    raise TypeError, "#{m.class} is not a Matrix or Vector" unless m.is_a?(Matrix) || m.is_a?(Vector)
    
    # convert Vector to Matrix
    m = self.convert_vector_to_matrix(m, :row) if m.is_a? Vector

    # check if dimensions match
    column_count ||= m.column_count
    Matrix.Raise ErrDimensionMismatch unless column_count == m.column_count
    
    # prepare array of columns
    m.row_vectors.each do |v|
      rows << v.to_a
    end
  end

  # create new matrix
  self.rows(rows)
end

Instance Method Details

#element_division(m) ⇒ Matrix

Element-wise division.

Parameters:

  • matrix

Returns:

  • matrix

Raises:

  • if dimensions don’t match



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/matrix_extensions.rb', line 132

def element_division(m)
  case m
  when Numeric
    return self./ m
  when Vector            
    if row_count > column_count
      # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch)
      m = self.class.convert_vector_to_matrix(m, :column)      
    else
      # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch)
      m = self.class.convert_vector_to_matrix(m, :row)
    end
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count

  rows = Array.new(row_count) do |i|
    Array.new(column_count) do|j|
      self[i, j] / m[i, j]
    end
  end
  new_matrix rows, column_count  
end

#element_exponentiation(m) ⇒ Matrix

Element-wise exponentiation.

Parameters:

  • matrix

Returns:

  • matrix

Raises:

  • if dimensions don’t match



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/matrix_extensions.rb', line 194

def element_exponentiation(m)
  case m
  when Numeric
    # self.** m will break
    rows = @rows.collect {|row|
      row.collect {|e| e ** m }
    }
    return new_matrix rows, column_count
  when Vector            
    if row_count > column_count
      # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch)
      m = self.class.convert_vector_to_matrix(m, :column)      
    else
      # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch)
      m = self.class.convert_vector_to_matrix(m, :row)
    end
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count

  rows = Array.new(row_count) do |i|
    Array.new(column_count) do|j|
      self[i, j] ** m[i, j]
    end
  end
  new_matrix rows, column_count 
end

#element_multiplication(m) ⇒ Matrix

Element-wise multiplication.

Parameters:

  • matrix

Returns:

  • matrix

Raises:

  • if dimensions don’t match



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/matrix_extensions.rb', line 163

def element_multiplication(m)
  case m
  when Numeric
    return self.* m
  when Vector            
    if row_count > column_count
      # Matrix is of dimension X * 1 (or there'll be an ErrDimensionMismatch)
      m = self.class.convert_vector_to_matrix(m, :column)      
    else
      # Matrix is of dimension 1 * X (or there'll be an ErrDimensionMismatch)
      m = self.class.convert_vector_to_matrix(m, :row)
    end
  when Matrix
  else
    return apply_through_coercion(m, __method__)
  end

  Matrix.Raise ErrDimensionMismatch unless row_count == m.row_count && column_count == m.column_count

  rows = Array.new(row_count) do |i|
    Array.new(column_count) do|j|
      self[i, j] * m[i, j]
    end
  end
  new_matrix rows, column_count  
end

#hcopy(number_of_copies = 1) ⇒ Matrix

Copies columns.

Parameters:

  • (defaults to: 1)

    number of times columns should be copied

Returns:

  • matrix



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/matrix_extensions.rb', line 116

def hcopy(number_of_copies = 1)        
  rows.each do |row|
    existing_row = row.clone
    number_of_copies.times do
      existing_row.each { |v| row << v }
    end
  end
  @column_count += @column_count * number_of_copies

  self
end

#hpop(number_of_columns = 1) ⇒ Matrix

Removes trailing columns from a Matrix (destructive).

Parameters:

  • (defaults to: 1)

    number of trailing columns to be removed

Returns:

  • matrix consisting of of dropped columns

Raises:

  • if Matrix does not have enough columns for operation



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/matrix_extensions.rb', line 73

def hpop(number_of_columns = 1)        
  Matrix.Raise ErrDimensionMismatch unless number_of_columns < self.column_count

  dropped_columns = []
  number_of_columns.times do
    dropped_column = []      
    @rows.each {|r| dropped_column << r.pop}
    dropped_columns << dropped_column
  end
  @column_count -= number_of_columns

  Matrix.columns(dropped_columns.reverse)
end

#vcopy(number_of_copies = 1) ⇒ Matrix

Copies rows.

Parameters:

  • (defaults to: 1)

    number of times rows should be copied

Returns:

  • matrix



103
104
105
106
107
108
109
110
111
# File 'lib/matrix_extensions.rb', line 103

def vcopy(number_of_copies = 1)        
  existing_rows = rows.clone

  number_of_copies.times do
    existing_rows.each { |row| rows << row }
  end

  self
end

#vpop(number_of_rows = 1) ⇒ Matrix

Removes trailing rows from a Matrix (destructive).

Parameters:

  • (defaults to: 1)

    number of trailing rows to be removed

Returns:

  • matrix consisting of of dropped rows

Raises:

  • if Matrix does not have enough rows for operation



91
92
93
94
95
96
97
98
# File 'lib/matrix_extensions.rb', line 91

def vpop(number_of_rows = 1)        
  Matrix.Raise ErrDimensionMismatch unless number_of_rows < self.row_count

  dropped_rows = []    
  number_of_rows.times { dropped_rows << @rows.pop }

  Matrix.rows(dropped_rows)      
end