Skip to content

Tentative NMatrix Tutorial

Carlos Agarie edited this page Aug 25, 2013 · 29 revisions

Credit & Disclaimer

  • This tutorial is meant to mimic as closely as possible the Tentative NumPy Tutorial (as of August 2013) but for SciRuby's NMatrix. Because of this, examples and wording are used extensively from the Tentative Numpy Tutorial with little or no modification from the original. This is intentional, hereby disclosed, and hopefully justified given the nature of this project. The authors of this tutorial express deep appreciation to those responsible for the excellent Numpy and Tentative Numpy Tutorial. In addition, NMatrix was based heavily off of Masahiro Tanaka's excellent NArray work.

Prerequisites

Before reading this tutorial you should know a bit of Ruby. If you would like to refresh your memory, take a look at the Ruby quickstart tutorial, the tutorials at rubymonk, or tryruby. If you wish to work the examples in this tutorial, you must also have some software installed on your computer. Minimally:

You may find these useful for plotting:

Also, take a look at:

  • pry for an enhanced interactive shell (better than irb)
  • SciRuby(http://sciruby.com/) for additional scientific tools with growing NMatrix compatibility

Rules for Editing

  1. Follow the Tentative NumPy Tutorial as closely as possible.
  2. Aim to implement similar functionality, but in a ruby-ish way.
  3. Make a note on the wiki if something needs to be implemented to provide a particular functionality. Then, ideally, go and implement it and update the wiki.

The Basics

An NMatrix is a homogeneous multidimensional array. It is a table of elements (usually numbers), all of the same type, indexed by a tuple of positive integers. In NMatrix dimensions are called axes. The number of axes is dim. For example, the coordinates of a point in 3D space [1, 2, 1] is an array of dim 1, because it has one axis. That axis has a length of 3. In example pictured below, the ruby Array has dim 2 (it is 2-dimensional). The first dimension (axis) has a length of 2, the second dimension has a length of 3.

# an array of dim 1 -- it has only one axis
[1, 2, 1]          # plain ol' ruby Array
N[1, 2, 1]         # an NMatrix
# an array of dim 2 -- has 3 columns and 2 rows.
[[1, 0, 0],        # the plain ol' ruby Array of two arrays
[0, 1, 2]] 
N[[1, 0, 0], [0, 1, 2]]  # as an NMatrix

Key attributes of an NMatrix are:

NMatrix#dim
the number of axes (dimensions) of the array.

NMatrix#shape
A matrix with m number of rows and n number of columns will have a shape (m,n). The right-most number changes most rapidly while traversing the array (like Matlab, Numpy, and ruby Arrays of Arrays and opposite FORTRAN and PDL).

NMatrix#dtype
A symbol representing the type of array. (:byte, :int8, :int16, :int32, :int64, :float32, :float64, :complex64, :complex128, :rational64, :rational128, :object)

NMatrix#stype
The storage type of the array (:dense, :list, :yale). Dense is the default and yale is for working with sparse arrays. List is less frequently used.

[NOTE: .itemsize and .size have no real equivalent right now. Also, access to underlying data (.data in numpy) is not well-defined]

An example

You should be able to type in every code block in this document from here on and duplicate these results. Some output lines are omitted for brevity. The 'pp' method is short for 'pretty_print' and will often be used to display the NMatrix object.

% irb --simple-prompt
>> require 'nmatrix'
=> true
>> a = NMatrix.seq([3,5])
>> a.pp
[[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[10, 11, 12, 13, 14]]

>> a.shape
=> [3, 5]
>> a.dim
=> 2
>> a.class
=> NMatrix
>> a.dtype
=> :int32
>> a.stype
=> :dense
# [[no concept of itemsize or size right now]]

>> b = N[6, 7, 8]
>> b.pp
=> [6, 7, 8]
>> #<NMatrix:0x007fec8d777780 shape:[3] dtype:int32 stype:dense>
>> b.class
=> NMatrix

NMatrix Creation

There are several ways to create NMatrix objects.

>> a = N[[2,3,4]]
>> a.dtype
=> :int32
>> b = N[[1.2, 3.5, 5.1]]
>> b.dtype
=> :float64
>> c = N[[2],[3],[4]] # same result as N[[2,3,4]].transpose

The simplest is using the N[ ] method. It understands arrays of arrays and will correctly deduce the correct type of the NMatrix (based on the element with highest typecode).

>> b = NMatrix[ [1.5, 2, 3], [4, 5, 6] ] 

Note that even when creating vectors, the number of opening brackets controls the dimensionality. A vector created with N[1,2,3] will have no orientation; but N[[1,2,3]] will be a row vector, and N[[1],[2],[3]] will be a column vector.

Once we have a matrix we can take a look at its attributes:

  >> b.dim
  => 2
  >> b.shape
  => [3, 2]
  >> b.typecode
  => 5
  >> b.element_size
  => 8

Printing Arrays

Basic Operations

Universal Methods

Indexing, Slicing and Iterating

Shape Manipulation

Changing the shape of an array

Stacking together different arrays

Splitting one array into several smaller ones

Copies and Views

No Copy at All

View or Shallow Copy

Deep Copy

Functions and Methods Overview

Less Basic

Broadcasting rules

Fancy indexing and index tricks

Indexing with Arrays of Indices

Indexing with Boolean Arrays

The ix_() function

Indexing with strings

Linear Algebra

Simple Array Operations

Indexing: Comparing Matrices and 2D Arrays

Tricks and Tips

"Automatic" Reshaping

Vector Stacking

Histograms

References

[Work in progress]

Clone this wiki locally