Working with matrices and vectors in Ruby before has been annoying because methods I expected to find were not there, and there wasn’t much documentation. Here, I present some simple additions to the Matrix and Vector classes that I found helpful.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
require 'matrix'
class Matrix
  # Assign the given value to the slot at the specified row and column
  def []=(row, column, value)
    @rows[row][column] = value
  end

  # Create an n by n matrix where each slot is initialized to the given value
  def Matrix.square(n, value)
    matrix = Matrix.zero(n)
    (0...n).each do |row|
      (0...n).each do |col|
        matrix[row, col] = value
      end
    end
    matrix
  end

  # Create an m by n matrix where each slot is initialized to the given value
  def Matrix.fill(m, n, value)
    rows = []
    m.times do
      row = []
      n.times { row << value }
      rows << row
    end
    Matrix.rows(rows)
  end

  # Returns a pretty string representation of the matrix
  def to_s
    [sprintf("%d x %d Matrix", @rows.length, column_size),
      @rows.map { |row| row.inspect }].flatten.join("\n")
  end
end

class Vector
  # Iterate over all elements in the vector
  def each
    raise ArgumentError unless block_given?
    @elements.each { |element| yield element }
  end

  # Returns true if the vector includes the given item
  def include?(other)
    to_a.include? other
  end
end

Here are some examples of how to use the new methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
irb(main):039:0> matrix = Matrix.square(3, 'a')
=> Matrix[["a", "a", "a"], ["a", "a", "a"], ["a", "a", "a"]]
irb(main):040:0> puts matrix
3 x 3 Matrix
["a", "a", "a"]
["a", "a", "a"]
["a", "a", "a"]
=> nil
irb(main):041:0> other_matrix = Matrix.fill(2, 3, 'b')
=> Matrix[["b", "b", "b"], ["b", "b", "b"]]
irb(main):042:0> other_matrix[1, 2] = 'new value'
=> "new value"
irb(main):043:0> puts other_matrix
2 x 3 Matrix
["b", "b", "b"]
["b", "b", "new value"]
=> nil
irb(main):055:0> other_matrix.row_vectors.each { |row| row.each { |el| puts el } }
b
b
b
b
b
new value
=> [Vector["b", "b", "b"], Vector["b", "b", "new value"]]
irb(main):056:0> num_matrix = Matrix.square(3, 0)
=> Matrix[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
irb(main):057:0> num_matrix[0, 1] = 1
=> 1
irb(main):058:0> num_matrix[0, 2] = 2
=> 2
irb(main):059:0> num_matrix[1, 0] = 3
=> 3
irb(main):060:0> num_matrix[1, 1] = 4
=> 4
irb(main):061:0> puts num_matrix
3 x 3 Matrix
[0, 1, 2]
[3, 4, 0]
[0, 0, 0]
=> nil
irb(main):062:0> num_matrix.row_vectors.select { |row| row.include? 4 }
=> [Vector[3, 4, 0]]