Simple Matrix

Simple Matrix is a lightweight matrix operations shard.

The module is specifically designed to have increased performance reserves. It can be used when designing the interaction of layers within neural network engines.

Please read the notes on operations below.

Installation

  1. Add the dependency to your shard.yml:

    dependencies:
      simple_matrix:
        github: fruktorum/simple_matrix
  2. Run shards install

Usage

require "simple_matrix"

For all calculations described below please pay attention for the:

Initialization

# height = 4, width = 3 (filled by 0)
matrix = SimpleMatrix( UInt32 ).new 4, 3

# type = UInt8, height = 4, width = 3, values = 99
matrix = SimpleMatrix( UInt8 ).new 4, 3, 99

# Custom values:
# 0  1  2
# 3  4  5
# 6  7  8
# 9 10 11
width, height = 3, 4
matrix = SimpleMatrix( UInt16 ).new( height, width ){ |y, x| ( y * width + x ).to_u16 }

# Matrix has public method to access internal buffer:
matrix.buffer # => Array( Array( UInt16 ) )

To initialize identity (in example: 5x5) matrix (zero-filled matrix which main diagonal filled by 1):

matrix = SimpleMatrix( UInt8 ).identity 5
1 0 0 0 0 ┐
│ 0 1 0 0 0 │
│ 0 0 1 0 0 │
│ 0 0 0 1 0 │
└ 0 0 0 0 1

Output

puts matrix # prints to stdout in pretty form

Operations

For the below assume that matrices are declared as m1, m2, etc. Result matrix is declared as r.

Multiplication. r = m1 · m2

m1.dot m2, r
m1.dot m2.buffer, r.buffer

Notes:

Elementwise multiplication. r = m1 * m2

m1.mul m2, r
m1.mul m2.buffer, r.buffer

Notes:

Summation. r = m1 + m2

m1.sum m2, r
m1.sum m2.buffer, r.buffer

Notes:

Transpose. r = m1 ^T

m.transpose r
m.transpose r.buffer

Notes:

Convolution. r = m convolved through k (window, or kernel)

m.convolve k, r, padding
m.convolve k.buffer, r.buffer, padding

Notes:

Apply function elementwise. r = f(m)

This is similar to applying the activation function to each neurons.

m.apply r do |m_matrix_value, m_y, m_x|
  # do something...
end

m.apply r.buffer do |m_matrix_value, m_y, m_x|
  # do something...
end

Notes:

Development

Please feel free to make an PR!

Please be sure that engine is still have the desired performance stats: no mallocs + best benchmark ips.

Contributing

  1. Fork it (https://github.com/fruktorum/simple_matrix/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors