kmat 0.0.3

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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +3 -0
  3. data/.gitignore +15 -0
  4. data/CHANGELOG.md +15 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.md +675 -0
  7. data/README.md +224 -0
  8. data/Rakefile +26 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/ext/kmat/arith/binary.c +1121 -0
  12. data/ext/kmat/arith/logical.c +332 -0
  13. data/ext/kmat/arith/math.c +34 -0
  14. data/ext/kmat/arith/statistics.c +173 -0
  15. data/ext/kmat/arith/unary.c +165 -0
  16. data/ext/kmat/auto_collect.rb +118 -0
  17. data/ext/kmat/elementwise_function.rb +149 -0
  18. data/ext/kmat/extconf.rb +75 -0
  19. data/ext/kmat/id.txt +80 -0
  20. data/ext/kmat/id_sym.rb +40 -0
  21. data/ext/kmat/km_util.h +97 -0
  22. data/ext/kmat/kmat.h +96 -0
  23. data/ext/kmat/lapack_headers/blas.h +354 -0
  24. data/ext/kmat/lapack_headers/lapacke.h +19455 -0
  25. data/ext/kmat/lapack_headers/lapacke_config.h +119 -0
  26. data/ext/kmat/lapack_headers/lapacke_mangling.h +17 -0
  27. data/ext/kmat/lapack_headers/lapacke_utils.h +579 -0
  28. data/ext/kmat/linalg/dla.c +1629 -0
  29. data/ext/kmat/linalg/linalg.c +267 -0
  30. data/ext/kmat/linalg/norm.c +727 -0
  31. data/ext/kmat/linalg/vla.c +102 -0
  32. data/ext/kmat/linalg/working.c +240 -0
  33. data/ext/kmat/main.c +95 -0
  34. data/ext/kmat/smat/accessor.c +719 -0
  35. data/ext/kmat/smat/array.c +108 -0
  36. data/ext/kmat/smat/boxmuller.c +72 -0
  37. data/ext/kmat/smat/constructer.c +302 -0
  38. data/ext/kmat/smat/convert.c +375 -0
  39. data/ext/kmat/smat/elem.c +171 -0
  40. data/ext/kmat/smat/fund.c +702 -0
  41. data/ext/kmat/smat/share.c +427 -0
  42. data/ext/kmat/smat/smat.c +530 -0
  43. data/ext/kmat/smat/sort.c +1156 -0
  44. data/ext/kmat/sym.txt +34 -0
  45. data/kmat.gemspec +46 -0
  46. data/lib/kmat.rb +20 -0
  47. data/lib/kmat/accessor.rb +164 -0
  48. data/lib/kmat/arith.rb +189 -0
  49. data/lib/kmat/linalg.rb +279 -0
  50. data/lib/kmat/logical.rb +150 -0
  51. data/lib/kmat/misc.rb +122 -0
  52. data/lib/kmat/random.rb +106 -0
  53. data/lib/kmat/statistics.rb +98 -0
  54. data/lib/kmat/version.rb +3 -0
  55. metadata +156 -0
