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
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
.rvmrc
|
19
|
+
.idea
|
20
|
+
*.DS_Store
|
21
|
+
lib/.DS_Store
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in pmatrix.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem 'guard'
|
9
|
+
gem 'rb-inotify', :require => false
|
10
|
+
gem 'rb-fsevent', :require => false
|
11
|
+
gem 'rb-fchange', :require => false
|
12
|
+
gem 'guard-rspec'
|
13
|
+
gem 'terminal-notifier-guard'
|
14
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
# watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec" }
|
8
|
+
watch('spec/spec_helper.rb') { "spec" }
|
9
|
+
|
10
|
+
# # Rails example
|
11
|
+
# watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
+
# watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
13
|
+
# watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
14
|
+
# watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
15
|
+
# watch('config/routes.rb') { "spec/routing" }
|
16
|
+
# watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
17
|
+
end
|
18
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Ryan Stout
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
# StairCar
|
2
|
+
|
3
|
+
StairCar is a matlab or numpy like matrix library gem for jruby. It provides several matrix classes that wrap different Java based matrix libraries in a simple ruby interface. It overloads ruby operators to provide a matlab like functionality.
|
4
|
+
|
5
|
+
# Goals
|
6
|
+
|
7
|
+
StairCar should be:
|
8
|
+
|
9
|
+
- Rubyish (object oriented, use operator overloading for math operations)
|
10
|
+
- Fast (use optimized underlying storage/algebra systems, use BLAS where available)
|
11
|
+
- Unified (It should provide a standard interface across multiple internal implementations)
|
12
|
+
|
13
|
+
StairCar is geared towards two dimensional matrices and treats vectors as a 1 by M or N x 1 matrix. StairCar currently does not support >2 dimensional matrices. It also currently only supports double and float matrices. Though support for integer and boolean matrices is planned.
|
14
|
+
|
15
|
+
## Features
|
16
|
+
|
17
|
+
- Dense and Sparse matrices (with 2^64 elements)
|
18
|
+
- Ability to efficiently iterate on non-zero elements in sparse matrices
|
19
|
+
- Subviews (that reference the original matrix)
|
20
|
+
- Matrix, vector, and scalar add, sub, mul, div, and matrix multiply. (In any combination)
|
21
|
+
- Easy iteration on rows, cols, or elements
|
22
|
+
- Element wise comparison >,>=,<,<= that returns a 1/0 matrix
|
23
|
+
- Mathematical operations on the full matrix, rows, or cols (currently only std, variance, mean, max, min)
|
24
|
+
- Shortcuts for making matricies (zeros, spzeros, rand, ones, asc, desc, etc...)
|
25
|
+
- .dup to copy
|
26
|
+
- == to compare values
|
27
|
+
- A good clean inspect
|
28
|
+
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
Once you have required stair_car, you will have access to two matrix classes (currently): PMatrix and UMatrix. PMatrix wraps the pcolt library and is good for sparse matrices. UMatrix wraps the ujmp library, which its self wraps many java libraries. Currently UMatrix support is still a work in progress.
|
33
|
+
|
34
|
+
### Basic Usage
|
35
|
+
|
36
|
+
To start, include the StairCar module into your current class
|
37
|
+
|
38
|
+
include StairCar
|
39
|
+
|
40
|
+
This provides you with many shortcut methods to make matricies:
|
41
|
+
|
42
|
+
Dense: zeros, ones, rand, asc, desc
|
43
|
+
Sparse: spzeros, spones, sprand, spasc, spdesc
|
44
|
+
|
45
|
+
m = asc(3,3)
|
46
|
+
=> <#PMatrix(double) 3x3 dense>
|
47
|
+
1 2 3
|
48
|
+
4 5 6
|
49
|
+
7 8 9
|
50
|
+
|
51
|
+
### Get elements
|
52
|
+
|
53
|
+
You can get any element by passing in its row and column:
|
54
|
+
|
55
|
+
m[0,1]
|
56
|
+
=> 2
|
57
|
+
|
58
|
+
### Subviews
|
59
|
+
|
60
|
+
StairCar supports many options to generate subviews. You can pass in the following:
|
61
|
+
|
62
|
+
- Arrays - Selects a row/column, treating the integer in the array as a row or column index.
|
63
|
+
- Ranges - Selects each row/column index within the range
|
64
|
+
- nil - Selects the whole row/column
|
65
|
+
- You can also pass in a combination of arrays and ranges.
|
66
|
+
|
67
|
+
For example:
|
68
|
+
|
69
|
+
m[0..1,nil]
|
70
|
+
=> <#PMatrix() 2x3 dense>
|
71
|
+
1 2 3
|
72
|
+
4 5 6
|
73
|
+
|
74
|
+
### Assignment
|
75
|
+
|
76
|
+
You can assign a single element:
|
77
|
+
|
78
|
+
m[0,1] = 22.5
|
79
|
+
|
80
|
+
m
|
81
|
+
=> <#PMatrix(double) 3x3 dense>
|
82
|
+
1 22.5 3
|
83
|
+
4 5 6
|
84
|
+
7 8 9
|
85
|
+
|
86
|
+
You can assign a scalar to every value in a subview
|
87
|
+
|
88
|
+
# Assign a row (row 0, all columns)
|
89
|
+
m[0,nil] = 2
|
90
|
+
|
91
|
+
=> <#PMatrix(double) 3x3 dense>
|
92
|
+
2 2 2
|
93
|
+
4 5 6
|
94
|
+
7 8 9
|
95
|
+
|
96
|
+
You can assign an array or other matrix to a subview
|
97
|
+
|
98
|
+
# Assign an array to a row
|
99
|
+
m[0..1,nil] = [[1,2,3],[4,5,6]]
|
100
|
+
|
101
|
+
=> <#PMatrix(double) 3x3 dense>
|
102
|
+
1 2 3
|
103
|
+
4 5 6
|
104
|
+
7 8 9
|
105
|
+
|
106
|
+
# Multiple row or column subviews
|
107
|
+
m[[1,2],2]
|
108
|
+
=> <#PMatrix() 2x1 dense>
|
109
|
+
6
|
110
|
+
9
|
111
|
+
|
112
|
+
### Math
|
113
|
+
|
114
|
+
Math is simple, just use the standard +,-,/ * does matrix multiplication and ** does element wise multiplication.
|
115
|
+
|
116
|
+
a = asc(3,3)
|
117
|
+
b = asc(3,3)
|
118
|
+
|
119
|
+
a + b
|
120
|
+
=> <#PMatrix(double) 3x3 dense>
|
121
|
+
2 4 6
|
122
|
+
8 10 12
|
123
|
+
14 16 18
|
124
|
+
|
125
|
+
a * b
|
126
|
+
=> <#PMatrix(double) 3x3 dense>
|
127
|
+
30 36 42
|
128
|
+
66 81 96
|
129
|
+
102 126 150
|
130
|
+
|
131
|
+
a ** b
|
132
|
+
=> <#PMatrix(double) 3x3 dense>
|
133
|
+
1 4 9
|
134
|
+
16 25 36
|
135
|
+
49 64 81
|
136
|
+
|
137
|
+
### Transpose and inverse
|
138
|
+
|
139
|
+
Transpose can be done with either matrix.transpose or ~matrix
|
140
|
+
|
141
|
+
### Stats
|
142
|
+
|
143
|
+
All stats operations can operate on the whole matrix, or just the columns or the rows. Just pass in a dimension to specify cols or rows (rows = 0, cols = 1)
|
144
|
+
|
145
|
+
m = asc(3,3)
|
146
|
+
m.sum
|
147
|
+
=> 45.0
|
148
|
+
|
149
|
+
m.sum(0)
|
150
|
+
=> <#PMatrix(double) 1x3 dense>
|
151
|
+
12 15 18
|
152
|
+
|
153
|
+
m.sum(1)
|
154
|
+
=> <#PMatrix(double) 3x1 dense>
|
155
|
+
6
|
156
|
+
15
|
157
|
+
24
|
158
|
+
|
159
|
+
Supported operations
|
160
|
+
|
161
|
+
- sum
|
162
|
+
- max
|
163
|
+
- min
|
164
|
+
- mean
|
165
|
+
- variance
|
166
|
+
- std
|
167
|
+
|
168
|
+
### Iteration
|
169
|
+
|
170
|
+
Matrices support the standard ruby each, each_with_index, and map operations. However each passes in a value, row, col instead of just a value.
|
171
|
+
|
172
|
+
It also supports each_column and each_row
|
173
|
+
|
174
|
+
You can also iterate or map on non-zero elements, which makes mapping sparse matrices much more efficient. Use #each_non_zero, #map_non_zero, or #map_non_zero! Using ! on the end of map or map_non_zero means all updates will happen to the original matrix, thus saving memory.
|
175
|
+
|
176
|
+
m = spzeros(5,5)
|
177
|
+
=> <#PMatrix(double) 5x5 sparse>
|
178
|
+
0 0 0 0 0
|
179
|
+
0 0 0 0 0
|
180
|
+
0 0 0 0 0
|
181
|
+
0 0 0 0 0
|
182
|
+
0 0 0 0 0
|
183
|
+
|
184
|
+
m[0,2] = 5
|
185
|
+
m[3,4] = 10
|
186
|
+
|
187
|
+
m
|
188
|
+
=> <#PMatrix(double) 5x5 sparse>
|
189
|
+
0 0 5 0 0
|
190
|
+
0 0 0 0 0
|
191
|
+
0 0 0 0 0
|
192
|
+
0 0 0 0 10
|
193
|
+
0 0 0 0 0
|
194
|
+
|
195
|
+
m.map_non_zero! {|value,row,col| value * 2 }
|
196
|
+
=> <#PMatrix(double) 5x5 sparse>
|
197
|
+
0 0 10 0 0
|
198
|
+
0 0 0 0 0
|
199
|
+
0 0 0 0 0
|
200
|
+
0 0 0 0 20
|
201
|
+
0 0 0 0 0
|
202
|
+
|
203
|
+
## Planned Features
|
204
|
+
|
205
|
+
- JBLAS support
|
206
|
+
- MRI support (perhaps with NMatrix)
|
207
|
+
- More statistical features
|
208
|
+
|
209
|
+
|
210
|
+
## Installation
|
211
|
+
|
212
|
+
Add this line to your application's Gemfile:
|
213
|
+
|
214
|
+
gem 'stair_car'
|
215
|
+
|
216
|
+
And then execute:
|
217
|
+
|
218
|
+
$ bundle
|
219
|
+
|
220
|
+
Or install it yourself as:
|
221
|
+
|
222
|
+
$ gem install stair_car
|
223
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../matlab/matlabcontrol-4.0.0'
|
2
|
+
class MatlabInterface
|
3
|
+
def initialize
|
4
|
+
factory = Java::Matlabcontrol::MatlabProxyFactory.new
|
5
|
+
@proxy = factory.proxy
|
6
|
+
@processor = Java::matlabcontrol.extensions.MatlabTypeConverter.new(@proxy)
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'stair_car/types'
|
2
|
+
require 'stair_car/inspect'
|
3
|
+
require 'stair_car/indicies'
|
4
|
+
require 'stair_car/iteration'
|
5
|
+
require 'stair_car/matrix_math'
|
6
|
+
require 'stair_car/transforms'
|
7
|
+
require 'stair_car/compare'
|
8
|
+
|
9
|
+
class MMatrix
|
10
|
+
# include Types
|
11
|
+
# include Inspect
|
12
|
+
# include Indicies
|
13
|
+
# include Iteration
|
14
|
+
# include MatrixMath
|
15
|
+
# include Transforms
|
16
|
+
# include Compare
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@@mi ||= MatlabInterface.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def [](rows, cols)
|
23
|
+
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module StairCar
|
2
|
+
module PMatrixCompare
|
3
|
+
def >(val)
|
4
|
+
map {|v| (v > val) ? 1 : 0 }
|
5
|
+
end
|
6
|
+
|
7
|
+
def >=(val)
|
8
|
+
map {|v| (v >= val) ? 1 : 0 }
|
9
|
+
end
|
10
|
+
|
11
|
+
def <(val)
|
12
|
+
map {|v| (v < val) ? 1 : 0 }
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=(val)
|
16
|
+
map {|v| (v <= val) ? 1 : 0 }
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(matrix)
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def any?
|
24
|
+
@data.cardinality > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# Compares this matrix to another to see if they are the same (in values)
|
29
|
+
def ==(matrix2)
|
30
|
+
self.data.equals(matrix2.data)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module StairCar
|
2
|
+
module PMatrixMatrixMath
|
3
|
+
class MatrixMathError < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
def perform(val, &block)
|
7
|
+
result = @data.copy
|
8
|
+
if val.is_a?(PMatrix)
|
9
|
+
if rows == val.rows && cols == val.cols
|
10
|
+
# Another matrix of the same size
|
11
|
+
result = result.assign(val.data, &block)
|
12
|
+
elsif rows == val.rows && val.cols == 1
|
13
|
+
# Vector on column (vertical)
|
14
|
+
PMatrix.new(result).each_column do |row|
|
15
|
+
row.data.assign(val.data, &block)
|
16
|
+
end
|
17
|
+
elsif cols == val.cols && val.rows == 1
|
18
|
+
# Vector on rows (horizontal)
|
19
|
+
PMatrix.new(result).each_row do |col|
|
20
|
+
col.data.assign(val.data, &block)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
# Incorrect size
|
24
|
+
raise MatrixMathError, "matrix dimensions incorrect"
|
25
|
+
end
|
26
|
+
else
|
27
|
+
# Passed in a number
|
28
|
+
perform_on_val = Proc.new do |cell_value|
|
29
|
+
yield(cell_value, val)
|
30
|
+
end
|
31
|
+
|
32
|
+
result.assign(perform_on_val)
|
33
|
+
end
|
34
|
+
|
35
|
+
return PMatrix.new(result)
|
36
|
+
end
|
37
|
+
|
38
|
+
def +(val)
|
39
|
+
perform(val) { |a,b| a + b }
|
40
|
+
# perform(val, Java::cern.jet.math.tdouble.DoubleFunctions.plus)
|
41
|
+
end
|
42
|
+
|
43
|
+
def -(val)
|
44
|
+
perform(val) { |a,b| a - b }
|
45
|
+
end
|
46
|
+
|
47
|
+
def **(val)
|
48
|
+
perform(val) { |a,b| a * b }
|
49
|
+
end
|
50
|
+
|
51
|
+
def /(val)
|
52
|
+
perform(val) { |a,b| a / b }
|
53
|
+
end
|
54
|
+
|
55
|
+
def *(val)
|
56
|
+
n = self.rows
|
57
|
+
m = self.cols
|
58
|
+
|
59
|
+
p = val.rows
|
60
|
+
q = val.cols
|
61
|
+
|
62
|
+
if m != p
|
63
|
+
raise MatrixMathError, "matricies can not be multiplied"
|
64
|
+
end
|
65
|
+
|
66
|
+
# Build a like matrix to receive
|
67
|
+
c = @data.like(n, q)
|
68
|
+
|
69
|
+
@data.z_mult(val.data, c)
|
70
|
+
|
71
|
+
return PMatrix.new(c)
|
72
|
+
end
|
73
|
+
|
74
|
+
def sum(dimension=nil)
|
75
|
+
if dimension == 0
|
76
|
+
# Sum rows
|
77
|
+
return PMatrix.ones(1, rows) * self
|
78
|
+
elsif dimension == 1
|
79
|
+
# Sum cols
|
80
|
+
return self * PMatrix.ones(cols, 1)
|
81
|
+
else
|
82
|
+
return @data.z_sum
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def max(dimension=nil)
|
87
|
+
if dimension
|
88
|
+
value = aggrate_on_dimension(:max, dimension)
|
89
|
+
else
|
90
|
+
value, row, col = @data.max_location
|
91
|
+
end
|
92
|
+
|
93
|
+
return value
|
94
|
+
end
|
95
|
+
|
96
|
+
def min(dimension=nil)
|
97
|
+
if dimension
|
98
|
+
value = aggrate_on_dimension(:min, dimension)
|
99
|
+
else
|
100
|
+
value, row, col = @data.min_location
|
101
|
+
end
|
102
|
+
|
103
|
+
return value
|
104
|
+
end
|
105
|
+
|
106
|
+
def mean(dimension=nil)
|
107
|
+
if dimension
|
108
|
+
value = aggrate_on_dimension(:mean, dimension)
|
109
|
+
else
|
110
|
+
value = self.sum / self.size
|
111
|
+
end
|
112
|
+
|
113
|
+
return value
|
114
|
+
end
|
115
|
+
|
116
|
+
def variance(dimension=nil, sample=false)
|
117
|
+
if dimension
|
118
|
+
value = aggrate_on_dimension(:variance, dimension, sample)
|
119
|
+
else
|
120
|
+
mean = self.mean
|
121
|
+
total = 0
|
122
|
+
self.each_non_zero do |v|
|
123
|
+
total += (mean - v) ** 2
|
124
|
+
end
|
125
|
+
|
126
|
+
if sample
|
127
|
+
value = total / (self.size - 1)
|
128
|
+
else
|
129
|
+
value = total / self.size
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
return value
|
134
|
+
end
|
135
|
+
|
136
|
+
def std(dimension=nil, sample=false)
|
137
|
+
if dimension
|
138
|
+
value = aggrate_on_dimension(:variance, dimension, sample)
|
139
|
+
else
|
140
|
+
value = Math.sqrt(self.variance(dimension, sample))
|
141
|
+
end
|
142
|
+
|
143
|
+
return value
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
def aggrate_on_dimension(method_name, dimension, *args)
|
148
|
+
if dimension == 1
|
149
|
+
# Get the per row
|
150
|
+
vals = PMatrix.new(@data.like(rows, 1))
|
151
|
+
|
152
|
+
self.each_row do |row, row_number|
|
153
|
+
vals[row_number,0] = row.send(method_name, nil, *args).to_f
|
154
|
+
end
|
155
|
+
|
156
|
+
return vals
|
157
|
+
elsif dimension == 0
|
158
|
+
# Get the per row
|
159
|
+
vals = PMatrix.new(@data.like(1, cols))
|
160
|
+
|
161
|
+
self.each_column do |col, col_number|
|
162
|
+
vals[0,col_number] = col.send(method_name, nil, *args).to_f
|
163
|
+
end
|
164
|
+
|
165
|
+
return vals
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|