runarray 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/LICENSE +11 -0
- data/README +36 -0
- data/Rakefile +149 -0
- data/lib/runarray/auto.rb +8 -0
- data/lib/runarray/narray.rb +1001 -0
- data/lib/runarray.rb +2 -0
- data/spec/runarray/narray_spec.rb +367 -0
- metadata +66 -0
data/lib/runarray.rb
ADDED
@@ -0,0 +1,367 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
require 'narray'
|
4
|
+
require 'runarray/narray'
|
5
|
+
|
6
|
+
class Object
|
7
|
+
alias_method :old_must_equal, :must_equal
|
8
|
+
|
9
|
+
def must_equal(*args)
|
10
|
+
if self.is_a? Runarray::NArray
|
11
|
+
other = args.first
|
12
|
+
self.each_with_index do |v,i|
|
13
|
+
v.old_must_equal other[i]
|
14
|
+
end
|
15
|
+
else
|
16
|
+
self.old_must_equal(*args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
class MimicNArrayUsageSpec < MiniTest::Spec
|
23
|
+
|
24
|
+
it 'initializes floats' do
|
25
|
+
na = NArray.float(10)
|
26
|
+
runa = Runarray::NArray.float(10)
|
27
|
+
runa.must_equal na
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
class RunarrayNArrayUnitSpec < MiniTest::Spec
|
33
|
+
include Runarray
|
34
|
+
|
35
|
+
def initialize(*args)
|
36
|
+
super(*args)
|
37
|
+
@klass = NArray
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'can be created with no arguments' do
|
41
|
+
@klass = NArray
|
42
|
+
obj1 = @klass.new
|
43
|
+
obj1.size.must_equal 0
|
44
|
+
obj1.class.must_equal @klass
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'can be created given a desired size' do
|
48
|
+
size = 10
|
49
|
+
obj2 = @klass.new(size)
|
50
|
+
obj2.size.must_equal size
|
51
|
+
obj2.class.must_equal @klass
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'can be created given an array' do
|
55
|
+
obj3 = @klass.new([1.0,2.0,3.0])
|
56
|
+
obj3.size.must_equal 3
|
57
|
+
obj3.class.must_equal @klass
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'will cast with prep and []' do
|
61
|
+
obj4 = @klass.new([0.0,2.0,5.0])
|
62
|
+
obj5 = @klass.prep([0,2,5]) # should be converted into floats
|
63
|
+
obj6 = @klass[0,2,5] # should be converted into floats
|
64
|
+
obj4.each_index do |i|
|
65
|
+
obj5[i].class.must_equal obj4[i].class # "prep converts to floats"
|
66
|
+
obj6[i].class.must_equal obj4[i].class # "Class[] -> prep"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'will NOT cast values with new' do
|
71
|
+
obj4 = @klass.new([0.0,2.0,5.0])
|
72
|
+
obj5 = @klass.prep([0,2,5]) # should be converted into floats
|
73
|
+
obj6 = @klass[0,2,5] # should be converted into floats
|
74
|
+
obj7 = @klass.new([0,2,5])
|
75
|
+
obj5.must_equal obj4
|
76
|
+
obj6.must_equal obj4
|
77
|
+
obj4.each_index do |i|
|
78
|
+
obj7[i].class.wont_equal obj4[i].class # "w/o prep class stays int"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'will call itself equal to another object if all vals equal' do
|
83
|
+
obj4 = @klass.new([0.0,2.0,5.0])
|
84
|
+
obj4.must_equal [0.0,2.0,5.0] # "arrays and objs may be equal"
|
85
|
+
obj4.must_equal [0,2,5] # even if the types arr different, but equal val"
|
86
|
+
|
87
|
+
obj8 = @klass[0,2,5]
|
88
|
+
obj9 = @klass.new(obj8)
|
89
|
+
obj9.must_equal obj8 # "new from #{@klass} object"
|
90
|
+
obj9.class.must_equal obj8.class
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'can do division' do
|
94
|
+
x = NArray[8,4,2]
|
95
|
+
y = NArray[4,2,1]
|
96
|
+
(x / 2).must_equal NArray[4,2,1]
|
97
|
+
vec_by_vec = NArray[2,2,2]
|
98
|
+
(x / y).must_equal vec_by_vec
|
99
|
+
x /= y
|
100
|
+
x.must_equal vec_by_vec
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'can do addition' do
|
104
|
+
x = NArray[8,4,2]
|
105
|
+
y = NArray[4,2,1]
|
106
|
+
vec_by_vec = NArray[12,6,3]
|
107
|
+
(x + y).must_equal vec_by_vec
|
108
|
+
(x + 2).must_equal NArray[10,6,4]
|
109
|
+
x += y
|
110
|
+
x.must_equal vec_by_vec
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'can do multiplication' do
|
114
|
+
x = NArray[8,4,2]
|
115
|
+
y = NArray[4,2,1]
|
116
|
+
vec_by_vec = NArray[32,8,2]
|
117
|
+
(x * y).must_equal vec_by_vec
|
118
|
+
(x * 2).must_equal NArray[16,8,4]
|
119
|
+
x *= y
|
120
|
+
x.must_equal vec_by_vec
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'can do subtraction' do
|
124
|
+
x = NArray[8,4,2]
|
125
|
+
y = NArray[4,2,1]
|
126
|
+
vec_by_vec = NArray[4,2,1]
|
127
|
+
(x - y).must_equal vec_by_vec
|
128
|
+
(x - 2).must_equal NArray[6,2,0]
|
129
|
+
x -= y
|
130
|
+
x.must_equal vec_by_vec
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'can calculate orders' do
|
134
|
+
x = NArray[0.05, 0.5, 0.0009, 0.05, 0.5]
|
135
|
+
x.order.must_equal [2,0,3,1,4]
|
136
|
+
end
|
137
|
+
|
138
|
+
def _inc_x(x,y,xexp, exp,mz_start,mz_end,inc,bl,type)
|
139
|
+
(xvec, answ) = x.inc_x(y,mz_start,mz_end,inc,bl,type)
|
140
|
+
xvec == xexp and answ.class == x.class and answ == exp
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'works for _inc_x (private)' do
|
144
|
+
|
145
|
+
bl = 33
|
146
|
+
x = NArray.new([300, 301, 302, 304, 304, 304.2, 305, 306, 307.6])
|
147
|
+
y = NArray.new([10, 20, 30, 50 , 55, 54, 70, 80, 90])
|
148
|
+
xexp = (300..310).to_a
|
149
|
+
exp = [10, 20, 30, bl, 159, 70, 80, bl, 90, bl, bl]
|
150
|
+
_inc_x(x,y,xexp,exp,300,310,1,bl,"sum").must_equal true
|
151
|
+
|
152
|
+
bl = 33
|
153
|
+
x = NArray.new([300, 301, 302, 304, 304, 304.2, 305, 306, 307.6])
|
154
|
+
y = NArray.new([10, 20, 30, 50 , 55, 54, 70, 80, 90])
|
155
|
+
xexp = (300..310).to_a
|
156
|
+
exp = [10, 20, 30, bl, 55, 70, 80, bl, 90, bl, bl]
|
157
|
+
_inc_x(x,y,xexp,exp,300,310, 1, bl, "max" ).must_equal true
|
158
|
+
|
159
|
+
bl = 15
|
160
|
+
x = NArray.new([300, 301, 302, 304, 304, 304.2, 305, 306, 307.6])
|
161
|
+
y = NArray.new([10, 20, 30, 50 , 55, 54, 70, 80, 90])
|
162
|
+
xexp = (300..310).to_a
|
163
|
+
exp = [bl, 20, 30, bl, 55, 70, 80, bl, 90, bl, bl]
|
164
|
+
_inc_x(x,y,xexp,exp, 300, 310, 1, bl, "maxb" ).must_equal true
|
165
|
+
|
166
|
+
bl = 33
|
167
|
+
x = NArray.new([300, 301, 302, 304, 304, 304.2, 305, 306, 307.6])
|
168
|
+
y = NArray.new([10, 20, 30, 50 , 55, 54, 70, 80, 90])
|
169
|
+
xexp = (300..310).to_a
|
170
|
+
exp = [10, 20, 30, bl, 54, 70, 80, bl, 90, bl, bl]
|
171
|
+
_inc_x(x,y,xexp,exp, 300, 310, 1, bl, "high" ).must_equal true
|
172
|
+
|
173
|
+
bl = 33
|
174
|
+
x = NArray.new([300, 301, 302, 304, 304, 304.2, 305, 306, 307.6])
|
175
|
+
y = NArray.new([10, 20, 30, 50 , 62, 68, 70, 80, 90])
|
176
|
+
xexp = (300..310).to_a
|
177
|
+
exp = [10, 20, 30, bl, 60, 70, 80, bl, 90, bl, bl]
|
178
|
+
_inc_x(x,y,xexp,exp, 300, 310, 1, bl, "avg" ).must_equal true
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'uses index notation' do
|
183
|
+
obj1 = NArray.new(10)
|
184
|
+
obj1[0].nil?.must_equal true
|
185
|
+
obj1[0] = 1
|
186
|
+
obj1[0].must_equal 1
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'can calculate Pearsons R' do
|
190
|
+
x = NArray.new([0,1,2,3,4,5,6,7,8,9,10])
|
191
|
+
y = NArray.new([3,4,5,6,9,6,5,4,3,4,5])
|
192
|
+
x.pearsons_r(y).must_be_close_to(-0.0709326902131908, 0.000000000001)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'can calculate rsq slope and intercept' do
|
196
|
+
obj1 = NArray[0,2,5,5]
|
197
|
+
obj2 = NArray[1,3,4,7]
|
198
|
+
rsq, slope, inter = obj1.rsq_slope_intercept(obj2)
|
199
|
+
rsq.must_be_close_to(0.758519, 0.000001)
|
200
|
+
slope.must_be_close_to(0.888888888, 0.000001)
|
201
|
+
inter.must_be_close_to(1.083333333, 0.000001)
|
202
|
+
|
203
|
+
obj3 = NArray[1,3]
|
204
|
+
obj4 = NArray[2,4]
|
205
|
+
rsq, slope, inter = obj3.rsq_slope_intercept(obj4)
|
206
|
+
[rsq, slope, inter].each {|v| v.must_equal 1.0 }
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
xit 'can find residuals from least squares' do
|
211
|
+
obj1 = NArray[0,2,5,5]
|
212
|
+
obj2 = NArray[1,3,4,7]
|
213
|
+
out = obj1.residuals_from_least_squares(obj2)
|
214
|
+
out.size.must_equal 4
|
215
|
+
# frozen
|
216
|
+
[-0.141112436470222, 0.235187394117037, -2.58706133528741, 2.49298637764059].zip(out) do |exp, ans|
|
217
|
+
ans.must_be_close_to(exp, 0.0000000001)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'can find sample stats (mean and stdev)' do
|
222
|
+
obj1 = NArray[0,2,5,5,6,7]
|
223
|
+
mean, std_dev = obj1.sample_stats
|
224
|
+
mean.must_be_close_to(4.166666, 0.00001)
|
225
|
+
std_dev.must_be_close_to(2.639444, 0.00001)
|
226
|
+
end
|
227
|
+
|
228
|
+
xit 'can find outliers by index' do
|
229
|
+
NArray[0,1,1,2,1,2,10,1,0,0,1].outliers(2).must_equal [6]
|
230
|
+
NArray[0,-10,1,2,1,2,10,1,0,0,1].outliers(2).must_equal [1,6]
|
231
|
+
end
|
232
|
+
|
233
|
+
xit 'can find outliers iteratively' do
|
234
|
+
NArray[-1,-1,0,0,0,0,1,1,15,100].outliers(2).must_equal [9]
|
235
|
+
NArray[-1,-1,0,0,0,0,1,1,15,100].outliers_iteratively(2).must_equal [8,9]
|
236
|
+
end
|
237
|
+
|
238
|
+
xit 'can delete outliers (for least squares residuals)' do
|
239
|
+
# Consistency/sanity checks right now (not accuracy)
|
240
|
+
x = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,10,0 ,1,2,3,4,5,6,7,8,9]
|
241
|
+
y = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0 ,10,1,2,3,4,5,6,7,8,9]
|
242
|
+
|
243
|
+
nx1, ny1 = x.delete_outliers(3.2, y)
|
244
|
+
expx1 = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,10,1,2,3,4,5,6,7,8,9]
|
245
|
+
expy1 = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0 ,1,2,3,4,5,6,7,8,9]
|
246
|
+
nx1.must_equal expx1
|
247
|
+
ny1.must_equal expy1
|
248
|
+
|
249
|
+
nx2, ny2 = x.delete_outliers(2.8, y)
|
250
|
+
expx2 = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8,9]
|
251
|
+
expy2 = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8,9]
|
252
|
+
nx2.must_equal expx2
|
253
|
+
ny2.must_equal expy2
|
254
|
+
|
255
|
+
#res = nx1.residuals_from_least_squares(ny1)
|
256
|
+
#mean, std = res.sample_stats
|
257
|
+
#puts res/std
|
258
|
+
|
259
|
+
nx, ny = x.delete_outliers_iteratively(3.2, y)
|
260
|
+
nx.must_equal expx2
|
261
|
+
ny.must_equal expy2
|
262
|
+
end
|
263
|
+
|
264
|
+
xit 'finds outliers (for least squares residuals)' do
|
265
|
+
# Consistency/sanity checks right now (not accuracy)
|
266
|
+
x = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,10,0 ,1,2,3,7,5,6,7,8,9]
|
267
|
+
y = NArray[-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0 ,10,1,2,3,4,5,6,7,8,9]
|
268
|
+
xdup = x
|
269
|
+
ydup = y
|
270
|
+
|
271
|
+
ind = x.outliers(0.5, y)
|
272
|
+
ind.must_equal [10,11,15]
|
273
|
+
|
274
|
+
ind = x.outliers(0.7, y)
|
275
|
+
ind.must_equal [10,11]
|
276
|
+
|
277
|
+
ind2 = x.outliers_iteratively(0.7, y)
|
278
|
+
ind2.must_equal [10,11,15]
|
279
|
+
x.must_equal xdup # "method didn't change vector"
|
280
|
+
y.must_equal ydup # "method didn't change vector"
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'finds _correct_indices (private)' do
|
284
|
+
NArray.new._correct_indices([[5],[0,3],[3],[1,4]]).must_equal [0,2,3,5,6,8]
|
285
|
+
end
|
286
|
+
|
287
|
+
# TODO: fix this spec
|
288
|
+
# something is wrong in this guy
|
289
|
+
=begin
|
290
|
+
it 'can noisify its values' do
|
291
|
+
[[100,10,1],[-100,-10,-1]].each do |arr|
|
292
|
+
x = NArray.prep(arr)
|
293
|
+
xdup = x.dup
|
294
|
+
fraction = 0.1
|
295
|
+
|
296
|
+
10.times do
|
297
|
+
# this line is suspect:
|
298
|
+
x = NArray.prep([0,2,3,5,6,8])
|
299
|
+
x.noisify!(fraction)
|
300
|
+
xdup.zip(x) do |arr|
|
301
|
+
arr[1].must_be_close_to(arr[0], (fraction*arr[0]).abs)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
=end
|
307
|
+
|
308
|
+
it 'can duplicate itself' do
|
309
|
+
x = NArray[100,10,1]
|
310
|
+
d = x.dup
|
311
|
+
d.must_equal x
|
312
|
+
d.class.must_equal x.class
|
313
|
+
x[0] = 10.0
|
314
|
+
d.wont_equal x
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'can do a moving average' do
|
318
|
+
obj = NArray[0,1,2,3,4,5,6].moving_avg
|
319
|
+
obj.must_equal [0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 5.5]
|
320
|
+
obj = NArray[0,1,2,3,10,5,6].moving_avg
|
321
|
+
obj.must_equal [0.5, 1.0, 2.0, 5.0, 6.0, 7.0, 5.5]
|
322
|
+
|
323
|
+
obj = NArray[0,1,2,3,4,5,6].moving_avg(4,4).must_equal [2.0, 2.5, 3.0, 3.0, 3.0, 3.5, 4.0]
|
324
|
+
obj = NArray[0,1,2,3,4,5,6].moving_avg(0,6).must_equal [3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0]
|
325
|
+
obj = NArray[0,1,2,3,4,5,6].moving_avg(6,0).must_equal [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'can find 3-point derivatives (with chim)' do
|
329
|
+
x = NArray[1]
|
330
|
+
y = NArray[2]
|
331
|
+
derivs = x.chim(y)
|
332
|
+
derivs.must_equal [0]
|
333
|
+
|
334
|
+
x = NArray[1,2]
|
335
|
+
y = NArray[2,4]
|
336
|
+
derivs = x.chim(y)
|
337
|
+
derivs.must_equal [2.0, 2.0]
|
338
|
+
|
339
|
+
x = NArray[0,1,2,3,4,5,6,7,8,9]
|
340
|
+
y = NArray[0,10,12,4,5,2,7,9,10,4]
|
341
|
+
derivs = x.chim(y)
|
342
|
+
[14, 3.3333333, 0, 0, 0, 0, 2.8571429, 1.3333333, 0, -9.5].zip(derivs) do |exp, act|
|
343
|
+
act.must_be_close_to(exp, 0.0001)
|
344
|
+
end
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'can do custom transformations (moving avg, stdev, etc)' do
|
349
|
+
vec = NArray[0,1,2,3,3,4,2,1]
|
350
|
+
# a three point moving average:
|
351
|
+
answ = vec.transform(1, 1) {|x| x.avg }
|
352
|
+
exp = [0.5, 1, 2, 8.0/3, 10.0/3, 3, 7.0/3, 3.0/2]
|
353
|
+
answ.must_equal exp
|
354
|
+
|
355
|
+
# 5 point stdeviation transformation
|
356
|
+
pre = 2
|
357
|
+
post = 2
|
358
|
+
# transform with the standard deviation
|
359
|
+
answ = vec.transform(pre, post) {|x| x.sample_stats[1] }
|
360
|
+
exp = [1.0, 1.29099444873581, 1.30384048104053, 1.14017542509914, 0.836660026534075, 1.14017542509914, 1.29099444873581, 1.52752523165195]
|
361
|
+
answ.zip(exp) do |ans, ex|
|
362
|
+
ans.must_be_close_to(ex, 0.000000001)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
|
367
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: runarray
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Prince
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-14 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: pure ruby implementation of narray
|
17
|
+
email: jtprince@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
- LICENSE
|
25
|
+
files:
|
26
|
+
- lib/runarray/auto.rb
|
27
|
+
- lib/runarray/narray.rb
|
28
|
+
- lib/runarray.rb
|
29
|
+
- README
|
30
|
+
- LICENSE
|
31
|
+
- Rakefile
|
32
|
+
has_rdoc: true
|
33
|
+
homepage: http://rubyforge.org/projects/mspire
|
34
|
+
licenses: []
|
35
|
+
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --main
|
39
|
+
- README
|
40
|
+
- --title
|
41
|
+
- runarray
|
42
|
+
- --line-numbers
|
43
|
+
- --inline-source
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project: mspire
|
61
|
+
rubygems_version: 1.3.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: pure ruby implementation of narray
|
65
|
+
test_files:
|
66
|
+
- spec/runarray/narray_spec.rb
|