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.
- checksums.yaml +7 -0
- data/.gitattributes +3 -0
- data/.gitignore +15 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +4 -0
- data/LICENSE.md +675 -0
- data/README.md +224 -0
- data/Rakefile +26 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/kmat/arith/binary.c +1121 -0
- data/ext/kmat/arith/logical.c +332 -0
- data/ext/kmat/arith/math.c +34 -0
- data/ext/kmat/arith/statistics.c +173 -0
- data/ext/kmat/arith/unary.c +165 -0
- data/ext/kmat/auto_collect.rb +118 -0
- data/ext/kmat/elementwise_function.rb +149 -0
- data/ext/kmat/extconf.rb +75 -0
- data/ext/kmat/id.txt +80 -0
- data/ext/kmat/id_sym.rb +40 -0
- data/ext/kmat/km_util.h +97 -0
- data/ext/kmat/kmat.h +96 -0
- data/ext/kmat/lapack_headers/blas.h +354 -0
- data/ext/kmat/lapack_headers/lapacke.h +19455 -0
- data/ext/kmat/lapack_headers/lapacke_config.h +119 -0
- data/ext/kmat/lapack_headers/lapacke_mangling.h +17 -0
- data/ext/kmat/lapack_headers/lapacke_utils.h +579 -0
- data/ext/kmat/linalg/dla.c +1629 -0
- data/ext/kmat/linalg/linalg.c +267 -0
- data/ext/kmat/linalg/norm.c +727 -0
- data/ext/kmat/linalg/vla.c +102 -0
- data/ext/kmat/linalg/working.c +240 -0
- data/ext/kmat/main.c +95 -0
- data/ext/kmat/smat/accessor.c +719 -0
- data/ext/kmat/smat/array.c +108 -0
- data/ext/kmat/smat/boxmuller.c +72 -0
- data/ext/kmat/smat/constructer.c +302 -0
- data/ext/kmat/smat/convert.c +375 -0
- data/ext/kmat/smat/elem.c +171 -0
- data/ext/kmat/smat/fund.c +702 -0
- data/ext/kmat/smat/share.c +427 -0
- data/ext/kmat/smat/smat.c +530 -0
- data/ext/kmat/smat/sort.c +1156 -0
- data/ext/kmat/sym.txt +34 -0
- data/kmat.gemspec +46 -0
- data/lib/kmat.rb +20 -0
- data/lib/kmat/accessor.rb +164 -0
- data/lib/kmat/arith.rb +189 -0
- data/lib/kmat/linalg.rb +279 -0
- data/lib/kmat/logical.rb +150 -0
- data/lib/kmat/misc.rb +122 -0
- data/lib/kmat/random.rb +106 -0
- data/lib/kmat/statistics.rb +98 -0
- data/lib/kmat/version.rb +3 -0
- 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
|
+
}
|