rmds 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.md +27 -0
- data/README.md +157 -0
- data/Rakefile +77 -0
- data/examples/adaptive_backend.rb +61 -0
- data/examples/extended_metric.rb +82 -0
- data/examples/minimal_metric.rb +52 -0
- data/examples/visualization.rb +75 -0
- data/examples/visualization_cities.rb +84 -0
- data/lib/mds.rb +22 -0
- data/lib/mds/backend.rb +105 -0
- data/lib/mds/interfaces/gsl_interface.rb +140 -0
- data/lib/mds/interfaces/linalg_interface.rb +149 -0
- data/lib/mds/interfaces/stdlib_interface.rb +155 -0
- data/lib/mds/io.rb +29 -0
- data/lib/mds/matrix.rb +258 -0
- data/lib/mds/matrix_interface.rb +358 -0
- data/lib/mds/metric.rb +150 -0
- data/lib/mds/test/bundles/bundle_matrix_interface.rb +199 -0
- data/lib/mds/test/bundles/bundle_metric.rb +82 -0
- data/lib/mds/test/matrix_assertions.rb +54 -0
- data/test/benchmark/benchmark_metric.rb +53 -0
- data/test/test_helper.rb +11 -0
- data/test/unit/dummy_interfaces.rb +20 -0
- data/test/unit/test_backend.rb +44 -0
- data/test/unit/test_gsl_interface.rb +22 -0
- data/test/unit/test_gsl_metric.rb +22 -0
- data/test/unit/test_linalg_interface.rb +22 -0
- data/test/unit/test_linalg_metric.rb +21 -0
- data/test/unit/test_stdlib_interface.rb +22 -0
- data/test/unit/test_stdlib_metric.rb +21 -0
- metadata +101 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
#
|
2
|
+
# RMDS - Ruby Multidimensional Scaling Library
|
3
|
+
# Copyright (c) Christoph Heindl, 2010
|
4
|
+
# http://github.com/cheind/rmds
|
5
|
+
#
|
6
|
+
|
7
|
+
module MDS
|
8
|
+
#
|
9
|
+
# Examples for RMDS
|
10
|
+
#
|
11
|
+
module Examples
|
12
|
+
|
13
|
+
#
|
14
|
+
# Visualization of {MDS::Metric} output.
|
15
|
+
#
|
16
|
+
# Visually illustrates that MDS finds an embedding
|
17
|
+
# that is unique except for any rigid transformation
|
18
|
+
# applied to it.
|
19
|
+
#
|
20
|
+
def Examples.visualization
|
21
|
+
require 'mds'
|
22
|
+
require 'mds/interfaces/stdlib_interface'
|
23
|
+
require 'gnuplot'
|
24
|
+
|
25
|
+
MDS::Backend.active = MDS::StdlibInterface
|
26
|
+
|
27
|
+
# Input
|
28
|
+
x = MDS::Matrix.create_rows(
|
29
|
+
[1.0, 2.0], # Point A
|
30
|
+
[4.0, 3.0], # Point B
|
31
|
+
[0.0, 1.0] # Point C
|
32
|
+
)
|
33
|
+
|
34
|
+
d2 = MDS::Metric.squared_distances(x)
|
35
|
+
|
36
|
+
# Embedding in R2
|
37
|
+
proj = MDS::Metric.projectd(d2, 2)
|
38
|
+
|
39
|
+
Gnuplot.open do |gp|
|
40
|
+
Gnuplot::Plot.new( gp ) do |plot|
|
41
|
+
|
42
|
+
# Uncomment the following lines to write result to image.
|
43
|
+
# plot.term 'png size'
|
44
|
+
# plot.output 'visualization.png'
|
45
|
+
|
46
|
+
plot.title "Original Input and Result of MDS in Two Dimensions"
|
47
|
+
plot.xrange "[-5:5]"
|
48
|
+
plot.yrange "[-5:5]"
|
49
|
+
|
50
|
+
plot.data << Gnuplot::DataSet.new(x.columns) do |ds|
|
51
|
+
ds.with = "points"
|
52
|
+
ds.title = "Input"
|
53
|
+
end
|
54
|
+
|
55
|
+
plot.data << Gnuplot::DataSet.new(proj.columns) do |ds|
|
56
|
+
ds.with = "points"
|
57
|
+
ds.title = "Output"
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
if __FILE__ == $0
|
70
|
+
require 'rubygems'
|
71
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
72
|
+
MDS::Examples.visualization
|
73
|
+
end
|
74
|
+
|
75
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
# RMDS - Ruby Multidimensional Scaling Library
|
3
|
+
# Copyright (c) Christoph Heindl, 2010
|
4
|
+
# http://github.com/cheind/rmds
|
5
|
+
#
|
6
|
+
|
7
|
+
module MDS
|
8
|
+
#
|
9
|
+
# Examples for RMDS
|
10
|
+
#
|
11
|
+
module Examples
|
12
|
+
|
13
|
+
#
|
14
|
+
# Visualization of air distances between major european cities.
|
15
|
+
#
|
16
|
+
# Compare result with http://bit.ly/bNdf0e but keep in mind that
|
17
|
+
#
|
18
|
+
# - MDS finds an embedding up to rotation and translation
|
19
|
+
# - The input matrix contains air-distances and the map shows correct goedesic distances.
|
20
|
+
#
|
21
|
+
def Examples.visualization_european_cities
|
22
|
+
require 'mds'
|
23
|
+
require 'gnuplot' # gem install gnuplot
|
24
|
+
|
25
|
+
# Load backend
|
26
|
+
MDS::Backend.try_require
|
27
|
+
MDS::Backend.active = MDS::Backend.first
|
28
|
+
puts "Using backend #{MDS::Backend.active}"
|
29
|
+
|
30
|
+
# Load matrix from file, contains city names in first column
|
31
|
+
path = File.join(File.dirname(__FILE__), 'european_city_distances.csv')
|
32
|
+
|
33
|
+
cities = []
|
34
|
+
rows = MDS::IO::read_csv(path, ';') do |entry|
|
35
|
+
begin
|
36
|
+
f = Float(entry)
|
37
|
+
f * f
|
38
|
+
rescue ArgumentError
|
39
|
+
cities << entry
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Invoke MDS
|
45
|
+
|
46
|
+
d2 = MDS::Matrix.create_rows(*rows)
|
47
|
+
proj = MDS::Metric.projectk(d2, 0.9)
|
48
|
+
|
49
|
+
# Plot results
|
50
|
+
|
51
|
+
Gnuplot.open do |gp|
|
52
|
+
Gnuplot::Plot.new( gp ) do |plot|
|
53
|
+
|
54
|
+
# Uncomment the following lines to write result to image.
|
55
|
+
# plot.term 'png size'
|
56
|
+
# plot.output 'visualization.png'
|
57
|
+
|
58
|
+
plot.title "Air Distances between European Cities"
|
59
|
+
plot.xrange "[-2000:2000]"
|
60
|
+
plot.yrange "[-1500:1200]"
|
61
|
+
|
62
|
+
plot.data << Gnuplot::DataSet.new(proj.columns) do |ds|
|
63
|
+
ds.with = "points"
|
64
|
+
ds.notitle
|
65
|
+
end
|
66
|
+
|
67
|
+
cities.each_with_index do |name, i|
|
68
|
+
plot.label "'#{name}' at #{proj[i,0] + 30}, #{proj[i,1] + 30}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
if __FILE__ == $0
|
79
|
+
require 'rubygems'
|
80
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
81
|
+
MDS::Examples.visualization_european_cities
|
82
|
+
end
|
83
|
+
|
84
|
+
|
data/lib/mds.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# RMDS - Ruby Multidimensional Scaling Library
|
3
|
+
# Copyright (c) Christoph Heindl, 2010
|
4
|
+
# http://github.com/cheind/rmds
|
5
|
+
#
|
6
|
+
|
7
|
+
#
|
8
|
+
# MDS - Ruby Multidimensional Scaling
|
9
|
+
#
|
10
|
+
module MDS
|
11
|
+
# Current version of MDS
|
12
|
+
VERSION = '0.2'
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
16
|
+
|
17
|
+
require 'mds/matrix_interface'
|
18
|
+
require 'mds/matrix'
|
19
|
+
require 'mds/backend'
|
20
|
+
require 'mds/metric'
|
21
|
+
require 'mds/io'
|
22
|
+
|
data/lib/mds/backend.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#
|
2
|
+
# RMDS - Ruby Multidimensional Scaling Library
|
3
|
+
# Copyright (c) Christoph Heindl, 2010
|
4
|
+
# http://github.com/cheind/rmds
|
5
|
+
#
|
6
|
+
|
7
|
+
module MDS
|
8
|
+
|
9
|
+
# Defines the preferrred order of interfaces.
|
10
|
+
PREFERRED_INTERFACE_ORDER = ['MDS::LinalgInterface', 'MDS::GSLInterface', 'MDS::StdlibInterface']
|
11
|
+
|
12
|
+
#
|
13
|
+
# Provides a common interface to matrix operations.
|
14
|
+
#
|
15
|
+
class Backend
|
16
|
+
# Stack of active matrix interfaces
|
17
|
+
@active = []
|
18
|
+
# Array of available interface classes
|
19
|
+
@available = []
|
20
|
+
|
21
|
+
class << self;
|
22
|
+
#
|
23
|
+
# Access the active matrix interface.
|
24
|
+
#
|
25
|
+
def active
|
26
|
+
@active.first;
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Set the active matrix interface.
|
31
|
+
#
|
32
|
+
def active=(i)
|
33
|
+
@active.pop
|
34
|
+
@active.push(i)
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Push matrix interface onto the stack and set it active.
|
39
|
+
#
|
40
|
+
def push_active(i)
|
41
|
+
@active.push(i)
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Deactivate active matrix interface by popping it from stack.
|
46
|
+
#
|
47
|
+
def pop_active
|
48
|
+
@active.pop()
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Add available interface class.
|
53
|
+
#
|
54
|
+
# Automatically called when interface is required.
|
55
|
+
#
|
56
|
+
def add(i)
|
57
|
+
@available << i
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Return available interface classes.
|
62
|
+
#
|
63
|
+
def available
|
64
|
+
@available
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Return the first interface class.
|
69
|
+
#
|
70
|
+
# If no interface class matches a string in +search_order+,
|
71
|
+
# the first available interface is returned.
|
72
|
+
#
|
73
|
+
def first(search_order = MDS::PREFERRED_INTERFACE_ORDER)
|
74
|
+
c = search_order.map do |name|
|
75
|
+
begin
|
76
|
+
name.split('::').inject(Kernel) do |scope, const_name|
|
77
|
+
scope.const_get(const_name)
|
78
|
+
end
|
79
|
+
rescue NameError
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end.compact!
|
83
|
+
|
84
|
+
(!c || c.length == 0) ? @available.first : c.first
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Require all interfaces from path and conceal possible errors.
|
89
|
+
#
|
90
|
+
# @param String path the path or globbing expression to pass to require
|
91
|
+
#
|
92
|
+
def try_require(path = File.join(File.dirname(__FILE__), 'interfaces', '*interface.rb'))
|
93
|
+
Dir.glob(File.expand_path(path)) do |path|
|
94
|
+
begin
|
95
|
+
require path
|
96
|
+
rescue LoadError
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#
|
2
|
+
# RMDS - Ruby Multidimensional Scaling Library
|
3
|
+
# Copyright (c) Christoph Heindl, 2010
|
4
|
+
# http://github.com/cheind/rmds
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'mds/matrix_interface'
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'rbgsl'
|
11
|
+
rescue LoadError
|
12
|
+
warn "\n**Notice: GSLAdapter requires \'rb-gsl\' which was not found."
|
13
|
+
warn "You can install the extension from : \n http://rb-gsl.rubyforge.org/ \n"
|
14
|
+
raise $!
|
15
|
+
end
|
16
|
+
|
17
|
+
module MDS
|
18
|
+
|
19
|
+
#
|
20
|
+
# Matrix interface for the Gnu Scientific Library.
|
21
|
+
#
|
22
|
+
# To succesfully use this interface 'rbgsl' bindings for GSL are required.
|
23
|
+
# For more information and installation instructions see
|
24
|
+
# http://rb-gsl.rubyforge.org/
|
25
|
+
#
|
26
|
+
# Compatible with 'rb-gsl >= 1.14.3'
|
27
|
+
#
|
28
|
+
class GSLInterface < MatrixInterface
|
29
|
+
|
30
|
+
#
|
31
|
+
# Create a new matrix with equal elements.
|
32
|
+
#
|
33
|
+
# @param (see MDS::MatrixInterface#create)
|
34
|
+
# @return (see MDS::MatrixInterface#create)
|
35
|
+
#
|
36
|
+
def GSLInterface.create(n, m, s)
|
37
|
+
mat = ::GSL::Matrix.alloc(n, m)
|
38
|
+
mat.set_all(s)
|
39
|
+
mat
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Return the number of matrix rows
|
44
|
+
#
|
45
|
+
# @param (see MDS::MatrixInterface#nrows)
|
46
|
+
# @return (see MDS::MatrixInterface#nrows)
|
47
|
+
#
|
48
|
+
def GSLInterface.nrows(m)
|
49
|
+
m.size1
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Return the number of matrix columns
|
54
|
+
#
|
55
|
+
# @param (see MDS::MatrixInterface#ncols)
|
56
|
+
# @return (see MDS::MatrixInterface#ncols)
|
57
|
+
#
|
58
|
+
def GSLInterface.ncols(m)
|
59
|
+
m.size2
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Set matrix element.
|
64
|
+
#
|
65
|
+
# @param (see MDS::MatrixInterface#set)
|
66
|
+
#
|
67
|
+
def GSLInterface.set(m, i, j, s)
|
68
|
+
m[i,j] = s
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Get matrix element.
|
73
|
+
#
|
74
|
+
# @param (see MDS::MatrixInterface#get)
|
75
|
+
# @return (see MDS::MatrixInterface#get)
|
76
|
+
#
|
77
|
+
def GSLInterface.get(m, i, j)
|
78
|
+
m[i,j]
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Calculate the product of two matrices or
|
83
|
+
# the product of a matrix and a scalar.
|
84
|
+
#
|
85
|
+
# @param (see MDS::MatrixInterface#prod)
|
86
|
+
# @return (see MDS::MatrixInterface#prod)
|
87
|
+
#
|
88
|
+
def GSLInterface.prod(m, n)
|
89
|
+
m * n
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Transpose a matrix.
|
94
|
+
#
|
95
|
+
# @param (see MDS::MatrixInterface#t)
|
96
|
+
# @return (see MDS::MatrixInterface#t)
|
97
|
+
#
|
98
|
+
def GSLInterface.t(m)
|
99
|
+
m.transpose
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Componentwise addition of two matrices.
|
104
|
+
#
|
105
|
+
# @param (see MDS::MatrixInterface#add)
|
106
|
+
# @return (see MDS::MatrixInterface#add)
|
107
|
+
#
|
108
|
+
def GSLInterface.add(m, n)
|
109
|
+
m + n
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Componentwise subtraction of two matrices.
|
114
|
+
#
|
115
|
+
# @param (see MDS::MatrixInterface#sub)
|
116
|
+
# @return (see MDS::MatrixInterface#sub)
|
117
|
+
#
|
118
|
+
def GSLInterface.sub(m, n)
|
119
|
+
m - n
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Compute the eigen-decomposition of a real symmetric matrix.
|
124
|
+
#
|
125
|
+
# @param (see MDS::MatrixInterface#ed)
|
126
|
+
# @return (see MDS::MatrixInterface#ed)
|
127
|
+
#
|
128
|
+
def GSLInterface.ed(m)
|
129
|
+
eigen_values, eigen_vectors = ::GSL::Eigen::symmv(m)
|
130
|
+
::GSL::Eigen::Symmv::sort(
|
131
|
+
eigen_values,
|
132
|
+
eigen_vectors,
|
133
|
+
::GSL::Eigen::SORT_VAL_DESC
|
134
|
+
)
|
135
|
+
|
136
|
+
[eigen_values.to_m_diagonal, eigen_vectors]
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#
|
2
|
+
# RMDS - Ruby Multidimensional Scaling Library
|
3
|
+
# Copyright (c) Christoph Heindl, 2010
|
4
|
+
# http://github.com/cheind/rmds
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'mds/matrix_interface'
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'linalg'
|
11
|
+
rescue LoadError
|
12
|
+
warn "\n**Notice: This matrix interface requires \'Linalg\' which was not found."
|
13
|
+
warn "You can install the extension from: \n http://rubyforge.org/projects/linalg/ \n"
|
14
|
+
raise $!
|
15
|
+
end
|
16
|
+
|
17
|
+
module MDS
|
18
|
+
|
19
|
+
#
|
20
|
+
# Common matrix interface for Linalg - Ruby Bindings for LAPACK.
|
21
|
+
#
|
22
|
+
# To succesfully use this interface 'Linalg' bindings for LAPCK/BLAS
|
23
|
+
# are required. For more information and installation instructions see
|
24
|
+
# http://rubyforge.org/projects/linalg/
|
25
|
+
#
|
26
|
+
# Compatible with 'Linalg >= 1.0.0'
|
27
|
+
#
|
28
|
+
class LinalgInterface < MatrixInterface
|
29
|
+
|
30
|
+
#
|
31
|
+
# Create a new matrix with equal elements.
|
32
|
+
#
|
33
|
+
# @param (see MatrixInterface#create)
|
34
|
+
# @return (see MatrixInterface#create)
|
35
|
+
#
|
36
|
+
def LinalgInterface.create(n, m, s)
|
37
|
+
::Linalg::DMatrix.new(n, m, s)
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Return the number of matrix rows
|
42
|
+
#
|
43
|
+
# @param (see MatrixInterface#nrows)
|
44
|
+
# @return (see MatrixInterface#nrows)
|
45
|
+
#
|
46
|
+
def LinalgInterface.nrows(m)
|
47
|
+
m.num_rows
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Return the number of matrix columns
|
52
|
+
#
|
53
|
+
# @param (see MatrixInterface#ncols)
|
54
|
+
# @return (see MatrixInterface#ncols)
|
55
|
+
#
|
56
|
+
def LinalgInterface.ncols(m)
|
57
|
+
m.num_columns
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Set matrix element.
|
62
|
+
#
|
63
|
+
# @param (see MatrixInterface#set)
|
64
|
+
#
|
65
|
+
def LinalgInterface.set(m, i, j, s)
|
66
|
+
m[i,j] = s
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Get matrix element.
|
71
|
+
#
|
72
|
+
# @param (see MatrixInterface#get)
|
73
|
+
# @return (see MatrixInterface#get)
|
74
|
+
#
|
75
|
+
def LinalgInterface.get(m, i, j)
|
76
|
+
m[i,j]
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Calculate the product of two matrices or
|
81
|
+
# the product of a matrix and a scalar.
|
82
|
+
#
|
83
|
+
# @param (see MatrixInterface#prod)
|
84
|
+
# @return (see MatrixInterface#prod)
|
85
|
+
#
|
86
|
+
def LinalgInterface.prod(m, n)
|
87
|
+
m * n
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Transpose a matrix.
|
92
|
+
#
|
93
|
+
# @param (see MatrixInterface#t)
|
94
|
+
# @return (see MatrixInterface#t)
|
95
|
+
#
|
96
|
+
def LinalgInterface.t(m)
|
97
|
+
m.transpose
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Componentwise addition of two matrices.
|
102
|
+
#
|
103
|
+
# @param (see MatrixInterface#add)
|
104
|
+
# @return (see MatrixInterface#add)
|
105
|
+
#
|
106
|
+
def LinalgInterface.add(m, n)
|
107
|
+
m + n
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Componentwise subtraction of two matrices.
|
112
|
+
#
|
113
|
+
# @param (see MatrixInterface#sub)
|
114
|
+
# @return (see MatrixInterface#sub)
|
115
|
+
#
|
116
|
+
def LinalgInterface.sub(m, n)
|
117
|
+
m - n
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Compute the eigen-decomposition of a real symmetric matrix.
|
122
|
+
#
|
123
|
+
# @param (see MatrixInterface#ed)
|
124
|
+
# @return (see MatrixInterface#ed)
|
125
|
+
#
|
126
|
+
def LinalgInterface.ed(m)
|
127
|
+
evecs, real, img = m.eigensystem
|
128
|
+
[Linalg::DMatrix.diagonal(real), evecs]
|
129
|
+
end
|
130
|
+
|
131
|
+
#---------------------------------------
|
132
|
+
# Optional
|
133
|
+
# Methods having default implementations.
|
134
|
+
#---------------------------------------
|
135
|
+
|
136
|
+
#
|
137
|
+
# Calculate minor matrix.
|
138
|
+
#
|
139
|
+
# @param (see MatrixInterface#minor)
|
140
|
+
# @return (see MatrixInterface#minor)
|
141
|
+
#
|
142
|
+
def LinalgInterface.minor(m, row_range, col_range)
|
143
|
+
nrows = (row_range.last - row_range.first) + 1
|
144
|
+
ncols = (col_range.last - col_range.first) + 1
|
145
|
+
m.minor(row_range.first, col_range.first, nrows, ncols)
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|