module CsrMatrix::Arithmetic
Constants
- C
Public Class Methods
included(exceptions)
click to toggle source
Brings in exception module for exception testing
# File lib/csrmatrix/arithmetic.rb, line 12 def self.included(exceptions) exceptions.send :include, Exceptions end
Public Instance Methods
count_in_dim()
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 282 def count_in_dim() is_invariant? # helper function, identifies the number of expected values in matrix # eg. 2x2 matrix returns 4 values return self.rows * self.columns end
inverse()
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 66 def inverse() is_invariant? # sets the inverse of this matrix # pre existing matrix (matrix.not_null?) # post inverted matrix m = Matrix.rows(self.decompose) self.build_from_array(m.inv().to_a()) end
inverse_multiply(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 266 def inverse_multiply(matrix) # divides (multiply by the inverse of ) a matrix to existing matrix # sets x * y^-1, where x is your matrix and y is the accepted matrix is_invariant? if !matrix.square? || !self.square? raise Exceptions::MatrixDimException.new, "Matrices does not have usable dimensions; cannot divide." return false end tmpmatrix = TwoDMatrix.new tmpmatrix = self tmpmatrix.inverse() return matrix.multiply_csr(tmpmatrix) end
is_same_dim(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 182 def is_same_dim(matrix) # helper function to determine dim count is equal is_invariant? return self.dimensions() == matrix.dimensions() end
matrix_add(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 189 def matrix_add(matrix) # adds a matrix to existing matrix is_invariant? if !self.is_same_dim(matrix) raise Exceptions::MatrixDimException.new, "Matrix does not have same dimensions; cannot add." return false end res = Array.new(@rows) { Array.new(@columns, 0) } row_idx = 0 cnta = 0 # total logged entries for matrix a cntb = 0 while row_idx < @rows # eg. 0 1 2 rowa = @row_ptr[row_idx + 1] # eg. 0 2 4 7 rowb = matrix.row_ptr[row_idx + 1] while cnta < rowa # keep adding values to res until they're equal res[row_idx][@col_ind[cnta]] += @val[cnta] cnta += 1; end while cntb < rowb res[row_idx][@col_ind[cntb]] += matrix.val[cntb] cntb += 1; end row_idx += 1; end return res end
matrix_division(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 290 def matrix_division(matrix) # linear division of one matrix to the next is_invariant? if matrix.val.count() != matrix.count_in_dim() raise Exceptions::DivideByZeroException.new, "Calculations return divide by zero error." return false end if !self.is_same_dim(matrix) raise Exceptions::MatrixDimException.new, "Matrix does not have same dimensions; cannot add." return false end res = Array.new(@rows) { Array.new(@columns, 0) } row_idx = 0 cnta = 0 # total logged entries for matrix a cntb = 0 while row_idx < @rows # eg. 0 1 2 rowa = @row_ptr[row_idx + 1] # eg. 0 2 4 7 rowb = matrix.row_ptr[row_idx + 1] while cnta < rowa # keep adding values to res until they're equal res[row_idx][@col_ind[cnta]] += @val[cnta] cnta += 1; end while cntb < rowb res[row_idx][@col_ind[cntb]] = res[row_idx][@col_ind[cntb]].to_f / matrix.val[cntb] cntb += 1; end row_idx += 1; end return res end
matrix_multiply(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 143 def matrix_multiply(matrix) # multiply dense (non-dense) matrix to csr matrix [eg. [1, 2]] x 2d array is_invariant? # pre matrix to multiply, existing matrix (matrix.not_null?) # post array holding resulting matrix res = Array.new(max_row(matrix)) { Array.new(@columns, 0) } # first denotes row, second denotes columns n = matrix.length i = 0 # res = dense X csr csr_row = 0 # Current row in CSR matrix while i < n do startv = @row_ptr[i] endv = @row_ptr[i + 1] j = startv while j < endv do col = @col_ind[j] csr_value = @val[j] k = 0 while k < n do dense_value = matrix[k][csr_row] res[k][col] += csr_value * dense_value k += 1 end j += 1 end csr_row += 1 i += 1 end return res end
matrix_subtract(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 219 def matrix_subtract(matrix) # subtracts a matrix to existing matrix is_invariant? if !self.is_same_dim(matrix) raise Exceptions::MatrixDimException.new, "Matrix does not have same dimensions; cannot subtract." return false end res = Array.new(@rows) { Array.new(@columns, 0) } row_idx = 0 cnta = 0 # total logged entries for matrix a cntb = 0 while row_idx < @rows # eg. 0 1 2 rowa = @row_ptr[row_idx + 1] # eg. 0 2 4 7 rowb = matrix.row_ptr[row_idx + 1] while cnta < rowa # keep adding values to res until they're equal res[row_idx][@col_ind[cnta]] += @val[cnta] cnta += 1; end while cntb < rowb res[row_idx][@col_ind[cntb]] -= matrix.val[cntb] cntb += 1; end row_idx += 1; end return res end
matrix_vector(vector)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 124 def matrix_vector(vector) # dev based on http://www.mathcs.emory.edu/~cheung/Courses/561/Syllabus/3-C/sparse.html # multiplies the matrix by a vector value (in array form) is_invariant? result = Array.new(vector.length, 0) i = 0 while i < vector.length do k = @row_ptr[i] while k < @row_ptr[i+1] do result[i] = result[i] + @val[k] * vector[@col_ind[k]] k += 1 end i += 1 end return result end
max_row(array)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 324 def max_row(array) # Identifies the 'row' value of an array (eg. the number of entries in a row) is_invariant? values = array max_count = 0 values.each_index do |i| max_count += 1 end return max_count end
multiply_csr(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 175 def multiply_csr(matrix) # multiply two csr together - ref: http://www.mcs.anl.gov/papers/P5007-0813_1.pdf is_invariant? return matrix.matrix_multiply(self.decompose()) end
multiply_inverse(matrix)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 249 def multiply_inverse(matrix) # divides (multiply by the inverse of ) a matrix to existing matrix # sets y * x^-1, where x is your matrix and y is the accepted matrix is_invariant? if !matrix.square? || !self.square? raise Exceptions::MatrixDimException.new, "Matrices does not have usable dimensions; cannot divide." return false end tmpmatrix = TwoDMatrix.new tmpmatrix = matrix tmpmatrix.inverse() return self.multiply_csr(tmpmatrix) end
scalar_add(value)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 27 def scalar_add(value) # manipulate the matrix by adding a value at each index is_invariant? @val.each_index do |i| @val[i] = @val[i] + value end end
scalar_division(value)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 47 def scalar_division(value) is_invariant? # manipulate the matrix by dividing the value at each index # post boolean, updated matrix (in floats, if previously was not) @val.each_index do |i| @val[i] = @val[i] / value.to_f end end
scalar_exp(value)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 57 def scalar_exp(value) is_invariant? # manipulate the matrix by finding the exponential at each index @val.each_index do |i| @val[i] = @val[i] ** value end end
scalar_multiply(value)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 17 def scalar_multiply(value) # multiply the matrix by a scalar value is_invariant? @val.each_index do |i| @val[i] = @val[i] * value end end
scalar_subtract(value)
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 37 def scalar_subtract(value) is_invariant? # manipulate the matrix by subtracting the value at each index @val.each_index do |i| @val[i] = @val[i] - value end end
t()
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 116 def t() is_invariant? # transpose the matrix # post array of decomposed matrix values self.transpose() end
transpose()
click to toggle source
# File lib/csrmatrix/arithmetic.rb, line 76 def transpose() is_invariant? # transpose the matrix new_row_ptr = Array.new(self.columns+1, 0) new_col_ind = Array.new(self.col_ind.count(), 0) new_val = Array.new(self.val.count(), 0) current_row = 0 current_column = 0 for i in 0..self.columns-1 for j in 0..self.col_ind.count(i)-1 # get the row index = self.col_ind.find_index(i) self.col_ind[index] = -1 for k in 1..self.row_ptr.count()-1 if self.row_ptr[k-1] <= index && index < self.row_ptr[k] current_row = k break end end # update values new_row_ptr[i+1] += 1 new_val[current_column] = val[index] new_col_ind[current_column] = current_row-1 current_column += 1 end end # fill in row_ptr for i in 1..self.rows-1 self.row_ptr[i] = new_row_ptr[i] + new_row_ptr[i-1] end @col_ind = new_col_ind @val = new_val end