Saturday, October 2, 2010

The Weka API: Matrix class

Weka includes a matrix library in weka.core.matrix.Matrix. This library is adapted from the JAMA package, originally developed by NIST and the University of Maryland. The aim of the library is to support functions for numerical linear algebra.

Creating a
Matrix Instance

To create a Matrix instance from jRuby, I use the following construction method. It takes a two-dimensional Ruby array as argument, and returns an instance of the Matrix class.

def make_matrix array_2d
matrix = Matrix.new(array_2d.length, array_2d[0].length)
array_2d.length.times do |i|
array_2d[0].length.times do |j|
matrix.set(i, j, array_2d[i][j])
end
end
return matrix
end


For example: puts make_matrix([[1,2,3], [4,5,6], [7,8,10]])
displays

1 2 3

4 5 6
7 8 10

Solving a Linear System

The example within the Weka documentation solves the following problem:

Solving using jRuby is equally trivial:

A = make_matrix [[1,2,3], [4,5,6], [7,8,10]]
b = make_matrix [[0.1],[0.2],[0.3]]
x = A.solve b

Warning: although the matrices can be converted to strings using to_s, the result is limited in decimal places, which can be misleading. Better to display the solution using explict 'get' statements, such as:

puts "Solution: "
puts x.get(0,0), x.get(1,0), x.get(2,0)

Solution:
-0.0333333333333334
0.0666666666666667
-3.46944695195361e-17

Arithmetic on Matrices

The Matrix library supports several standard operations on matrices. It is easy to add, subtract, or multiply two matrices which are of the right 'shape'. For example, to find the 'residual' from the above solution: ||Ax - b||

r = A.times(x).minus(b)
puts r.normInf

(Here, 'normInf' is the infinity norm: the maximum value in the rows of the matrix 'r'. The library supports other norms. The popular "square root of sum of squares" is represented by 'normF', the Frobenius norm.)

0 comments:

Post a Comment