stair_car 0.0.1
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/.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
|