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,375 @@
|
|
1
|
+
#include "../kmat.h"
|
2
|
+
|
3
|
+
// alias to_m!
|
4
|
+
VALUE
|
5
|
+
kmm_mat_to_mat_destl(int argc, VALUE *argv, VALUE self)
|
6
|
+
{
|
7
|
+
rb_check_arity(argc, 0, 1);
|
8
|
+
if ( argc == 0 ) {
|
9
|
+
return self;
|
10
|
+
} else {
|
11
|
+
VT_SWITCH( km_sym2vt(argv[0]),
|
12
|
+
return kmm_mat_to_fmat_destl(self);,
|
13
|
+
return kmm_mat_to_cmat_destl(self);,
|
14
|
+
return kmm_mat_to_imat_destl(self);,
|
15
|
+
return kmm_mat_to_bmat_destl(self);,
|
16
|
+
return kmm_mat_to_omat_destl(self);
|
17
|
+
);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
// alias to_m
|
22
|
+
VALUE
|
23
|
+
kmm_mat_to_mat(int argc, VALUE *argv, VALUE self)
|
24
|
+
{
|
25
|
+
rb_check_arity(argc, 0, 1);
|
26
|
+
if ( argc == 0 ) {
|
27
|
+
return rb_funcall(self, id_dup, 0);
|
28
|
+
} else {
|
29
|
+
VT_SWITCH( km_sym2vt(argv[0]),
|
30
|
+
return kmm_mat_to_fmat(self);,
|
31
|
+
return kmm_mat_to_cmat(self);,
|
32
|
+
return kmm_mat_to_imat(self);,
|
33
|
+
return kmm_mat_to_bmat(self);,
|
34
|
+
return kmm_mat_to_omat(self);
|
35
|
+
);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
|
40
|
+
struct km_conv_arg {
|
41
|
+
union {
|
42
|
+
void *body;
|
43
|
+
double *dbody;
|
44
|
+
COMPLEX *zbody;
|
45
|
+
int *ibody;
|
46
|
+
bool *bbody;
|
47
|
+
VALUE *vbody;
|
48
|
+
};
|
49
|
+
int ldb;
|
50
|
+
};
|
51
|
+
|
52
|
+
static void
|
53
|
+
z2d_func(COMPLEX *ent, int i, int j, void *data_)
|
54
|
+
{
|
55
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
56
|
+
(data->dbody)[i+j*(data->ldb)] = creal(*ent);
|
57
|
+
}
|
58
|
+
static void
|
59
|
+
i2d_func(int *ent, int i, int j, void *data_)
|
60
|
+
{
|
61
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
62
|
+
(data->dbody)[i+j*(data->ldb)] = (double)*ent;
|
63
|
+
}
|
64
|
+
static void
|
65
|
+
b2d_func(bool *ent, int i, int j, void *data_)
|
66
|
+
{
|
67
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
68
|
+
(data->dbody)[i+j*(data->ldb)] = (*ent ? 1.0 : 0.0);
|
69
|
+
}
|
70
|
+
static void
|
71
|
+
v2d_func(VALUE *ent, int i, int j, void *data_)
|
72
|
+
{
|
73
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
74
|
+
(data->dbody)[i+j*(data->ldb)] = NUM2DBL(*ent);
|
75
|
+
}
|
76
|
+
VALUE
|
77
|
+
kmm_mat_to_fmat_destl(VALUE self)
|
78
|
+
{
|
79
|
+
km_check_frozen(self);
|
80
|
+
SMAT *src = km_mat2smat(self);
|
81
|
+
if ( src->vtype == VT_DOUBLE ) {
|
82
|
+
return self;
|
83
|
+
}
|
84
|
+
SMAT *dest = km_smat_alloc(src->m, src->n, VT_DOUBLE);
|
85
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
86
|
+
VT_SWITCH( src->vtype,
|
87
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
88
|
+
km_smat_each_with_index_z(src, z2d_func, &data);,
|
89
|
+
km_smat_each_with_index_i(src, i2d_func, &data);,
|
90
|
+
km_smat_each_with_index_b(src, b2d_func, &data);,
|
91
|
+
km_smat_each_with_index_v(src, v2d_func, &data);
|
92
|
+
);
|
93
|
+
km_smat_copy(src, dest);
|
94
|
+
return self;
|
95
|
+
}
|
96
|
+
VALUE
|
97
|
+
kmm_mat_to_fmat(VALUE self)
|
98
|
+
{
|
99
|
+
km_check_frozen(self);
|
100
|
+
SMAT *src = km_mat2smat(self);
|
101
|
+
if ( src->vtype == VT_DOUBLE ) {
|
102
|
+
return rb_funcall(self, id_dup, 0);
|
103
|
+
}
|
104
|
+
VALUE ret = km_Mat(src->m, src->n, VT_DOUBLE);
|
105
|
+
SMAT *dest = km_mat2smat(ret);
|
106
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
107
|
+
VT_SWITCH( src->vtype,
|
108
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
109
|
+
km_smat_each_with_index_z(src, z2d_func, &data);,
|
110
|
+
km_smat_each_with_index_i(src, i2d_func, &data);,
|
111
|
+
km_smat_each_with_index_b(src, b2d_func, &data);,
|
112
|
+
km_smat_each_with_index_v(src, v2d_func, &data);
|
113
|
+
);
|
114
|
+
return ret;
|
115
|
+
}
|
116
|
+
|
117
|
+
static void
|
118
|
+
d2z_func(double *ent, int i, int j, void *data_)
|
119
|
+
{
|
120
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
121
|
+
(data->zbody)[i+j*(data->ldb)] = cpack(*ent, 0.0);
|
122
|
+
}
|
123
|
+
static void
|
124
|
+
i2z_func(int *ent, int i, int j, void *data_)
|
125
|
+
{
|
126
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
127
|
+
(data->zbody)[i+j*(data->ldb)] = cpack((double)*ent, 0.0);
|
128
|
+
}
|
129
|
+
static void
|
130
|
+
b2z_func(bool *ent, int i, int j, void *data_)
|
131
|
+
{
|
132
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
133
|
+
(data->zbody)[i+j*(data->ldb)] = (*ent ? cpack(1.0, 0.0) : cpack(0.0, 0.0));
|
134
|
+
}
|
135
|
+
static void
|
136
|
+
v2z_func(VALUE *ent, int i, int j, void *data_)
|
137
|
+
{
|
138
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
139
|
+
(data->zbody)[i+j*(data->ldb)] = km_v2c(*ent);
|
140
|
+
}
|
141
|
+
VALUE
|
142
|
+
kmm_mat_to_cmat_destl(VALUE self)
|
143
|
+
{
|
144
|
+
km_check_frozen(self);
|
145
|
+
SMAT *src = km_mat2smat(self);
|
146
|
+
if ( src->vtype == VT_COMPLEX ) {
|
147
|
+
return self;
|
148
|
+
}
|
149
|
+
SMAT *dest = km_smat_alloc(src->m, src->n, VT_COMPLEX);
|
150
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
151
|
+
VT_SWITCH( src->vtype,
|
152
|
+
km_smat_each_with_index_d(src, d2z_func, &data);,
|
153
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
154
|
+
km_smat_each_with_index_i(src, i2z_func, &data);,
|
155
|
+
km_smat_each_with_index_b(src, b2z_func, &data);,
|
156
|
+
km_smat_each_with_index_v(src, v2z_func, &data);
|
157
|
+
);
|
158
|
+
km_smat_copy(src, dest);
|
159
|
+
return self;
|
160
|
+
}
|
161
|
+
VALUE
|
162
|
+
kmm_mat_to_cmat(VALUE self)
|
163
|
+
{
|
164
|
+
km_check_frozen(self);
|
165
|
+
SMAT *src = km_mat2smat(self);
|
166
|
+
if ( src->vtype == VT_COMPLEX ) {
|
167
|
+
return rb_funcall(self, id_dup, 0);
|
168
|
+
}
|
169
|
+
VALUE ret = km_Mat(src->m, src->n, VT_COMPLEX);
|
170
|
+
SMAT *dest = km_mat2smat(ret);
|
171
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
172
|
+
VT_SWITCH( src->vtype,
|
173
|
+
km_smat_each_with_index_d(src, d2z_func, &data);,
|
174
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
175
|
+
km_smat_each_with_index_i(src, i2z_func, &data);,
|
176
|
+
km_smat_each_with_index_b(src, b2z_func, &data);,
|
177
|
+
km_smat_each_with_index_v(src, v2z_func, &data);
|
178
|
+
);
|
179
|
+
return ret;
|
180
|
+
}
|
181
|
+
|
182
|
+
static void
|
183
|
+
d2i_func(double *ent, int i, int j, void *data_)
|
184
|
+
{
|
185
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
186
|
+
(data->ibody)[i+j*(data->ldb)] = (int)(*ent);
|
187
|
+
}
|
188
|
+
static void
|
189
|
+
z2i_func(COMPLEX *ent, int i, int j, void *data_)
|
190
|
+
{
|
191
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
192
|
+
(data->ibody)[i+j*(data->ldb)] = (int)creal(*ent);
|
193
|
+
}
|
194
|
+
static void
|
195
|
+
b2i_func(bool *ent, int i, int j, void *data_)
|
196
|
+
{
|
197
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
198
|
+
(data->ibody)[i+j*(data->ldb)] = (*ent ? 1 : 0);
|
199
|
+
}
|
200
|
+
static void
|
201
|
+
v2i_func(VALUE *ent, int i, int j, void *data_)
|
202
|
+
{
|
203
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
204
|
+
(data->ibody)[i+j*(data->ldb)] = NUM2INT(*ent);
|
205
|
+
}
|
206
|
+
VALUE
|
207
|
+
kmm_mat_to_imat_destl(VALUE self)
|
208
|
+
{
|
209
|
+
km_check_frozen(self);
|
210
|
+
SMAT *src = km_mat2smat(self);
|
211
|
+
if ( src->vtype == VT_INT ) {
|
212
|
+
return self;
|
213
|
+
}
|
214
|
+
SMAT *dest = km_smat_alloc(src->m, src->n, VT_INT);
|
215
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
216
|
+
VT_SWITCH( src->vtype,
|
217
|
+
km_smat_each_with_index_d(src, d2i_func, &data);,
|
218
|
+
km_smat_each_with_index_z(src, z2i_func, &data);,
|
219
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
220
|
+
km_smat_each_with_index_b(src, b2i_func, &data);,
|
221
|
+
km_smat_each_with_index_v(src, v2i_func, &data);
|
222
|
+
);
|
223
|
+
km_smat_copy(src, dest);
|
224
|
+
return self;
|
225
|
+
}
|
226
|
+
VALUE
|
227
|
+
kmm_mat_to_imat(VALUE self)
|
228
|
+
{
|
229
|
+
km_check_frozen(self);
|
230
|
+
SMAT *src = km_mat2smat(self);
|
231
|
+
if ( src->vtype == VT_INT ) {
|
232
|
+
return rb_funcall(self, id_dup, 0);
|
233
|
+
}
|
234
|
+
VALUE ret = km_Mat(src->m, src->n, VT_INT);
|
235
|
+
SMAT *dest = km_mat2smat(ret);
|
236
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
237
|
+
VT_SWITCH( src->vtype,
|
238
|
+
km_smat_each_with_index_d(src, d2i_func, &data);,
|
239
|
+
km_smat_each_with_index_z(src, z2i_func, &data);,
|
240
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
241
|
+
km_smat_each_with_index_b(src, b2i_func, &data);,
|
242
|
+
km_smat_each_with_index_v(src, v2i_func, &data);
|
243
|
+
);
|
244
|
+
return ret;
|
245
|
+
}
|
246
|
+
|
247
|
+
static void
|
248
|
+
d2b_func(double *ent, int i, int j, void *data_)
|
249
|
+
{
|
250
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
251
|
+
(data->bbody)[i+j*(data->ldb)] = (*ent != 0.0);
|
252
|
+
}
|
253
|
+
static void
|
254
|
+
z2b_func(COMPLEX *ent, int i, int j, void *data_)
|
255
|
+
{
|
256
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
257
|
+
(data->bbody)[i+j*(data->ldb)] = (*ent != cpack(0.0, 0.0));
|
258
|
+
}
|
259
|
+
static void
|
260
|
+
i2b_func(int *ent, int i, int j, void *data_)
|
261
|
+
{
|
262
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
263
|
+
(data->bbody)[i+j*(data->ldb)] = (*ent != 0);
|
264
|
+
}
|
265
|
+
static void
|
266
|
+
v2b_func(VALUE *ent, int i, int j, void *data_)
|
267
|
+
{
|
268
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
269
|
+
(data->bbody)[i+j*(data->ldb)] = RTEST(*ent);
|
270
|
+
}
|
271
|
+
VALUE
|
272
|
+
kmm_mat_to_bmat_destl(VALUE self)
|
273
|
+
{
|
274
|
+
km_check_frozen(self);
|
275
|
+
SMAT *src = km_mat2smat(self);
|
276
|
+
if ( src->vtype == VT_BOOL ) {
|
277
|
+
return self;
|
278
|
+
}
|
279
|
+
SMAT *dest = km_smat_alloc(src->m, src->n, VT_BOOL);
|
280
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
281
|
+
VT_SWITCH( src->vtype,
|
282
|
+
km_smat_each_with_index_d(src, d2b_func, &data);,
|
283
|
+
km_smat_each_with_index_z(src, z2b_func, &data);,
|
284
|
+
km_smat_each_with_index_i(src, i2b_func, &data);,
|
285
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
286
|
+
km_smat_each_with_index_v(src, v2b_func, &data);
|
287
|
+
);
|
288
|
+
km_smat_copy(src, dest);
|
289
|
+
return self;
|
290
|
+
}
|
291
|
+
VALUE
|
292
|
+
kmm_mat_to_bmat(VALUE self)
|
293
|
+
{
|
294
|
+
km_check_frozen(self);
|
295
|
+
SMAT *src = km_mat2smat(self);
|
296
|
+
if ( src->vtype == VT_BOOL ) {
|
297
|
+
return rb_funcall(self, id_dup, 0);
|
298
|
+
}
|
299
|
+
VALUE ret = km_Mat(src->m, src->n, VT_BOOL);
|
300
|
+
SMAT *dest = km_mat2smat(ret);
|
301
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
302
|
+
VT_SWITCH( src->vtype,
|
303
|
+
km_smat_each_with_index_d(src, d2b_func, &data);,
|
304
|
+
km_smat_each_with_index_z(src, z2b_func, &data);,
|
305
|
+
km_smat_each_with_index_i(src, i2b_func, &data);,
|
306
|
+
rb_raise(km_eInternal, "unexpected reach");,
|
307
|
+
km_smat_each_with_index_v(src, v2b_func, &data);
|
308
|
+
);
|
309
|
+
return ret;
|
310
|
+
}
|
311
|
+
|
312
|
+
static void
|
313
|
+
d2v_func(double *ent, int i, int j, void *data_)
|
314
|
+
{
|
315
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
316
|
+
(data->vbody)[i+j*(data->ldb)] = rb_float_new(*ent);
|
317
|
+
}
|
318
|
+
static void
|
319
|
+
z2v_func(COMPLEX *ent, int i, int j, void *data_)
|
320
|
+
{
|
321
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
322
|
+
(data->vbody)[i+j*(data->ldb)] = km_c2v(*ent);
|
323
|
+
}
|
324
|
+
static void
|
325
|
+
i2v_func(int *ent, int i, int j, void *data_)
|
326
|
+
{
|
327
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
328
|
+
(data->vbody)[i+j*(data->ldb)] = INT2NUM(*ent);
|
329
|
+
}
|
330
|
+
static void
|
331
|
+
b2v_func(bool *ent, int i, int j, void *data_)
|
332
|
+
{
|
333
|
+
struct km_conv_arg *data = (struct km_conv_arg *)data_;
|
334
|
+
(data->vbody)[i+j*(data->ldb)] = TF2V(*ent);
|
335
|
+
}
|
336
|
+
VALUE
|
337
|
+
kmm_mat_to_omat_destl(VALUE self)
|
338
|
+
{
|
339
|
+
km_check_frozen(self);
|
340
|
+
SMAT *src = km_mat2smat(self);
|
341
|
+
if ( src->vtype == VT_VALUE ) {
|
342
|
+
return self;
|
343
|
+
}
|
344
|
+
SMAT *dest = km_smat_alloc(src->m, src->n, VT_VALUE);
|
345
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
346
|
+
VT_SWITCH( src->vtype,
|
347
|
+
km_smat_each_with_index_d(src, d2v_func, &data);,
|
348
|
+
km_smat_each_with_index_z(src, z2v_func, &data);,
|
349
|
+
km_smat_each_with_index_i(src, i2v_func, &data);,
|
350
|
+
km_smat_each_with_index_b(src, b2v_func, &data);,
|
351
|
+
rb_raise(km_eInternal, "unexpected reach");
|
352
|
+
);
|
353
|
+
km_smat_copy(src, dest);
|
354
|
+
return self;
|
355
|
+
}
|
356
|
+
VALUE
|
357
|
+
kmm_mat_to_omat(VALUE self)
|
358
|
+
{
|
359
|
+
km_check_frozen(self);
|
360
|
+
SMAT *src = km_mat2smat(self);
|
361
|
+
if ( src->vtype == VT_VALUE ) {
|
362
|
+
return rb_funcall(self, id_dup, 0);
|
363
|
+
}
|
364
|
+
VALUE ret = km_Mat(src->m, src->n, VT_VALUE);
|
365
|
+
SMAT *dest = km_mat2smat(ret);
|
366
|
+
struct km_conv_arg data = {{dest->body}, dest->ld};
|
367
|
+
VT_SWITCH( src->vtype,
|
368
|
+
km_smat_each_with_index_d(src, d2v_func, &data);,
|
369
|
+
km_smat_each_with_index_z(src, z2v_func, &data);,
|
370
|
+
km_smat_each_with_index_i(src, i2v_func, &data);,
|
371
|
+
km_smat_each_with_index_b(src, b2v_func, &data);,
|
372
|
+
rb_raise(km_eInternal, "unexpected reach");
|
373
|
+
);
|
374
|
+
return ret;
|
375
|
+
}
|
@@ -0,0 +1,171 @@
|
|
1
|
+
#include "../kmat.h"
|
2
|
+
|
3
|
+
// returns sizeof values of the elements with value type `vt'
|
4
|
+
size_t
|
5
|
+
km_sizeof_vt(VTYPE vt)
|
6
|
+
{
|
7
|
+
VT_SWITCH( vt,
|
8
|
+
return sizeof(double);,
|
9
|
+
return sizeof(COMPLEX);,
|
10
|
+
return sizeof(int);,
|
11
|
+
return sizeof(bool);,
|
12
|
+
return sizeof(VALUE);
|
13
|
+
);
|
14
|
+
}
|
15
|
+
|
16
|
+
// replace the body of `dest' by complex values with real parts `real' and imaginary parts `imag'
|
17
|
+
static void
|
18
|
+
km_smat_complex_func(COMPLEX *ed, const double *er, const double *ei, void *null)
|
19
|
+
{
|
20
|
+
*ed = cpack(*er, *ei);
|
21
|
+
}
|
22
|
+
|
23
|
+
void
|
24
|
+
km_smat_complex(SMAT *dest, const SMAT *real, const SMAT *imag)
|
25
|
+
{
|
26
|
+
if ( dest->vtype != VT_COMPLEX || real->vtype != VT_DOUBLE || imag->vtype != VT_DOUBLE ) {
|
27
|
+
rb_raise(km_eVT, "unmatched value type");
|
28
|
+
}
|
29
|
+
CHECK_SAME_SIZE(dest, real);
|
30
|
+
CHECK_SAME_SIZE(dest, imag);
|
31
|
+
dest->trans = false;
|
32
|
+
km_smat_each3_zcdcd(dest, real, imag, km_smat_complex_func, NULL);
|
33
|
+
}
|
34
|
+
|
35
|
+
// returns value type from a Symbol `vsym'
|
36
|
+
VTYPE
|
37
|
+
km_sym2vt(VALUE vsym)
|
38
|
+
{
|
39
|
+
if ( rb_respond_to(vsym, id_to_sym) ) {
|
40
|
+
vsym = rb_funcall(vsym, id_to_sym, 0);
|
41
|
+
}
|
42
|
+
if ( vsym == sym_float || vsym == sym_f || vsym == sym_double || vsym == sym_d ) {
|
43
|
+
return VT_DOUBLE;
|
44
|
+
} else if ( vsym == sym_complex || vsym == sym_c || vsym == sym_z ) {
|
45
|
+
return VT_COMPLEX;
|
46
|
+
} else if ( vsym == sym_int || vsym == sym_integer || vsym == sym_i ) {
|
47
|
+
return VT_INT;
|
48
|
+
} else if ( vsym == sym_bool || vsym == sym_boolean || vsym == sym_b ) {
|
49
|
+
return VT_BOOL;
|
50
|
+
} else if ( vsym == sym_object || vsym == sym_o || vsym == sym_value || vsym == sym_v ) {
|
51
|
+
return VT_VALUE;
|
52
|
+
} else {
|
53
|
+
rb_raise(rb_eArgError, "unknown value type");
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
// convert ruby-object `obj' to COMPLEX value in C
|
58
|
+
COMPLEX
|
59
|
+
km_v2c(VALUE obj)
|
60
|
+
{
|
61
|
+
VALUE c_obj = rb_funcall(obj, id_to_c, 0);
|
62
|
+
double x = NUM2DBL(rb_funcall(c_obj, id_real, 0));
|
63
|
+
double y = NUM2DBL(rb_funcall(c_obj, id_imag, 0));
|
64
|
+
return cpack(x, y);
|
65
|
+
}
|
66
|
+
|
67
|
+
// convert COMPLEX value `c' in C to an instance of Complex in Ruby
|
68
|
+
VALUE
|
69
|
+
km_c2v(COMPLEX c)
|
70
|
+
{
|
71
|
+
return rb_complex_new(rb_float_new(creal(c)), rb_float_new(cimag(c)));
|
72
|
+
}
|
73
|
+
|
74
|
+
VALUE
|
75
|
+
kmm_mat_row_size(VALUE self)
|
76
|
+
{
|
77
|
+
return INT2NUM(km_mat2smat(self)->m);
|
78
|
+
}
|
79
|
+
|
80
|
+
// alias column_size
|
81
|
+
VALUE
|
82
|
+
kmm_mat_col_size(VALUE self)
|
83
|
+
{
|
84
|
+
return INT2NUM(km_mat2smat(self)->n);
|
85
|
+
}
|
86
|
+
|
87
|
+
VALUE
|
88
|
+
kmm_mat_length(VALUE self)
|
89
|
+
{
|
90
|
+
return INT2NUM(LENGTH(km_mat2smat(self)));
|
91
|
+
}
|
92
|
+
|
93
|
+
// alias size
|
94
|
+
VALUE
|
95
|
+
kmm_mat_shape(VALUE self)
|
96
|
+
{
|
97
|
+
SMAT *smat = km_mat2smat(self);
|
98
|
+
return rb_ary_new3(2, INT2NUM(smat->m), INT2NUM(smat->n));
|
99
|
+
}
|
100
|
+
|
101
|
+
VALUE
|
102
|
+
kmm_mat_vtype(VALUE self)
|
103
|
+
{
|
104
|
+
return km_vt2sym(km_mat2smat(self)->vtype);
|
105
|
+
}
|
106
|
+
|
107
|
+
VALUE
|
108
|
+
km_vt2sym(VTYPE vt)
|
109
|
+
{
|
110
|
+
VT_SWITCH( vt,
|
111
|
+
return sym_float;,
|
112
|
+
return sym_complex;,
|
113
|
+
return sym_int;,
|
114
|
+
return sym_bool;,
|
115
|
+
return sym_object;
|
116
|
+
);
|
117
|
+
}
|
118
|
+
|
119
|
+
VALUE
|
120
|
+
kmm_Mat_vt_refine(VALUE klass, VALUE vsym)
|
121
|
+
{
|
122
|
+
VTYPE vt = km_sym2vt(vsym);
|
123
|
+
VT_SWITCH( vt,
|
124
|
+
return sym_float;,
|
125
|
+
return sym_complex;,
|
126
|
+
return sym_int;,
|
127
|
+
return sym_bool;,
|
128
|
+
return sym_object;
|
129
|
+
);
|
130
|
+
}
|
131
|
+
|
132
|
+
// transform the value type of `self' by a Symbol vsym
|
133
|
+
// alias vtype=
|
134
|
+
VALUE
|
135
|
+
kmm_mat_set_vtype(VALUE self, VALUE vsym)
|
136
|
+
{
|
137
|
+
VT_SWITCH( km_sym2vt(vsym),
|
138
|
+
return kmm_mat_to_fmat_destl(self);,
|
139
|
+
return kmm_mat_to_cmat_destl(self);,
|
140
|
+
return kmm_mat_to_imat_destl(self);,
|
141
|
+
return kmm_mat_to_bmat_destl(self);,
|
142
|
+
return kmm_mat_to_omat_destl(self);
|
143
|
+
);
|
144
|
+
}
|
145
|
+
|
146
|
+
VALUE
|
147
|
+
kmm_mat_stype(VALUE self)
|
148
|
+
{
|
149
|
+
STYPE st = km_mat2smat(self)->stype;
|
150
|
+
if ( st == ST_FULL ) {
|
151
|
+
return sym_full;
|
152
|
+
} else if ( st == ST_SSUB ) {
|
153
|
+
return sym_serial;
|
154
|
+
} else if ( st == ST_RSUB ) {
|
155
|
+
return sym_random;
|
156
|
+
} else {
|
157
|
+
rb_raise(km_eInternal, "unknown storage type");
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
VALUE
|
162
|
+
kmm_mat_vector_p(VALUE self)
|
163
|
+
{
|
164
|
+
return TF2V(VECTOR_P(km_mat2smat(self)));
|
165
|
+
}
|
166
|
+
VALUE
|
167
|
+
kmm_mat_square_p(VALUE self)
|
168
|
+
{
|
169
|
+
SMAT *smat = km_mat2smat(self);
|
170
|
+
return TF2V(smat->m==smat->n);
|
171
|
+
}
|