Method: Matrix#*

Defined in:
lib/y_support/abstract_algebra.rb

#*(arg) ⇒ Object

Matrix multiplication.



185
186
187
188
189
190
191
192
193
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
224
225
# File 'lib/y_support/abstract_algebra.rb', line 185

def * arg # arg is matrix or vector or number
  case arg
  when Numeric
    rows = @rows.map { |row| row.map { |e| e * arg } }
    return new_matrix rows, column_size
  when Vector
    arg = Matrix.column_vector arg
    result = self * arg
    return result.column 0
  when Matrix
    Matrix.Raise ErrDimensionMismatch if column_size != arg.row_size
    if empty? then # if empty?, then reduce uses WILDCARD_ZERO
      rows = Array.new row_size do |i|
        Array.new arg.column_size do |j|
          ( 0...column_size ).reduce WILDCARD_ZERO do |sum, c|
            sum + arg[c, j] * self[i, c]
          end
        end
      end
    else             # if non-empty, reduce proceeds without WILDCARD_ZERO
      rows = Array.new row_size do |i|
        Array.new arg.column_size do |j|
          ( 0...column_size ).map { |c| arg[c, j] * self[i, c] }.reduce :+
        end
      end
    end
    return new_matrix( rows, arg.column_size )
  when SY::Magnitude # newly added - multiplication by a magnitude
    # I am not happy with this explicit switch on SY::Magnitude type here.
    # Perhaps coerce should handle this?
    rows = Array.new row_size do |i|
      Array.new column_size do |j|
        self[i, j] * arg
      end
    end
    return self.class[ *rows ]
  else
    compat_1, compat_2 = arg.coerce self
    return compat_1 * compat_2
  end
end