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.
Files changed (46) hide show
  1. data/.gitignore +21 -0
  2. data/Gemfile +14 -0
  3. data/Guardfile +18 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +223 -0
  6. data/Rakefile +1 -0
  7. data/lib/matlab/matlabcontrol-4.0.0.jar +0 -0
  8. data/lib/pcolt/lib/arpack-combo.jar +0 -0
  9. data/lib/pcolt/lib/csparsej.jar +0 -0
  10. data/lib/pcolt/lib/jplasma.jar +0 -0
  11. data/lib/pcolt/lib/jtransforms.jar +0 -0
  12. data/lib/pcolt/lib/junit.jar +0 -0
  13. data/lib/pcolt/lib/netlib-java.jar +0 -0
  14. data/lib/pcolt/lib/optimization.jar +0 -0
  15. data/lib/pcolt/parallelcolt-0.9.4.jar +0 -0
  16. data/lib/stair_car/mmatrix/matlab_interface.rb +9 -0
  17. data/lib/stair_car/mmatrix/mmatrix.rb +26 -0
  18. data/lib/stair_car/pmatrix/compare.rb +34 -0
  19. data/lib/stair_car/pmatrix/matrix_math.rb +169 -0
  20. data/lib/stair_car/pmatrix/pmatrix.rb +151 -0
  21. data/lib/stair_car/pmatrix/transforms.rb +74 -0
  22. data/lib/stair_car/pmatrix/types.rb +106 -0
  23. data/lib/stair_car/shared/errors.rb +7 -0
  24. data/lib/stair_car/shared/indicies.rb +33 -0
  25. data/lib/stair_car/shared/init_methods.rb +56 -0
  26. data/lib/stair_car/shared/inspect.rb +113 -0
  27. data/lib/stair_car/shared/iteration.rb +32 -0
  28. data/lib/stair_car/umatrix/compare.rb +34 -0
  29. data/lib/stair_car/umatrix/matrix_math.rb +190 -0
  30. data/lib/stair_car/umatrix/transforms.rb +49 -0
  31. data/lib/stair_car/umatrix/types.rb +42 -0
  32. data/lib/stair_car/umatrix/umatrix.rb +166 -0
  33. data/lib/stair_car.rb +35 -0
  34. data/lib/ujmp/ujmp-complete-0.2.5.jar +0 -0
  35. data/spec/pmatrix/matrix_math_spec.rb +65 -0
  36. data/spec/pmatrix/pmatrix_spec.rb +103 -0
  37. data/spec/pmatrix/transforms_spec.rb +44 -0
  38. data/spec/shared/indicies_spec.rb +52 -0
  39. data/spec/shared/inspect_spec.rb +23 -0
  40. data/spec/shared/iteration_spec.rb +17 -0
  41. data/spec/spec_helper.rb +5 -0
  42. data/spec/umatrix/matrix_math_spec.rb +68 -0
  43. data/spec/umatrix/transform_spec.rb +32 -0
  44. data/spec/umatrix/umatrix_spec.rb +104 -0
  45. data/stair_car.gemspec +19 -0
  46. 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