Class: MDS::MatrixInterface
- Inherits:
-
Object
- Object
- MDS::MatrixInterface
- Defined in:
- lib/mds/matrix_interface.rb
Overview
Provides a common interface to matrix operations.
RMDS does not implement any linear algebra routine itself, but rather provides a non intrusive mechanism to plugin third party linear algebra packages. MatrixInterface defines a minimal set of required methods to be implemented for any linear algebra packages which are to be used with RMDS.
Making linear algebra backends compatible with RMDS is easy: simply subclass from MatrixInterface and implement all abstract methods. Not all of MatrixInterface methods are abstract, some come with a default implementation. If your linear algebra package does better at some of those methods, you should override them in your interface subclass.
RMDS helps you in testing your matrix interfaces through test bundles that ship with RMDS. Each test bundle contains a set of tests that work independently of the matrix interface chosen. The following file unit tests a matrix interface.
require 'test/unit'
require 'mds/test/bundles/bundle_matrix_interface.rb'
require 'mds/interfaces/linalg_interface'
class TestLinalgInteface < Test::Unit::TestCase
include MDS::Test::BundleMatrixInterface
def setup
MDS::Backend.push_active(MDS::LinalgInterface)
end
def teardown
MDS::Backend.pop_active
end
end
Finally, tell RMDS to use your matrix interface by setting the default matrix interface, like so
# Set active interface
MDS::Backend.active = YourMatrixInterface
# Push onto interface stack and set active interface
MDS::Backend.push_active(YourMatrixInterface)
# Restore the previously active interface
MDS::Backend.pop_active
Direct Known Subclasses
Class Method Summary collapse
-
.add(m, n) ⇒ Object
abstract
Componentwise addition of two matrices.
-
.columns(m) ⇒ Array<Array>
Returns matrix as array of columns.
-
.create(n, m, s) ⇒ Object
abstract
Create a new matrix having all elements equal values.
-
.create_block(n, m, &block) ⇒ Object
Create a new matrix and assign each element as the result of invoking the given block.
-
.create_diagonal(*elements) ⇒ Object
Create a new diagonal matrix.
-
.create_identity(n) ⇒ Object
Create a new identity matrix.
-
.create_random(n, m, smin = -1.0,, smax = 1.0) ⇒ Object
Create a new matrix with uniform random elements.
-
.create_rows(*rows) ⇒ Object
Create matrix from rows.
-
.diagonals(m) ⇒ Object
Retrieve the diagonal elements as an array.
-
.ed(m) ⇒ Array
abstract
Compute the eigen-decomposition of a real symmetric matrix.
-
.get(m, i, j) ⇒ Float
abstract
Get value of matrix element.
-
.inherited(subclass) ⇒ Object
Record creation of a subclass of this class at the MDS::Backend.
-
.minor(m, row_range, col_range) ⇒ Object
Calculate minor matrix.
-
.ncols(m) ⇒ Object
abstract
Return the number of matrix columns.
-
.nrows(m) ⇒ Object
abstract
Return the number of matrix rows.
-
.prod(m, n) ⇒ Object
abstract
Calculate the product of two matrices or the product of a matrix and a scalar.
-
.rows(m) ⇒ Array<Array>
Returns matrix as array of rows.
-
.set(m, i, j, s) ⇒ Object
abstract
Set value of matrix element.
-
.sub(m, n) ⇒ Object
abstract
Componentwise subtraction of two matrices.
-
.t(m) ⇒ Object
abstract
Transpose a matrix.
-
.trace(m) ⇒ Object
Calculate the sum of diagonal matrix elements.
Instance Method Summary collapse
-
#to_s(m) ⇒ Object
Convert to string.
Class Method Details
.add(m, n) ⇒ Object
Componentwise addition of two matrices.
154 155 156 |
# File 'lib/mds/matrix_interface.rb', line 154 def MatrixInterface.add(m, n) raise NotImplementedError end |
.columns(m) ⇒ Array<Array>
Returns matrix as array of columns.
306 307 308 309 310 311 312 313 314 |
# File 'lib/mds/matrix_interface.rb', line 306 def MatrixInterface.columns(m) a = Array.new(self.ncols(m)) {Array.new(self.nrows(m))} for i in 0..self.nrows(m)-1 do for j in 0..self.ncols(m)-1 do a[j][i] = self.get(m, i, j) end end a end |
.create(n, m, s) ⇒ Object
Create a new matrix having all elements equal values.
83 84 85 |
# File 'lib/mds/matrix_interface.rb', line 83 def MatrixInterface.create(n, m, s) raise NotImplementedError end |
.create_block(n, m, &block) ⇒ Object
Create a new matrix and assign each element as the result of invoking the given block.
211 212 213 214 215 216 217 218 219 |
# File 'lib/mds/matrix_interface.rb', line 211 def MatrixInterface.create_block(n, m, &block) mat = self.create(n, m, 0.0) for i in 0..self.nrows(mat)-1 for j in 0..self.ncols(mat)-1 self.set(mat, i, j, block.call(i,j)) end end mat end |
.create_diagonal(*elements) ⇒ Object
Create a new diagonal matrix.
253 254 255 256 257 258 259 260 |
# File 'lib/mds/matrix_interface.rb', line 253 def MatrixInterface.create_diagonal(*elements) n = elements.length m = self.create(n, n, 0.0) for i in 0..self.nrows(m)-1 self.set(m, i, i, elements[i]) end m end |
.create_identity(n) ⇒ Object
Create a new identity matrix.
243 244 245 |
# File 'lib/mds/matrix_interface.rb', line 243 def MatrixInterface.create_identity(n) self.create_diagonal(*[1.0]*n) end |
.create_random(n, m, smin = -1.0,, smax = 1.0) ⇒ Object
Create a new matrix with uniform random elements.
230 231 232 233 234 235 |
# File 'lib/mds/matrix_interface.rb', line 230 def MatrixInterface.create_random(n, m, smin = -1.0, smax = 1.0) range = smax - smin self.create_block(n, m) do |i,j| smin + range*rand() end end |
.create_rows(*rows) ⇒ Object
Create matrix from rows.
268 269 270 271 272 273 274 275 |
# File 'lib/mds/matrix_interface.rb', line 268 def MatrixInterface.create_rows(*rows) nrows = rows.length ncols = rows.first.length self.create_block(nrows, ncols) do |i,j| rows[i][j] end end |
.diagonals(m) ⇒ Object
Retrieve the diagonal elements as an array.
The number of diagonals of an NxM matrix is defined as min(N,M).
286 287 288 289 |
# File 'lib/mds/matrix_interface.rb', line 286 def MatrixInterface.diagonals(m) size = [self.nrows(m), self.ncols(m)].min (0..size-1).map{|i| self.get(m,i,i)} end |
.ed(m) ⇒ Array
Compute the eigen-decomposition of a real symmetric matrix.
The eigen-decomposition consists of a diagonal matrix D
containing the eigen values and a square matrix N
having the normalized eigenvectors in columns. It is assumed that the result of MatrixInterface#ed yields the matrices as an array and that the eigen-vectors and values are sorted in descending order of importance.
194 195 196 |
# File 'lib/mds/matrix_interface.rb', line 194 def MatrixInterface.ed(m) raise NotImplementedError end |
.get(m, i, j) ⇒ Float
Get value of matrix element.
130 131 132 |
# File 'lib/mds/matrix_interface.rb', line 130 def MatrixInterface.get(m, i, j) raise NotImplementedError end |
.inherited(subclass) ⇒ Object
Record creation of a subclass of this class at the MDS::Backend
65 66 67 |
# File 'lib/mds/matrix_interface.rb', line 65 def MatrixInterface.inherited(subclass) MDS::Backend.add(subclass) end |
.minor(m, row_range, col_range) ⇒ Object
Calculate minor matrix.
338 339 340 341 342 343 344 |
# File 'lib/mds/matrix_interface.rb', line 338 def MatrixInterface.minor(m, row_range, col_range) nrows = (row_range.last - row_range.first) + 1 ncols = (col_range.last - col_range.first) + 1 self.create_block(nrows, ncols) do |i,j| self.get(m, i + row_range.first, j + col_range.first) end end |
.ncols(m) ⇒ Object
Return the number of matrix columns
105 106 107 |
# File 'lib/mds/matrix_interface.rb', line 105 def MatrixInterface.ncols(m) raise NotImplementedError end |
.nrows(m) ⇒ Object
Return the number of matrix rows
94 95 96 |
# File 'lib/mds/matrix_interface.rb', line 94 def MatrixInterface.nrows(m) raise NotImplementedError end |
.prod(m, n) ⇒ Object
Calculate the product of two matrices or the product of a matrix and a scalar.
143 144 145 |
# File 'lib/mds/matrix_interface.rb', line 143 def MatrixInterface.prod(m, n) raise NotImplementedError end |
.rows(m) ⇒ Array<Array>
Returns matrix as array of rows.
321 322 323 324 325 326 327 328 329 |
# File 'lib/mds/matrix_interface.rb', line 321 def MatrixInterface.rows(m) a = Array.new(self.nrows(m)) {Array.new(self.ncols(m))} for i in 0..self.nrows(m)-1 do for j in 0..self.ncols(m)-1 do a[i][j] = self.get(m, i, j) end end a end |
.set(m, i, j, s) ⇒ Object
Set value of matrix element.
117 118 119 |
# File 'lib/mds/matrix_interface.rb', line 117 def MatrixInterface.set(m, i, j, s) raise NotImplementedError end |
.sub(m, n) ⇒ Object
Componentwise subtraction of two matrices.
166 167 168 |
# File 'lib/mds/matrix_interface.rb', line 166 def MatrixInterface.sub(m, n) raise NotImplementedError end |
.t(m) ⇒ Object
Transpose a matrix.
177 178 179 |
# File 'lib/mds/matrix_interface.rb', line 177 def MatrixInterface.t(m) raise NotImplementedError end |
.trace(m) ⇒ Object
Calculate the sum of diagonal matrix elements.
297 298 299 |
# File 'lib/mds/matrix_interface.rb', line 297 def MatrixInterface.trace(m) self.diagonals(m).inject(0) {|sum,e| sum += e} end |
Instance Method Details
#to_s(m) ⇒ Object
Convert to string.
Invokes #to_s from wrapped matrix.
353 354 355 |
# File 'lib/mds/matrix_interface.rb', line 353 def to_s(m) m.to_s end |