@@ -0,0 +1,332 @@
1
+ #include "../kmat.h"
2
+
3
+ // the number of SMATs is specified by `argc'
4
+ // check whether the value types of the arguments are VT_BOOL or not
5
+ // raise Mat::ValueTypeError if at least one of the arguments is not a boolean matrix
6
+ void
7
+ km_check_bool(int argc, ...)
8
+ {
9
+ va_list argp;
10
+ va_start(argp, argc);
11
+ for ( int i=0; i<argc; i++ ) {
12
+ SMAT *smat = va_arg(argp, SMAT *);
13
+ if ( smat->vtype != VT_BOOL ) {
14
+ va_end(argp);
15
+ rb_raise(km_eVT, "boolean matrix is expected");
16
+ }
17
+ }
18
+ va_end(argp);
19
+ }
20
+
21
+
22
+ // element-wise logical operations
23
+ static void
24
+ km_not_func(bool *ent, void *null)
25
+ {
26
+ *ent = !(*ent);
27
+ }
28
+ VALUE
29
+ kmm_mat_not_dest(VALUE self)
30
+ {
31
+ km_check_frozen(self);
32
+ SMAT *smat = km_mat2smat(self);
33
+ km_check_bool(1, smat);
34
+ km_smat_each_b(smat, km_not_func, NULL);
35
+ return self;
36
+ }
37
+
38
+ static void
39
+ km_and_func(bool *dest, bool *other, void *null)
40
+ {
41
+ *dest = ( *dest && *other );
42
+ }
43
+ VALUE
44
+ kmm_mat_and_dest(VALUE self, VALUE other)
45
+ {
46
+ km_check_frozen(self);
47
+ SMAT *ss = km_mat2smat(self), *so = km_mat2smat(other);
48
+ km_check_bool(2, ss, so);
49
+ CHECK_SAME_SIZE(ss, so);
50
+ km_smat_each2_b(ss, so, km_and_func, NULL);
51
+ return self;
52
+ }
53
+
54
+ static void
55
+ km_or_func(bool *dest, bool *other, void *null)
56
+ {
57
+ *dest = ( *dest || *other );
58
+ }
59
+ VALUE
60
+ kmm_mat_or_dest(VALUE self, VALUE other)
61
+ {
62
+ km_check_frozen(self);
63
+ SMAT *ss = km_mat2smat(self), *so = km_mat2smat(other);
64
+ km_check_bool(2, ss, so);
65
+ CHECK_SAME_SIZE(ss, so);
66
+ km_smat_each2_b(ss, so, km_or_func, NULL);
67
+ return self;
68
+ }
69
+
70
+ static void
71
+ km_xor_func(bool *dest, bool *other, void *null)
72
+ {
73
+ *dest = XOR( *dest, *other );
74
+ }
75
+ VALUE
76
+ kmm_mat_xor_dest(VALUE self, VALUE other)
77
+ {
78
+ km_check_frozen(self);
79
+ SMAT *ss = km_mat2smat(self), *so = km_mat2smat(other);
80
+ km_check_bool(2, ss, so);
81
+ CHECK_SAME_SIZE(ss, so);
82
+ km_smat_each2_b(ss, so, km_xor_func, NULL);
83
+ return self;
84
+ }
85
+
86
+ // compare operations
87
+ static void
88
+ km_eq_d(bool *r, const double *a, const double *b, void *null)
89
+ {
90
+ *r = (*a == *b);
91
+ }
92
+ static void
93
+ km_eq_z(bool *r, const COMPLEX *a, const COMPLEX *b, void *null)
94
+ {
95
+ *r = (*a == *b);
96
+ }
97
+ static void
98
+ km_eq_i(bool *r, const int *a, const int *b, void *null)
99
+ {
100
+ *r = (*a == *b);
101
+ }
102
+ static void
103
+ km_eq_b(bool *r, const bool *a, const bool *b, void *null)
104
+ {
105
+ *r = (*a == *b);
106
+ }
107
+ static void
108
+ km_eq_v(bool *r, const VALUE *a, const VALUE *b, void *null)
109
+ {
110
+ *r = rb_funcall(*a, id_op_eq, 1, *b);
111
+ }
112
+ VALUE
113
+ kmm_mat_eq_destl(VALUE self, VALUE va, VALUE vb)
114
+ {
115
+ km_check_frozen(self);
116
+ SMAT *sr=km_mat2smat(self), *sa=km_mat2smat(va), *sb=km_mat2smat(vb);
117
+ km_check_bool(1, sr);
118
+ CHECK_SAME_SIZE(sr, sa);
119
+ CHECK_SAME_SIZE(sr, sb);
120
+ if ( sa->vtype != sb->vtype ) {
121
+ rb_raise(km_eVT, "value types must be same");
122
+ }
123
+ VT_SWITCH( sa->vtype,
124
+ km_smat_each3_bcdcd(sr, sa, sb, km_eq_d, NULL);,
125
+ km_smat_each3_bczcz(sr, sa, sb, km_eq_z, NULL);,
126
+ km_smat_each3_bcici(sr, sa, sb, km_eq_i, NULL);,
127
+ km_smat_each3_bcbcb(sr, sa, sb, km_eq_b, NULL);,
128
+ km_smat_each3_bcvcv(sr, sa, sb, km_eq_v, NULL);
129
+ );
130
+ return self;
131
+ }
132
+ static void
133
+ km_ne_d(bool *r, const double *a, const double *b, void *null)
134
+ {
135
+ *r = (*a != *b);
136
+ }
137
+ static void
138
+ km_ne_z(bool *r, const COMPLEX *a, const COMPLEX *b, void *null)
139
+ {
140
+ *r = (*a != *b);
141
+ }
142
+ static void
143
+ km_ne_i(bool *r, const int *a, const int *b, void *null)
144
+ {
145
+ *r = (*a != *b);
146
+ }
147
+ static void
148
+ km_ne_b(bool *r, const bool *a, const bool *b, void *null)
149
+ {
150
+ *r = (*a != *b);
151
+ }
152
+ static void
153
+ km_ne_v(bool *r, const VALUE *a, const VALUE *b, void *null)
154
+ {
155
+ *r = rb_funcall(*a, id_op_ne, 1, *b);
156
+ }
157
+ VALUE
158
+ kmm_mat_ne_destl(VALUE self, VALUE va, VALUE vb)
159
+ {
160
+ km_check_frozen(self);
161
+ SMAT *sr=km_mat2smat(self), *sa=km_mat2smat(va), *sb=km_mat2smat(vb);
162
+ km_check_bool(1, sr);
163
+ CHECK_SAME_SIZE(sr, sa);
164
+ CHECK_SAME_SIZE(sr, sb);
165
+ if ( sa->vtype != sb->vtype ) {
166
+ rb_raise(km_eVT, "value types must be same");
167
+ }
168
+ VT_SWITCH( sa->vtype,
169
+ km_smat_each3_bcdcd(sr, sa, sb, km_ne_d, NULL);,
170
+ km_smat_each3_bczcz(sr, sa, sb, km_ne_z, NULL);,
171
+ km_smat_each3_bcici(sr, sa, sb, km_ne_i, NULL);,
172
+ km_smat_each3_bcbcb(sr, sa, sb, km_ne_b, NULL);,
173
+ km_smat_each3_bcvcv(sr, sa, sb, km_ne_v, NULL);
174
+ );
175
+ return self;
176
+ }
177
+ static void
178
+ km_lt_d(bool *r, const double *a, const double *b, void *null)
179
+ {
180
+ *r = (*a < *b);
181
+ }
182
+ static void
183
+ km_lt_i(bool *r, const int *a, const int *b, void *null)
184
+ {
185
+ *r = (*a < *b);
186
+ }
187
+ static void
188
+ km_lt_v(bool *r, const VALUE *a, const VALUE *b, void *null)
189
+ {
190
+ *r = rb_funcall(*a, id_op_lt, 1, *b);
191
+ }
192
+ VALUE
193
+ kmm_mat_lt_destl(VALUE self, VALUE va, VALUE vb)
194
+ {
195
+ km_check_frozen(self);
196
+ SMAT *sr=km_mat2smat(self), *sa=km_mat2smat(va), *sb=km_mat2smat(vb);
197
+ km_check_bool(1, sr);
198
+ CHECK_SAME_SIZE(sr, sa);
199
+ CHECK_SAME_SIZE(sr, sb);
200
+ if ( sa->vtype != sb->vtype ) {
201
+ rb_raise(km_eVT, "value types must be same");
202
+ }
203
+ if ( sa->vtype == VT_DOUBLE ) {
204
+ km_smat_each3_bcdcd(sr, sa, sb, km_lt_d, NULL);
205
+ } else if ( sa->vtype == VT_INT ) {
206
+ km_smat_each3_bcici(sr, sa, sb, km_lt_i, NULL);
207
+ } else {
208
+ if ( sa->vtype != VT_VALUE ) {
209
+ sa = km_mat2smat(kmm_mat_to_omat(va));
210
+ sb = km_mat2smat(kmm_mat_to_omat(vb));
211
+ }
212
+ km_smat_each3_bcvcv(sr, sa, sb, km_lt_v, NULL);
213
+ }
214
+ return self;
215
+ }
216
+ static void
217
+ km_le_d(bool *r, const double *a, const double *b, void *null)
218
+ {
219
+ *r = (*a <= *b);
220
+ }
221
+ static void
222
+ km_le_i(bool *r, const int *a, const int *b, void *null)
223
+ {
224
+ *r = (*a <= *b);
225
+ }
226
+ static void
227
+ km_le_v(bool *r, const VALUE *a, const VALUE *b, void *null)
228
+ {
229
+ *r = rb_funcall(*a, id_op_le, 1, *b);
230
+ }
231
+ VALUE
232
+ kmm_mat_le_destl(VALUE self, VALUE va, VALUE vb)
233
+ {
234
+ km_check_frozen(self);
235
+ SMAT *sr=km_mat2smat(self), *sa=km_mat2smat(va), *sb=km_mat2smat(vb);
236
+ km_check_bool(1, sr);
237
+ CHECK_SAME_SIZE(sr, sa);
238
+ CHECK_SAME_SIZE(sr, sb);
239
+ if ( sa->vtype != sb->vtype ) {
240
+ rb_raise(km_eVT, "value types must be same");
241
+ }
242
+ if ( sa->vtype == VT_DOUBLE ) {
243
+ km_smat_each3_bcdcd(sr, sa, sb, km_le_d, NULL);
244
+ } else if ( sa->vtype == VT_INT ) {
245
+ km_smat_each3_bcici(sr, sa, sb, km_le_i, NULL);
246
+ } else {
247
+ if ( sa->vtype != VT_VALUE ) {
248
+ sa = km_mat2smat(kmm_mat_to_omat(va));
249
+ sb = km_mat2smat(kmm_mat_to_omat(vb));
250
+ }
251
+ km_smat_each3_bcvcv(sr, sa, sb, km_le_v, NULL);
252
+ }
253
+ return self;
254
+ }
255
+ static void
256
+ km_gt_d(bool *r, const double *a, const double *b, void *null)
257
+ {
258
+ *r = (*a > *b);
259
+ }
260
+ static void
261
+ km_gt_i(bool *r, const int *a, const int *b, void *null)
262
+ {
263
+ *r = (*a > *b);
264
+ }
265
+ static void
266
+ km_gt_v(bool *r, const VALUE *a, const VALUE *b, void *null)
267
+ {
268
+ *r = rb_funcall(*a, id_op_gt, 1, *b);
269
+ }
270
+ VALUE
271
+ kmm_mat_gt_destl(VALUE self, VALUE va, VALUE vb)
272
+ {
273
+ km_check_frozen(self);
274
+ SMAT *sr=km_mat2smat(self), *sa=km_mat2smat(va), *sb=km_mat2smat(vb);
275
+ km_check_bool(1, sr);
276
+ CHECK_SAME_SIZE(sr, sa);
277
+ CHECK_SAME_SIZE(sr, sb);
278
+ if ( sa->vtype != sb->vtype ) {
279
+ rb_raise(km_eVT, "value types must be same");
280
+ }
281
+ if ( sa->vtype == VT_DOUBLE ) {
282
+ km_smat_each3_bcdcd(sr, sa, sb, km_gt_d, NULL);
283
+ } else if ( sa->vtype == VT_INT ) {
284
+ km_smat_each3_bcici(sr, sa, sb, km_gt_i, NULL);
285
+ } else {
286
+ if ( sa->vtype != VT_VALUE ) {
287
+ sa = km_mat2smat(kmm_mat_to_omat(va));
288
+ sb = km_mat2smat(kmm_mat_to_omat(vb));
289
+ }
290
+ km_smat_each3_bcvcv(sr, sa, sb, km_gt_v, NULL);
291
+ }
292
+ return self;
293
+ }
294
+ static void
295
+ km_ge_d(bool *r, const double *a, const double *b, void *null)
296
+ {
297
+ *r = (*a >= *b);
298
+ }
299
+ static void
300
+ km_ge_i(bool *r, const int *a, const int *b, void *null)
301
+ {
302
+ *r = (*a >= *b);
303
+ }
304
+ static void
305
+ km_ge_v(bool *r, const VALUE *a, const VALUE *b, void *null)
306
+ {
307
+ *r = rb_funcall(*a, id_op_ge, 1, *b);
308
+ }
309
+ VALUE
310
+ kmm_mat_ge_destl(VALUE self, VALUE va, VALUE vb)
311
+ {
312
+ km_check_frozen(self);
313
+ SMAT *sr=km_mat2smat(self), *sa=km_mat2smat(va), *sb=km_mat2smat(vb);
314
+ km_check_bool(1, sr);
315
+ CHECK_SAME_SIZE(sr, sa);
316
+ CHECK_SAME_SIZE(sr, sb);
317
+ if ( sa->vtype != sb->vtype ) {
318
+ rb_raise(km_eVT, "value types must be same");
319
+ }
320
+ if ( sa->vtype == VT_DOUBLE ) {
321
+ km_smat_each3_bcdcd(sr, sa, sb, km_ge_d, NULL);
322
+ } else if ( sa->vtype == VT_INT ) {
323
+ km_smat_each3_bcici(sr, sa, sb, km_ge_i, NULL);
324
+ } else {
325
+ if ( sa->vtype != VT_VALUE ) {
326
+ sa = km_mat2smat(kmm_mat_to_omat(va));
327
+ sb = km_mat2smat(kmm_mat_to_omat(vb));
328
+ }
329
+ km_smat_each3_bcvcv(sr, sa, sb, km_ge_v, NULL);
330
+ }
331
+ return self;
332
+ }
@@ -0,0 +1,34 @@
1
+ #include "../kmat.h"
2
+
3
+ VALUE
4
+ kmm_MATH_exp2(VALUE self, VALUE x)
5
+ {
6
+ return rb_float_new(exp2(NUM2DBL(x)));
7
+ }
8
+
9
+ VALUE
10
+ kmm_MATH_expm1(VALUE self, VALUE x)
11
+ {
12
+ return rb_float_new(expm1(NUM2DBL(x)));
13
+ }
14
+
15
+ VALUE
16
+ kmm_MATH_log1p(VALUE self, VALUE x)
17
+ {
18
+ return rb_float_new(log1p(NUM2DBL(x)));
19
+ }
20
+
21
+ VALUE
22
+ kmm_float_sign(VALUE self)
23
+ {
24
+ double x = NUM2DBL(self);
25
+ if ( x == 0.0 ) {
26
+ return INT2NUM(0);
27
+ } else if ( x > 0.0 ) {
28
+ return INT2NUM(1);
29
+ } else if ( x < 0.0 ) {
30
+ return INT2NUM(-1);
31
+ } else {
32
+ return self;
33
+ }
34
+ }
@@ -0,0 +1,173 @@
1
+ #include "../kmat.h"
2
+
3
+ // product of all elements
4
+ void
5
+ km_prod_d(double *ent, void *data)
6
+ {
7
+ double *ret = (double *)data;
8
+ *ret *= *ent;
9
+ }
10
+ void
11
+ km_prod_z(COMPLEX *ent, void *data)
12
+ {
13
+ COMPLEX *ret = (COMPLEX *)data;
14
+ *ret *= *ent;
15
+ }
16
+ void
17
+ km_prod_i(int *ent, void *data)
18
+ {
19
+ int *ret = (int *)data;
20
+ *ret *= *ent;
21
+ }
22
+ void
23
+ km_prod_v(VALUE *ent, void *data)
24
+ {
25
+ VALUE *ret = (VALUE *)data;
26
+ *ret = rb_funcall(*ret, id_op_mul, 1, *ent);
27
+ }
28
+ VALUE
29
+ kmm_mat_prod(VALUE self)
30
+ {
31
+ SMAT *smat = km_mat2smat(self);
32
+ VT_SWITCH( smat->vtype,
33
+ double ret=1.0; km_smat_each_d(smat, km_prod_d, (void *)(&ret)); return rb_float_new(ret);,
34
+ COMPLEX ret=cpack(1.0, 0.0); km_smat_each_z(smat, km_prod_z, (void *)(&ret)); return km_c2v(ret);,
35
+ int ret=1; km_smat_each_i(smat, km_prod_i, (void *)(&ret)); return INT2NUM(ret);,
36
+ return rb_funcall(self, id_all_p, 0);,
37
+ VALUE ret=INT2NUM(1); km_smat_each_v(smat, km_prod_v, (void *)(&ret)); return ret;
38
+ );
39
+ }
40
+
41
+ // summation
42
+ // the shape of the output-argument determines the axis of summations
43
+ void
44
+ km_sum_all_d(double *ent, void *data)
45
+ {
46
+ double *ret = (double *)data;
47
+ *ret += *ent;
48
+ }
49
+ void
50
+ km_sum_all_z(COMPLEX *ent, void *data)
51
+ {
52
+ COMPLEX *ret = (COMPLEX *)data;
53
+ *ret += *ent;
54
+ }
55
+ void
56
+ km_sum_all_i(int *ent, void *data)
57
+ {
58
+ int *ret = (int *)data;
59
+ *ret += *ent;
60
+ }
61
+ void
62
+ km_sum_all_b(bool *ent, void *data)
63
+ {
64
+ bool *ret = (bool *)data;
65
+ *ret = XOR(*ret, *ent);
66
+ }
67
+ void
68
+ km_sum_all_v(VALUE *ent, void *data)
69
+ {
70
+ VALUE *ret = (VALUE *)data;
71
+ *ret = rb_funcall(*ret, id_op_plus, 1, *ent);
72
+ }
73
+ void
74
+ km_sum_col_d(double *ent, int i, int j, void *data)
75
+ {
76
+ double *r = (double *)data;
77
+ r[j] += *ent;
78
+ }
79
+ void
80
+ km_sum_col_z(COMPLEX *ent, int i, int j, void *data)
81
+ {
82
+ COMPLEX *r = (COMPLEX *)data;
83
+ r[j] += *ent;
84
+ }
85
+ void
86
+ km_sum_col_i(int *ent, int i, int j, void *data)
87
+ {
88
+ int *r = (int *)data;
89
+ r[j] += *ent;
90
+ }
91
+ void
92
+ km_sum_col_b(bool *ent, int i, int j, void *data)
93
+ {
94
+ bool *r = (bool *)data;
95
+ r[j] = XOR(r[j], *ent);
96
+ }
97
+ void
98
+ km_sum_col_v(VALUE *ent, int i, int j, void *data)
99
+ {
100
+ VALUE *r = (VALUE *)data;
101
+ r[j] = rb_funcall(r[j], id_op_plus, 1, *ent);
102
+ }
103
+ void
104
+ km_sum_row_d(double *ent, int i, int j, void *data)
105
+ {
106
+ double *r = (double *)data;
107
+ r[i] += *ent;
108
+ }
109
+ void
110
+ km_sum_row_z(COMPLEX *ent, int i, int j, void *data)
111
+ {
112
+ COMPLEX *r = (COMPLEX *)data;
113
+ r[i] += *ent;
114
+ }
115
+ void
116
+ km_sum_row_i(int *ent, int i, int j, void *data)
117
+ {
118
+ int *r = (int *)data;
119
+ r[i] += *ent;
120
+ }
121
+ void
122
+ km_sum_row_b(bool *ent, int i, int j, void *data)
123
+ {
124
+ bool *r = (bool *)data;
125
+ r[i] = XOR(r[i], *ent);
126
+ }
127
+ void
128
+ km_sum_row_v(VALUE *ent, int i, int j, void *data)
129
+ {
130
+ VALUE *r = (VALUE *)data;
131
+ r[i] = rb_funcall(r[i], id_op_plus, 1, *ent);
132
+ }
133
+ VALUE
134
+ kmm_mat__sum(VALUE self, VALUE dest)
135
+ {
136
+ km_check_frozen(dest);
137
+ SMAT *sr = km_mat2smat(dest), *sa = km_mat2smat(self);
138
+ if ( sr->vtype != sa->vtype ) { rb_raise(km_eVT, "value types must be same"); }
139
+ if ( sr->stype != ST_FULL ) { rb_raise(km_eShare, "the argument must be a full matrix"); }
140
+ sr->trans = false; sr->ld = sr->m;
141
+ if ( sr->m == 1 && sr->n == 1 ) {
142
+ VT_SWITCH( sr->vtype,
143
+ sr->dbody[0]=0.0; km_smat_each_d(sa, km_sum_all_d, sr->body); return rb_float_new(sr->dbody[0]);,
144
+ sr->zbody[0]=cpack(0.0, 0.0); km_smat_each_z(sa, km_sum_all_z, sr->body); return km_c2v(sr->zbody[0]);,
145
+ sr->ibody[0]=0; km_smat_each_i(sa, km_sum_all_i, sr->body); return INT2NUM(sr->ibody[0]);,
146
+ sr->bbody[0]=false; km_smat_each_b(sa, km_sum_all_b, sr->body); return TF2V(sr->bbody[0]);,
147
+ sr->vbody[0]=INT2NUM(0); km_smat_each_v(sa, km_sum_all_v, sr->body); return sr->vbody[0];
148
+ );
149
+ } else if ( sr->m == 1 && sr->n == sa->n ) {
150
+ kmm_mat_zero(dest);
151
+ VT_SWITCH( sr->vtype,
152
+ km_smat_each_with_index_d(sa, km_sum_col_d, sr->body);,
153
+ km_smat_each_with_index_z(sa, km_sum_col_z, sr->body);,
154
+ km_smat_each_with_index_i(sa, km_sum_col_i, sr->body);,
155
+ km_smat_each_with_index_b(sa, km_sum_col_b, sr->body);,
156
+ km_smat_each_with_index_v(sa, km_sum_col_v, sr->body);
157
+ );
158
+ } else if ( sr->m == sa->m && sr->n == 1 ) {
159
+ kmm_mat_zero(dest);
160
+ VT_SWITCH( sr->vtype,
161
+ km_smat_each_with_index_d(sa, km_sum_row_d, sr->body);,
162
+ km_smat_each_with_index_z(sa, km_sum_row_z, sr->body);,
163
+ km_smat_each_with_index_i(sa, km_sum_row_i, sr->body);,
164
+ km_smat_each_with_index_b(sa, km_sum_row_b, sr->body);,
165
+ km_smat_each_with_index_v(sa, km_sum_row_v, sr->body);
166
+ );
167
+ } else if ( SAME_SIZE(sr, sa) ) {
168
+ km_smat_copy(sr, sa);
169
+ } else {
170
+ rb_raise(km_eDim, "sum from size (%d, %d) to size (%d, %d) is not defined", sa->m, sa->n, sr->m, sr->n);
171
+ }
172
+ return dest;
173
+ }