kmat 0.0.3 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +10 -0
- data/README.md +11 -11
- data/ext/kmat/arith/binary.c +161 -139
- data/ext/kmat/arith/math.c +1 -1
- data/ext/kmat/arith/statistics.c +11 -11
- data/ext/kmat/arith/unary.c +6 -6
- data/ext/kmat/extconf.rb +3 -0
- data/ext/kmat/km_util.h +34 -13
- data/ext/kmat/kmat.h +3 -3
- data/ext/kmat/linalg/dla.c +185 -133
- data/ext/kmat/linalg/linalg.c +33 -17
- data/ext/kmat/linalg/norm.c +83 -69
- data/ext/kmat/linalg/vla.c +23 -23
- data/ext/kmat/linalg/working.c +42 -38
- data/ext/kmat/main.c +4 -4
- data/ext/kmat/smat/accessor.c +104 -104
- data/ext/kmat/smat/array.c +3 -3
- data/ext/kmat/smat/boxmuller.c +5 -5
- data/ext/kmat/smat/constructer.c +52 -52
- data/ext/kmat/smat/convert.c +21 -21
- data/ext/kmat/smat/elem.c +7 -7
- data/ext/kmat/smat/fund.c +37 -37
- data/ext/kmat/smat/share.c +28 -27
- data/ext/kmat/smat/smat.c +58 -42
- data/ext/kmat/smat/sort.c +148 -146
- data/kmat.gemspec +5 -4
- data/lib/kmat/accessor.rb +5 -5
- data/lib/kmat/linalg.rb +1 -2
- data/lib/kmat/random.rb +2 -2
- data/lib/kmat/version.rb +1 -1
- data/lib/kmat.rb +9 -9
- metadata +25 -10
data/ext/kmat/smat/sort.c
CHANGED
@@ -29,43 +29,43 @@ km_value_comp(const void *a, const void *b)
|
|
29
29
|
return NUM2INT(rb_funcall(*(VALUE *)a, id_op_comp, 1, *(VALUE *)b));
|
30
30
|
}
|
31
31
|
static void
|
32
|
-
km_sort_seg(
|
32
|
+
km_sort_seg(size_t size_seg, size_t ld, size_t num_seg, void *body, VTYPE vt)
|
33
33
|
{
|
34
34
|
if ( vt == VT_DOUBLE ) {
|
35
|
-
for (
|
36
|
-
int info; char id[] = "I";
|
37
|
-
dlasrt_(id, &
|
35
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
36
|
+
int info, sseg=s2i(size_seg); char id[] = "I";
|
37
|
+
dlasrt_(id, &sseg, ((double *)body)+(i*ld), &info);
|
38
38
|
}
|
39
39
|
} else if ( vt == VT_INT ) {
|
40
|
-
for (
|
41
|
-
qsort(((int *)body)+(i*ld),
|
40
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
41
|
+
qsort(((int *)body)+(i*ld), size_seg, sizeof(int), km_int_comp);
|
42
42
|
}
|
43
43
|
} else if ( vt == VT_BOOL ) {
|
44
|
-
for (
|
45
|
-
qsort(((bool *)body)+(i*ld),
|
44
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
45
|
+
qsort(((bool *)body)+(i*ld), size_seg, sizeof(bool), km_bool_comp);
|
46
46
|
}
|
47
47
|
} else {
|
48
|
-
for (
|
49
|
-
qsort(((VALUE *)body)+(i*ld),
|
48
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
49
|
+
qsort(((VALUE *)body)+(i*ld), size_seg, sizeof(VALUE), km_value_comp);
|
50
50
|
}
|
51
51
|
}
|
52
52
|
}
|
53
53
|
#define SKEWER(type) type *b = (type *)body; type *b2 = ZALLOC_N(type, size_sk*num_sk); \
|
54
|
-
for (
|
55
|
-
for (
|
54
|
+
for ( size_t i=0; i<size_sk; i++ ) { \
|
55
|
+
for ( size_t j=0; j<num_sk; j++ ) { \
|
56
56
|
b2[i+j*size_sk] = b[j+i*ld]; \
|
57
57
|
} \
|
58
58
|
} \
|
59
59
|
km_sort_seg(size_sk, size_sk, num_sk, b2, vt); \
|
60
|
-
for (
|
61
|
-
for (
|
60
|
+
for ( size_t i=0; i<size_sk; i++ ) { \
|
61
|
+
for ( size_t j=0; j<num_sk; j++ ) { \
|
62
62
|
b[j+i*ld] = b2[i+j*size_sk]; \
|
63
63
|
} \
|
64
64
|
} \
|
65
65
|
ruby_xfree(b2)
|
66
66
|
|
67
67
|
static void
|
68
|
-
km_sort_skewer(
|
68
|
+
km_sort_skewer(size_t size_sk, size_t ld, size_t num_sk, void *body, VTYPE vt)
|
69
69
|
{
|
70
70
|
if ( vt == VT_DOUBLE ) {
|
71
71
|
SKEWER(double);
|
@@ -167,43 +167,43 @@ km_value_rcomp(const void *a, const void *b)
|
|
167
167
|
return NUM2INT(rb_funcall(*(VALUE *)b, id_op_comp, 1, *(VALUE *)a));
|
168
168
|
}
|
169
169
|
static void
|
170
|
-
km_rsort_seg(
|
170
|
+
km_rsort_seg(size_t size_seg, size_t ld, size_t num_seg, void *body, VTYPE vt)
|
171
171
|
{
|
172
172
|
if ( vt == VT_DOUBLE ) {
|
173
|
-
for (
|
174
|
-
int info; char id[] = "D";
|
175
|
-
dlasrt_(id, &
|
173
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
174
|
+
int info, sseg=s2i(size_seg); char id[] = "D";
|
175
|
+
dlasrt_(id, &sseg, ((double *)body)+(i*ld), &info);
|
176
176
|
}
|
177
177
|
} else if ( vt == VT_INT ) {
|
178
|
-
for (
|
179
|
-
qsort(((int *)body)+(i*ld),
|
178
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
179
|
+
qsort(((int *)body)+(i*ld), size_seg, sizeof(int), km_int_rcomp);
|
180
180
|
}
|
181
181
|
} else if ( vt == VT_BOOL ) {
|
182
|
-
for (
|
183
|
-
qsort(((bool *)body)+(i*ld),
|
182
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
183
|
+
qsort(((bool *)body)+(i*ld), size_seg, sizeof(bool), km_bool_rcomp);
|
184
184
|
}
|
185
185
|
} else {
|
186
|
-
for (
|
187
|
-
qsort(((VALUE *)body)+(i*ld),
|
186
|
+
for ( size_t i=0; i<num_seg; i++ ) {
|
187
|
+
qsort(((VALUE *)body)+(i*ld), size_seg, sizeof(VALUE), km_value_rcomp);
|
188
188
|
}
|
189
189
|
}
|
190
190
|
}
|
191
191
|
#define rSKEWER(type) type *b = (type *)body; type *b2 = ZALLOC_N(type, size_sk*num_sk); \
|
192
|
-
for (
|
193
|
-
for (
|
192
|
+
for ( size_t i=0; i<size_sk; i++ ) { \
|
193
|
+
for ( size_t j=0; j<num_sk; j++ ) { \
|
194
194
|
b2[i+j*size_sk] = b[j+i*ld]; \
|
195
195
|
} \
|
196
196
|
} \
|
197
197
|
km_rsort_seg(size_sk, size_sk, num_sk, b2, vt); \
|
198
|
-
for (
|
199
|
-
for (
|
198
|
+
for ( size_t i=0; i<size_sk; i++ ) { \
|
199
|
+
for ( size_t j=0; j<num_sk; j++ ) { \
|
200
200
|
b[j+i*ld] = b2[i+j*size_sk]; \
|
201
201
|
} \
|
202
202
|
} \
|
203
203
|
ruby_xfree(b2)
|
204
204
|
|
205
205
|
static void
|
206
|
-
km_rsort_skewer(
|
206
|
+
km_rsort_skewer(size_t size_sk, size_t ld, size_t num_sk, void *body, VTYPE vt)
|
207
207
|
{
|
208
208
|
if ( vt == VT_DOUBLE ) {
|
209
209
|
rSKEWER(double);
|
@@ -286,28 +286,28 @@ static union {
|
|
286
286
|
bool *b;
|
287
287
|
VALUE *v;
|
288
288
|
} as_body;
|
289
|
-
static
|
289
|
+
static size_t as_step;
|
290
290
|
static int
|
291
291
|
as_dcomp(const void *a, const void *b)
|
292
292
|
{
|
293
|
-
return (int)copysign(1.0, as_body.d[(*(
|
293
|
+
return (int)copysign(1.0, as_body.d[(*(size_t *)a)*as_step]-as_body.d[(*(size_t *)b)*as_step]);
|
294
294
|
}
|
295
295
|
static int
|
296
296
|
as_icomp(const void *a, const void *b)
|
297
297
|
{
|
298
|
-
return as_body.i[(*(
|
298
|
+
return as_body.i[(*(size_t *)a)*as_step] - as_body.i[(*(size_t *)b)*as_step];
|
299
299
|
}
|
300
300
|
static int
|
301
301
|
as_bcomp(const void *a, const void *b)
|
302
302
|
{
|
303
|
-
if ( as_body.b[(*(
|
304
|
-
if ( as_body.b[(*(
|
303
|
+
if ( as_body.b[(*(size_t *)a)*as_step] ) {
|
304
|
+
if ( as_body.b[(*(size_t *)b)*as_step] ) {
|
305
305
|
return 0;
|
306
306
|
} else {
|
307
307
|
return 1;
|
308
308
|
}
|
309
309
|
} else {
|
310
|
-
if ( as_body.b[(*(
|
310
|
+
if ( as_body.b[(*(size_t *)b)*as_step] ) {
|
311
311
|
return -1;
|
312
312
|
} else {
|
313
313
|
return 0;
|
@@ -317,7 +317,7 @@ as_bcomp(const void *a, const void *b)
|
|
317
317
|
static int
|
318
318
|
as_vcomp(const void *a, const void *b)
|
319
319
|
{
|
320
|
-
return NUM2INT(rb_funcall(as_body.v[(*(
|
320
|
+
return NUM2INT(rb_funcall(as_body.v[(*(size_t *)a)*as_step], id_op_comp, 1, as_body.v[(*(size_t *)b)*as_step]));
|
321
321
|
}
|
322
322
|
VALUE
|
323
323
|
kmm_mat_argsort_destl(VALUE self, VALUE va, VALUE vp)
|
@@ -328,18 +328,19 @@ kmm_mat_argsort_destl(VALUE self, VALUE va, VALUE vp)
|
|
328
328
|
rb_raise(rb_eRuntimeError, "self must be an int full vector");
|
329
329
|
}
|
330
330
|
si->trans = false; si->ld = si->m; // this is available because si is a vector
|
331
|
-
int *idx = si->ibody
|
331
|
+
int *idx = si->ibody;
|
332
|
+
size_t p=NUM2ZU(vp), offset;
|
332
333
|
if ( si->m == sa->m && si->n == 1 ) {
|
333
|
-
if (
|
334
|
-
for (
|
334
|
+
if ( sa->n <= p ) { rb_raise(rb_eIndexError, "p is out of range"); }
|
335
|
+
for ( size_t i=0; i<si->m; i++ ) { idx[i] = s2i(i); }
|
335
336
|
if ( sa->trans ) {
|
336
337
|
offset = p; as_step = sa->ld;
|
337
338
|
} else {
|
338
339
|
offset = p*si->ld; as_step = 1;
|
339
340
|
}
|
340
341
|
} else if ( si->m == 1 && si->n == sa->n ) {
|
341
|
-
if (
|
342
|
-
for (
|
342
|
+
if ( sa->m <= p ) { rb_raise(rb_eIndexError, "p is out of range"); }
|
343
|
+
for ( size_t i=0; i<si->n; i++ ) { idx[i] = s2i(i); }
|
343
344
|
if ( sa->trans ) {
|
344
345
|
offset = p*si->ld; as_step = 1;
|
345
346
|
} else {
|
@@ -350,20 +351,20 @@ kmm_mat_argsort_destl(VALUE self, VALUE va, VALUE vp)
|
|
350
351
|
}
|
351
352
|
if ( sa->vtype == VT_DOUBLE ) {
|
352
353
|
as_body.d = sa->dbody; as_body.d += offset;
|
353
|
-
qsort(idx,
|
354
|
+
qsort(idx, LENGTH(si), sizeof(int), as_dcomp);
|
354
355
|
} else if ( sa->vtype == VT_INT ) {
|
355
356
|
as_body.i = sa->ibody; as_body.i += offset;
|
356
|
-
qsort(idx,
|
357
|
+
qsort(idx, LENGTH(si), sizeof(int), as_icomp);
|
357
358
|
} else if ( sa->vtype == VT_BOOL ) {
|
358
359
|
as_body.b = sa->bbody; as_body.b += offset;
|
359
|
-
qsort(idx,
|
360
|
+
qsort(idx, LENGTH(si), sizeof(int), as_bcomp);
|
360
361
|
} else if ( sa->vtype == VT_VALUE ) {
|
361
362
|
as_body.v = sa->vbody; as_body.v += offset;
|
362
|
-
qsort(idx,
|
363
|
+
qsort(idx, LENGTH(si), sizeof(int), as_vcomp);
|
363
364
|
} else {
|
364
365
|
SMAT *sa2 = km_mat2smat(kmm_mat_to_omat(va));
|
365
366
|
as_body.v = sa2->vbody; as_body.v += offset;
|
366
|
-
qsort(idx,
|
367
|
+
qsort(idx, LENGTH(si), sizeof(int), as_vcomp);
|
367
368
|
}
|
368
369
|
return self;
|
369
370
|
}
|
@@ -404,24 +405,24 @@ kmm_mat_argsort(int argc, VALUE *argv, VALUE va)
|
|
404
405
|
static int
|
405
406
|
ras_dcomp(const void *a, const void *b)
|
406
407
|
{
|
407
|
-
return (int)copysign(1.0, as_body.d[(*(
|
408
|
+
return (int)copysign(1.0, as_body.d[(*(size_t *)a)*as_step]-as_body.d[(*(size_t *)b)*as_step]);
|
408
409
|
}
|
409
410
|
static int
|
410
411
|
ras_icomp(const void *a, const void *b)
|
411
412
|
{
|
412
|
-
return as_body.i[(*(
|
413
|
+
return as_body.i[(*(size_t *)a)*as_step] - as_body.i[(*(size_t *)b)*as_step];
|
413
414
|
}
|
414
415
|
static int
|
415
416
|
ras_bcomp(const void *a, const void *b)
|
416
417
|
{
|
417
|
-
if ( as_body.b[(*(
|
418
|
-
if ( as_body.b[(*(
|
418
|
+
if ( as_body.b[(*(size_t *)a)*as_step] ) {
|
419
|
+
if ( as_body.b[(*(size_t *)b)*as_step] ) {
|
419
420
|
return 0;
|
420
421
|
} else {
|
421
422
|
return -1;
|
422
423
|
}
|
423
424
|
} else {
|
424
|
-
if ( as_body.b[(*(
|
425
|
+
if ( as_body.b[(*(size_t *)b)*as_step] ) {
|
425
426
|
return 1;
|
426
427
|
} else {
|
427
428
|
return 0;
|
@@ -431,7 +432,7 @@ ras_bcomp(const void *a, const void *b)
|
|
431
432
|
static int
|
432
433
|
ras_vcomp(const void *a, const void *b)
|
433
434
|
{
|
434
|
-
return NUM2INT(rb_funcall(as_body.v[(*(
|
435
|
+
return NUM2INT(rb_funcall(as_body.v[(*(size_t *)a)*as_step], id_op_comp, 1, as_body.v[(*(size_t *)b)*as_step]));
|
435
436
|
}
|
436
437
|
VALUE
|
437
438
|
kmm_mat_rargsort_destl(VALUE self, VALUE va, VALUE vp)
|
@@ -442,18 +443,19 @@ kmm_mat_rargsort_destl(VALUE self, VALUE va, VALUE vp)
|
|
442
443
|
rb_raise(rb_eRuntimeError, "self must be an int full vector");
|
443
444
|
}
|
444
445
|
si->trans = false; si->ld = si->m; // this is available because si is a vector
|
445
|
-
int *idx = si->ibody
|
446
|
+
int *idx = si->ibody;
|
447
|
+
size_t p=NUM2ZU(vp), offset;
|
446
448
|
if ( si->m == sa->m && si->n == 1 ) {
|
447
|
-
if (
|
448
|
-
for (
|
449
|
+
if ( sa->n <= p ) { rb_raise(rb_eIndexError, "p is out of range"); }
|
450
|
+
for ( size_t i=0; i<si->m; i++ ) { idx[i] = s2i(i); }
|
449
451
|
if ( sa->trans ) {
|
450
452
|
offset = p; as_step = sa->ld;
|
451
453
|
} else {
|
452
454
|
offset = p*si->ld; as_step = 1;
|
453
455
|
}
|
454
456
|
} else if ( si->m == 1 && si->n == sa->n ) {
|
455
|
-
if (
|
456
|
-
for (
|
457
|
+
if ( sa->m <= p ) { rb_raise(rb_eIndexError, "p is out of range"); }
|
458
|
+
for ( size_t i=0; i<si->n; i++ ) { idx[i] = s2i(i); }
|
457
459
|
if ( sa->trans ) {
|
458
460
|
offset = p*si->ld; as_step = 1;
|
459
461
|
} else {
|
@@ -464,20 +466,20 @@ kmm_mat_rargsort_destl(VALUE self, VALUE va, VALUE vp)
|
|
464
466
|
}
|
465
467
|
if ( sa->vtype == VT_DOUBLE ) {
|
466
468
|
as_body.d = sa->dbody; as_body.d += offset;
|
467
|
-
qsort(idx,
|
469
|
+
qsort(idx, LENGTH(si), sizeof(int), ras_dcomp);
|
468
470
|
} else if ( sa->vtype == VT_INT ) {
|
469
471
|
as_body.i = sa->ibody; as_body.i += offset;
|
470
|
-
qsort(idx,
|
472
|
+
qsort(idx, LENGTH(si), sizeof(int), ras_icomp);
|
471
473
|
} else if ( sa->vtype == VT_BOOL ) {
|
472
474
|
as_body.b = sa->bbody; as_body.b += offset;
|
473
|
-
qsort(idx,
|
475
|
+
qsort(idx, LENGTH(si), sizeof(int), ras_bcomp);
|
474
476
|
} else if ( sa->vtype == VT_VALUE ) {
|
475
477
|
as_body.v = sa->vbody; as_body.v += offset;
|
476
|
-
qsort(idx,
|
478
|
+
qsort(idx, LENGTH(si), sizeof(int), ras_vcomp);
|
477
479
|
} else {
|
478
480
|
SMAT *sa2 = km_mat2smat(kmm_mat_to_omat(va));
|
479
481
|
as_body.v = sa2->vbody; as_body.v += offset;
|
480
|
-
qsort(idx,
|
482
|
+
qsort(idx, LENGTH(si), sizeof(int), ras_vcomp);
|
481
483
|
}
|
482
484
|
return self;
|
483
485
|
}
|
@@ -604,31 +606,31 @@ static VALUE \
|
|
604
606
|
km_mat_##mm##_col(VALUE self, SMAT *sr, SMAT *sa, VALUE va) \
|
605
607
|
{ \
|
606
608
|
if ( sr->vtype == VT_DOUBLE ) { \
|
607
|
-
for (
|
609
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
608
610
|
sr->dbody[j] = ENTITY(sa, d, 0, j); \
|
609
|
-
for (
|
610
|
-
double tmp = ENTITY(sa, d, i, j); \
|
611
|
+
for ( size_t i=1; i<sa->m; i++ ) { \
|
612
|
+
const double tmp = ENTITY(sa, d, i, j); \
|
611
613
|
if ( sr->dbody[j] op tmp ) { \
|
612
614
|
sr->dbody[j] = tmp; \
|
613
615
|
} \
|
614
616
|
} \
|
615
617
|
} \
|
616
618
|
} else if ( sr->vtype == VT_INT ) { \
|
617
|
-
for (
|
619
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
618
620
|
sr->ibody[j] = ENTITY(sa, i, 0, j); \
|
619
|
-
for (
|
620
|
-
int tmp = ENTITY(sa, i, i, j); \
|
621
|
+
for ( size_t i=1; i<sa->m; i++ ) { \
|
622
|
+
const int tmp = ENTITY(sa, i, i, j); \
|
621
623
|
if ( sr->ibody[j] op tmp ) { \
|
622
624
|
sr->ibody[j] = tmp; \
|
623
625
|
} \
|
624
626
|
} \
|
625
627
|
} \
|
626
628
|
} else if ( sr->vtype == VT_BOOL ) { \
|
627
|
-
for (
|
629
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
628
630
|
sr->bbody[j] = ENTITY(sa, b, 0, j); \
|
629
631
|
if ( !(opb sr->bbody[j]) ) { \
|
630
|
-
for (
|
631
|
-
bool tmp = ENTITY(sa, b, i, j); \
|
632
|
+
for ( size_t i=1; i<sa->m; i++ ) { \
|
633
|
+
const bool tmp = ENTITY(sa, b, i, j); \
|
632
634
|
if ( opb tmp ) { \
|
633
635
|
sr->bbody[j] = tmp; \
|
634
636
|
} \
|
@@ -636,10 +638,10 @@ km_mat_##mm##_col(VALUE self, SMAT *sr, SMAT *sa, VALUE va) \
|
|
636
638
|
} \
|
637
639
|
} \
|
638
640
|
} else if ( sr->vtype == VT_VALUE ) { \
|
639
|
-
for (
|
641
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
640
642
|
sr->vbody[j] = ENTITY(sa, v, 0, j); \
|
641
|
-
for (
|
642
|
-
VALUE tmp = ENTITY(sa, v, i, j); \
|
643
|
+
for ( size_t i=1; i<sa->m; i++ ) { \
|
644
|
+
const VALUE tmp = ENTITY(sa, v, i, j); \
|
643
645
|
if ( RTEST(rb_funcall(sr->vbody[j], op_id, 1, tmp)) ) { \
|
644
646
|
sr->vbody[j] = tmp; \
|
645
647
|
} \
|
@@ -659,31 +661,31 @@ static VALUE \
|
|
659
661
|
km_mat_##mm##_row(VALUE self, SMAT *sr, SMAT *sa, VALUE va) \
|
660
662
|
{ \
|
661
663
|
if ( sr->vtype == VT_DOUBLE ) { \
|
662
|
-
for (
|
664
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
663
665
|
sr->dbody[i] = ENTITY(sa, d, i, 0); \
|
664
|
-
for (
|
665
|
-
double tmp = ENTITY(sa, d, i, j); \
|
666
|
+
for ( size_t j=1; j<sa->n; j++ ) { \
|
667
|
+
const double tmp = ENTITY(sa, d, i, j); \
|
666
668
|
if ( sr->dbody[i] op tmp ) { \
|
667
669
|
sr->dbody[i] = tmp; \
|
668
670
|
} \
|
669
671
|
} \
|
670
672
|
} \
|
671
673
|
} else if ( sr->vtype == VT_INT ) { \
|
672
|
-
for (
|
674
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
673
675
|
sr->ibody[i] = ENTITY(sa, i, i, 0); \
|
674
|
-
for (
|
675
|
-
int tmp = ENTITY(sa, i, i, j); \
|
676
|
+
for ( size_t j=1; j<sa->n; j++ ) { \
|
677
|
+
const int tmp = ENTITY(sa, i, i, j); \
|
676
678
|
if ( sr->ibody[i] op tmp ) { \
|
677
679
|
sr->ibody[i] = tmp; \
|
678
680
|
} \
|
679
681
|
} \
|
680
682
|
} \
|
681
683
|
} else if ( sr->vtype == VT_BOOL ) { \
|
682
|
-
for (
|
684
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
683
685
|
sr->bbody[i] = ENTITY(sa, b, i, 0); \
|
684
686
|
if ( !(opb sr->bbody[i]) ) { \
|
685
|
-
for (
|
686
|
-
bool tmp = ENTITY(sa, b, i, j); \
|
687
|
+
for ( size_t j=0; j<sa->n; j++ ) { \
|
688
|
+
const bool tmp = ENTITY(sa, b, i, j); \
|
687
689
|
if ( opb tmp ) { \
|
688
690
|
sr->bbody[i] = tmp; \
|
689
691
|
} \
|
@@ -691,10 +693,10 @@ km_mat_##mm##_row(VALUE self, SMAT *sr, SMAT *sa, VALUE va) \
|
|
691
693
|
} \
|
692
694
|
} \
|
693
695
|
} else if ( sr->vtype == VT_VALUE ) { \
|
694
|
-
for (
|
696
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
695
697
|
sr->vbody[i] = ENTITY(sa, v, i, 0); \
|
696
|
-
for (
|
697
|
-
VALUE tmp = ENTITY(sa, v, i, j); \
|
698
|
+
for ( size_t j=1; j<sa->n; j++ ) { \
|
699
|
+
const VALUE tmp = ENTITY(sa, v, i, j); \
|
698
700
|
if ( RTEST(rb_funcall(sr->vbody[i], op_id, 1, tmp)) ) { \
|
699
701
|
sr->vbody[i] = tmp; \
|
700
702
|
} \
|
@@ -743,7 +745,7 @@ kmm_mat_max_destl(VALUE self, VALUE vr)
|
|
743
745
|
km_smat_copy(sr, sa);
|
744
746
|
return self;
|
745
747
|
} else {
|
746
|
-
rb_raise(km_eDim, "max/min from size (%
|
748
|
+
rb_raise(km_eDim, "max/min from size (%zu, %zu) to size (%zu, %zu) is not defined", sa->m, sa->n, sr->m, sr->n);
|
747
749
|
}
|
748
750
|
}
|
749
751
|
// the argument is a Symbol which specify the axis
|
@@ -807,7 +809,7 @@ kmm_mat_min_destl(VALUE self, VALUE vr)
|
|
807
809
|
km_smat_copy(sr, sa);
|
808
810
|
return self;
|
809
811
|
} else {
|
810
|
-
rb_raise(km_eDim, "max/min from size (%
|
812
|
+
rb_raise(km_eDim, "max/min from size (%zu, %zu) to size (%zu, %zu) is not defined", sa->m, sa->n, sr->m, sr->n);
|
811
813
|
}
|
812
814
|
}
|
813
815
|
VALUE
|
@@ -837,8 +839,8 @@ kmm_mat_min(int argc, VALUE *argv, VALUE self)
|
|
837
839
|
}
|
838
840
|
|
839
841
|
struct km_amm_arg {
|
840
|
-
|
841
|
-
|
842
|
+
size_t i;
|
843
|
+
size_t j;
|
842
844
|
union {
|
843
845
|
double dmm;
|
844
846
|
int imm;
|
@@ -847,7 +849,7 @@ struct km_amm_arg {
|
|
847
849
|
};
|
848
850
|
};
|
849
851
|
static void
|
850
|
-
km_argmax_func_d(double *ea,
|
852
|
+
km_argmax_func_d(double *ea, size_t i, size_t j, void *data)
|
851
853
|
{
|
852
854
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
853
855
|
if ( arg->dmm < *ea ) {
|
@@ -855,7 +857,7 @@ km_argmax_func_d(double *ea, int i, int j, void *data)
|
|
855
857
|
}
|
856
858
|
}
|
857
859
|
static void
|
858
|
-
km_argmax_func_i(int *ea,
|
860
|
+
km_argmax_func_i(int *ea, size_t i, size_t j, void *data)
|
859
861
|
{
|
860
862
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
861
863
|
if ( arg->imm < *ea ) {
|
@@ -863,7 +865,7 @@ km_argmax_func_i(int *ea, int i, int j, void *data)
|
|
863
865
|
}
|
864
866
|
}
|
865
867
|
static void
|
866
|
-
km_argmax_func_b(bool *ea,
|
868
|
+
km_argmax_func_b(bool *ea, size_t i, size_t j, void *data)
|
867
869
|
{
|
868
870
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
869
871
|
if ( (!(arg->bmm)) && *ea ) {
|
@@ -871,7 +873,7 @@ km_argmax_func_b(bool *ea, int i, int j, void *data)
|
|
871
873
|
}
|
872
874
|
}
|
873
875
|
static void
|
874
|
-
km_argmax_func_v(VALUE *ea,
|
876
|
+
km_argmax_func_v(VALUE *ea, size_t i, size_t j, void *data)
|
875
877
|
{
|
876
878
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
877
879
|
if ( RTEST(rb_funcall(arg->vmm, id_op_lt, 1, *ea)) ) {
|
@@ -885,38 +887,38 @@ km_mat_arg##mm##_all(SMAT *sr, SMAT *sa, VALUE va) \
|
|
885
887
|
if ( sa->vtype == VT_DOUBLE ) { \
|
886
888
|
struct km_amm_arg data = {0, 0, {.dmm = sa->dbody[0]}}; \
|
887
889
|
km_smat_each_with_index_d(sa, km_arg##mm##_func_d, &data); \
|
888
|
-
sr->ibody[0] =
|
890
|
+
sr->ibody[0] = INDEXi(sa, data.i, data.j); \
|
889
891
|
if ( VECTOR_P(sa) ) { \
|
890
|
-
return
|
892
|
+
return ZU2NUM(MAX(data.i, data.j)); \
|
891
893
|
} else { \
|
892
|
-
return rb_ary_new3(2,
|
894
|
+
return rb_ary_new3(2, ZU2NUM(data.i), ZU2NUM(data.j)); \
|
893
895
|
} \
|
894
896
|
} else if ( sa->vtype == VT_INT ) { \
|
895
897
|
struct km_amm_arg data = {0, 0, {.imm = sa->ibody[0]}}; \
|
896
898
|
km_smat_each_with_index_i(sa, km_arg##mm##_func_i, &data); \
|
897
|
-
sr->ibody[0] =
|
899
|
+
sr->ibody[0] = INDEXi(sa, data.i, data.j); \
|
898
900
|
if ( VECTOR_P(sa) ) { \
|
899
|
-
return
|
901
|
+
return ZU2NUM(MAX(data.i, data.j)); \
|
900
902
|
} else { \
|
901
|
-
return rb_ary_new3(2,
|
903
|
+
return rb_ary_new3(2, ZU2NUM(data.i), ZU2NUM(data.j)); \
|
902
904
|
} \
|
903
905
|
} else if ( sa->vtype == VT_BOOL ) { \
|
904
906
|
struct km_amm_arg data = {0, 0, {.bmm = sa->bbody[0]}}; \
|
905
907
|
km_smat_each_with_index_b(sa, km_arg##mm##_func_b, &data); \
|
906
|
-
sr->ibody[0] =
|
908
|
+
sr->ibody[0] = INDEXi(sa, data.i, data.j); \
|
907
909
|
if ( VECTOR_P(sa) ) { \
|
908
|
-
return
|
910
|
+
return ZU2NUM(MAX(data.i, data.j)); \
|
909
911
|
} else { \
|
910
|
-
return rb_ary_new3(2,
|
912
|
+
return rb_ary_new3(2, ZU2NUM(data.i), ZU2NUM(data.j)); \
|
911
913
|
} \
|
912
914
|
} else if ( sa->vtype == VT_VALUE ) { \
|
913
915
|
struct km_amm_arg data = {0, 0, {.vmm = sa->vbody[0]}}; \
|
914
916
|
km_smat_each_with_index_v(sa, km_arg##mm##_func_v, &data); \
|
915
|
-
sr->ibody[0] =
|
917
|
+
sr->ibody[0] = INDEXi(sa, data.i, data.j); \
|
916
918
|
if ( VECTOR_P(sa) ) { \
|
917
|
-
return
|
919
|
+
return ZU2NUM(MAX(data.i, data.j)); \
|
918
920
|
} else { \
|
919
|
-
return rb_ary_new3(2,
|
921
|
+
return rb_ary_new3(2, ZU2NUM(data.i), ZU2NUM(data.j)); \
|
920
922
|
} \
|
921
923
|
} else { \
|
922
924
|
VALUE omat = kmm_mat_to_omat(va); \
|
@@ -927,44 +929,44 @@ static VALUE \
|
|
927
929
|
km_mat_arg##mm##_col(VALUE self, SMAT *sr, SMAT *sa, VALUE va) \
|
928
930
|
{ \
|
929
931
|
if ( sa->vtype == VT_DOUBLE ) { \
|
930
|
-
for (
|
932
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
931
933
|
sr->ibody[j] = 0; double mm = ENTITY(sa, d, 0, j); \
|
932
|
-
for (
|
933
|
-
double tmp = ENTITY(sa, d, i, j); \
|
934
|
+
for ( size_t i=0; i<sa->m; i++ ) { \
|
935
|
+
const double tmp = ENTITY(sa, d, i, j); \
|
934
936
|
if ( mm op tmp ) { \
|
935
|
-
sr->ibody[j] = i; mm = tmp; \
|
937
|
+
sr->ibody[j] = s2i(i); mm = tmp; \
|
936
938
|
} \
|
937
939
|
} \
|
938
940
|
} \
|
939
941
|
} else if ( sa->vtype == VT_INT ) { \
|
940
|
-
for (
|
942
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
941
943
|
sr->ibody[j] = 0; int mm = ENTITY(sa, i, 0, j); \
|
942
|
-
for (
|
943
|
-
int tmp = ENTITY(sa, i, i, j); \
|
944
|
+
for ( size_t i=0; i<sa->m; i++ ) { \
|
945
|
+
const int tmp = ENTITY(sa, i, i, j); \
|
944
946
|
if ( mm op tmp ) { \
|
945
|
-
sr->ibody[j] = i; mm = tmp; \
|
947
|
+
sr->ibody[j] = s2i(i); mm = tmp; \
|
946
948
|
} \
|
947
949
|
} \
|
948
950
|
} \
|
949
951
|
} else if ( sa->vtype == VT_BOOL ) { \
|
950
|
-
for (
|
952
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
951
953
|
sr->ibody[j] = 0; bool mm = ENTITY(sa, b, 0, j); \
|
952
954
|
if ( !( opb mm ) ) { \
|
953
|
-
for (
|
954
|
-
|
955
|
+
for ( size_t i=0; i<sa->m; i++ ) { \
|
956
|
+
const bool tmp = ENTITY(sa, b, i, j); \
|
955
957
|
if ( opb tmp ) { \
|
956
|
-
sr->
|
958
|
+
sr->ibody[j] = s2i(i); mm = tmp; break; \
|
957
959
|
} \
|
958
960
|
} \
|
959
961
|
} \
|
960
962
|
} \
|
961
963
|
} else if ( sa->vtype == VT_VALUE ) { \
|
962
|
-
for (
|
964
|
+
for ( size_t j=0; j<sr->n; j++ ) { \
|
963
965
|
sr->ibody[j] = 0; VALUE mm = ENTITY(sa, v, 0, j); \
|
964
|
-
for (
|
965
|
-
VALUE tmp = ENTITY(sa, v, i, j); \
|
966
|
+
for ( size_t i=0; i<sa->m; i++ ) { \
|
967
|
+
const VALUE tmp = ENTITY(sa, v, i, j); \
|
966
968
|
if ( rb_funcall(mm, op_id, 1, tmp) ) { \
|
967
|
-
sr->ibody[j] = i; mm = tmp; \
|
969
|
+
sr->ibody[j] = s2i(i); mm = tmp; \
|
968
970
|
} \
|
969
971
|
} \
|
970
972
|
} \
|
@@ -978,44 +980,44 @@ static VALUE \
|
|
978
980
|
km_mat_arg##mm##_row(VALUE self, SMAT *sr, SMAT *sa, VALUE va) \
|
979
981
|
{ \
|
980
982
|
if ( sa->vtype == VT_DOUBLE ) { \
|
981
|
-
for (
|
983
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
982
984
|
sr->ibody[i] = 0; double mm = ENTITY(sa, d, i, 0); \
|
983
|
-
for (
|
984
|
-
double tmp = ENTITY(sa, d, i, j); \
|
985
|
+
for ( size_t j=1; j<sa->n; j++ ) { \
|
986
|
+
const double tmp = ENTITY(sa, d, i, j); \
|
985
987
|
if ( mm op tmp ) { \
|
986
|
-
sr->ibody[i] = j; mm = tmp; \
|
988
|
+
sr->ibody[i] = s2i(j); mm = tmp; \
|
987
989
|
} \
|
988
990
|
} \
|
989
991
|
} \
|
990
992
|
} else if ( sa->vtype == VT_INT ) { \
|
991
|
-
for (
|
993
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
992
994
|
sr->ibody[i] = 0; int mm = ENTITY(sa, i, i, 0); \
|
993
|
-
for (
|
994
|
-
int tmp = ENTITY(sa, i, i, j); \
|
995
|
+
for ( size_t j=1; j<sa->n; j++ ) { \
|
996
|
+
const int tmp = ENTITY(sa, i, i, j); \
|
995
997
|
if ( mm op tmp ) { \
|
996
|
-
sr->ibody[i] = j; mm = tmp; \
|
998
|
+
sr->ibody[i] = s2i(j); mm = tmp; \
|
997
999
|
} \
|
998
1000
|
} \
|
999
1001
|
} \
|
1000
1002
|
} else if ( sa->vtype == VT_BOOL ) { \
|
1001
|
-
for (
|
1002
|
-
sr->ibody[i] = 0;
|
1003
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
1004
|
+
sr->ibody[i] = 0; bool mm = ENTITY(sa, b, i, 0); \
|
1003
1005
|
if ( ! (opb mm) ) { \
|
1004
|
-
for (
|
1005
|
-
|
1006
|
+
for ( size_t j=1; j<sa->n; j++ ) { \
|
1007
|
+
const bool tmp = ENTITY(sa, i, i, j); \
|
1006
1008
|
if ( opb tmp ) { \
|
1007
|
-
sr->ibody[i] = j; break; \
|
1009
|
+
sr->ibody[i] = s2i(j); mm=tmp; break; \
|
1008
1010
|
} \
|
1009
1011
|
} \
|
1010
1012
|
} \
|
1011
1013
|
} \
|
1012
1014
|
} else if ( sa->vtype == VT_VALUE ) { \
|
1013
|
-
for (
|
1015
|
+
for ( size_t i=0; i<sr->m; i++ ) { \
|
1014
1016
|
sr->ibody[i] = 0; VALUE mm = ENTITY(sa, v, i, 0); \
|
1015
|
-
for (
|
1016
|
-
VALUE tmp = ENTITY(sa, v, i, j); \
|
1017
|
+
for ( size_t j=1; j<sa->n; j++ ) { \
|
1018
|
+
const VALUE tmp = ENTITY(sa, v, i, j); \
|
1017
1019
|
if ( rb_funcall(mm, op_id, 1, tmp) ) { \
|
1018
|
-
sr->ibody[i] = j; mm = tmp; \
|
1020
|
+
sr->ibody[i] = s2i(j); mm = tmp; \
|
1019
1021
|
} \
|
1020
1022
|
} \
|
1021
1023
|
} \
|
@@ -1047,7 +1049,7 @@ kmm_mat_argmax_destl(VALUE self, VALUE va)
|
|
1047
1049
|
} else if ( sr->m == sa->m && sr->n == 1 ) {
|
1048
1050
|
return km_mat_argmax_row(self, sr, sa, va);
|
1049
1051
|
} else {
|
1050
|
-
rb_raise(km_eDim, "argmax/min from size (%
|
1052
|
+
rb_raise(km_eDim, "argmax/min from size (%zu, %zu) to size (%zu, %zu) is not defined", sa->m, sa->n, sr->m, sr->n);
|
1051
1053
|
}
|
1052
1054
|
}
|
1053
1055
|
VALUE
|
@@ -1075,7 +1077,7 @@ kmm_mat_argmax(int argc, VALUE *argv, VALUE va)
|
|
1075
1077
|
}
|
1076
1078
|
|
1077
1079
|
static void
|
1078
|
-
km_argmin_func_d(double *ea,
|
1080
|
+
km_argmin_func_d(double *ea, size_t i, size_t j, void *data)
|
1079
1081
|
{
|
1080
1082
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
1081
1083
|
if ( arg->dmm > *ea ) {
|
@@ -1083,7 +1085,7 @@ km_argmin_func_d(double *ea, int i, int j, void *data)
|
|
1083
1085
|
}
|
1084
1086
|
}
|
1085
1087
|
static void
|
1086
|
-
km_argmin_func_i(int *ea,
|
1088
|
+
km_argmin_func_i(int *ea, size_t i, size_t j, void *data)
|
1087
1089
|
{
|
1088
1090
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
1089
1091
|
if ( arg->imm > *ea ) {
|
@@ -1091,7 +1093,7 @@ km_argmin_func_i(int *ea, int i, int j, void *data)
|
|
1091
1093
|
}
|
1092
1094
|
}
|
1093
1095
|
static void
|
1094
|
-
km_argmin_func_b(bool *ea,
|
1096
|
+
km_argmin_func_b(bool *ea, size_t i, size_t j, void *data)
|
1095
1097
|
{
|
1096
1098
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
1097
1099
|
if ( (arg->bmm) && (!(*ea)) ) {
|
@@ -1099,7 +1101,7 @@ km_argmin_func_b(bool *ea, int i, int j, void *data)
|
|
1099
1101
|
}
|
1100
1102
|
}
|
1101
1103
|
static void
|
1102
|
-
km_argmin_func_v(VALUE *ea,
|
1104
|
+
km_argmin_func_v(VALUE *ea, size_t i, size_t j, void *data)
|
1103
1105
|
{
|
1104
1106
|
struct km_amm_arg *arg = (struct km_amm_arg *)data;
|
1105
1107
|
if ( RTEST(rb_funcall(arg->vmm, id_op_gt, 1, *ea)) ) {
|
@@ -1128,7 +1130,7 @@ kmm_mat_argmin_destl(VALUE self, VALUE va)
|
|
1128
1130
|
} else if ( sr->m == sa->m && sr->n == 1 ) {
|
1129
1131
|
return km_mat_argmin_row(self, sr, sa, va);
|
1130
1132
|
} else {
|
1131
|
-
rb_raise(km_eDim, "argmax/min from size (%
|
1133
|
+
rb_raise(km_eDim, "argmax/min from size (%zu, %zu) to size (%zu, %zu) is not defined", sa->m, sa->n, sr->m, sr->n);
|
1132
1134
|
}
|
1133
1135
|
}
|
1134
1136
|
VALUE
|