Class: Silicium::Sparse::SparseMatrix

Inherits:
Object
  • Object
show all
Defined in:
lib/silicium/multi.rb,
lib/silicium/sugar.rb,
lib/silicium/trans.rb,
lib/silicium/adding.rb,
lib/silicium/sparse.rb,
lib/silicium/conversions.rb

Overview

here goes the Sparse class

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rows, cols) ⇒ SparseMatrix

Initialize matrix with count of rows and columns

Parameters:

  • rows (Integer)
    • Count of rows

  • cols (Integer)
    • Count of columns



20
21
22
23
24
# File 'lib/silicium/sparse.rb', line 20

def initialize(rows, cols)
  @n = rows
  @m = cols
  @triplets = []
end

Instance Attribute Details

#mObject (readonly)

Returns the value of attribute m.



14
15
16
# File 'lib/silicium/sparse.rb', line 14

def m
  @m
end

#nObject (readonly)

Returns the value of attribute n.



13
14
15
# File 'lib/silicium/sparse.rb', line 13

def n
  @n
end

#tripletsObject (readonly)

Returns the value of attribute triplets.



12
13
14
# File 'lib/silicium/sparse.rb', line 12

def triplets
  @triplets
end

Class Method Details

.sparse(mat) ⇒ Object

# A static method for initializing sparse matrix from a regular one

Parameters:

  • mat (Array)
    • Source matrix for conversion



8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/silicium/conversions.rb', line 8

def self.sparse(mat)
  new = SparseMatrix.new(mat.count, mat[0].count)
  i = 0
  mat.each do |row|
    j = 0
    row.each do |elem|
      new.add(i, j, elem) unless elem.zero?
      j += 1
    end
    i += 1
  end
  new
end

Instance Method Details

#*(other) ⇒ Object

doesn’t match count of rows of left matrix

Returns a matrix in its regular view but multiplied by other matrix

Parameters:

  • other (SparseMatrix::Object)
    • A matrix to multiply to

Raises:

  • (ArgumentError)

    if count of columns of right matrix



31
32
33
# File 'lib/silicium/sugar.rb', line 31

def *(other)
  multiply(other)
end

#+(other) ⇒ SparseMatrix

Makes the sum of two matrix

Parameters:

Returns:

  • (SparseMatrix)

    Matrix as the sum of the other two matrices

Raises:

  • (ArgumentError)

    If the size of the first matrix doesn’t match the size of the second matrix



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

def +(other)
  adding(other)
end

#-(other) ⇒ SparseMatrix

Makes the sum of two matrix

Parameters:

Returns:

  • (SparseMatrix)

    Matrix as the sum of the other two matrices

Raises:

  • (ArgumentError)

    If the size of the first matrix doesn’t match the size of the second matrix



21
22
23
# File 'lib/silicium/sugar.rb', line 21

def -(other)
  adding(other.mult_by_num(-1))
end

#add(i_pos, j_pos, elem) ⇒ Object

Adds an element to matrix by its position and value

Parameters:

  • i_pos (Integer)
    • The i position of an element

  • j_pos (Integer)
    • The j position of an element

  • elem (Integer)
    • The value of an element to be added



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/silicium/sparse.rb', line 44

def add(i_pos, j_pos, elem)
  if i_pos > @n || j_pos > @m || i_pos.negative? || j_pos.negative?
    raise 'out of range'
  end

  f = false
  @triplets.each do |item|
    if item[0] == i_pos && item[1] == j_pos
      item = [i_pos, j_pos, elem]
      f =  true
      break
    end
  end
  @triplets.push([i_pos, j_pos, elem]) unless f
end

#adding(matrix) ⇒ SparseMatrix

match the size of the second matrix Makes the sum of two matrix

Parameters:

Returns:

  • (SparseMatrix)

    Matrix as the sum of the other two matrices

Raises:

  • (ArgumentError)

    If the size of the first matrix doesn’t



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/silicium/adding.rb', line 12

def adding(matrix)
  raise 'wrong argument' if @n != matrix.m

  res = SparseMatrix.new(@n, @m)
  (0..@n).each { |i|
    help_row1 = get_row(i)
    help_row2 = matrix.get_row(i)
    res_row = Array.new(@m, 0)
    j = 0
    help_row1.each do |elem|
      res_row[j] = elem + help_row2[j]
      j = j + 1
    end
    k = 0
    res_row.each do |elem|
      if (elem != 0)
        res.add(i, k, elem)
      end
      k = k+1
    end
  }
  res
end

#copySparseMatrix::Object

Creates a copy of matrix object

Returns:

  • (SparseMatrix::Object)
    • Returns a copy of a SparseMatrix object



30
31
32
33
34
35
36
# File 'lib/silicium/sparse.rb', line 30

def copy
  new = SparseMatrix.new(@n, @m)
  triplets.each do |triplet|
    new.add(triplet[0], triplet[1], triplet[2])
  end
  new
end

#get(i_pos, j_pos) ⇒ Integer

Returns an element by its position

Parameters:

  • i_pos (Integer)
    • The i position of an element

  • j_pos (Integer)
    • The j position of an element

Returns:

  • (Integer)

    The element on i,j position



66
67
68
69
70
71
72
73
# File 'lib/silicium/sparse.rb', line 66

def get(i_pos, j_pos)
  triplets.each do |triplet|
    if triplet[0] == i_pos && triplet[1] == j_pos
      return triplet[2]
    end
  end
  0
end

#get_col(pos) ⇒ Array

Returns a column of sparse matrix by its position

Parameters:

  • pos (Integer)
    • Position of a column to return

Returns:

  • (Array)

    The array that contains elements of column

Raises:

  • (ArgumentError)

    if position was less or bigger than count of rows



21
22
23
# File 'lib/silicium/multi.rb', line 21

def get_col(pos)
  get_dimension({dimension: 1, position: 0}, pos)
end

#get_row(pos) ⇒ Array

Returns a row of sparse matrix by its position

Parameters:

  • pos (Integer)
    • Position of a row to return

Returns:

  • (Array)

    The array contains elements of row

Raises:

  • (ArgumentError)

    if position was less or bigger than count of cols



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

def get_row(pos)
  get_dimension({dimension: 0, position: 1}, pos)
end

#mult_by_num(num) ⇒ Object

Multiplies matrix by a number

Parameters:

  • num (Integer)
    • A number to multiply to



58
59
60
61
62
63
64
65
66
# File 'lib/silicium/multi.rb', line 58

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

#multiply(matrix) ⇒ Object

doesn’t match count of rows of left matrix

Returns a matrix in its regular view but multiplied by other matrix

Parameters:

  • matrix (SparseMatrix::Object)
    • A matrix to multiply to

Raises:

  • (ArgumentError)

    if count of columns of right matrix



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/silicium/multi.rb', line 38

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

#regular_viewArray

Returns sparse matrix in its regular view

Returns:

  • (Array)

    The array that contains rows of matrix



28
29
30
# File 'lib/silicium/multi.rb', line 28

def regular_view
  Array.new(@n) { |i| get_row(i) }
end

#transposeObject

Returns a transposed copy of matrix



7
8
9
10
11
12
13
# File 'lib/silicium/trans.rb', line 7

def transpose
  new = copy
  new.triplets.each do |triplet|
    triplet[0], triplet[1] = triplet[1], triplet[0]
  end
  new
end

#transpose!Object

Transposes matrix



17
18
19
20
21
# File 'lib/silicium/trans.rb', line 17

def transpose!
  triplets.each do |triplet|
    triplet[0], triplet[1] = triplet[1], triplet[0]
  end
end