numo-linalg-alt 0.3.0 → 0.4.1
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/CHANGELOG.md +9 -0
- data/ext/numo/linalg/blas/dot.c +61 -61
- data/ext/numo/linalg/blas/dot_sub.c +60 -60
- data/ext/numo/linalg/blas/gemm.c +161 -152
- data/ext/numo/linalg/blas/gemv.c +135 -131
- data/ext/numo/linalg/blas/nrm2.c +54 -54
- data/ext/numo/linalg/lapack/gebal.c +87 -0
- data/ext/numo/linalg/lapack/gebal.h +15 -0
- data/ext/numo/linalg/lapack/gees.c +243 -224
- data/ext/numo/linalg/lapack/geev.c +131 -114
- data/ext/numo/linalg/lapack/gelsd.c +85 -74
- data/ext/numo/linalg/lapack/geqrf.c +56 -55
- data/ext/numo/linalg/lapack/gerqf.c +70 -0
- data/ext/numo/linalg/lapack/gerqf.h +15 -0
- data/ext/numo/linalg/lapack/gesdd.c +100 -90
- data/ext/numo/linalg/lapack/gesv.c +84 -82
- data/ext/numo/linalg/lapack/gesvd.c +144 -133
- data/ext/numo/linalg/lapack/getrf.c +55 -54
- data/ext/numo/linalg/lapack/getri.c +68 -67
- data/ext/numo/linalg/lapack/getrs.c +96 -92
- data/ext/numo/linalg/lapack/gges.c +214 -0
- data/ext/numo/linalg/lapack/gges.h +15 -0
- data/ext/numo/linalg/lapack/heev.c +56 -54
- data/ext/numo/linalg/lapack/heevd.c +56 -54
- data/ext/numo/linalg/lapack/heevr.c +111 -100
- data/ext/numo/linalg/lapack/hegv.c +79 -76
- data/ext/numo/linalg/lapack/hegvd.c +79 -76
- data/ext/numo/linalg/lapack/hegvx.c +134 -122
- data/ext/numo/linalg/lapack/hetrf.c +56 -52
- data/ext/numo/linalg/lapack/lange.c +49 -48
- data/ext/numo/linalg/lapack/orgqr.c +65 -64
- data/ext/numo/linalg/lapack/orgrq.c +78 -0
- data/ext/numo/linalg/lapack/orgrq.h +15 -0
- data/ext/numo/linalg/lapack/potrf.c +53 -52
- data/ext/numo/linalg/lapack/potri.c +53 -52
- data/ext/numo/linalg/lapack/potrs.c +78 -76
- data/ext/numo/linalg/lapack/syev.c +56 -54
- data/ext/numo/linalg/lapack/syevd.c +56 -54
- data/ext/numo/linalg/lapack/syevr.c +109 -100
- data/ext/numo/linalg/lapack/sygv.c +79 -75
- data/ext/numo/linalg/lapack/sygvd.c +79 -75
- data/ext/numo/linalg/lapack/sygvx.c +134 -122
- data/ext/numo/linalg/lapack/sytrf.c +58 -54
- data/ext/numo/linalg/lapack/trtrs.c +83 -79
- data/ext/numo/linalg/lapack/ungqr.c +65 -64
- data/ext/numo/linalg/lapack/ungrq.c +78 -0
- data/ext/numo/linalg/lapack/ungrq.h +15 -0
- data/ext/numo/linalg/linalg.c +24 -13
- data/ext/numo/linalg/linalg.h +5 -0
- data/ext/numo/linalg/util.c +8 -0
- data/ext/numo/linalg/util.h +1 -0
- data/lib/numo/linalg/version.rb +1 -1
- data/lib/numo/linalg.rb +235 -3
- metadata +12 -2
|
@@ -5,54 +5,55 @@ struct _potrf_option {
|
|
|
5
5
|
char uplo;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc)
|
|
9
|
-
static void _iter_##fLapackFunc(na_loop_t* const lp) {
|
|
10
|
-
tDType* a = (tDType*)NDL_PTR(lp, 0);
|
|
11
|
-
int* info = (int*)NDL_PTR(lp, 1);
|
|
12
|
-
struct _potrf_option* opt = (struct _potrf_option*)(lp->opt_ptr);
|
|
13
|
-
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0];
|
|
14
|
-
const lapack_int lda = (lapack_int)NDL_SHAPE(lp, 0)[1];
|
|
15
|
-
const lapack_int i = LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, a, lda);
|
|
16
|
-
*info = (int)i;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) {
|
|
20
|
-
VALUE a_vnary = Qnil;
|
|
21
|
-
VALUE kw_args = Qnil;
|
|
22
|
-
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args);
|
|
23
|
-
ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") };
|
|
24
|
-
VALUE kw_values[2] = { Qundef, Qundef };
|
|
25
|
-
rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values);
|
|
26
|
-
const int matrix_layout =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
VALUE
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
8
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
|
9
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
|
10
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
|
11
|
+
int* info = (int*)NDL_PTR(lp, 1); \
|
|
12
|
+
struct _potrf_option* opt = (struct _potrf_option*)(lp->opt_ptr); \
|
|
13
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
|
14
|
+
const lapack_int lda = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
|
|
15
|
+
const lapack_int i = LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, a, lda); \
|
|
16
|
+
*info = (int)i; \
|
|
17
|
+
} \
|
|
18
|
+
\
|
|
19
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
|
20
|
+
VALUE a_vnary = Qnil; \
|
|
21
|
+
VALUE kw_args = Qnil; \
|
|
22
|
+
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args); \
|
|
23
|
+
ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") }; \
|
|
24
|
+
VALUE kw_values[2] = { Qundef, Qundef }; \
|
|
25
|
+
rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values); \
|
|
26
|
+
const int matrix_layout = \
|
|
27
|
+
kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
|
|
28
|
+
const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
|
|
29
|
+
\
|
|
30
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
|
31
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
|
32
|
+
} \
|
|
33
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
|
34
|
+
a_vnary = nary_dup(a_vnary); \
|
|
35
|
+
} \
|
|
36
|
+
\
|
|
37
|
+
narray_t* a_nary = NULL; \
|
|
38
|
+
GetNArray(a_vnary, a_nary); \
|
|
39
|
+
if (NA_NDIM(a_nary) != 2) { \
|
|
40
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
|
41
|
+
return Qnil; \
|
|
42
|
+
} \
|
|
43
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
|
44
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
|
45
|
+
return Qnil; \
|
|
46
|
+
} \
|
|
47
|
+
\
|
|
48
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
|
|
49
|
+
ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
|
|
50
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 1, ain, aout }; \
|
|
51
|
+
struct _potrf_option opt = { matrix_layout, uplo }; \
|
|
52
|
+
VALUE res = na_ndloop3(&ndf, &opt, 1, a_vnary); \
|
|
53
|
+
VALUE ret = rb_ary_new3(2, a_vnary, res); \
|
|
54
|
+
\
|
|
55
|
+
RB_GC_GUARD(a_vnary); \
|
|
56
|
+
return ret; \
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
DEF_LINALG_FUNC(double, numo_cDFloat, dpotrf)
|
|
@@ -63,8 +64,8 @@ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cpotrf)
|
|
|
63
64
|
#undef DEF_LINALG_FUNC
|
|
64
65
|
|
|
65
66
|
void define_linalg_lapack_potrf(VALUE mLapack) {
|
|
66
|
-
rb_define_module_function(mLapack, "dpotrf",
|
|
67
|
-
rb_define_module_function(mLapack, "spotrf",
|
|
68
|
-
rb_define_module_function(mLapack, "zpotrf",
|
|
69
|
-
rb_define_module_function(mLapack, "cpotrf",
|
|
67
|
+
rb_define_module_function(mLapack, "dpotrf", _linalg_lapack_dpotrf, -1);
|
|
68
|
+
rb_define_module_function(mLapack, "spotrf", _linalg_lapack_spotrf, -1);
|
|
69
|
+
rb_define_module_function(mLapack, "zpotrf", _linalg_lapack_zpotrf, -1);
|
|
70
|
+
rb_define_module_function(mLapack, "cpotrf", _linalg_lapack_cpotrf, -1);
|
|
70
71
|
}
|
|
@@ -5,54 +5,55 @@ struct _potri_option {
|
|
|
5
5
|
char uplo;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc)
|
|
9
|
-
static void _iter_##fLapackFunc(na_loop_t* const lp) {
|
|
10
|
-
tDType* a = (tDType*)NDL_PTR(lp, 0);
|
|
11
|
-
int* info = (int*)NDL_PTR(lp, 1);
|
|
12
|
-
struct _potri_option* opt = (struct _potri_option*)(lp->opt_ptr);
|
|
13
|
-
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0];
|
|
14
|
-
const lapack_int lda = (lapack_int)NDL_SHAPE(lp, 0)[1];
|
|
15
|
-
const lapack_int i = LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, a, lda);
|
|
16
|
-
*info = (int)i;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) {
|
|
20
|
-
VALUE a_vnary = Qnil;
|
|
21
|
-
VALUE kw_args = Qnil;
|
|
22
|
-
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args);
|
|
23
|
-
ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") };
|
|
24
|
-
VALUE kw_values[2] = { Qundef, Qundef };
|
|
25
|
-
rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values);
|
|
26
|
-
const int matrix_layout =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
VALUE
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
8
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
|
9
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
|
10
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
|
11
|
+
int* info = (int*)NDL_PTR(lp, 1); \
|
|
12
|
+
struct _potri_option* opt = (struct _potri_option*)(lp->opt_ptr); \
|
|
13
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
|
14
|
+
const lapack_int lda = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
|
|
15
|
+
const lapack_int i = LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, a, lda); \
|
|
16
|
+
*info = (int)i; \
|
|
17
|
+
} \
|
|
18
|
+
\
|
|
19
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
|
20
|
+
VALUE a_vnary = Qnil; \
|
|
21
|
+
VALUE kw_args = Qnil; \
|
|
22
|
+
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args); \
|
|
23
|
+
ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") }; \
|
|
24
|
+
VALUE kw_values[2] = { Qundef, Qundef }; \
|
|
25
|
+
rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values); \
|
|
26
|
+
const int matrix_layout = \
|
|
27
|
+
kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
|
|
28
|
+
const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
|
|
29
|
+
\
|
|
30
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
|
31
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
|
32
|
+
} \
|
|
33
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
|
34
|
+
a_vnary = nary_dup(a_vnary); \
|
|
35
|
+
} \
|
|
36
|
+
\
|
|
37
|
+
narray_t* a_nary = NULL; \
|
|
38
|
+
GetNArray(a_vnary, a_nary); \
|
|
39
|
+
if (NA_NDIM(a_nary) != 2) { \
|
|
40
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
|
41
|
+
return Qnil; \
|
|
42
|
+
} \
|
|
43
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
|
44
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
|
45
|
+
return Qnil; \
|
|
46
|
+
} \
|
|
47
|
+
\
|
|
48
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
|
|
49
|
+
ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
|
|
50
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 1, ain, aout }; \
|
|
51
|
+
struct _potri_option opt = { matrix_layout, uplo }; \
|
|
52
|
+
VALUE res = na_ndloop3(&ndf, &opt, 1, a_vnary); \
|
|
53
|
+
VALUE ret = rb_ary_new3(2, a_vnary, res); \
|
|
54
|
+
\
|
|
55
|
+
RB_GC_GUARD(a_vnary); \
|
|
56
|
+
return ret; \
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
DEF_LINALG_FUNC(double, numo_cDFloat, dpotri)
|
|
@@ -63,8 +64,8 @@ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cpotri)
|
|
|
63
64
|
#undef DEF_LINALG_FUNC
|
|
64
65
|
|
|
65
66
|
void define_linalg_lapack_potri(VALUE mLapack) {
|
|
66
|
-
rb_define_module_function(mLapack, "dpotri",
|
|
67
|
-
rb_define_module_function(mLapack, "spotri",
|
|
68
|
-
rb_define_module_function(mLapack, "zpotri",
|
|
69
|
-
rb_define_module_function(mLapack, "cpotri",
|
|
67
|
+
rb_define_module_function(mLapack, "dpotri", _linalg_lapack_dpotri, -1);
|
|
68
|
+
rb_define_module_function(mLapack, "spotri", _linalg_lapack_spotri, -1);
|
|
69
|
+
rb_define_module_function(mLapack, "zpotri", _linalg_lapack_zpotri, -1);
|
|
70
|
+
rb_define_module_function(mLapack, "cpotri", _linalg_lapack_cpotri, -1);
|
|
70
71
|
}
|
|
@@ -5,78 +5,80 @@ struct _potrs_option {
|
|
|
5
5
|
char uplo;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc)
|
|
9
|
-
static void _iter_##fLapackFunc(na_loop_t* const lp) {
|
|
10
|
-
tDType* a = (tDType*)NDL_PTR(lp, 0);
|
|
11
|
-
tDType* b = (tDType*)NDL_PTR(lp, 1);
|
|
12
|
-
int* info = (int*)NDL_PTR(lp, 2);
|
|
13
|
-
struct _potrs_option* opt = (struct _potrs_option*)(lp->opt_ptr);
|
|
14
|
-
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0];
|
|
15
|
-
const lapack_int nrhs = lp->args[1].ndim == 1 ? 1 : (lapack_int)NDL_SHAPE(lp, 1)[1];
|
|
16
|
-
const lapack_int lda = n;
|
|
17
|
-
const lapack_int ldb = nrhs;
|
|
18
|
-
const lapack_int i =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
VALUE
|
|
25
|
-
VALUE
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
8
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
|
9
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
|
10
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
|
11
|
+
tDType* b = (tDType*)NDL_PTR(lp, 1); \
|
|
12
|
+
int* info = (int*)NDL_PTR(lp, 2); \
|
|
13
|
+
struct _potrs_option* opt = (struct _potrs_option*)(lp->opt_ptr); \
|
|
14
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
|
15
|
+
const lapack_int nrhs = lp->args[1].ndim == 1 ? 1 : (lapack_int)NDL_SHAPE(lp, 1)[1]; \
|
|
16
|
+
const lapack_int lda = n; \
|
|
17
|
+
const lapack_int ldb = nrhs; \
|
|
18
|
+
const lapack_int i = \
|
|
19
|
+
LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, nrhs, a, lda, b, ldb); \
|
|
20
|
+
*info = (int)i; \
|
|
21
|
+
} \
|
|
22
|
+
\
|
|
23
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
|
24
|
+
VALUE a_vnary = Qnil; \
|
|
25
|
+
VALUE b_vnary = Qnil; \
|
|
26
|
+
VALUE kw_args = Qnil; \
|
|
27
|
+
rb_scan_args(argc, argv, "2:", &a_vnary, &b_vnary, &kw_args); \
|
|
28
|
+
ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") }; \
|
|
29
|
+
VALUE kw_values[2] = { Qundef, Qundef }; \
|
|
30
|
+
rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values); \
|
|
31
|
+
const int matrix_layout = \
|
|
32
|
+
kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
|
|
33
|
+
const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
|
|
34
|
+
\
|
|
35
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
|
36
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
|
37
|
+
} \
|
|
38
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
|
39
|
+
a_vnary = nary_dup(a_vnary); \
|
|
40
|
+
} \
|
|
41
|
+
if (CLASS_OF(b_vnary) != tNAryClass) { \
|
|
42
|
+
b_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, b_vnary); \
|
|
43
|
+
} \
|
|
44
|
+
if (!RTEST(nary_check_contiguous(b_vnary))) { \
|
|
45
|
+
b_vnary = nary_dup(b_vnary); \
|
|
46
|
+
} \
|
|
47
|
+
\
|
|
48
|
+
narray_t* a_nary = NULL; \
|
|
49
|
+
GetNArray(a_vnary, a_nary); \
|
|
50
|
+
if (NA_NDIM(a_nary) != 2) { \
|
|
51
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
|
52
|
+
return Qnil; \
|
|
53
|
+
} \
|
|
54
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
|
55
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
|
56
|
+
return Qnil; \
|
|
57
|
+
} \
|
|
58
|
+
narray_t* b_nary = NULL; \
|
|
59
|
+
GetNArray(b_vnary, b_nary); \
|
|
60
|
+
const int b_n_dims = NA_NDIM(b_nary); \
|
|
61
|
+
if (b_n_dims != 1 && b_n_dims != 2) { \
|
|
62
|
+
rb_raise(rb_eArgError, "input array b must be 1- or 2-dimensional"); \
|
|
63
|
+
return Qnil; \
|
|
64
|
+
} \
|
|
65
|
+
\
|
|
66
|
+
lapack_int n = (lapack_int)NA_SHAPE(a_nary)[0]; \
|
|
67
|
+
lapack_int nb = (lapack_int)NA_SHAPE(b_nary)[0]; \
|
|
68
|
+
if (n != nb) { \
|
|
69
|
+
rb_raise(nary_eShapeError, "shape1[0](=%d) != shape2[0](=%d)", n, nb); \
|
|
70
|
+
} \
|
|
71
|
+
\
|
|
72
|
+
ndfunc_arg_in_t ain[2] = { { tNAryClass, 2 }, { OVERWRITE, b_n_dims } }; \
|
|
73
|
+
ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
|
|
74
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 2, 1, ain, aout }; \
|
|
75
|
+
struct _potrs_option opt = { matrix_layout, uplo }; \
|
|
76
|
+
VALUE res = na_ndloop3(&ndf, &opt, 2, a_vnary, b_vnary); \
|
|
77
|
+
VALUE ret = rb_ary_new3(2, b_vnary, res); \
|
|
78
|
+
\
|
|
79
|
+
RB_GC_GUARD(a_vnary); \
|
|
80
|
+
RB_GC_GUARD(b_vnary); \
|
|
81
|
+
return ret; \
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
DEF_LINALG_FUNC(double, numo_cDFloat, dpotrs)
|
|
@@ -87,8 +89,8 @@ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cpotrs)
|
|
|
87
89
|
#undef DEF_LINALG_FUNC
|
|
88
90
|
|
|
89
91
|
void define_linalg_lapack_potrs(VALUE mLapack) {
|
|
90
|
-
rb_define_module_function(mLapack, "dpotrs",
|
|
91
|
-
rb_define_module_function(mLapack, "spotrs",
|
|
92
|
-
rb_define_module_function(mLapack, "zpotrs",
|
|
93
|
-
rb_define_module_function(mLapack, "cpotrs",
|
|
92
|
+
rb_define_module_function(mLapack, "dpotrs", _linalg_lapack_dpotrs, -1);
|
|
93
|
+
rb_define_module_function(mLapack, "spotrs", _linalg_lapack_spotrs, -1);
|
|
94
|
+
rb_define_module_function(mLapack, "zpotrs", _linalg_lapack_zpotrs, -1);
|
|
95
|
+
rb_define_module_function(mLapack, "cpotrs", _linalg_lapack_cpotrs, -1);
|
|
94
96
|
}
|
|
@@ -6,58 +6,60 @@ struct _syev_option {
|
|
|
6
6
|
char uplo;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc)
|
|
10
|
-
static void _iter_##fLapackFunc(na_loop_t* const lp) {
|
|
11
|
-
tDType* a = (tDType*)NDL_PTR(lp, 0);
|
|
12
|
-
tDType* w = (tDType*)NDL_PTR(lp, 1);
|
|
13
|
-
int* info = (int*)NDL_PTR(lp, 2);
|
|
14
|
-
struct _syev_option* opt = (struct _syev_option*)(lp->opt_ptr);
|
|
15
|
-
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1];
|
|
16
|
-
const lapack_int lda = (lapack_int)NDL_SHAPE(lp, 0)[0];
|
|
17
|
-
const lapack_int i =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
VALUE
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const char
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
9
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
|
10
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
|
11
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
|
12
|
+
tDType* w = (tDType*)NDL_PTR(lp, 1); \
|
|
13
|
+
int* info = (int*)NDL_PTR(lp, 2); \
|
|
14
|
+
struct _syev_option* opt = (struct _syev_option*)(lp->opt_ptr); \
|
|
15
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
|
|
16
|
+
const lapack_int lda = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
|
17
|
+
const lapack_int i = \
|
|
18
|
+
LAPACKE_##fLapackFunc(opt->matrix_layout, opt->jobz, opt->uplo, n, a, lda, w); \
|
|
19
|
+
*info = (int)i; \
|
|
20
|
+
} \
|
|
21
|
+
\
|
|
22
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
|
23
|
+
VALUE a_vnary = Qnil; \
|
|
24
|
+
VALUE kw_args = Qnil; \
|
|
25
|
+
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args); \
|
|
26
|
+
ID kw_table[3] = { rb_intern("jobz"), rb_intern("uplo"), rb_intern("order") }; \
|
|
27
|
+
VALUE kw_values[3] = { Qundef, Qundef, Qundef }; \
|
|
28
|
+
rb_get_kwargs(kw_args, kw_table, 0, 3, kw_values); \
|
|
29
|
+
const char jobz = kw_values[0] != Qundef ? get_jobz(kw_values[0]) : 'V'; \
|
|
30
|
+
const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
|
|
31
|
+
const int matrix_layout = \
|
|
32
|
+
kw_values[2] != Qundef ? get_matrix_layout(kw_values[2]) : LAPACK_ROW_MAJOR; \
|
|
33
|
+
\
|
|
34
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
|
35
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
|
36
|
+
} \
|
|
37
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
|
38
|
+
a_vnary = nary_dup(a_vnary); \
|
|
39
|
+
} \
|
|
40
|
+
\
|
|
41
|
+
narray_t* a_nary = NULL; \
|
|
42
|
+
GetNArray(a_vnary, a_nary); \
|
|
43
|
+
if (NA_NDIM(a_nary) != 2) { \
|
|
44
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
|
45
|
+
return Qnil; \
|
|
46
|
+
} \
|
|
47
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
|
48
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
|
49
|
+
return Qnil; \
|
|
50
|
+
} \
|
|
51
|
+
\
|
|
52
|
+
const size_t n = NA_SHAPE(a_nary)[1]; \
|
|
53
|
+
size_t shape[1] = { n }; \
|
|
54
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
|
|
55
|
+
ndfunc_arg_out_t aout[2] = { { tNAryClass, 1, shape }, { numo_cInt32, 0 } }; \
|
|
56
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 2, ain, aout }; \
|
|
57
|
+
struct _syev_option opt = { matrix_layout, jobz, uplo }; \
|
|
58
|
+
VALUE res = na_ndloop3(&ndf, &opt, 1, a_vnary); \
|
|
59
|
+
VALUE ret = rb_ary_new3(3, a_vnary, rb_ary_entry(res, 0), rb_ary_entry(res, 1)); \
|
|
60
|
+
\
|
|
61
|
+
RB_GC_GUARD(a_vnary); \
|
|
62
|
+
return ret; \
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
DEF_LINALG_FUNC(double, numo_cDFloat, dsyev)
|
|
@@ -66,6 +68,6 @@ DEF_LINALG_FUNC(float, numo_cSFloat, ssyev)
|
|
|
66
68
|
#undef DEFINE_LINALG_FUNC
|
|
67
69
|
|
|
68
70
|
void define_linalg_lapack_syev(VALUE mLapack) {
|
|
69
|
-
rb_define_module_function(mLapack, "dsyev",
|
|
70
|
-
rb_define_module_function(mLapack, "ssyev",
|
|
71
|
+
rb_define_module_function(mLapack, "dsyev", _linalg_lapack_dsyev, -1);
|
|
72
|
+
rb_define_module_function(mLapack, "ssyev", _linalg_lapack_ssyev, -1);
|
|
71
73
|
}
|