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/linalg/linalg.c
CHANGED
@@ -20,6 +20,20 @@ km_check_size(int pairc, ...)
|
|
20
20
|
}
|
21
21
|
va_end(argp);
|
22
22
|
}
|
23
|
+
void
|
24
|
+
km_check_size_s(int pairc, ...)
|
25
|
+
{
|
26
|
+
va_list argp;
|
27
|
+
va_start(argp, pairc);
|
28
|
+
for (int i=0; i<pairc; i++ ) {
|
29
|
+
size_t a = va_arg(argp, size_t); size_t b = va_arg(argp, size_t);
|
30
|
+
if ( a != b ) {
|
31
|
+
va_end(argp);
|
32
|
+
rb_raise(km_eDim, "dimension mismatched (%zu != %zu)", a, b);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
va_end(argp);
|
36
|
+
}
|
23
37
|
|
24
38
|
// the number of SMATs is specified by `argc'
|
25
39
|
// check whether the value types of the arguments are VT_DOUBLE or not
|
@@ -123,8 +137,8 @@ km_recover_trans(VALUE vab)
|
|
123
137
|
{
|
124
138
|
SMAT *sa = km_mat2smat(rb_ary_entry(vab, 0));
|
125
139
|
SMAT *sb = km_mat2smat(rb_ary_entry(vab, 1));
|
126
|
-
sa->trans = !sa->trans; SWAP(
|
127
|
-
sb->trans = !sb->trans; SWAP(
|
140
|
+
sa->trans = !sa->trans; SWAP(size_t, sa->m, sa->n);
|
141
|
+
sb->trans = !sb->trans; SWAP(size_t, sb->m, sb->n);
|
128
142
|
return vab;
|
129
143
|
}
|
130
144
|
static VALUE
|
@@ -174,8 +188,8 @@ kmm_mat_inverse(VALUE va)
|
|
174
188
|
void
|
175
189
|
km_dmprod(int m, int n, int k, double *a, int lda, double *b, int ldb, double *r, int ldr)
|
176
190
|
{
|
177
|
-
|
178
|
-
|
191
|
+
char trans[] = "N";
|
192
|
+
const double alpha=1.0, beta=0.0;
|
179
193
|
dgemm_(trans, trans, &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, r, &ldr);
|
180
194
|
}
|
181
195
|
struct km_mprod_arg {
|
@@ -187,8 +201,8 @@ km_mprod_body(VALUE data)
|
|
187
201
|
{
|
188
202
|
struct km_mprod_arg *a = (struct km_mprod_arg *)data;
|
189
203
|
|
190
|
-
int m = a->sr->m, n = a->sr->n, k = a->sa->n;
|
191
|
-
km_check_size(3, a->sb->m,k, a->sa->m,m, a->sb->n,n);
|
204
|
+
int m = s2i(a->sr->m), n = s2i(a->sr->n), k = s2i(a->sa->n);
|
205
|
+
km_check_size(3, s2i(a->sb->m),k, s2i(a->sa->m),m, s2i(a->sb->n),n);
|
192
206
|
|
193
207
|
KALLOCz(a->r, a->sr);
|
194
208
|
KALLOCn(a->a, a->sa);
|
@@ -198,35 +212,37 @@ km_mprod_body(VALUE data)
|
|
198
212
|
if ( vt == VT_DOUBLE ) {
|
199
213
|
char trans[] = "N";
|
200
214
|
double alpha=1.0, beta=0.0;
|
201
|
-
|
215
|
+
int lda=s2i(a->a.ld), ldb=s2i(a->b.ld), ldr=s2i(a->r.ld);
|
216
|
+
dgemm_(trans, trans, &m, &n, &k, &alpha, a->a.d, &lda, a->b.d, &ldb, &beta, a->r.d, &ldr);
|
202
217
|
} else if ( vt == VT_COMPLEX ) {
|
203
218
|
char trans[] = "N";
|
204
219
|
COMPLEX alpha=cpack(1.0, 0.0), beta=cpack(0.0, 0.0);
|
205
|
-
|
220
|
+
int lda=s2i(a->a.ld), ldb=s2i(a->b.ld), ldr=s2i(a->r.ld);
|
221
|
+
zgemm_(trans, trans, &m, &n, &k, &alpha, a->a.z, &lda, a->b.z, &ldb, &beta, a->r.z, &ldr);
|
206
222
|
} else if ( vt == VT_INT ) {
|
207
223
|
for ( int i=0; i<m; i++ ) { for ( int j=0; j<n; j++ ) {
|
208
|
-
int *foo=(a->r.i)+(i+j*(a->r.ld));
|
209
|
-
int jldb = j*(a->b.ld);
|
224
|
+
int *foo=(a->r.i)+(i+j*s2i(a->r.ld));
|
225
|
+
const int jldb = j*s2i(a->b.ld);
|
210
226
|
for ( int l=0; l<k; l++ ) {
|
211
|
-
*foo += (a->a.i)[i+l*(a->a.ld)] * (a->b.i)[l+jldb];
|
227
|
+
*foo += (a->a.i)[i+l*s2i(a->a.ld)] * (a->b.i)[l+jldb];
|
212
228
|
}
|
213
229
|
} }
|
214
230
|
} else if ( vt == VT_BOOL ) {
|
215
231
|
for ( int i=0; i<m; i++ ) { for ( int j=0; j<n; j++ ) {
|
216
|
-
bool *foo=(a->r.b)+(i+j*(a->r.ld));
|
217
|
-
int jldb = j*(a->b.ld);
|
232
|
+
bool *foo=(a->r.b)+(i+j*s2i(a->r.ld));
|
233
|
+
const int jldb = j*s2i(a->b.ld);
|
218
234
|
for ( int l=0; l<k; l++ ) {
|
219
|
-
bool bar = ( (a->a.b)[i+l*(a->a.ld)] && (a->b.b)[l+jldb] );
|
235
|
+
const bool bar = ( (a->a.b)[i+l*s2i(a->a.ld)] && (a->b.b)[l+jldb] );
|
220
236
|
*foo = XOR(*foo, bar);
|
221
237
|
}
|
222
238
|
} }
|
223
239
|
} else if ( vt == VT_VALUE ) {
|
224
240
|
for ( int i=0; i<m; i++ ) { for ( int j=0; j<n; j++ ) {
|
225
|
-
VALUE *foo=(a->r.v)+(i+j*(a->r.ld));
|
241
|
+
VALUE *foo=(a->r.v)+(i+j*s2i(a->r.ld));
|
226
242
|
*foo = INT2NUM(0);
|
227
|
-
int jldb = j*(a->b.ld);
|
243
|
+
const int jldb = j*s2i(a->b.ld);
|
228
244
|
for ( int l=0; l<k; l++ ) {
|
229
|
-
VALUE bar = rb_funcall( (a->a.v)[i+l*(a->a.ld)], id_op_mul, 1, (a->b.v)[l+jldb] );
|
245
|
+
const VALUE bar = rb_funcall( (a->a.v)[i+l*s2i(a->a.ld)], id_op_mul, 1, (a->b.v)[l+jldb] );
|
230
246
|
*foo = rb_funcall(*foo, id_op_plus, 1, bar);
|
231
247
|
}
|
232
248
|
} }
|
data/ext/kmat/linalg/norm.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "../kmat.h"
|
2
2
|
|
3
|
-
#define SET_LD(ldx, smat)
|
3
|
+
#define SET_LD(ldx, smat) size_t ldx; \
|
4
4
|
if ( smat->n == 1 ) { \
|
5
5
|
if ( smat->trans ) { \
|
6
6
|
ldx = smat->ld; \
|
@@ -14,23 +14,37 @@
|
|
14
14
|
ldx = smat->ld; \
|
15
15
|
} \
|
16
16
|
}
|
17
|
+
#define SET_LDi(ldx, smat) int ldx; \
|
18
|
+
if ( smat->n == 1 ) { \
|
19
|
+
if ( smat->trans ) { \
|
20
|
+
ldx = s2i(smat->ld); \
|
21
|
+
} else { \
|
22
|
+
ldx = 1; \
|
23
|
+
} \
|
24
|
+
} else { \
|
25
|
+
if ( smat->trans ) { \
|
26
|
+
ldx = 1; \
|
27
|
+
} else { \
|
28
|
+
ldx = s2i(smat->ld); \
|
29
|
+
} \
|
30
|
+
}
|
17
31
|
#define DEF_IPROD(id, type, mul, add, zero) static type \
|
18
32
|
km_##id##mat_iprod(SMAT *sa, SMAT *sb) { \
|
19
33
|
type ret; \
|
20
34
|
SET_LD(lda, sa) \
|
21
35
|
SET_LD(ldb, sb) \
|
22
|
-
|
36
|
+
const size_t len = LENGTH(sa); \
|
23
37
|
if ( len == 0 ) { return zero; } \
|
24
38
|
if ( sa->stype == ST_RSUB ) { \
|
25
39
|
if ( sb->stype == ST_RSUB ) { \
|
26
40
|
ret = mul( *(sa->id##pbody[0]), *(sb->id##pbody[0]) ); \
|
27
|
-
for (
|
41
|
+
for ( size_t i=1; i<len; i++ ) { \
|
28
42
|
type temp = mul( *(sa->id##pbody[i*lda]), *(sb->id##pbody[i*ldb]) ); \
|
29
43
|
ret = add(ret, temp); \
|
30
44
|
} \
|
31
45
|
} else { \
|
32
46
|
ret = mul( *(sa->id##pbody[0]), (sb->id##body[0]) ); \
|
33
|
-
for (
|
47
|
+
for ( size_t i=1; i<len; i++ ) { \
|
34
48
|
type temp = mul( *(sa->id##pbody[i*lda]), (sb->id##body[i*ldb]) ); \
|
35
49
|
ret = add(ret, temp); \
|
36
50
|
} \
|
@@ -38,13 +52,13 @@ km_##id##mat_iprod(SMAT *sa, SMAT *sb) { \
|
|
38
52
|
} else { \
|
39
53
|
if ( sb->stype == ST_RSUB ) { \
|
40
54
|
ret = mul( (sa->id##body[0]), *(sb->id##pbody[0]) ); \
|
41
|
-
for (
|
55
|
+
for ( size_t i=1; i<len; i++ ) { \
|
42
56
|
type temp = mul( (sa->id##body[i*lda]), *(sb->id##pbody[i*ldb]) ); \
|
43
57
|
ret = add(ret, temp); \
|
44
58
|
} \
|
45
59
|
} else { \
|
46
60
|
ret = mul( (sa->id##body[0]), (sb->id##body[0]) ); \
|
47
|
-
for (
|
61
|
+
for ( size_t i=1; i<len; i++ ) { \
|
48
62
|
type temp = mul( (sa->id##body[i*lda]), (sb->id##body[i*ldb]) ); \
|
49
63
|
ret = add(ret, temp); \
|
50
64
|
} \
|
@@ -68,9 +82,9 @@ km_dmat_iprodb(SMAT *sa, SMAT *sb)
|
|
68
82
|
if ( sa->stype == ST_RSUB || sb->stype == ST_RSUB ) {
|
69
83
|
return km_dmat_iprod(sa, sb);
|
70
84
|
}
|
71
|
-
|
72
|
-
|
73
|
-
int n =
|
85
|
+
SET_LDi(lda, sa)
|
86
|
+
SET_LDi(ldb, sb)
|
87
|
+
const int n = LENGTHi(sa);
|
74
88
|
return ddot_(&n, sa->dbody, &lda, sb->dbody, &ldb);
|
75
89
|
}
|
76
90
|
static COMPLEX
|
@@ -79,9 +93,9 @@ km_zmat_iprodb(SMAT *sa, SMAT *sb)
|
|
79
93
|
if ( sa->stype == ST_RSUB || sb->stype == ST_RSUB ) {
|
80
94
|
return km_zmat_iprod(sa, sb);
|
81
95
|
}
|
82
|
-
|
83
|
-
|
84
|
-
int n =
|
96
|
+
SET_LDi(lda, sa)
|
97
|
+
SET_LDi(ldb, sb)
|
98
|
+
const int n = LENGTHi(sa);
|
85
99
|
return zdotu_(&n, sa->zbody, &lda, sb->zbody, &ldb);
|
86
100
|
}
|
87
101
|
VALUE
|
@@ -91,7 +105,7 @@ kmm_mat__iprod(VALUE self, VALUE vb)
|
|
91
105
|
if ( !VECTOR_P(sa) || !VECTOR_P(sb) ) {
|
92
106
|
rb_raise(km_eDim, "both self and the argument must be vectors");
|
93
107
|
} else if ( LENGTH(sa) != LENGTH(sb) ) {
|
94
|
-
rb_raise(km_eDim, "dimensions must be the same (%
|
108
|
+
rb_raise(km_eDim, "dimensions must be the same (%zu != %zu)", LENGTH(sa), LENGTH(sb));
|
95
109
|
} else if ( sa->vtype != sb->vtype ) {
|
96
110
|
rb_raise(km_eVT, "value types must be the same");
|
97
111
|
}
|
@@ -141,16 +155,16 @@ kmm_mat_normf(VALUE self)
|
|
141
155
|
SMAT *smat = km_mat2smat(self);
|
142
156
|
if ( smat->vtype == VT_DOUBLE ) {
|
143
157
|
if ( smat->stype == ST_FULL ) {
|
144
|
-
int ione=1, n =
|
158
|
+
const int ione=1, n = LENGTHi(smat);
|
145
159
|
return rb_float_new(dnrm2_(&n, smat->dbody, &ione));
|
146
160
|
} else if ( smat->stype == ST_SSUB ) {
|
147
|
-
int ione=1
|
161
|
+
const int ione=1; int size; size_t lps; double ret=0.0;
|
148
162
|
if ( smat->trans ) {
|
149
|
-
lps = smat->m; size = smat->n;
|
163
|
+
lps = smat->m; size = s2i(smat->n);
|
150
164
|
} else {
|
151
|
-
lps = smat->n; size = smat->m;
|
165
|
+
lps = smat->n; size = s2i(smat->m);
|
152
166
|
}
|
153
|
-
for (
|
167
|
+
for ( size_t i=0; i<lps; i++ ) {
|
154
168
|
ret = hypot(ret, dnrm2_(&size, smat->dbody+i*(smat->ld), &ione));
|
155
169
|
}
|
156
170
|
return rb_float_new(ret);
|
@@ -161,16 +175,16 @@ kmm_mat_normf(VALUE self)
|
|
161
175
|
}
|
162
176
|
} else if ( smat->vtype == VT_COMPLEX ) {
|
163
177
|
if ( smat->stype == ST_FULL ) {
|
164
|
-
int ione=1, n =
|
178
|
+
const int ione=1, n = LENGTHi(smat);
|
165
179
|
return rb_float_new(dznrm2_(&n, smat->zbody, &ione));
|
166
180
|
} else if ( smat->stype == ST_SSUB ) {
|
167
|
-
int ione=1
|
181
|
+
const int ione=1; int size; size_t lps; double ret=0.0;
|
168
182
|
if ( smat->trans ) {
|
169
|
-
lps = smat->m; size = smat->n;
|
183
|
+
lps = smat->m; size = s2i(smat->n);
|
170
184
|
} else {
|
171
|
-
lps = smat->n; size = smat->m;
|
185
|
+
lps = smat->n; size = s2i(smat->m);
|
172
186
|
}
|
173
|
-
for (
|
187
|
+
for ( size_t i=0; i<lps; i++ ) {
|
174
188
|
ret = hypot(ret, dznrm2_(&size, smat->zbody+i*(smat->ld), &ione));
|
175
189
|
}
|
176
190
|
return rb_float_new(ret);
|
@@ -199,13 +213,13 @@ kmm_mat_normf(VALUE self)
|
|
199
213
|
// L-1, L-infinity norm
|
200
214
|
#define NORM1(type, id, m_ent, m, n, m_abs, m_add, m_cmp, x2v) \
|
201
215
|
type ret = m_abs(m_ent(smat, id, 0)); \
|
202
|
-
for (
|
216
|
+
for ( size_t i=1; i<m; i++ ) { \
|
203
217
|
type foo = m_abs(m_ent(smat, id, i)); \
|
204
218
|
ret = m_add(ret, foo); \
|
205
219
|
} \
|
206
|
-
for (
|
220
|
+
for ( size_t j=1; j<n; j++ ) { \
|
207
221
|
type bar = m_abs(m_ent(smat, id, j*(smat->ld))); \
|
208
|
-
for (
|
222
|
+
for ( size_t i=1; i<m; i++ ) { \
|
209
223
|
type foo = m_abs(m_ent(smat, id, i+j*(smat->ld))); \
|
210
224
|
bar = m_add(bar, foo); \
|
211
225
|
} \
|
@@ -216,10 +230,10 @@ kmm_mat_normf(VALUE self)
|
|
216
230
|
if ( smat->stype == ST_RSUB ) { \
|
217
231
|
NORM1(double, id, ENTITYr0, m, n, m_abs, NUM_ADD, NUM_CMP, rb_float_new); \
|
218
232
|
} else { \
|
219
|
-
const int ione=1; \
|
220
|
-
double ret = bid##asum_(&
|
221
|
-
for (
|
222
|
-
double temp = bid##asum_(&
|
233
|
+
const int ione=1, m_i=s2i(m); \
|
234
|
+
double ret = bid##asum_(&m_i, smat->id##body, &ione); \
|
235
|
+
for ( size_t j=1; j<n; j++ ) { \
|
236
|
+
double temp = bid##asum_(&m_i, smat->id##body+(j*(smat->ld)), &ione); \
|
223
237
|
if ( ret < temp ) { ret = temp; } \
|
224
238
|
} \
|
225
239
|
return rb_float_new(ret); \
|
@@ -227,13 +241,13 @@ kmm_mat_normf(VALUE self)
|
|
227
241
|
} while (0)
|
228
242
|
#define NORMi(type, id, m_ent, m, n, m_abs, m_add, m_cmp, x2v) \
|
229
243
|
type ret = m_abs(m_ent(smat, id, 0)); \
|
230
|
-
for (
|
244
|
+
for ( size_t j=1; j<n; j++ ) { \
|
231
245
|
type foo = m_abs(m_ent(smat, id, j*(smat->ld))); \
|
232
246
|
ret = m_add(ret, foo); \
|
233
247
|
} \
|
234
|
-
for (
|
248
|
+
for ( size_t i=1; i<m; i++ ) { \
|
235
249
|
type bar = m_abs(m_ent(smat, id, i)); \
|
236
|
-
for (
|
250
|
+
for ( size_t j=1; j<n; j++ ) { \
|
237
251
|
type foo = m_abs(m_ent(smat, id, i+j*(smat->ld))); \
|
238
252
|
bar = m_add(bar, foo); \
|
239
253
|
} \
|
@@ -244,9 +258,10 @@ kmm_mat_normf(VALUE self)
|
|
244
258
|
if ( smat->stype == ST_RSUB ) { \
|
245
259
|
NORMi(double, id, ENTITYr0, m, n, m_abs, NUM_ADD, NUM_CMP, rb_float_new); \
|
246
260
|
} else { \
|
247
|
-
|
248
|
-
|
249
|
-
|
261
|
+
const int ld=s2i(smat->ld), n_i=s2i(n); \
|
262
|
+
double ret = bid##asum_(&n_i, smat->id##body, &ld); \
|
263
|
+
for ( size_t i=1; i<m; i++ ) { \
|
264
|
+
const double temp = bid##asum_(&n_i, smat->id##body+i, &ld); \
|
250
265
|
if ( ret < temp ) { ret = temp; } \
|
251
266
|
} \
|
252
267
|
return rb_float_new(ret); \
|
@@ -350,16 +365,16 @@ kmm_mat_norm_e1(VALUE self)
|
|
350
365
|
SMAT *smat = km_mat2smat(self);
|
351
366
|
if ( smat->vtype == VT_DOUBLE ) {
|
352
367
|
if ( smat->stype == ST_FULL ) {
|
353
|
-
int ione = 1, n =
|
368
|
+
const int ione = 1, n = LENGTHi(smat);
|
354
369
|
return rb_float_new(dasum_(&n, smat->dbody, &ione));
|
355
370
|
} else if ( smat->stype == ST_SSUB ) {
|
356
|
-
int ione = 1
|
371
|
+
const int ione = 1; int size; size_t lps; double ret = 0.0;
|
357
372
|
if ( smat->trans ) {
|
358
|
-
lps = smat->m; size = smat->n;
|
373
|
+
lps = smat->m; size = s2i(smat->n);
|
359
374
|
} else {
|
360
|
-
lps = smat->n; size = smat->m;
|
375
|
+
lps = smat->n; size = s2i(smat->m);
|
361
376
|
}
|
362
|
-
for (
|
377
|
+
for ( size_t i=0; i<lps; i++ ) {
|
363
378
|
ret += dasum_(&size, smat->dbody+(i*(smat->ld)), &ione);
|
364
379
|
}
|
365
380
|
return rb_float_new(ret);
|
@@ -370,16 +385,16 @@ kmm_mat_norm_e1(VALUE self)
|
|
370
385
|
}
|
371
386
|
} else if ( smat->vtype == VT_COMPLEX ) {
|
372
387
|
if ( smat->stype == ST_FULL ) {
|
373
|
-
int ione = 1, n =
|
388
|
+
const int ione = 1, n = LENGTHi(smat);
|
374
389
|
return rb_float_new(dzasum_(&n, smat->zbody, &ione));
|
375
390
|
} else if ( smat->stype == ST_SSUB ) {
|
376
|
-
int ione = 1
|
391
|
+
const int ione = 1; int size; size_t lps; double ret = 0.0;
|
377
392
|
if ( smat->trans ) {
|
378
|
-
lps = smat->m; size = smat->n;
|
393
|
+
lps = smat->m; size = s2i(smat->n);
|
379
394
|
} else {
|
380
|
-
lps = smat->n; size = smat->m;
|
395
|
+
lps = smat->n; size = s2i(smat->m);
|
381
396
|
}
|
382
|
-
for (
|
397
|
+
for ( size_t i=0; i<lps; i++ ) {
|
383
398
|
ret += dzasum_(&size, smat->zbody+(i*(smat->ld)), &ione);
|
384
399
|
}
|
385
400
|
return rb_float_new(ret);
|
@@ -410,7 +425,7 @@ static void
|
|
410
425
|
km_amax_d(double *ent, void *data)
|
411
426
|
{
|
412
427
|
double *ret = (double *)data;
|
413
|
-
double temp = fabs(*ent);
|
428
|
+
const double temp = fabs(*ent);
|
414
429
|
if ( *ret < temp ) {
|
415
430
|
*ret = temp;
|
416
431
|
}
|
@@ -419,7 +434,7 @@ static void
|
|
419
434
|
km_amax_z(COMPLEX *ent, void *data)
|
420
435
|
{
|
421
436
|
double *ret = (double *)data;
|
422
|
-
double temp = cabs(*ent);
|
437
|
+
const double temp = cabs(*ent);
|
423
438
|
if ( *ret < temp ) {
|
424
439
|
*ret = temp;
|
425
440
|
}
|
@@ -428,7 +443,7 @@ static void
|
|
428
443
|
km_amax_i(int *ent, void *data)
|
429
444
|
{
|
430
445
|
int *ret = (int *)data;
|
431
|
-
int temp = ABS(*ent);
|
446
|
+
const int temp = ABS(*ent);
|
432
447
|
if ( *ret < temp ) {
|
433
448
|
*ret = temp;
|
434
449
|
}
|
@@ -443,7 +458,7 @@ static void
|
|
443
458
|
km_amax_v(VALUE *ent, void *data)
|
444
459
|
{
|
445
460
|
VALUE *ret = (VALUE *)data;
|
446
|
-
VALUE temp = rb_funcall(*ent, id_abs, 0);
|
461
|
+
const VALUE temp = rb_funcall(*ent, id_abs, 0);
|
447
462
|
if ( rb_funcall(*ret, id_op_lt, 1, temp) ) {
|
448
463
|
*ret = temp;
|
449
464
|
}
|
@@ -454,16 +469,16 @@ kmm_mat_norm_einf(VALUE self)
|
|
454
469
|
SMAT *smat = km_mat2smat(self);
|
455
470
|
if ( smat->vtype == VT_DOUBLE ) {
|
456
471
|
if ( smat->stype == ST_FULL ) {
|
457
|
-
int ione=1, n=
|
472
|
+
const int ione=1, n=LENGTHi(smat);
|
458
473
|
return rb_float_new(fabs(smat->dbody[idamax_(&n, smat->dbody, &ione)-1]));
|
459
474
|
} else if ( smat->stype == ST_SSUB ) {
|
460
|
-
int ione=1
|
475
|
+
const int ione=1; int size; size_t lps; double ret = 0.0;
|
461
476
|
if ( smat->trans ) {
|
462
|
-
lps = smat->m; size = smat->n;
|
477
|
+
lps = smat->m; size = s2i(smat->n);
|
463
478
|
} else {
|
464
|
-
lps = smat->n; size = smat->m;
|
479
|
+
lps = smat->n; size = s2i(smat->m);
|
465
480
|
}
|
466
|
-
for (
|
481
|
+
for ( size_t i=0; i<lps; i++ ) {
|
467
482
|
double temp = fabs(smat->dbody[idamax_(&size, smat->dbody+(i*(smat->ld)), &ione)-1]);
|
468
483
|
if ( ret < temp ) { ret = temp; }
|
469
484
|
}
|
@@ -475,16 +490,16 @@ kmm_mat_norm_einf(VALUE self)
|
|
475
490
|
}
|
476
491
|
} else if ( smat->vtype == VT_COMPLEX ) {
|
477
492
|
if ( smat->stype == ST_FULL ) {
|
478
|
-
int ione=1, n=
|
493
|
+
const int ione=1, n=LENGTHi(smat);
|
479
494
|
return rb_float_new(cabs(smat->zbody[izamax_(&n, smat->zbody, &ione)-1]));
|
480
495
|
} else if ( smat->stype == ST_SSUB ) {
|
481
|
-
int ione=1
|
496
|
+
const int ione=1; int size; size_t lps; double ret = 0.0;
|
482
497
|
if ( smat->trans ) {
|
483
|
-
lps = smat->m; size = smat->n;
|
498
|
+
lps = smat->m; size = s2i(smat->n);
|
484
499
|
} else {
|
485
|
-
lps = smat->n; size = smat->m;
|
500
|
+
lps = smat->n; size = s2i(smat->m);
|
486
501
|
}
|
487
|
-
for (
|
502
|
+
for ( size_t i=0; i<lps; i++ ) {
|
488
503
|
double temp = cabs(smat->zbody[izamax_(&size, smat->zbody+(i*(smat->ld)), &ione)-1]);
|
489
504
|
if ( ret < temp ) { ret = temp; }
|
490
505
|
}
|
@@ -522,7 +537,7 @@ km_norm2_body(VALUE data)
|
|
522
537
|
{
|
523
538
|
struct km_norm2_arg *a = (struct km_norm2_arg *)data;
|
524
539
|
|
525
|
-
int m = a->sa->m, n = a->sa->n;
|
540
|
+
int m = s2i(a->sa->m), n = s2i(a->sa->n);
|
526
541
|
|
527
542
|
double opt; int lwork=-1, info;
|
528
543
|
char jobz[] = "N";
|
@@ -573,8 +588,8 @@ km__rcond2_body(VALUE data)
|
|
573
588
|
{
|
574
589
|
struct km__rcond2_arg *a = (struct km__rcond2_arg *)data;
|
575
590
|
|
576
|
-
int n = a->sa->m;
|
577
|
-
km_check_size(1, a->sa->n,n);
|
591
|
+
int n = s2i(a->sa->m);
|
592
|
+
km_check_size(1, s2i(a->sa->n),n);
|
578
593
|
|
579
594
|
double opt; int lwork=-1, info;
|
580
595
|
char jobz[]="N";
|
@@ -625,8 +640,8 @@ km__rcondf_body(VALUE data)
|
|
625
640
|
{
|
626
641
|
struct km__rcondf_arg *a = (struct km__rcondf_arg *)data;
|
627
642
|
|
628
|
-
int n = a->sa->m;
|
629
|
-
km_check_size(1, a->sa->n,n);
|
643
|
+
int n = s2i(a->sa->m);
|
644
|
+
km_check_size(1, s2i(a->sa->n),n);
|
630
645
|
|
631
646
|
double opt; int lwork=-1, info;
|
632
647
|
dgetri_(&n, NULL, &n, NULL, &opt, &lwork, &info);
|
@@ -640,7 +655,7 @@ km__rcondf_body(VALUE data)
|
|
640
655
|
km_check_info(info, km_eUncomp, "the matrix is exactry singular", "dgetrf");
|
641
656
|
dgetri_(&n, a->a, &n, a->ipiv, a->work, &lwork, &info);
|
642
657
|
km_check_info(info, rb_eRuntimeError, "unexpected info value", "dgetri");
|
643
|
-
int len = n*n, ione = 1;
|
658
|
+
const int len = n*n, ione = 1;
|
644
659
|
return rb_float_new(1.0/((a->normf)*dnrm2_(&len, a->a, &ione)));
|
645
660
|
}
|
646
661
|
static VALUE
|
@@ -678,8 +693,8 @@ km__rcondoi_body(VALUE data)
|
|
678
693
|
{
|
679
694
|
struct km__rcondoi_arg *a = (struct km__rcondoi_arg *)data;
|
680
695
|
|
681
|
-
int n = a->sa->m;
|
682
|
-
km_check_size(1, a->sa->n,n);
|
696
|
+
int n = s2i(a->sa->m);
|
697
|
+
km_check_size(1, s2i(a->sa->n),n);
|
683
698
|
|
684
699
|
KALLOCc(a->a, a->sa);
|
685
700
|
KALLOC(a->iwork, n);
|
@@ -724,4 +739,3 @@ kmm_mat__rcondoi(VALUE self, VALUE sym)
|
|
724
739
|
|
725
740
|
return self;
|
726
741
|
}
|
727
|
-
|
data/ext/kmat/linalg/vla.c
CHANGED
@@ -9,23 +9,23 @@ static VALUE
|
|
9
9
|
km_vmat_solve_body(VALUE data)
|
10
10
|
{
|
11
11
|
struct km_vmat_solve_arg *a = (struct km_vmat_solve_arg *)data;
|
12
|
-
|
13
|
-
|
12
|
+
const size_t n=a->sx->m, nrhs=a->sx->n;
|
13
|
+
km_check_size_s(4, a->sa->m,n, a->sa->n,n, a->sb->m,n, a->sb->n,nrhs);
|
14
14
|
|
15
15
|
KALLOCc(a->a, a->sa);
|
16
16
|
km_alloc_if_needed(a->sx, &(a->x));
|
17
17
|
km_copy2work(a->x.v, a->x.ld, a->sb);
|
18
|
-
VALUE zero=INT2NUM(0);
|
18
|
+
const VALUE zero=INT2NUM(0);
|
19
19
|
|
20
20
|
// forward elimination
|
21
|
-
for (
|
21
|
+
for ( size_t k=0; k<n; k++ ) {
|
22
22
|
if ( rb_funcall((a->a)[k+k*n], id_op_eq, 1, zero) ) {
|
23
|
-
for (
|
23
|
+
for ( size_t i=k+1; i<n; i++ ) {
|
24
24
|
if ( !rb_funcall((a->a)[i+k*n], id_op_eq, 1, zero) ) {
|
25
|
-
for (
|
25
|
+
for ( size_t j=k; j<n; j++ ) {
|
26
26
|
SWAP(VALUE, (a->a)[k+j*n], (a->a)[i+j*n]);
|
27
27
|
}
|
28
|
-
for (
|
28
|
+
for ( size_t j=0; j<nrhs; j++ ) {
|
29
29
|
SWAP(VALUE, (a->x.v)[k+j*(a->x.ld)], (a->x.v)[i+j*(a->x.ld)]);
|
30
30
|
}
|
31
31
|
goto nonsingular;
|
@@ -34,32 +34,32 @@ km_vmat_solve_body(VALUE data)
|
|
34
34
|
rb_raise(km_eUncomp, "matrix is singular");
|
35
35
|
nonsingular: ;
|
36
36
|
}
|
37
|
-
VALUE akk = (a->a)[k+k*n];
|
38
|
-
for (
|
37
|
+
const VALUE akk = (a->a)[k+k*n];
|
38
|
+
for ( size_t j=k+1; j<n; j++ ) {
|
39
39
|
(a->a)[k+j*n] = rb_funcall((a->a)[k+j*n], id_quo, 1, akk);
|
40
40
|
}
|
41
|
-
for (
|
41
|
+
for ( size_t j=0; j<nrhs; j++ ) {
|
42
42
|
(a->x.v)[k+j*(a->x.ld)] = rb_funcall((a->x.v)[k+j*(a->x.ld)], id_quo, 1, akk);
|
43
43
|
}
|
44
|
-
for(
|
45
|
-
VALUE aik = (a->a)[i+k*n];
|
46
|
-
for (
|
47
|
-
VALUE tmp = rb_funcall(aik, id_op_mul, 1, (a->a)[k+j*n]);
|
44
|
+
for( size_t i=k+1; i<n; i++ ) {
|
45
|
+
const VALUE aik = (a->a)[i+k*n];
|
46
|
+
for ( size_t j=k+1; j<n; j++ ) {
|
47
|
+
const VALUE tmp = rb_funcall(aik, id_op_mul, 1, (a->a)[k+j*n]);
|
48
48
|
(a->a)[i+j*n] = rb_funcall((a->a)[i+j*n], id_op_minus, 1, tmp);
|
49
49
|
}
|
50
|
-
for (
|
51
|
-
VALUE tmp = rb_funcall(aik, id_op_mul, 1, (a->x.v)[k+j*(a->x.ld)]);
|
50
|
+
for ( size_t j=0; j<nrhs; j++ ) {
|
51
|
+
const VALUE tmp = rb_funcall(aik, id_op_mul, 1, (a->x.v)[k+j*(a->x.ld)]);
|
52
52
|
(a->x.v)[i+j*(a->x.ld)] = rb_funcall((a->x.v)[i+j*(a->x.ld)], id_op_minus, 1, tmp);
|
53
53
|
}
|
54
54
|
}
|
55
55
|
}
|
56
56
|
|
57
57
|
// back substitution
|
58
|
-
for (
|
59
|
-
for (
|
60
|
-
VALUE aik = (a->a)[i+k*n];
|
61
|
-
for (
|
62
|
-
VALUE tmp = rb_funcall(aik, id_op_mul, 1, (a->x.v)[k+j*(a->x.ld)]);
|
58
|
+
for ( size_t k=n-1; k>0; k-- ) {
|
59
|
+
for ( size_t i=0; i<k; i++ ) {
|
60
|
+
const VALUE aik = (a->a)[i+k*n];
|
61
|
+
for ( size_t j=0; j<nrhs; j++ ) {
|
62
|
+
const VALUE tmp = rb_funcall(aik, id_op_mul, 1, (a->x.v)[k+j*(a->x.ld)]);
|
63
63
|
(a->x.v)[i+j*(a->x.ld)] = rb_funcall((a->x.v)[i+j*(a->x.ld)], id_op_minus, 1, tmp);
|
64
64
|
}
|
65
65
|
}
|
@@ -94,8 +94,8 @@ km_vmat_inverse(VALUE self, VALUE va)
|
|
94
94
|
{
|
95
95
|
SMAT *sx = km_mat2smat(self), *sa = km_mat2smat(va);
|
96
96
|
km_check_value(2, sx, sa);
|
97
|
-
|
98
|
-
|
97
|
+
const size_t n = sa->m;
|
98
|
+
km_check_size_s(3, sx->m,n, sx->n,n, sa->n,n);
|
99
99
|
VALUE ident = km_Mat(n, n, VT_VALUE);
|
100
100
|
kmm_mat_eye(ident);
|
101
101
|
return km_vmat_solve(self, va, ident);
|