nmatrix 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +5 -0
- data/History.txt +97 -0
- data/Manifest.txt +34 -7
- data/README.rdoc +13 -13
- data/Rakefile +36 -26
- data/ext/nmatrix/data/data.cpp +15 -2
- data/ext/nmatrix/data/data.h +4 -0
- data/ext/nmatrix/data/ruby_object.h +5 -14
- data/ext/nmatrix/extconf.rb +3 -2
- data/ext/nmatrix/{util/math.cpp → math.cpp} +296 -6
- data/ext/nmatrix/math/asum.h +143 -0
- data/ext/nmatrix/math/geev.h +82 -0
- data/ext/nmatrix/math/gemm.h +267 -0
- data/ext/nmatrix/math/gemv.h +208 -0
- data/ext/nmatrix/math/ger.h +96 -0
- data/ext/nmatrix/math/gesdd.h +80 -0
- data/ext/nmatrix/math/gesvd.h +78 -0
- data/ext/nmatrix/math/getf2.h +86 -0
- data/ext/nmatrix/math/getrf.h +240 -0
- data/ext/nmatrix/math/getri.h +107 -0
- data/ext/nmatrix/math/getrs.h +125 -0
- data/ext/nmatrix/math/idamax.h +86 -0
- data/ext/nmatrix/{util → math}/lapack.h +60 -356
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +52 -0
- data/ext/nmatrix/math/math.h +1154 -0
- data/ext/nmatrix/math/nrm2.h +181 -0
- data/ext/nmatrix/math/potrs.h +125 -0
- data/ext/nmatrix/math/rot.h +141 -0
- data/ext/nmatrix/math/rotg.h +115 -0
- data/ext/nmatrix/math/scal.h +73 -0
- data/ext/nmatrix/math/swap.h +73 -0
- data/ext/nmatrix/math/trsm.h +383 -0
- data/ext/nmatrix/nmatrix.cpp +176 -152
- data/ext/nmatrix/nmatrix.h +1 -2
- data/ext/nmatrix/ruby_constants.cpp +9 -4
- data/ext/nmatrix/ruby_constants.h +1 -0
- data/ext/nmatrix/storage/dense.cpp +57 -41
- data/ext/nmatrix/storage/list.cpp +52 -50
- data/ext/nmatrix/storage/storage.cpp +59 -43
- data/ext/nmatrix/storage/yale.cpp +352 -333
- data/ext/nmatrix/storage/yale.h +4 -0
- data/lib/nmatrix.rb +2 -2
- data/lib/nmatrix/blas.rb +4 -4
- data/lib/nmatrix/enumerate.rb +241 -0
- data/lib/nmatrix/lapack.rb +54 -1
- data/lib/nmatrix/math.rb +462 -0
- data/lib/nmatrix/nmatrix.rb +210 -486
- data/lib/nmatrix/nvector.rb +0 -62
- data/lib/nmatrix/rspec.rb +75 -0
- data/lib/nmatrix/shortcuts.rb +136 -108
- data/lib/nmatrix/version.rb +1 -1
- data/spec/blas_spec.rb +20 -12
- data/spec/elementwise_spec.rb +22 -13
- data/spec/io_spec.rb +1 -0
- data/spec/lapack_spec.rb +197 -0
- data/spec/nmatrix_spec.rb +39 -38
- data/spec/nvector_spec.rb +3 -9
- data/spec/rspec_monkeys.rb +29 -0
- data/spec/rspec_spec.rb +34 -0
- data/spec/shortcuts_spec.rb +14 -16
- data/spec/slice_spec.rb +242 -186
- data/spec/spec_helper.rb +19 -0
- metadata +33 -5
- data/ext/nmatrix/util/math.h +0 -2612
data/ext/nmatrix/nmatrix.h
CHANGED
@@ -303,8 +303,7 @@ NM_DEF_STRUCT_POST(NMATRIX); // };
|
|
303
303
|
#define NM_STORAGE_DENSE(val) ((struct NM_DENSE_STORAGE*)(NM_STORAGE(val)))
|
304
304
|
#endif
|
305
305
|
|
306
|
-
#define
|
307
|
-
#define NM_LIST_SRC(val) (NM_STORAGE_LIST(val)->src)
|
306
|
+
#define NM_SRC(val) (NM_STORAGE(val)->src)
|
308
307
|
#define NM_DIM(val) (NM_STORAGE(val)->dim)
|
309
308
|
#define NM_DTYPE(val) (NM_STORAGE(val)->dtype)
|
310
309
|
#define NM_ITYPE(val) (NM_STORAGE_YALE(val)->itype)
|
@@ -9,8 +9,8 @@
|
|
9
9
|
//
|
10
10
|
// == Copyright Information
|
11
11
|
//
|
12
|
-
// SciRuby is Copyright (c) 2010 -
|
13
|
-
// NMatrix is Copyright (c)
|
12
|
+
// SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012, Ruby Science Foundation
|
14
14
|
//
|
15
15
|
// Please see LICENSE.txt for additional copyright notices.
|
16
16
|
//
|
@@ -57,11 +57,12 @@ ID nm_rb_real,
|
|
57
57
|
|
58
58
|
nm_rb_row,
|
59
59
|
nm_rb_column,
|
60
|
-
|
61
60
|
nm_rb_add,
|
62
61
|
nm_rb_sub,
|
63
62
|
nm_rb_mul,
|
64
63
|
nm_rb_div,
|
64
|
+
nm_rb_both,
|
65
|
+
nm_rb_none,
|
65
66
|
|
66
67
|
nm_rb_negate,
|
67
68
|
|
@@ -84,6 +85,7 @@ VALUE cNMatrix,
|
|
84
85
|
cNMatrix_LAPACK,
|
85
86
|
|
86
87
|
nm_eDataTypeError,
|
88
|
+
nm_eConvergenceError,
|
87
89
|
nm_eStorageTypeError;
|
88
90
|
|
89
91
|
/*
|
@@ -127,9 +129,12 @@ void nm_init_ruby_constants(void) {
|
|
127
129
|
nm_rb_lower = rb_intern("lower");
|
128
130
|
nm_rb_unit = rb_intern("unit");
|
129
131
|
nm_rb_nonunit = rb_intern("nonunit");
|
130
|
-
|
131
132
|
nm_rb_hash = rb_intern("hash");
|
132
133
|
|
133
134
|
nm_rb_column = rb_intern("column");
|
134
135
|
nm_rb_row = rb_intern("row");
|
136
|
+
|
137
|
+
//Added by Ryan
|
138
|
+
nm_rb_both = rb_intern("both");
|
139
|
+
nm_rb_none = rb_intern("none");
|
135
140
|
}
|
@@ -35,9 +35,11 @@
|
|
35
35
|
* Project Includes
|
36
36
|
*/
|
37
37
|
// #include "types.h"
|
38
|
-
#include "util/math.h"
|
39
|
-
|
40
38
|
#include "data/data.h"
|
39
|
+
#include "math/long_dtype.h"
|
40
|
+
#include "math/gemm.h"
|
41
|
+
#include "math/gemv.h"
|
42
|
+
#include "math/math.h"
|
41
43
|
#include "common.h"
|
42
44
|
#include "dense.h"
|
43
45
|
|
@@ -73,6 +75,30 @@ namespace nm { namespace dense_storage {
|
|
73
75
|
template <typename DType>
|
74
76
|
bool is_symmetric(const DENSE_STORAGE* mat, int lda);
|
75
77
|
|
78
|
+
|
79
|
+
/*
|
80
|
+
* Recursive slicing for N-dimensional matrix.
|
81
|
+
*/
|
82
|
+
template <typename LDType, typename RDType>
|
83
|
+
static void slice_copy(DENSE_STORAGE *dest, const DENSE_STORAGE *src, size_t* lengths, size_t pdest, size_t psrc, size_t n) {
|
84
|
+
if (src->dim - n > 1) {
|
85
|
+
for (size_t i = 0; i < lengths[n]; ++i) {
|
86
|
+
slice_copy<LDType,RDType>(dest, src, lengths,
|
87
|
+
pdest + dest->stride[n]*i,
|
88
|
+
psrc + src->stride[n]*i,
|
89
|
+
n + 1);
|
90
|
+
}
|
91
|
+
} else {
|
92
|
+
for (size_t p = 0; p < dest->shape[n]; ++p) {
|
93
|
+
reinterpret_cast<LDType*>(dest->elements)[p+pdest] = reinterpret_cast<RDType*>(src->elements)[p+psrc];
|
94
|
+
}
|
95
|
+
/*memcpy((char*)dest->elements + pdest*DTYPE_SIZES[dest->dtype],
|
96
|
+
(char*)src->elements + psrc*DTYPE_SIZES[src->dtype],
|
97
|
+
dest->shape[n]*DTYPE_SIZES[dest->dtype]); */
|
98
|
+
}
|
99
|
+
|
100
|
+
}
|
101
|
+
|
76
102
|
}} // end of namespace nm::dense_storage
|
77
103
|
|
78
104
|
|
@@ -163,12 +189,12 @@ void nm_dense_storage_delete(STORAGE* s) {
|
|
163
189
|
if (s) {
|
164
190
|
DENSE_STORAGE* storage = (DENSE_STORAGE*)s;
|
165
191
|
if(storage->count-- == 1) {
|
166
|
-
|
167
|
-
|
168
|
-
|
192
|
+
xfree(storage->shape);
|
193
|
+
xfree(storage->offset);
|
194
|
+
xfree(storage->stride);
|
169
195
|
if (storage->elements != NULL) // happens with dummy objects
|
170
|
-
|
171
|
-
|
196
|
+
xfree(storage->elements);
|
197
|
+
xfree(storage);
|
172
198
|
}
|
173
199
|
}
|
174
200
|
}
|
@@ -181,9 +207,9 @@ void nm_dense_storage_delete_ref(STORAGE* s) {
|
|
181
207
|
if (s) {
|
182
208
|
DENSE_STORAGE* storage = (DENSE_STORAGE*)s;
|
183
209
|
nm_dense_storage_delete( reinterpret_cast<STORAGE*>(storage->src) );
|
184
|
-
|
185
|
-
|
186
|
-
|
210
|
+
xfree(storage->shape);
|
211
|
+
xfree(storage->offset);
|
212
|
+
xfree(storage);
|
187
213
|
}
|
188
214
|
}
|
189
215
|
|
@@ -367,6 +393,16 @@ VALUE nm_dense_each(VALUE nmatrix) {
|
|
367
393
|
}
|
368
394
|
|
369
395
|
|
396
|
+
/*
|
397
|
+
* Non-templated version of nm::dense_storage::slice_copy
|
398
|
+
*/
|
399
|
+
static void slice_copy(DENSE_STORAGE *dest, const DENSE_STORAGE *src, size_t* lengths, size_t pdest, size_t psrc, size_t n) {
|
400
|
+
NAMED_LR_DTYPE_TEMPLATE_TABLE(slice_copy_table, nm::dense_storage::slice_copy, void, DENSE_STORAGE*, const DENSE_STORAGE*, size_t*, size_t, size_t, size_t)
|
401
|
+
|
402
|
+
slice_copy_table[dest->dtype][src->dtype](dest, src, lengths, pdest, psrc, n);
|
403
|
+
}
|
404
|
+
|
405
|
+
|
370
406
|
/*
|
371
407
|
* Get a slice or one element, using copying.
|
372
408
|
*
|
@@ -374,17 +410,16 @@ VALUE nm_dense_each(VALUE nmatrix) {
|
|
374
410
|
*/
|
375
411
|
void* nm_dense_storage_get(STORAGE* storage, SLICE* slice) {
|
376
412
|
DENSE_STORAGE* s = (DENSE_STORAGE*)storage;
|
377
|
-
DENSE_STORAGE* ns;
|
378
413
|
|
379
414
|
if (slice->single)
|
380
415
|
return (char*)(s->elements) + nm_dense_storage_pos(s, slice->coords) * DTYPE_SIZES[s->dtype];
|
381
|
-
else {
|
416
|
+
else {
|
382
417
|
size_t *shape = ALLOC_N(size_t, s->dim);
|
383
418
|
for (size_t i = 0; i < s->dim; ++i) {
|
384
419
|
shape[i] = slice->lengths[i];
|
385
420
|
}
|
386
421
|
|
387
|
-
ns = nm_dense_storage_create(s->dtype, shape, s->dim, NULL, 0);
|
422
|
+
DENSE_STORAGE* ns = nm_dense_storage_create(s->dtype, shape, s->dim, NULL, 0);
|
388
423
|
|
389
424
|
slice_copy(ns,
|
390
425
|
reinterpret_cast<const DENSE_STORAGE*>(s->src),
|
@@ -392,6 +427,7 @@ void* nm_dense_storage_get(STORAGE* storage, SLICE* slice) {
|
|
392
427
|
0,
|
393
428
|
nm_dense_storage_pos(s, slice->coords),
|
394
429
|
0);
|
430
|
+
|
395
431
|
return ns;
|
396
432
|
}
|
397
433
|
}
|
@@ -552,24 +588,6 @@ static size_t* stride(size_t* shape, size_t dim) {
|
|
552
588
|
return stride;
|
553
589
|
}
|
554
590
|
|
555
|
-
/*
|
556
|
-
* Recursive slicing for N-dimensional matrix.
|
557
|
-
*/
|
558
|
-
static void slice_copy(DENSE_STORAGE *dest, const DENSE_STORAGE *src, size_t* lengths, size_t pdest, size_t psrc, size_t n) {
|
559
|
-
if (src->dim - n > 1) {
|
560
|
-
for (size_t i = 0; i < lengths[n]; ++i) {
|
561
|
-
slice_copy(dest, src, lengths,
|
562
|
-
pdest + dest->stride[n]*i,
|
563
|
-
psrc + src->stride[n]*i,
|
564
|
-
n + 1);
|
565
|
-
}
|
566
|
-
} else {
|
567
|
-
memcpy((char*)dest->elements + pdest*DTYPE_SIZES[dest->dtype],
|
568
|
-
(char*)src->elements + psrc*DTYPE_SIZES[src->dtype],
|
569
|
-
dest->shape[n]*DTYPE_SIZES[dest->dtype]);
|
570
|
-
}
|
571
|
-
|
572
|
-
}
|
573
591
|
|
574
592
|
/////////////////////////
|
575
593
|
// Copying and Casting //
|
@@ -694,22 +712,20 @@ DENSE_STORAGE* cast_copy(const DENSE_STORAGE* rhs, dtype_t new_dtype) {
|
|
694
712
|
|
695
713
|
DENSE_STORAGE* lhs = nm_dense_storage_create(new_dtype, shape, rhs->dim, NULL, 0);
|
696
714
|
|
697
|
-
RDType* rhs_els = reinterpret_cast<RDType*>(rhs->elements);
|
698
|
-
LDType* lhs_els = reinterpret_cast<LDType*>(lhs->elements);
|
699
|
-
|
700
715
|
// Ensure that allocation worked before copying.
|
701
716
|
if (lhs && count) {
|
702
717
|
if (rhs->src != rhs) { // Make a copy of a ref to a matrix.
|
718
|
+
size_t* offset = ALLOCA_N(size_t, rhs->dim);
|
719
|
+
memset(offset, 0, sizeof(size_t) * rhs->dim);
|
703
720
|
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
while (count-- > 0) {
|
708
|
-
lhs_els[count] = tmp_els[count];
|
709
|
-
}
|
710
|
-
nm_dense_storage_delete(tmp);
|
721
|
+
slice_copy(lhs, reinterpret_cast<const DENSE_STORAGE*>(rhs->src),
|
722
|
+
rhs->shape, 0,
|
723
|
+
nm_dense_storage_pos(rhs, offset), 0);
|
711
724
|
|
712
725
|
} else { // Make a regular copy.
|
726
|
+
RDType* rhs_els = reinterpret_cast<RDType*>(rhs->elements);
|
727
|
+
LDType* lhs_els = reinterpret_cast<LDType*>(lhs->elements);
|
728
|
+
|
713
729
|
while (count-- > 0) lhs_els[count] = rhs_els[count];
|
714
730
|
}
|
715
731
|
}
|
@@ -33,6 +33,7 @@
|
|
33
33
|
#include <ruby.h>
|
34
34
|
#include <algorithm> // std::min
|
35
35
|
#include <iostream>
|
36
|
+
#include <vector>
|
36
37
|
|
37
38
|
/*
|
38
39
|
* Project Includes
|
@@ -45,7 +46,7 @@
|
|
45
46
|
#include "common.h"
|
46
47
|
#include "list.h"
|
47
48
|
|
48
|
-
#include "
|
49
|
+
#include "math/math.h"
|
49
50
|
#include "util/sl_list.h"
|
50
51
|
|
51
52
|
/*
|
@@ -83,7 +84,7 @@ public:
|
|
83
84
|
|
84
85
|
size_t dim() const { return ref->dim; }
|
85
86
|
|
86
|
-
size_t
|
87
|
+
size_t ref_shape(size_t rec) const {
|
87
88
|
return shape_[ref->dim - rec - 1];
|
88
89
|
}
|
89
90
|
|
@@ -143,7 +144,7 @@ static void map_empty_stored_r(RecurseData& result, RecurseData& s, LIST* x, con
|
|
143
144
|
|
144
145
|
// For reference matrices, make sure we start in the correct place.
|
145
146
|
size_t offset = result.offset(rec);
|
146
|
-
size_t x_shape = result.
|
147
|
+
size_t x_shape = result.ref_shape(rec);
|
147
148
|
|
148
149
|
while (curr && curr->key < offset) { curr = curr->next; }
|
149
150
|
if (curr && curr->key - offset >= x_shape) curr = NULL;
|
@@ -188,8 +189,8 @@ static void map_merged_stored_r(RecurseData& result, RecurseData& left, RecurseD
|
|
188
189
|
while (lcurr && lcurr->key < left.offset(rec)) { lcurr = lcurr->next; }
|
189
190
|
while (rcurr && rcurr->key < right.offset(rec)) { rcurr = rcurr->next; }
|
190
191
|
|
191
|
-
if (rcurr && rcurr->key - right.offset(rec) >= result.
|
192
|
-
if (lcurr && lcurr->key - left.offset(rec) >= result.
|
192
|
+
if (rcurr && rcurr->key - right.offset(rec) >= result.ref_shape(rec)) rcurr = NULL;
|
193
|
+
if (lcurr && lcurr->key - left.offset(rec) >= result.ref_shape(rec)) lcurr = NULL;
|
193
194
|
|
194
195
|
if (rec) {
|
195
196
|
while (lcurr || rcurr) {
|
@@ -214,8 +215,8 @@ static void map_merged_stored_r(RecurseData& result, RecurseData& left, RecurseD
|
|
214
215
|
if (!val->first) nm::list::del(val, 0); // empty list -- don't insert
|
215
216
|
else xcurr = nm::list::insert_helper(x, xcurr, key, val);
|
216
217
|
|
217
|
-
if (rcurr && rcurr->key - right.offset(rec) >= result.
|
218
|
-
if (lcurr && lcurr->key - left.offset(rec) >= result.
|
218
|
+
if (rcurr && rcurr->key - right.offset(rec) >= result.ref_shape(rec)) rcurr = NULL;
|
219
|
+
if (lcurr && lcurr->key - left.offset(rec) >= result.ref_shape(rec)) lcurr = NULL;
|
219
220
|
}
|
220
221
|
} else {
|
221
222
|
while (lcurr || rcurr) {
|
@@ -239,8 +240,8 @@ static void map_merged_stored_r(RecurseData& result, RecurseData& left, RecurseD
|
|
239
240
|
if (rb_funcall(val, rb_intern("!="), 1, result.init_obj()) == Qtrue)
|
240
241
|
xcurr = nm::list::insert_helper(x, xcurr, key, val);
|
241
242
|
|
242
|
-
if (rcurr && rcurr->key - right.offset(rec) >= result.
|
243
|
-
if (lcurr && lcurr->key - left.offset(rec) >= result.
|
243
|
+
if (rcurr && rcurr->key - right.offset(rec) >= result.ref_shape(rec)) rcurr = NULL;
|
244
|
+
if (lcurr && lcurr->key - left.offset(rec) >= result.ref_shape(rec)) lcurr = NULL;
|
244
245
|
}
|
245
246
|
}
|
246
247
|
}
|
@@ -293,10 +294,10 @@ void nm_list_storage_delete(STORAGE* s) {
|
|
293
294
|
if (storage->count-- == 1) {
|
294
295
|
list::del( storage->rows, storage->dim - 1 );
|
295
296
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
297
|
+
xfree(storage->shape);
|
298
|
+
xfree(storage->offset);
|
299
|
+
xfree(storage->default_val);
|
300
|
+
xfree(s);
|
300
301
|
}
|
301
302
|
}
|
302
303
|
}
|
@@ -309,9 +310,9 @@ void nm_list_storage_delete_ref(STORAGE* s) {
|
|
309
310
|
LIST_STORAGE* storage = (LIST_STORAGE*)s;
|
310
311
|
|
311
312
|
nm_list_storage_delete( reinterpret_cast<STORAGE*>(storage->src ) );
|
312
|
-
|
313
|
-
|
314
|
-
|
313
|
+
xfree(storage->shape);
|
314
|
+
xfree(storage->offset);
|
315
|
+
xfree(s);
|
315
316
|
}
|
316
317
|
}
|
317
318
|
|
@@ -334,7 +335,7 @@ void nm_list_storage_mark(void* storage_base) {
|
|
334
335
|
/*
|
335
336
|
* Documentation goes here.
|
336
337
|
*/
|
337
|
-
NODE* list_storage_get_single_node(LIST_STORAGE* s, SLICE* slice)
|
338
|
+
static NODE* list_storage_get_single_node(LIST_STORAGE* s, SLICE* slice)
|
338
339
|
{
|
339
340
|
size_t r;
|
340
341
|
LIST* l = s->rows;
|
@@ -358,7 +359,7 @@ static void each_empty_with_indices_r(nm::list_storage::RecurseData& s, size_t r
|
|
358
359
|
VALUE empty = s.dtype() == nm::RUBYOBJ ? *reinterpret_cast<VALUE*>(s.init()) : s.init_obj();
|
359
360
|
|
360
361
|
if (rec) {
|
361
|
-
for (long index = 0; index < s.
|
362
|
+
for (long index = 0; index < s.ref_shape(rec); ++index) {
|
362
363
|
// Don't do an unshift/shift here -- we'll let that be handled in the lowest-level iteration (recursions == 0)
|
363
364
|
rb_ary_push(stack, LONG2NUM(index));
|
364
365
|
each_empty_with_indices_r(s, rec-1, stack);
|
@@ -366,7 +367,7 @@ static void each_empty_with_indices_r(nm::list_storage::RecurseData& s, size_t r
|
|
366
367
|
}
|
367
368
|
} else {
|
368
369
|
rb_ary_unshift(stack, empty);
|
369
|
-
for (long index = 0; index < s.
|
370
|
+
for (long index = 0; index < s.ref_shape(rec); ++index) {
|
370
371
|
rb_ary_push(stack, LONG2NUM(index));
|
371
372
|
rb_yield_splat(stack);
|
372
373
|
rb_ary_pop(stack);
|
@@ -382,18 +383,18 @@ static void each_with_indices_r(nm::list_storage::RecurseData& s, const LIST* l,
|
|
382
383
|
NODE* curr = l->first;
|
383
384
|
|
384
385
|
size_t offset = s.offset(rec);
|
385
|
-
size_t shape = s.
|
386
|
+
size_t shape = s.ref_shape(rec);
|
386
387
|
|
387
388
|
while (curr && curr->key < offset) curr = curr->next;
|
388
|
-
if (curr && curr->key >= shape) curr = NULL;
|
389
|
+
if (curr && curr->key - offset >= shape) curr = NULL;
|
389
390
|
|
390
391
|
|
391
392
|
if (rec) {
|
392
|
-
for (long index = 0; index < shape; ++index) {
|
393
|
+
for (long index = 0; index < shape; ++index) { // index in reference
|
393
394
|
rb_ary_push(stack, LONG2NUM(index));
|
394
395
|
if (!curr || index < curr->key - offset) {
|
395
396
|
each_empty_with_indices_r(s, rec-1, stack);
|
396
|
-
} else {
|
397
|
+
} else { // index == curr->key - offset
|
397
398
|
each_with_indices_r(s, reinterpret_cast<const LIST*>(curr->val), rec-1, stack);
|
398
399
|
curr = curr->next;
|
399
400
|
}
|
@@ -407,7 +408,7 @@ static void each_with_indices_r(nm::list_storage::RecurseData& s, const LIST* l,
|
|
407
408
|
if (!curr || index < curr->key - offset) {
|
408
409
|
rb_ary_unshift(stack, s.dtype() == nm::RUBYOBJ ? *reinterpret_cast<VALUE*>(s.init()) : s.init_obj());
|
409
410
|
|
410
|
-
} else { // index == curr->key
|
411
|
+
} else { // index == curr->key - offset
|
411
412
|
rb_ary_unshift(stack, s.dtype() == nm::RUBYOBJ ? *reinterpret_cast<VALUE*>(curr->val) : rubyobj_from_cval(curr->val, s.dtype()).rval);
|
412
413
|
|
413
414
|
curr = curr->next;
|
@@ -429,7 +430,7 @@ static void each_stored_with_indices_r(nm::list_storage::RecurseData& s, const L
|
|
429
430
|
NODE* curr = l->first;
|
430
431
|
|
431
432
|
size_t offset = s.offset(rec);
|
432
|
-
size_t shape = s.
|
433
|
+
size_t shape = s.ref_shape(rec);
|
433
434
|
|
434
435
|
while (curr && curr->key < offset) { curr = curr->next; }
|
435
436
|
if (curr && curr->key - offset >= shape) curr = NULL;
|
@@ -460,7 +461,7 @@ static void each_stored_with_indices_r(nm::list_storage::RecurseData& s, const L
|
|
460
461
|
rb_ary_pop(stack);
|
461
462
|
|
462
463
|
curr = curr->next;
|
463
|
-
if (curr && curr->key >= shape) curr = NULL;
|
464
|
+
if (curr && curr->key - offset >= shape) curr = NULL;
|
464
465
|
}
|
465
466
|
}
|
466
467
|
}
|
@@ -500,7 +501,6 @@ VALUE nm_list_map_merged_stored(VALUE left, VALUE right, VALUE init) {
|
|
500
501
|
nm::list_storage::RecurseData sdata(s);
|
501
502
|
|
502
503
|
void* scalar_init = NULL;
|
503
|
-
size_t* shape;
|
504
504
|
|
505
505
|
// right might be a scalar, in which case this is a scalar operation.
|
506
506
|
if (TYPE(right) != T_DATA || (RDATA(right)->dfree != (RUBY_DATA_FUNC)nm_delete && RDATA(right)->dfree != (RUBY_DATA_FUNC)nm_delete_ref)) {
|
@@ -541,8 +541,11 @@ VALUE nm_list_map_merged_stored(VALUE left, VALUE right, VALUE init) {
|
|
541
541
|
}
|
542
542
|
|
543
543
|
|
544
|
-
|
544
|
+
/*
|
545
|
+
* Copy a slice of a list matrix into a regular list matrix.
|
546
|
+
*/
|
545
547
|
static LIST* slice_copy(const LIST_STORAGE *src, LIST *src_rows, size_t *coords, size_t *lengths, size_t n) {
|
548
|
+
|
546
549
|
NODE *src_node;
|
547
550
|
LIST *dst_rows = NULL;
|
548
551
|
void *val = NULL;
|
@@ -586,10 +589,9 @@ void* nm_list_storage_get(STORAGE* storage, SLICE* slice) {
|
|
586
589
|
NODE* n;
|
587
590
|
|
588
591
|
if (slice->single) {
|
589
|
-
n = list_storage_get_single_node(s, slice);
|
592
|
+
n = list_storage_get_single_node(s, slice);
|
590
593
|
return (n ? n->val : s->default_val);
|
591
|
-
}
|
592
|
-
else {
|
594
|
+
} else {
|
593
595
|
void *init_val = ALLOC_N(char, DTYPE_SIZES[s->dtype]);
|
594
596
|
memcpy(init_val, s->default_val, DTYPE_SIZES[s->dtype]);
|
595
597
|
|
@@ -597,7 +599,7 @@ void* nm_list_storage_get(STORAGE* storage, SLICE* slice) {
|
|
597
599
|
memcpy(shape, slice->lengths, sizeof(size_t) * s->dim);
|
598
600
|
|
599
601
|
ns = nm_list_storage_create(s->dtype, shape, s->dim, init_val);
|
600
|
-
|
602
|
+
|
601
603
|
ns->rows = slice_copy(s, s->rows, slice->coords, slice->lengths, 0);
|
602
604
|
return ns;
|
603
605
|
}
|
@@ -618,23 +620,23 @@ void* nm_list_storage_ref(STORAGE* storage, SLICE* slice) {
|
|
618
620
|
return (n ? n->val : s->default_val);
|
619
621
|
}
|
620
622
|
else {
|
621
|
-
ns
|
623
|
+
ns = ALLOC( LIST_STORAGE );
|
622
624
|
|
623
|
-
ns->dim
|
624
|
-
ns->dtype
|
625
|
-
ns->offset
|
626
|
-
ns->shape
|
625
|
+
ns->dim = s->dim;
|
626
|
+
ns->dtype = s->dtype;
|
627
|
+
ns->offset = ALLOC_N(size_t, ns->dim);
|
628
|
+
ns->shape = ALLOC_N(size_t, ns->dim);
|
627
629
|
|
628
630
|
for (size_t i = 0; i < ns->dim; ++i) {
|
629
631
|
ns->offset[i] = slice->coords[i] + s->offset[i];
|
630
632
|
ns->shape[i] = slice->lengths[i];
|
631
633
|
}
|
632
634
|
|
633
|
-
ns->rows
|
635
|
+
ns->rows = s->rows;
|
634
636
|
ns->default_val = s->default_val;
|
635
637
|
|
636
638
|
s->src->count++;
|
637
|
-
ns->src
|
639
|
+
ns->src = s->src;
|
638
640
|
|
639
641
|
return ns;
|
640
642
|
}
|
@@ -874,21 +876,21 @@ static bool eqeq_empty_r(RecurseData& s, const LIST* l, size_t rec, const TDType
|
|
874
876
|
|
875
877
|
// For reference matrices, make sure we start in the correct place.
|
876
878
|
while (curr && curr->key < s.offset(rec)) { curr = curr->next; }
|
877
|
-
if (curr && curr->key - s.offset(rec) >= s.
|
879
|
+
if (curr && curr->key - s.offset(rec) >= s.ref_shape(rec)) curr = NULL;
|
878
880
|
|
879
881
|
if (rec) {
|
880
882
|
while (curr) {
|
881
883
|
if (!eqeq_empty_r<SDType,TDType>(s, reinterpret_cast<const LIST*>(curr->val), rec-1, t_init)) return false;
|
882
884
|
curr = curr->next;
|
883
885
|
|
884
|
-
if (curr && curr->key - s.offset(rec) >= s.
|
886
|
+
if (curr && curr->key - s.offset(rec) >= s.ref_shape(rec)) curr = NULL;
|
885
887
|
}
|
886
888
|
} else {
|
887
889
|
while (curr) {
|
888
890
|
if (*reinterpret_cast<SDType*>(curr->val) != *t_init) return false;
|
889
891
|
curr = curr->next;
|
890
892
|
|
891
|
-
if (curr && curr->key - s.offset(rec) >= s.
|
893
|
+
if (curr && curr->key - s.offset(rec) >= s.ref_shape(rec)) curr = NULL;
|
892
894
|
}
|
893
895
|
}
|
894
896
|
return true;
|
@@ -909,8 +911,8 @@ static bool eqeq_r(RecurseData& left, RecurseData& right, const LIST* l, const L
|
|
909
911
|
// For reference matrices, make sure we start in the correct place.
|
910
912
|
while (lcurr && lcurr->key < left.offset(rec)) { lcurr = lcurr->next; }
|
911
913
|
while (rcurr && rcurr->key < right.offset(rec)) { rcurr = rcurr->next; }
|
912
|
-
if (rcurr && rcurr->key - right.offset(rec) >= left.
|
913
|
-
if (lcurr && lcurr->key - left.offset(rec) >= left.
|
914
|
+
if (rcurr && rcurr->key - right.offset(rec) >= left.ref_shape(rec)) rcurr = NULL;
|
915
|
+
if (lcurr && lcurr->key - left.offset(rec) >= left.ref_shape(rec)) lcurr = NULL;
|
914
916
|
|
915
917
|
bool compared = false;
|
916
918
|
|
@@ -929,15 +931,15 @@ static bool eqeq_r(RecurseData& left, RecurseData& right, const LIST* l, const L
|
|
929
931
|
lcurr = lcurr->next;
|
930
932
|
rcurr = rcurr->next;
|
931
933
|
}
|
932
|
-
if (rcurr && rcurr->key - right.offset(rec) >=
|
933
|
-
if (lcurr && lcurr->key - left.offset(rec)
|
934
|
+
if (rcurr && rcurr->key - right.offset(rec) >= right.ref_shape(rec)) rcurr = NULL;
|
935
|
+
if (lcurr && lcurr->key - left.offset(rec) >= left.ref_shape(rec)) lcurr = NULL;
|
934
936
|
compared = true;
|
935
937
|
}
|
936
938
|
} else {
|
937
939
|
while (lcurr || rcurr) {
|
938
940
|
|
939
|
-
if (rcurr && rcurr->key - right.offset(rec) >= left.
|
940
|
-
if (lcurr && lcurr->key - left.offset(rec) >= left.
|
941
|
+
if (rcurr && rcurr->key - right.offset(rec) >= left.ref_shape(rec)) rcurr = NULL;
|
942
|
+
if (lcurr && lcurr->key - left.offset(rec) >= left.ref_shape(rec)) lcurr = NULL;
|
941
943
|
|
942
944
|
if (!rcurr || (lcurr && (lcurr->key - left.offset(rec) < rcurr->key - right.offset(rec)))) {
|
943
945
|
if (*reinterpret_cast<LDType*>(lcurr->val) != *reinterpret_cast<const RDType*>(right.init())) return false;
|
@@ -950,8 +952,8 @@ static bool eqeq_r(RecurseData& left, RecurseData& right, const LIST* l, const L
|
|
950
952
|
lcurr = lcurr->next;
|
951
953
|
rcurr = rcurr->next;
|
952
954
|
}
|
953
|
-
if (rcurr && rcurr->key - right.offset(rec) >=
|
954
|
-
if (lcurr && lcurr->key - left.offset(rec)
|
955
|
+
if (rcurr && rcurr->key - right.offset(rec) >= right.ref_shape(rec)) rcurr = NULL;
|
956
|
+
if (lcurr && lcurr->key - left.offset(rec) >= left.ref_shape(rec)) lcurr = NULL;
|
955
957
|
compared = true;
|
956
958
|
}
|
957
959
|
}
|