stair_car 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/Gemfile +14 -0
- data/Guardfile +18 -0
- data/LICENSE.txt +22 -0
- data/README.md +223 -0
- data/Rakefile +1 -0
- data/lib/matlab/matlabcontrol-4.0.0.jar +0 -0
- data/lib/pcolt/lib/arpack-combo.jar +0 -0
- data/lib/pcolt/lib/csparsej.jar +0 -0
- data/lib/pcolt/lib/jplasma.jar +0 -0
- data/lib/pcolt/lib/jtransforms.jar +0 -0
- data/lib/pcolt/lib/junit.jar +0 -0
- data/lib/pcolt/lib/netlib-java.jar +0 -0
- data/lib/pcolt/lib/optimization.jar +0 -0
- data/lib/pcolt/parallelcolt-0.9.4.jar +0 -0
- data/lib/stair_car/mmatrix/matlab_interface.rb +9 -0
- data/lib/stair_car/mmatrix/mmatrix.rb +26 -0
- data/lib/stair_car/pmatrix/compare.rb +34 -0
- data/lib/stair_car/pmatrix/matrix_math.rb +169 -0
- data/lib/stair_car/pmatrix/pmatrix.rb +151 -0
- data/lib/stair_car/pmatrix/transforms.rb +74 -0
- data/lib/stair_car/pmatrix/types.rb +106 -0
- data/lib/stair_car/shared/errors.rb +7 -0
- data/lib/stair_car/shared/indicies.rb +33 -0
- data/lib/stair_car/shared/init_methods.rb +56 -0
- data/lib/stair_car/shared/inspect.rb +113 -0
- data/lib/stair_car/shared/iteration.rb +32 -0
- data/lib/stair_car/umatrix/compare.rb +34 -0
- data/lib/stair_car/umatrix/matrix_math.rb +190 -0
- data/lib/stair_car/umatrix/transforms.rb +49 -0
- data/lib/stair_car/umatrix/types.rb +42 -0
- data/lib/stair_car/umatrix/umatrix.rb +166 -0
- data/lib/stair_car.rb +35 -0
- data/lib/ujmp/ujmp-complete-0.2.5.jar +0 -0
- data/spec/pmatrix/matrix_math_spec.rb +65 -0
- data/spec/pmatrix/pmatrix_spec.rb +103 -0
- data/spec/pmatrix/transforms_spec.rb +44 -0
- data/spec/shared/indicies_spec.rb +52 -0
- data/spec/shared/inspect_spec.rb +23 -0
- data/spec/shared/iteration_spec.rb +17 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/umatrix/matrix_math_spec.rb +68 -0
- data/spec/umatrix/transform_spec.rb +32 -0
- data/spec/umatrix/umatrix_spec.rb +104 -0
- data/stair_car.gemspec +19 -0
- metadata +120 -0
@@ -0,0 +1,190 @@
|
|
1
|
+
module StairCar
|
2
|
+
module UMatrixMatrixMath
|
3
|
+
class MatrixMathError < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
# In jruby, we need to pass the params to java_methods to distinguish them
|
7
|
+
# when multiple java methods (with different params) have the same name.
|
8
|
+
def find_params(object, method_name, &search)
|
9
|
+
while object
|
10
|
+
object.declared_instance_methods.each do |method|
|
11
|
+
if method.name == method_name
|
12
|
+
if yield(method.parameter_types)
|
13
|
+
# Method checks to see if the parameter types are correct, if they
|
14
|
+
# are then we return them.
|
15
|
+
return method.parameter_types
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# If we didn't find it here, move up the chain
|
21
|
+
object = object.superclass
|
22
|
+
end
|
23
|
+
|
24
|
+
return nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def perform(method, val)
|
28
|
+
method = method.to_s
|
29
|
+
result = @data.clone
|
30
|
+
if val.is_a?(UMatrix)
|
31
|
+
@param_types ||= {}
|
32
|
+
@param_types[method] ||= find_params(result.java_class, method) do |params|
|
33
|
+
# params.first.name == 'org.ujmp.core.Matrix'
|
34
|
+
params.size == 3 &&
|
35
|
+
params[0].name == 'org.ujmp.core.calculation.Calculation$Ret' &&
|
36
|
+
params[1].name == 'boolean' &&
|
37
|
+
params[2].name == 'org.ujmp.core.Matrix'
|
38
|
+
end
|
39
|
+
if rows == val.rows && cols == val.cols
|
40
|
+
# Another matrix of the same size
|
41
|
+
# result = result.java_send(method, @param_types[method], val.data)
|
42
|
+
result.java_send(method, @param_types[method], Java::OrgUjmpCoreCalculation::Calculation.ORIG, false.to_java, val.data)
|
43
|
+
elsif rows == val.rows && val.cols == 1
|
44
|
+
# Vector on column (vertical)
|
45
|
+
UMatrix.new(result).each_column do |row|
|
46
|
+
# row.data.send(method, Java::OrgUjmpCoreCalculation::Calculation.ORIG, false.to_java, val.data)
|
47
|
+
# row.data.java_send(method, @param_types[method], val.data)
|
48
|
+
row.data.java_send(method, @param_types[method], Java::OrgUjmpCoreCalculation::Calculation.ORIG, false.to_java, val.data)
|
49
|
+
end
|
50
|
+
elsif cols == val.cols && val.rows == 1
|
51
|
+
# Vector on rows (horizontal)
|
52
|
+
UMatrix.new(result).each_row do |col|
|
53
|
+
col.data.java_send(method, @param_types[method], Java::OrgUjmpCoreCalculation::Calculation.ORIG, false.to_java, val.data)
|
54
|
+
# col.data.send(method, Java::OrgUjmpCoreCalculation::Calculation.ORIG, false.to_java, val.data)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
# Incorrect size
|
58
|
+
raise MatrixMathError, "matrix dimensions incorrect"
|
59
|
+
end
|
60
|
+
else
|
61
|
+
# Passed in a number
|
62
|
+
result = result.send(method, Java::OrgUjmpCoreCalculation::Calculation.ORIG, false.to_java, val.to_java(:double))
|
63
|
+
end
|
64
|
+
|
65
|
+
return UMatrix.new(result)
|
66
|
+
end
|
67
|
+
|
68
|
+
def +(val)
|
69
|
+
perform(:plus, val)
|
70
|
+
end
|
71
|
+
|
72
|
+
def -(val)
|
73
|
+
perform(:minus, val)
|
74
|
+
end
|
75
|
+
|
76
|
+
def **(val)
|
77
|
+
end
|
78
|
+
|
79
|
+
def /(val)
|
80
|
+
end
|
81
|
+
|
82
|
+
def *(val)
|
83
|
+
n = self.rows
|
84
|
+
m = self.cols
|
85
|
+
|
86
|
+
p = val.rows
|
87
|
+
q = val.cols
|
88
|
+
|
89
|
+
if m != p
|
90
|
+
raise MatrixMathError, "matricies can not be multiplied"
|
91
|
+
end
|
92
|
+
|
93
|
+
# Build a like matrix to receive
|
94
|
+
c = @data.like(n, q)
|
95
|
+
|
96
|
+
@data.z_mult(val.data, c)
|
97
|
+
|
98
|
+
return UMatrix.new(c)
|
99
|
+
end
|
100
|
+
|
101
|
+
# ujmp requires you pass in a special code for all dimensions
|
102
|
+
def dim_convert(dimension)
|
103
|
+
if dimension == nil
|
104
|
+
dimension = Java::org.ujmp.core.Matrix::ALL
|
105
|
+
end
|
106
|
+
|
107
|
+
return dimension
|
108
|
+
end
|
109
|
+
|
110
|
+
# Calls aggraration method on the data
|
111
|
+
def call_data_method(method, dimension, *args)
|
112
|
+
result = UMatrix.new(@data.send(method, Java::OrgUjmpCoreCalculation::Calculation.NEW, dim_convert(dimension), *args))
|
113
|
+
if dimension
|
114
|
+
return result
|
115
|
+
else
|
116
|
+
# Just return the first element
|
117
|
+
return result[0,0]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def sum(dimension=nil)
|
122
|
+
return call_data_method(:sum, dimension, false)
|
123
|
+
end
|
124
|
+
|
125
|
+
def max(dimension=nil)
|
126
|
+
return call_data_method(:max, dimension)
|
127
|
+
end
|
128
|
+
|
129
|
+
def min(dimension=nil)
|
130
|
+
return call_data_method(:min, dimension)
|
131
|
+
end
|
132
|
+
|
133
|
+
def mean(dimension=nil)
|
134
|
+
return call_data_method(:mean, dimension, false)
|
135
|
+
end
|
136
|
+
|
137
|
+
def variance(dimension=nil, sample=false)
|
138
|
+
if dimension
|
139
|
+
value = aggrate_on_dimension(:variance, dimension, sample)
|
140
|
+
else
|
141
|
+
mean = self.mean
|
142
|
+
total = 0
|
143
|
+
self.each_non_zero do |v|
|
144
|
+
total += (mean - v) ** 2
|
145
|
+
end
|
146
|
+
|
147
|
+
if sample
|
148
|
+
value = total / (self.size - 1)
|
149
|
+
else
|
150
|
+
value = total / self.size
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
return value
|
155
|
+
end
|
156
|
+
|
157
|
+
def std(dimension=nil, sample=false)
|
158
|
+
if dimension
|
159
|
+
value = aggrate_on_dimension(:variance, dimension, sample)
|
160
|
+
else
|
161
|
+
value = Math.sqrt(self.variance(dimension, sample))
|
162
|
+
end
|
163
|
+
|
164
|
+
return value
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
def aggrate_on_dimension(method_name, dimension, *args)
|
169
|
+
if dimension == 0
|
170
|
+
# Get the per row
|
171
|
+
vals = UMatrix.new(@data.like(rows, 1))
|
172
|
+
|
173
|
+
self.each_row do |row, row_number|
|
174
|
+
vals[row_number,0] = row.send(method_name, nil, *args).to_f
|
175
|
+
end
|
176
|
+
|
177
|
+
return vals
|
178
|
+
elsif dimension == 1
|
179
|
+
# Get the per row
|
180
|
+
vals = UMatrix.new(@data.like(1, cols))
|
181
|
+
|
182
|
+
self.each_column do |col, col_number|
|
183
|
+
vals[0,col_number] = col.send(method_name, nil, *args).to_f
|
184
|
+
end
|
185
|
+
|
186
|
+
return vals
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module StairCar
|
2
|
+
module UMatrixTransforms
|
3
|
+
def transpose
|
4
|
+
return UMatrix.new(@data.transpose)
|
5
|
+
end
|
6
|
+
|
7
|
+
def ~
|
8
|
+
return transpose
|
9
|
+
end
|
10
|
+
|
11
|
+
def map(&block)
|
12
|
+
dup.map!(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def map!
|
16
|
+
result = self.each_with_index do |val,row,col|
|
17
|
+
self[row,col] = yield(val, row, col)
|
18
|
+
end
|
19
|
+
|
20
|
+
return self
|
21
|
+
end
|
22
|
+
|
23
|
+
def map_non_zero(&block)
|
24
|
+
dup.map_non_zero!(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def map_non_zero!
|
28
|
+
each_non_zero do |val,row,col|
|
29
|
+
self[row,col] = yield(val, row, col)
|
30
|
+
end
|
31
|
+
|
32
|
+
return self
|
33
|
+
end
|
34
|
+
|
35
|
+
# Converts the matrix into an array
|
36
|
+
def to_a
|
37
|
+
array = []
|
38
|
+
rows.times do |row|
|
39
|
+
col_array = []
|
40
|
+
cols.times do |col|
|
41
|
+
col_array << self[row,col]
|
42
|
+
end
|
43
|
+
array << col_array
|
44
|
+
end
|
45
|
+
|
46
|
+
return array
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Lookup the type for the underlying matrix implementation
|
2
|
+
module StairCar
|
3
|
+
module UMatrixTypes
|
4
|
+
|
5
|
+
def type
|
6
|
+
return :double
|
7
|
+
end
|
8
|
+
|
9
|
+
def sparse?
|
10
|
+
@data.sparse?
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def type_class(type, sparse, initialize_values)
|
15
|
+
if sparse
|
16
|
+
base = Java::org.ujmp.parallelcolt::ParallelColtSparseDoubleMatrix2D
|
17
|
+
else
|
18
|
+
base = Java::org.ujmp.core.Matrix.factory
|
19
|
+
end
|
20
|
+
|
21
|
+
# if sparse
|
22
|
+
# base = Java::org.ujmp.core.matrix.SparseMatrix.factory
|
23
|
+
# else
|
24
|
+
# base = Java::org.ujmp.core.Matrix.factory
|
25
|
+
# end
|
26
|
+
|
27
|
+
if [:zeros, :ones, :rand, :desc, :asc].include?(initialize_values)
|
28
|
+
if [:asc, :desc].include?(initialize_values)
|
29
|
+
initialize_values = :zeros
|
30
|
+
end
|
31
|
+
|
32
|
+
if sparse && initialize_values == :zeros
|
33
|
+
initialize_values = :new
|
34
|
+
end
|
35
|
+
|
36
|
+
return Proc.new { |rows, cols| base.send(initialize_values, rows, cols) }
|
37
|
+
else
|
38
|
+
raise "Type is not valid"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../pcolt/parallelcolt-0.9.4'
|
2
|
+
require File.dirname(__FILE__) + '/../../ujmp/ujmp-complete-0.2.5'
|
3
|
+
|
4
|
+
require 'stair_car/umatrix/types'
|
5
|
+
require 'stair_car/umatrix/matrix_math'
|
6
|
+
require 'stair_car/umatrix/transforms'
|
7
|
+
require 'stair_car/umatrix/compare'
|
8
|
+
require 'stair_car/shared/iteration'
|
9
|
+
require 'stair_car/shared/inspect'
|
10
|
+
require 'stair_car/shared/indicies'
|
11
|
+
require 'stair_car/shared/init_methods'
|
12
|
+
require 'stair_car/shared/errors'
|
13
|
+
|
14
|
+
module StairCar
|
15
|
+
class UMatrix
|
16
|
+
include UMatrixTypes
|
17
|
+
# include Indicies
|
18
|
+
include UMatrixMatrixMath
|
19
|
+
include UMatrixTransforms
|
20
|
+
include UMatrixCompare
|
21
|
+
include Iteration
|
22
|
+
include Inspect
|
23
|
+
include Indicies
|
24
|
+
include InitMethods
|
25
|
+
|
26
|
+
attr_accessor :data
|
27
|
+
|
28
|
+
def initialize(rows_or_data=nil, cols=nil, type=:double, sparse=false, initialize_values=:zeros)
|
29
|
+
if rows_or_data.is_a?(Array)
|
30
|
+
klass = type_class(type, sparse, initialize_values)
|
31
|
+
|
32
|
+
# Create the matrix from an array
|
33
|
+
from_array(rows_or_data, klass)
|
34
|
+
elsif rows_or_data.is_a?(Fixnum)
|
35
|
+
raise MatrixDimensionsError, "Must specify columns and rows" unless rows_or_data && cols
|
36
|
+
klass = type_class(type, sparse, initialize_values)
|
37
|
+
if klass.is_a?(Method) || klass.is_a?(Proc)
|
38
|
+
# A factory method was returned, call to build
|
39
|
+
@data = klass.call(rows_or_data, cols)
|
40
|
+
else
|
41
|
+
# A class was returned, create new
|
42
|
+
@data = klass.new(rows_or_data, cols)
|
43
|
+
end
|
44
|
+
|
45
|
+
setup_default_values(initialize_values)
|
46
|
+
else
|
47
|
+
# Passing in data directly
|
48
|
+
@data = rows_or_data
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def setup_default_values(initialize_values)
|
53
|
+
if initialize_values == :asc
|
54
|
+
i = 0
|
55
|
+
self.map! do |val,row,col|
|
56
|
+
self[row,col] = i
|
57
|
+
i += 1
|
58
|
+
end
|
59
|
+
elsif initialize_values == :desc
|
60
|
+
i = size
|
61
|
+
self.map! do |val,row,col|
|
62
|
+
self[row,col] = i
|
63
|
+
i -= 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def shape
|
70
|
+
rows, cols = data.size
|
71
|
+
|
72
|
+
return [rows, cols]
|
73
|
+
end
|
74
|
+
|
75
|
+
def size
|
76
|
+
rows, cols = shape
|
77
|
+
return rows * cols
|
78
|
+
end
|
79
|
+
|
80
|
+
def rows
|
81
|
+
return shape[0]
|
82
|
+
end
|
83
|
+
|
84
|
+
def cols
|
85
|
+
return shape[1]
|
86
|
+
end
|
87
|
+
|
88
|
+
def [](rows, cols)
|
89
|
+
rows = convert_indicies(rows, self.rows)
|
90
|
+
cols = convert_indicies(cols, self.cols)
|
91
|
+
|
92
|
+
# Returns either the value in a cell or a subview
|
93
|
+
if rows && cols && rows.size == 1 && cols.size == 1 && rows.first.is_a?(Fixnum) && cols.first.is_a?(Fixnum)
|
94
|
+
if @data.is_a?(Java::org.ujmp.core.objectmatrix.impl.ObjectCalculationMatrix)
|
95
|
+
@data.getObject(rows.first.to_java(:int), cols.first.to_java(:int)) || 0.0
|
96
|
+
else
|
97
|
+
# From jruby we have to call this way for doubles
|
98
|
+
@data.java_send(:getObject, [Java::long, Java::long], rows.first, cols.first) || 0.0
|
99
|
+
end
|
100
|
+
else
|
101
|
+
# Get subview, also convert rows/cols to java arrays
|
102
|
+
if !rows && !cols
|
103
|
+
return self.class.new(@data)
|
104
|
+
else
|
105
|
+
if rows
|
106
|
+
return self.class.new(@data.select(Java::OrgUjmpCoreCalculation::Calculation.LINK, rows, cols))
|
107
|
+
else
|
108
|
+
# If row is nil, we need to lookup by columns directly
|
109
|
+
return self.class.new(@data.select_columns(Java::OrgUjmpCoreCalculation::Calculation.LINK, cols))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def []=(rows, cols, value)
|
116
|
+
rows = convert_indicies(rows, self.rows)
|
117
|
+
cols = convert_indicies(cols, self.cols)
|
118
|
+
|
119
|
+
# Set either the value in a cell or a subview with a matrix
|
120
|
+
if rows && cols && rows.size == 1 && cols.size == 1 && rows.first.is_a?(Fixnum) && cols.first.is_a?(Fixnum)
|
121
|
+
@data.setObject(value.to_java(:double), rows.first, cols.first)
|
122
|
+
else
|
123
|
+
subview = self[rows, cols]
|
124
|
+
|
125
|
+
# Assign a single array or a nested array
|
126
|
+
if value.is_a?(Array)
|
127
|
+
value_rows, value_cols = array_dimensions(value)
|
128
|
+
|
129
|
+
# If one dimentional, and they want to set cols
|
130
|
+
if value_rows == 1 && subview.cols == 1
|
131
|
+
# Transpose so we can place an array vertically
|
132
|
+
subview = subview.transpose
|
133
|
+
end
|
134
|
+
|
135
|
+
# Check to make sure the sizes match
|
136
|
+
if value_rows != subview.rows || value_cols != subview.cols
|
137
|
+
raise MatrixDimensionsError, "the array you are trying to assign is not the correct size"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# value = convert_value(value)
|
142
|
+
unless value[0].is_a?(Array)
|
143
|
+
value = [value]
|
144
|
+
end
|
145
|
+
|
146
|
+
value.each_with_index do |row,row_index|
|
147
|
+
row.each_with_index do |cell,col_index|
|
148
|
+
subview[row_index, col_index] = cell
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Loop through each non-zero value, pass in the value, row, column
|
155
|
+
def each_non_zero(&block)
|
156
|
+
@data.available_coordinates.each do |row, col|
|
157
|
+
val = self[row,col]
|
158
|
+
yield(val, row, col)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def dup
|
163
|
+
UMatrix.new(@data.clone)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/lib/stair_car.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'java'
|
2
|
+
require 'stair_car/pmatrix/pmatrix'
|
3
|
+
require 'stair_car/umatrix/umatrix'
|
4
|
+
|
5
|
+
module StairCar
|
6
|
+
def self.included(klass)
|
7
|
+
# Add easy access methods
|
8
|
+
PMatrix.init_method_names do |method_name, sparse, type, initialize_values|
|
9
|
+
klass.send(:define_method, method_name) do |cols, rows|
|
10
|
+
PMatrix.new(cols, rows, type, sparse, initialize_values)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_java_nested_array(array, type=:double)
|
16
|
+
if type == :double
|
17
|
+
type = java.lang.Double::TYPE
|
18
|
+
else
|
19
|
+
type = java.lang.Float::TYPE
|
20
|
+
end
|
21
|
+
|
22
|
+
rows = array.size
|
23
|
+
cols = array[0].size
|
24
|
+
|
25
|
+
java_array = java.lang.reflect.Array.newInstance(type, [rows,cols].to_java(:int))
|
26
|
+
|
27
|
+
rows.times do |row|
|
28
|
+
cols.times do |col|
|
29
|
+
java_array[row][col] = array[row][col]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
return java_array
|
34
|
+
end
|
35
|
+
end
|
Binary file
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stair_car'
|
3
|
+
|
4
|
+
describe StairCar::PMatrixMatrixMath do
|
5
|
+
before(:all) do
|
6
|
+
@a = StairCar::PMatrix.asc(5,5)
|
7
|
+
@b = StairCar::PMatrix.asc(5,5)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should add matricies' do
|
11
|
+
c = @a + @b
|
12
|
+
c[0,0].should == 2
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should add scalars' do
|
16
|
+
c = @a + 5
|
17
|
+
# Should copy
|
18
|
+
@a[0,0].should == 1
|
19
|
+
|
20
|
+
c[0,0].should == 6
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should add vectors' do
|
24
|
+
c = StairCar::PMatrix.new([[1,2,3,4,5]])
|
25
|
+
# (@a + c).should == StairCar::PMatrix.new([[2,4,6,8,10]])
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
it 'should sum all' do
|
30
|
+
matrix = StairCar::PMatrix.asc(3,3)
|
31
|
+
matrix.sum.should == 45
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should sum columns' do
|
35
|
+
matrix = StairCar::PMatrix.asc(3,5)
|
36
|
+
matrix.sum(0).should == StairCar::PMatrix.new([[18, 21, 24, 27, 30]])
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should get the max on columns or rows' do
|
40
|
+
matrix = StairCar::PMatrix.asc(3,5)
|
41
|
+
matrix.max(1).should == StairCar::PMatrix.new([[5],[10],[15]])
|
42
|
+
matrix.max(0).should == StairCar::PMatrix.new([[11, 12, 13, 14, 15]])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should get the mins on columns or rows' do
|
46
|
+
matrix = StairCar::PMatrix.asc(3,5)
|
47
|
+
matrix.min(1).should == StairCar::PMatrix.new([[1],[6],[11]])
|
48
|
+
matrix.min(0).should == StairCar::PMatrix.new([[1, 2, 3, 4, 5]])
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return the mean on each dimension" do
|
52
|
+
matrix = StairCar::PMatrix.asc(3,5)
|
53
|
+
matrix.mean.should == 8.0
|
54
|
+
matrix.mean(1).should == StairCar::PMatrix.new([[3],[8],[13]])
|
55
|
+
matrix.mean(0).should == StairCar::PMatrix.new([[6, 7, 8, 9, 10]])
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return the variance" do
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return the standard deviation" do
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stair_car'
|
3
|
+
|
4
|
+
describe StairCar::PMatrix do
|
5
|
+
it "should initialize" do
|
6
|
+
matrix = StairCar::PMatrix.zeros(5,4)
|
7
|
+
matrix.cols.should == 4
|
8
|
+
matrix.rows.should == 5
|
9
|
+
matrix.size.should == 20
|
10
|
+
|
11
|
+
matrix = StairCar::PMatrix.spzeros(5,4)
|
12
|
+
matrix.size.should == 20
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should initialize with values" do
|
16
|
+
matrix1 = StairCar::PMatrix.new([[3,8,13]])
|
17
|
+
matrix1[0,0].should == 3
|
18
|
+
matrix1[0,2].should == 13
|
19
|
+
|
20
|
+
matrix2 = StairCar::PMatrix.new([[3],[8],[13]])
|
21
|
+
matrix2[0,0].should == 3
|
22
|
+
matrix2[2,0].should == 13
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set and get" do
|
26
|
+
matrix = StairCar::PMatrix.zeros(3,4)
|
27
|
+
matrix[0,0] = 5
|
28
|
+
matrix[0,0].should == 5
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should assign a matrix to a subview' do
|
32
|
+
matrix = StairCar::PMatrix.asc(3,3)
|
33
|
+
s = matrix[0,nil]
|
34
|
+
matrix[1,nil] = s
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should set via arrays" do
|
38
|
+
matrix = StairCar::PMatrix.zeros(3,4)
|
39
|
+
matrix[0,nil] = [1,2,3,4]
|
40
|
+
matrix[0,nil].should == StairCar::PMatrix.new([1,2,3,4])
|
41
|
+
matrix[nil,0] = [1,2,3]
|
42
|
+
matrix[nil,nil] = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should raise an error when trying to assign an array with invalid dimensions" do
|
46
|
+
matrix = StairCar::PMatrix.zeros(3,4)
|
47
|
+
|
48
|
+
lambda {
|
49
|
+
matrix[0,nil] = [1,2,3,4,5,6]
|
50
|
+
}.should raise_error(StairCar::MatrixDimensionsError)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should get and set with negative values" do
|
54
|
+
matrix = StairCar::PMatrix.zeros(5,4)
|
55
|
+
matrix[4,3] = 5
|
56
|
+
matrix[-1,-1].should == 5
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow you to setup ones" do
|
60
|
+
matrix = StairCar::PMatrix.ones(5,5)
|
61
|
+
matrix[2,2].should == 1
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
it 'should compare matrix values' do
|
66
|
+
matrix1 = StairCar::PMatrix.asc(3,3)
|
67
|
+
matrix2 = StairCar::PMatrix.asc(3,3)
|
68
|
+
matrix3 = StairCar::PMatrix.zeros(3,3)
|
69
|
+
|
70
|
+
matrix1.should == matrix2
|
71
|
+
matrix1.should_not == matrix3
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should allow you to set with an array" do
|
75
|
+
matrix = StairCar::PMatrix.zeros(2,2)
|
76
|
+
matrix[nil,nil] = [[1,2],[3,4]]
|
77
|
+
matrix[0,0].should == 1.0
|
78
|
+
matrix[1,1].should == 4.0
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should allow you to initialize by an array" do
|
82
|
+
matrix = StairCar::PMatrix.new([[1,2],[3,4]])
|
83
|
+
matrix[0,0].should == 1.0
|
84
|
+
matrix[1,1].should == 4.0
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "dimensions" do
|
88
|
+
before(:all) do
|
89
|
+
@matrix = StairCar::PMatrix.zeros(3,2)
|
90
|
+
end
|
91
|
+
it "should return its shape" do
|
92
|
+
@matrix.shape.should == [3,2]
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should return the rows" do
|
96
|
+
@matrix.rows.should == 3
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should return the cols" do
|
100
|
+
@matrix.cols.should == 2
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stair_car'
|
3
|
+
|
4
|
+
describe StairCar::PMatrixTransforms do
|
5
|
+
it "should transpose" do
|
6
|
+
matrix = StairCar::PMatrix.asc(3,4)
|
7
|
+
(~matrix).should_not == matrix
|
8
|
+
(~~matrix).should == matrix
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should invert' do
|
12
|
+
matrix = StairCar::PMatrix.new([[4,3],[3,2]])
|
13
|
+
matrix.inv.should == StairCar::PMatrix.new([[-2, 3], [3, -4]])
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should raise an error when it fails to invert' do
|
17
|
+
matrix = StairCar::PMatrix.asc(3,3)
|
18
|
+
lambda {
|
19
|
+
matrix.inv
|
20
|
+
}.should raise_error(StairCar::InverseMatrixIsSignular)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should map and map_non_zero" do
|
24
|
+
matrix = StairCar::PMatrix.zeros(2,3)
|
25
|
+
matrix[0,0] = 5
|
26
|
+
matrix[1,2] = 10
|
27
|
+
mapped_matrix = matrix.map {|v| v * 2 }
|
28
|
+
mapped_matrix[0,0].should == 10
|
29
|
+
mapped_matrix[1,2].should == 20
|
30
|
+
mapped_matrix[0,1].should == 0
|
31
|
+
|
32
|
+
calls = 0
|
33
|
+
matrix.map_non_zero! {|v,row,col| calls += 1; v + 2 }
|
34
|
+
calls.should == 2
|
35
|
+
matrix[0,0].should == 7
|
36
|
+
matrix[1,2].should == 12
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should convert back to a ruby array" do
|
40
|
+
matrix = StairCar::PMatrix.asc(3,3)
|
41
|
+
matrix.to_a.should == [[1,2,3],[4,5,6],[7,8,9]]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|