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,108 @@
|
|
1
|
+
#include "../kmat.h"
|
2
|
+
|
3
|
+
static VALUE
|
4
|
+
km_block(VALUE idx, VALUE ary, VALUE self)
|
5
|
+
{
|
6
|
+
VALUE row = rb_ary_entry(ary, NUM2LONG(rb_ary_entry(idx, 0)));
|
7
|
+
return rb_ary_entry(row, NUM2LONG(rb_ary_entry(idx, 1)));
|
8
|
+
}
|
9
|
+
static VALUE
|
10
|
+
km_block_vector(VALUE idx, VALUE ary, VALUE self)
|
11
|
+
{
|
12
|
+
return rb_ary_entry(ary, NUM2LONG(rb_ary_entry(idx, 0)));
|
13
|
+
}
|
14
|
+
static long
|
15
|
+
km_check_col_size(VALUE ary)
|
16
|
+
{
|
17
|
+
long ret = RARRAY_LEN(rb_ary_entry(ary, 0));
|
18
|
+
for ( long i=1; i<RARRAY_LEN(ary); i++ ) {
|
19
|
+
if ( RARRAY_LEN(rb_ary_entry(ary, i)) != ret ) {
|
20
|
+
rb_raise(km_eDim, "the length of rows must be the same");
|
21
|
+
}
|
22
|
+
}
|
23
|
+
return ret;
|
24
|
+
}
|
25
|
+
|
26
|
+
VALUE
|
27
|
+
kmm_ary_to_fmat(VALUE self)
|
28
|
+
{
|
29
|
+
if ( RARRAY_LEN(self) == 0 ) {
|
30
|
+
return km_Mat(0, 0, VT_DOUBLE);
|
31
|
+
} else if ( TYPE(rb_ary_entry(self, 0)) == T_ARRAY ) {
|
32
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), LONG2NUM(km_check_col_size(self)), sym_float};
|
33
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block, self);
|
34
|
+
} else {
|
35
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), INT2NUM(1), sym_float};
|
36
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block_vector, self);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
VALUE
|
40
|
+
kmm_ary_to_cmat(VALUE self)
|
41
|
+
{
|
42
|
+
if ( RARRAY_LEN(self) == 0 ) {
|
43
|
+
return km_Mat(0, 0, VT_COMPLEX);
|
44
|
+
} else if ( TYPE(rb_ary_entry(self, 0)) == T_ARRAY ) {
|
45
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), LONG2NUM(km_check_col_size(self)), sym_complex};
|
46
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block, self);
|
47
|
+
} else {
|
48
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), INT2NUM(1), sym_complex};
|
49
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block_vector, self);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
VALUE
|
53
|
+
kmm_ary_to_imat(VALUE self)
|
54
|
+
{
|
55
|
+
if ( RARRAY_LEN(self) == 0 ) {
|
56
|
+
return km_Mat(0, 0, VT_INT);
|
57
|
+
} else if ( TYPE(rb_ary_entry(self, 0)) == T_ARRAY ) {
|
58
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), LONG2NUM(km_check_col_size(self)), sym_int};
|
59
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block, self);
|
60
|
+
} else {
|
61
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), INT2NUM(1), sym_int};
|
62
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block_vector, self);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
VALUE
|
66
|
+
kmm_ary_to_bmat(VALUE self)
|
67
|
+
{
|
68
|
+
if ( RARRAY_LEN(self) == 0 ) {
|
69
|
+
return km_Mat(0, 0, VT_BOOL);
|
70
|
+
} else if ( TYPE(rb_ary_entry(self, 0)) == T_ARRAY ) {
|
71
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), LONG2NUM(km_check_col_size(self)), sym_bool};
|
72
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block, self);
|
73
|
+
} else {
|
74
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), INT2NUM(1), sym_bool};
|
75
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block_vector, self);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
VALUE
|
79
|
+
kmm_ary_to_omat(VALUE self)
|
80
|
+
{
|
81
|
+
if ( RARRAY_LEN(self) == 0 ) {
|
82
|
+
return km_Mat(0, 0, VT_VALUE);
|
83
|
+
} else if ( TYPE(rb_ary_entry(self, 0)) == T_ARRAY ) {
|
84
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), LONG2NUM(km_check_col_size(self)), sym_object};
|
85
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block, self);
|
86
|
+
} else {
|
87
|
+
VALUE new_arg[3] = {LONG2NUM(RARRAY_LEN(self)), INT2NUM(1), sym_object};
|
88
|
+
return rb_block_call(km_cMat, id_new, 3, new_arg, km_block_vector, self);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
// alias to_m
|
93
|
+
VALUE
|
94
|
+
kmm_ary_to_mat(int argc, VALUE *argv, VALUE self)
|
95
|
+
{
|
96
|
+
rb_check_arity(argc, 0, 1);
|
97
|
+
if ( argc == 0 ) {
|
98
|
+
return kmm_ary_to_fmat(self);
|
99
|
+
} else {
|
100
|
+
VT_SWITCH( km_sym2vt(argv[0]),
|
101
|
+
return kmm_ary_to_fmat(self);,
|
102
|
+
return kmm_ary_to_cmat(self);,
|
103
|
+
return kmm_ary_to_imat(self);,
|
104
|
+
return kmm_ary_to_bmat(self);,
|
105
|
+
return kmm_ary_to_omat(self);
|
106
|
+
);
|
107
|
+
}
|
108
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#include "../kmat.h"
|
2
|
+
|
3
|
+
VALUE kmgv_mat_random;
|
4
|
+
|
5
|
+
// return a random number which follows N(0, 1)
|
6
|
+
// `random' is an instance of Random
|
7
|
+
double
|
8
|
+
km_rand_normal(VALUE random)
|
9
|
+
{
|
10
|
+
if (RTEST(rb_ivar_get(random, id_iv_kmat_stored))) {
|
11
|
+
rb_ivar_set(random, id_iv_kmat_stored, Qfalse);
|
12
|
+
return NUM2DBL(rb_ivar_get(random, id_iv_kmat_stored_value));
|
13
|
+
} else {
|
14
|
+
rb_ivar_set(random, id_iv_kmat_stored, Qtrue);
|
15
|
+
double sqrt_m2_log_x = sqrt(-2.0*log1p(-NUM2DBL(rb_funcall(random, id_rand, 0))));
|
16
|
+
double two_pi_y = M_2PI*NUM2DBL(rb_funcall(random, id_rand, 0));
|
17
|
+
rb_ivar_set(random, id_iv_kmat_stored_value, rb_float_new(sqrt_m2_log_x*sin(two_pi_y)));
|
18
|
+
return sqrt_m2_log_x*cos(two_pi_y);
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
// replace ary[0..(len-1)] by random numbers which follow N(0, 1)
|
23
|
+
// `random' is an instance of Random
|
24
|
+
void
|
25
|
+
km_fill_normal(int len, double *ary, VALUE random)
|
26
|
+
{
|
27
|
+
int i;
|
28
|
+
double sqrt_m2_log_x, two_pi_y;
|
29
|
+
len--;
|
30
|
+
if (RTEST(rb_ivar_get(random, id_iv_kmat_stored))) {
|
31
|
+
ary[0] = NUM2DBL(rb_ivar_get(random, id_iv_kmat_stored_value));
|
32
|
+
i = 1;
|
33
|
+
} else {
|
34
|
+
i = 0;
|
35
|
+
}
|
36
|
+
for ( ; i<len; i+= 2 ) {
|
37
|
+
sqrt_m2_log_x = sqrt(-2.0*log1p(-NUM2DBL(rb_funcall(random, id_rand, 0))));
|
38
|
+
two_pi_y = M_2PI*NUM2DBL(rb_funcall(random, id_rand, 0));
|
39
|
+
ary[i] = sqrt_m2_log_x*cos(two_pi_y);
|
40
|
+
ary[i+1] = sqrt_m2_log_x*sin(two_pi_y);
|
41
|
+
}
|
42
|
+
if ( i==len ) {
|
43
|
+
sqrt_m2_log_x = sqrt(-2.0*log1p(-NUM2DBL(rb_funcall(random, id_rand, 0))));
|
44
|
+
two_pi_y = M_2PI*NUM2DBL(rb_funcall(random, id_rand, 0));
|
45
|
+
ary[i] = sqrt_m2_log_x*cos(two_pi_y);
|
46
|
+
rb_ivar_set(random, id_iv_kmat_stored, Qtrue);
|
47
|
+
rb_ivar_set(random, id_iv_kmat_stored_value, rb_float_new(sqrt_m2_log_x*sin(two_pi_y)));
|
48
|
+
} else {
|
49
|
+
rb_ivar_set(random, id_iv_kmat_stored, Qfalse);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
static VALUE
|
54
|
+
km_random_randn(int argc, VALUE *argv, VALUE random)
|
55
|
+
{
|
56
|
+
rb_check_arity(argc, 0, 2);
|
57
|
+
if ( argc == 0 ) {
|
58
|
+
return rb_float_new(km_rand_normal(random));
|
59
|
+
} else if ( argc == 2 ) {
|
60
|
+
return rb_float_new(NUM2DBL(argv[0]) + km_rand_normal(random) * sqrt(NUM2DBL(argv[1])));
|
61
|
+
} else {
|
62
|
+
rb_raise(rb_eArgError, "when mean or standard deviation is specified, the other must be specified");
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
void
|
67
|
+
km_Mat_rand_init(void)
|
68
|
+
{
|
69
|
+
kmgv_mat_random = rb_const_get(rb_cRandom, id_DEFAULT);
|
70
|
+
rb_define_variable("$MatRandom", &kmgv_mat_random);
|
71
|
+
rb_define_method(rb_cRandom, "randn", km_random_randn, -1);
|
72
|
+
}
|
@@ -0,0 +1,302 @@
|
|
1
|
+
#include "../kmat.h"
|
2
|
+
|
3
|
+
// alias []
|
4
|
+
VALUE
|
5
|
+
kmm_Mat_array_m2(VALUE self, VALUE args)
|
6
|
+
{
|
7
|
+
return kmm_ary_to_fmat(args);
|
8
|
+
}
|
9
|
+
|
10
|
+
static VALUE
|
11
|
+
km_Mat_uninitialized(int argc, VALUE *argv)
|
12
|
+
{
|
13
|
+
rb_check_arity(argc, 0, 2);
|
14
|
+
if ( argc == 2 ) {
|
15
|
+
return km_Mat(NUM2INT(argv[0]), NUM2INT(argv[1]), VT_DOUBLE);
|
16
|
+
} else if ( argc == 1 ) {
|
17
|
+
return km_Mat(NUM2INT(argv[0]), 1, VT_DOUBLE);
|
18
|
+
} else {
|
19
|
+
return km_Mat(0, 0, VT_DOUBLE);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
// alias O
|
24
|
+
VALUE
|
25
|
+
kmm_Mat_zeros(int argc, VALUE *argv, VALUE self)
|
26
|
+
{
|
27
|
+
return km_Mat_uninitialized(argc, argv);
|
28
|
+
}
|
29
|
+
|
30
|
+
static void
|
31
|
+
km_ones_func(double *ent, void *null)
|
32
|
+
{
|
33
|
+
*ent = 1.0;
|
34
|
+
}
|
35
|
+
// alias J
|
36
|
+
VALUE
|
37
|
+
kmm_Mat_ones(int argc, VALUE *argv, VALUE self)
|
38
|
+
{
|
39
|
+
VALUE ret = km_Mat_uninitialized(argc, argv);
|
40
|
+
SMAT *smat = km_mat2smat(ret);
|
41
|
+
km_smat_each_d(smat, km_ones_func, NULL);
|
42
|
+
return ret;
|
43
|
+
}
|
44
|
+
|
45
|
+
// make a Mat which filled the last argument
|
46
|
+
// the value type of the return is determined by the class of the last argument
|
47
|
+
VALUE
|
48
|
+
kmm_Mat_fill(int argc, VALUE *argv, VALUE self)
|
49
|
+
{
|
50
|
+
rb_check_arity(argc, 1, 3);
|
51
|
+
VTYPE vt; VALUE ret;
|
52
|
+
VALUE v = argv[argc-1];
|
53
|
+
int type = TYPE(v);
|
54
|
+
if ( type == T_FLOAT ) {
|
55
|
+
vt = VT_DOUBLE;
|
56
|
+
} else if ( type == T_COMPLEX ) {
|
57
|
+
VALUE x = rb_funcall(v, id_real, 0);
|
58
|
+
VALUE y = rb_funcall(v, id_imag, 0);
|
59
|
+
if ( ( TYPE(x) == T_FLOAT || TYPE(x) == T_FIXNUM ) && ( TYPE(y) == T_FLOAT || TYPE(y) == T_FIXNUM ) ) {
|
60
|
+
vt = VT_COMPLEX;
|
61
|
+
} else {
|
62
|
+
vt = VT_VALUE;
|
63
|
+
}
|
64
|
+
} else if ( type == T_FIXNUM ) {
|
65
|
+
vt = VT_INT;
|
66
|
+
} else if ( type == T_TRUE || type == T_FALSE ) {
|
67
|
+
vt = VT_BOOL;
|
68
|
+
} else {
|
69
|
+
vt = VT_VALUE;
|
70
|
+
}
|
71
|
+
if ( argc == 3 ) {
|
72
|
+
ret = km_Mat(NUM2INT(argv[0]), NUM2INT(argv[1]), vt);
|
73
|
+
} else if ( argc == 2 ) {
|
74
|
+
ret = km_Mat(NUM2INT(argv[0]), 1, vt);
|
75
|
+
} else {
|
76
|
+
ret = km_Mat(1, 1, vt);
|
77
|
+
}
|
78
|
+
return kmm_mat_fill(ret, v);
|
79
|
+
}
|
80
|
+
|
81
|
+
// return a Mat which diagonals are 1.0 and the other elements are 0.0
|
82
|
+
VALUE
|
83
|
+
kmm_Mat_eye(int argc, VALUE *argv, VALUE self)
|
84
|
+
{
|
85
|
+
VALUE ret = kmm_Mat_zeros(argc, argv, self);
|
86
|
+
SMAT *smat = km_mat2smat(ret);
|
87
|
+
const int n = MIN(smat->m, smat->n);
|
88
|
+
for ( int i=0; i<n; i++ ) {
|
89
|
+
smat->dbody[i+i*(smat->ld)] = 1.0;
|
90
|
+
}
|
91
|
+
return ret;
|
92
|
+
}
|
93
|
+
|
94
|
+
// almost the same as Mat.eye but Mat.identity returns only square matrix
|
95
|
+
// alias I
|
96
|
+
VALUE
|
97
|
+
kmm_Mat_identity(VALUE self, VALUE vn)
|
98
|
+
{
|
99
|
+
const int n = NUM2INT(vn);
|
100
|
+
VALUE ret = km_Mat(n, n, VT_DOUBLE);
|
101
|
+
SMAT *smat = km_mat2smat(ret);
|
102
|
+
for ( int i=0; i<n; i++ ) {
|
103
|
+
smat->dbody[i+i*n] = 1.0;
|
104
|
+
}
|
105
|
+
return ret;
|
106
|
+
}
|
107
|
+
|
108
|
+
// make a diagonal matrix, the diagonal elements are specified by the arguments
|
109
|
+
// if the first argument is a vector or an Array, the diagonal elements are the elements of the first argument
|
110
|
+
// if the first argument is a matrix, the diagonal elements are the diagonal elements of the first argument
|
111
|
+
// if the second argument `k' given, the elements are set to k-th diagonal
|
112
|
+
VALUE
|
113
|
+
kmm_Mat_diag(int argc, VALUE *argv, VALUE self)
|
114
|
+
{
|
115
|
+
rb_check_arity(argc, 1, 2);
|
116
|
+
VALUE vsrc = argv[0];
|
117
|
+
if ( argc == 1 ) {
|
118
|
+
if ( rb_obj_is_kind_of(vsrc, km_cMat) ) {
|
119
|
+
VALUE ret;
|
120
|
+
SMAT *src = km_mat2smat(vsrc);
|
121
|
+
if ( src->vtype != VT_DOUBLE ) {
|
122
|
+
vsrc = kmm_mat_to_fmat(argv[0]);
|
123
|
+
src = km_mat2smat(vsrc);
|
124
|
+
}
|
125
|
+
if ( VECTOR_P(src) ) { // the argument is a vector
|
126
|
+
const int len = LENGTH(src);
|
127
|
+
ret = km_Mat(len, len, VT_DOUBLE);
|
128
|
+
SMAT *dest = km_mat2smat(ret);
|
129
|
+
if ( src->stype == ST_RSUB ) {
|
130
|
+
for ( int i=0; i<len; i++ ) {
|
131
|
+
dest->dbody[i+i*len] = *((src->dpbody)[i]);
|
132
|
+
}
|
133
|
+
} else {
|
134
|
+
for ( int i=0; i<len; i++ ) {
|
135
|
+
dest->dbody[i+i*len] = src->dbody[i];
|
136
|
+
}
|
137
|
+
}
|
138
|
+
} else { // the argument is a matrix
|
139
|
+
ret = km_Mat(src->m, src->n, VT_DOUBLE);
|
140
|
+
SMAT *dest = km_mat2smat(ret);
|
141
|
+
const int n = MIN(src->m, src->n);
|
142
|
+
if ( src->stype == ST_RSUB ) {
|
143
|
+
for ( int i=0; i<n; i++ ) {
|
144
|
+
dest->dbody[i+i*(dest->ld)] = *((src->dpbody)[i+i*(src->ld)]);
|
145
|
+
}
|
146
|
+
} else {
|
147
|
+
for ( int i=0; i<n; i++ ) {
|
148
|
+
dest->dbody[i+i*(dest->ld)] = src->dbody[i+i*(src->ld)];
|
149
|
+
}
|
150
|
+
}
|
151
|
+
}
|
152
|
+
return ret;
|
153
|
+
} else if ( TYPE(vsrc) == T_ARRAY ) { // the argument is an Array
|
154
|
+
const long len = RARRAY_LEN(argv[0]);
|
155
|
+
VALUE ret = km_Mat((int)len, (int)len, VT_DOUBLE);
|
156
|
+
double *body = km_mat2smat(ret)->dbody;
|
157
|
+
for ( long i=0; i<len; i++ ) {
|
158
|
+
body[i+i*len] = NUM2DBL(rb_ary_entry(vsrc, i));
|
159
|
+
}
|
160
|
+
return ret;
|
161
|
+
} else { // (1, 1)-matrix. the (0, 0)-th element is the argument
|
162
|
+
VALUE ret = km_Mat(1, 1, VT_DOUBLE);
|
163
|
+
km_mat2smat(ret)->dbody[0] = NUM2DBL(vsrc);
|
164
|
+
return ret;
|
165
|
+
}
|
166
|
+
} else { // k is given
|
167
|
+
int k = NUM2INT(argv[1]);
|
168
|
+
if ( rb_obj_is_kind_of(vsrc, km_cMat) ) {
|
169
|
+
VALUE ret;
|
170
|
+
SMAT *src = km_mat2smat(vsrc);
|
171
|
+
if ( src->vtype != VT_DOUBLE ) {
|
172
|
+
vsrc = kmm_mat_to_fmat(argv[0]);
|
173
|
+
src = km_mat2smat(vsrc);
|
174
|
+
}
|
175
|
+
if ( VECTOR_P(src) ) { // the argument is a vector
|
176
|
+
const int len_s = LENGTH(src);
|
177
|
+
const int len = len_s + ABS(k);
|
178
|
+
ret = km_Mat(len, len, VT_DOUBLE);
|
179
|
+
SMAT *dest = km_mat2smat(ret);
|
180
|
+
if ( 0 < k ) {
|
181
|
+
if ( src->stype == ST_RSUB ) {
|
182
|
+
for ( int i=0; i<len_s; i++ ) {
|
183
|
+
dest->dbody[i+(i+k)*len] = *((src->dpbody)[i]);
|
184
|
+
}
|
185
|
+
} else {
|
186
|
+
for ( int i=0; i<len_s; i++ ) {
|
187
|
+
dest->dbody[i+(i+k)*len] = src->dbody[i];
|
188
|
+
}
|
189
|
+
}
|
190
|
+
} else {
|
191
|
+
if ( src->stype == ST_RSUB ) {
|
192
|
+
for ( int i=0; i<len_s; i++ ) {
|
193
|
+
dest->dbody[(i-k)+i*len] = *((src->dpbody)[i]);
|
194
|
+
}
|
195
|
+
} else {
|
196
|
+
for ( int i=0; i<len_s; i++ ) {
|
197
|
+
dest->dbody[(i-k)+i*len] = src->dbody[i];
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}
|
201
|
+
} else { // the argument is a matrix
|
202
|
+
ret = km_Mat(src->m, src->n, VT_DOUBLE);
|
203
|
+
SMAT *dest = km_mat2smat(ret);
|
204
|
+
int len, i_s, j_s;
|
205
|
+
if ( 0 < k ) {
|
206
|
+
if ( k < (src->n)-(src->m) ) {
|
207
|
+
len = src->m;
|
208
|
+
} else {
|
209
|
+
len = src->n-k;
|
210
|
+
}
|
211
|
+
i_s = 0; j_s = k;
|
212
|
+
} else {
|
213
|
+
if ( k < (src->n)-(src->m) ) {
|
214
|
+
len = src->m+k;
|
215
|
+
} else {
|
216
|
+
len = src->n;
|
217
|
+
}
|
218
|
+
i_s = -k; j_s = 0;
|
219
|
+
}
|
220
|
+
for ( int i=0; i<len; i++ ) {
|
221
|
+
dest->dbody[i_s+i+(j_s+i)*(dest->ld)] = ENTITY(src, d, i_s+i, j_s+i);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
return ret;
|
225
|
+
} else if ( TYPE(vsrc) == T_ARRAY ) { // the argument is an Array
|
226
|
+
const long len_s = RARRAY_LEN(argv[0]);
|
227
|
+
int len = ((int)len_s)+ABS(k);
|
228
|
+
VALUE ret = km_Mat(len, len, VT_DOUBLE);
|
229
|
+
double *body = km_mat2smat(ret)->dbody;
|
230
|
+
if ( 0 < k ) {
|
231
|
+
for ( long i=0; i<len_s; i++ ) {
|
232
|
+
body[i+(i+k)*len] = NUM2DBL(rb_ary_entry(vsrc, i));
|
233
|
+
}
|
234
|
+
} else {
|
235
|
+
for ( long i=0; i<len_s; i++ ) {
|
236
|
+
body[i-k+i*len] = NUM2DBL(rb_ary_entry(vsrc, i));
|
237
|
+
}
|
238
|
+
}
|
239
|
+
return ret;
|
240
|
+
} else { // (1+abs(k), 1+abs(k))-matrix. the (0, k)-th element (0<k) or (-k, 0)-th element (k<0) is the argument
|
241
|
+
const int len = 1+ABS(k);
|
242
|
+
VALUE ret = km_Mat(len, len, VT_DOUBLE);
|
243
|
+
if ( 0 < k ) {
|
244
|
+
km_mat2smat(ret)->dbody[k*len] = NUM2DBL(vsrc);
|
245
|
+
} else {
|
246
|
+
km_mat2smat(ret)->dbody[-k] = NUM2DBL(vsrc);
|
247
|
+
}
|
248
|
+
return ret;
|
249
|
+
}
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
// make a vector which contains 0..(vn-1)
|
254
|
+
VALUE
|
255
|
+
kmm_Mat_range(VALUE self, VALUE vn)
|
256
|
+
{
|
257
|
+
const int n = NUM2INT(vn);
|
258
|
+
VALUE ret = km_Mat(n, 1, VT_DOUBLE);
|
259
|
+
double *body = km_mat2smat(ret)->dbody;
|
260
|
+
for ( int i=0; i<n; i++ ) {
|
261
|
+
body[i] = (double)i;
|
262
|
+
}
|
263
|
+
return ret;
|
264
|
+
}
|
265
|
+
VALUE
|
266
|
+
kmm_Mat_irange(VALUE self, VALUE vn)
|
267
|
+
{
|
268
|
+
const int n = NUM2INT(vn);
|
269
|
+
VALUE ret = km_Mat(n, 1, VT_INT);
|
270
|
+
int *body = km_mat2smat(ret)->ibody;
|
271
|
+
for ( int i=0; i<n; i++ ) {
|
272
|
+
body[i] = i;
|
273
|
+
}
|
274
|
+
return ret;
|
275
|
+
}
|
276
|
+
|
277
|
+
// make a matrix which elements follows U(0, 1)
|
278
|
+
VALUE
|
279
|
+
kmm_Mat__rand0(VALUE self, VALUE vm, VALUE vn, VALUE random)
|
280
|
+
{
|
281
|
+
VALUE ret = km_Mat(NUM2INT(vm), NUM2INT(vn), VT_DOUBLE);
|
282
|
+
return kmm_mat__rand0(ret, random, Qnil);
|
283
|
+
}
|
284
|
+
|
285
|
+
// make a matrix which elements follows N(0, 1)
|
286
|
+
VALUE
|
287
|
+
kmm_Mat__randn0(VALUE self, VALUE vm, VALUE vn, VALUE random)
|
288
|
+
{
|
289
|
+
VALUE ret = km_Mat(NUM2INT(vm), NUM2INT(vn), VT_DOUBLE);
|
290
|
+
return kmm_mat__randn0(ret, random);
|
291
|
+
}
|
292
|
+
|
293
|
+
// make a complex matrix. the real parts are `vr' and the imaginary parts are `vi'
|
294
|
+
VALUE
|
295
|
+
kmm_Mat_complex(VALUE self, VALUE vr, VALUE vi)
|
296
|
+
{
|
297
|
+
SMAT *real = km_mat2smat(kmm_mat_to_fmat(vr));
|
298
|
+
SMAT *imag = km_mat2smat(kmm_mat_to_fmat(vi));
|
299
|
+
VALUE ret = km_Mat(real->m, real->n, VT_COMPLEX);
|
300
|
+
km_smat_complex(km_mat2smat(ret), real, imag);
|
301
|
+
return ret;
|
302
|
+
}
|