module Silicium module Sparse # here goes tha addition to SparseMatrix class class SparseMatrix ## # @param [Integer] pos - Position of a row to return # @raise [ArgumentError] if position was less or bigger than count of cols # @return [Array] The array contains elements of row # # Returns a row of sparse matrix by its position def get_row(pos) get_dimension({dimension: 0, position: 1}, pos) end ## # @param [Integer] pos - Position of a column to return # @raise [ArgumentError] if position was less or bigger than count of rows # @return [Array] The array that contains elements of column # # Returns a column of sparse matrix by its position def get_col(pos) get_dimension({dimension: 1, position: 0}, pos) end ## # @return [Array] The array that contains rows of matrix # Returns sparse matrix in its regular view def regular_view Array.new(@n) { |i| get_row(i) } end ## # @param [SparseMatrix::Object] matrix - A matrix to multiply to # @raise [ArgumentError] if count of columns of right matrix # doesn't match count of rows of left matrix # # Returns a matrix in its regular view but multiplied by other matrix def multiply(matrix) raise 'wrong argument' if @n != matrix.m rows = regular_view result = Array.new(@n) { Array.new } (0...@n).each { |i| (0...matrix.m).each { |j| result[i] << matrix .get_col(j) .zip(rows[i]) .inject(0) { |acc, current| acc + current[0] * current[1] } } } result end ## # @param [Integer] num - A number to multiply to # # Multiplies matrix by a number def mult_by_num(num) return SparseMatrix.new(@n, @m) if num.zero? res = copy res.triplets.each do |triplet| triplet[2] *= num end res end private def get_dimension(selector, pos) raise 'wrong argument' if pos.negative? || pos > @m result = Array.new(@m, 0) @triplets .select { |triplet| triplet[selector[:dimension]] == pos } .each { |triplet| result[triplet[selector[:position]]] = triplet[2] } result end end end end