## 2014年11月5日 星期三

### [ RubyAlg ] Matrix creation and basic operations

Preface
In order to handle linear algerbra in ruby, I create a package/library called "RubyAlg" to create matrix and handle common matrix operations through the created Matrix class. Below will introduce how to use this package and introduce basic operations among created Matrix object.

Matrix Creation
There are multiple ways to create Matrix object through alg/math/LinearAlgebra. Let's check a few examples:
- Create Matrix Object (1)
>> require "alg/math/LinearAlgebra"
=> true
>> LA=LinearAlgebra
=> LinearAlgebra
>> m1 = LA.newIM(3) # Build-up 3x3 identity matrix
=> #
>> puts m1
1 0 0
0 1 0
0 0 1

>> m2 = LA.newMtx(3,3,2) # Create a 3x3 matrix with default value=2
=> #
>> printf("m1+m2:\n%s\n", m1+m2) # Demonstrate matrix addition
m1+m2:
3 2 2
2 3 2
2 2 3

=> nil

Or you can just do translation from Array object to Matrix object:
- Create Matrix Object (2)
>> a = [[1,2,3],[4,5,6],[7,8,9]]
=> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>> m1 = LA.A2M(a)
=> #
>> b = [[1,2],[3],[4,5,6]]
=> [[1, 2], [3], [4, 5, 6]] # array b has row=3. But each row has different column size.
>> m2 = LA.A2M(b)
=> # # The translation will choose the max column size as matrix column size.
>> printf("m1-m2:\n%s", m1-m2) # Demonstration of subtraction.
m1-m2:
0 0 3
1 5 6
3 3 3
=> nil

There are some advanced ways to create Matrix object:
- Create Matrix Object (3)
>> m1 = LA.newIM(2)
=> #
>> m2 = LA.newMtx3(2,2,[1,2,3,4]) # Build up 2x2 matrix with values in array [1,2,3,4]
=> #
>> m1*m2
=> # # The result of matrix multiplying Identity matrix is self
>> m3 = LA.newSMtx(2,1) # Build 2x2 Square Matrix with every value=1
=> #
>> m3[0][0]=2 # You can modify value of matrix just like array in ruby
=> 2
>> puts m3
2 1
1 1
=> nil

>> m3[1][1]
=> 1
>> m3[1][2] # Access element out of range will have nil value
=> nil

Basic Matrix Operations
There are a number of basic operations that can be applied to modify matrices, called matrix additionscalar multiplicationtranspositionmatrix multiplication, row operations, and submatrix.
- Addition, scalar multiplication and transposition
Main articles: Matrix additionScalar multiplication and Transpose. Let's check how to do them in Matrix object:
>> m1 = LA.newMtx3(2,3,[1,3,1,1,0,0])
=> #
>> m2 = LA.newMtx3(2,3,[0,0,5,7,5,0])
=> #
>> puts m1+m2 # Addition
1 3 6
8 5 0
=> nil

>> m3 = LA.newMtx3(2,3,[1,8,-3,4,-2,5])
=> #
>> m3*2 # scalar multiplication
=> #
>> 2*m3
TypeError: Matrix can't be coerced into Fixnum
>> m4 = LA.newMtx3(2,3,[1,2,3,0,-6,7])
=> #
>> m4.t # Transposition
=> #
>> puts m4.t
1 0
2 -6
3 7
=> nil

- Matrix multiplication
Multiplication of two matrices is defined if and only if the number of columns of the left matrix is the same as the number of rows of the right matrix. If A is an m-by-n matrix and B is an n-by-p matrix, then their matrix product AB is the m-by-p matrix whose entries are given by dot product of the corresponding row of A and the corresponding column of B

Let's check how to do them in Matrix object:
>> a = LA.newMtx3(2,2,[1,2,3,4])
=> #
>> b = LA.newMtx3(2,2,[0,1,0,0])
=> #
>> c = LA.newMtx3(2,2, [4,3,2,1])
=> #
>> a*b # Matrix multiplication
=> #
>> (a*b)*c == a*(b*c) # associativity
=> true
>> (a+b)*c == a*c + b*c # distributivity
=> true
>> c*(a+b) == c*a + c*b
=> true
>> a*b == b*c # matrix multiplication is not commutative!
=> false

- Submatrix
A submatrix of a matrix is obtained by deleting any collection of rows and/or columns. For example, for the following 3-by-4 matrix, we can construct a 2-by-3 submatrix by removing row 3 and column 2:

Let's check how to do them in Matrix object:
>> A = LA.newMtx3(3,4,[1,2,3,4,5,6,7,8,9,10,11,12])
=> #
>> s = A.sub(2,1) # Submatrix operation. The row/column number in Matrix start from 0!
=> #
>> puts s
1 3 4
5 7 8
=> nil

Performance Concern
So far this package doesn't do any optimization (Multipthreading etc). Maybe in the future I will try to focus on this part when I have time. But it is only a PoC and help me to do some matrix operations more directly and easily.

Supplement
SciRuby - Tools for Scientific Computing in Ruby

## 關於我自己

Where there is a will, there is a way!