numo-linalg-alt 0.2.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +27 -0
- data/README.md +106 -0
- data/ext/numo/linalg/blas/dot.c +72 -0
- data/ext/numo/linalg/blas/dot.h +13 -0
- data/ext/numo/linalg/blas/dot_sub.c +71 -0
- data/ext/numo/linalg/blas/dot_sub.h +13 -0
- data/ext/numo/linalg/blas/gemm.c +184 -0
- data/ext/numo/linalg/blas/gemm.h +16 -0
- data/ext/numo/linalg/blas/gemv.c +161 -0
- data/ext/numo/linalg/blas/gemv.h +16 -0
- data/ext/numo/linalg/blas/nrm2.c +67 -0
- data/ext/numo/linalg/blas/nrm2.h +13 -0
- data/ext/numo/linalg/converter.c +67 -0
- data/ext/numo/linalg/converter.h +23 -0
- data/ext/numo/linalg/extconf.rb +99 -0
- data/ext/numo/linalg/lapack/geev.c +152 -0
- data/ext/numo/linalg/lapack/geev.h +15 -0
- data/ext/numo/linalg/lapack/gelsd.c +92 -0
- data/ext/numo/linalg/lapack/gelsd.h +15 -0
- data/ext/numo/linalg/lapack/geqrf.c +72 -0
- data/ext/numo/linalg/lapack/geqrf.h +15 -0
- data/ext/numo/linalg/lapack/gesdd.c +108 -0
- data/ext/numo/linalg/lapack/gesdd.h +15 -0
- data/ext/numo/linalg/lapack/gesv.c +99 -0
- data/ext/numo/linalg/lapack/gesv.h +15 -0
- data/ext/numo/linalg/lapack/gesvd.c +152 -0
- data/ext/numo/linalg/lapack/gesvd.h +15 -0
- data/ext/numo/linalg/lapack/getrf.c +71 -0
- data/ext/numo/linalg/lapack/getrf.h +15 -0
- data/ext/numo/linalg/lapack/getri.c +82 -0
- data/ext/numo/linalg/lapack/getri.h +15 -0
- data/ext/numo/linalg/lapack/getrs.c +110 -0
- data/ext/numo/linalg/lapack/getrs.h +15 -0
- data/ext/numo/linalg/lapack/heev.c +71 -0
- data/ext/numo/linalg/lapack/heev.h +15 -0
- data/ext/numo/linalg/lapack/heevd.c +71 -0
- data/ext/numo/linalg/lapack/heevd.h +15 -0
- data/ext/numo/linalg/lapack/heevr.c +111 -0
- data/ext/numo/linalg/lapack/heevr.h +15 -0
- data/ext/numo/linalg/lapack/hegv.c +94 -0
- data/ext/numo/linalg/lapack/hegv.h +15 -0
- data/ext/numo/linalg/lapack/hegvd.c +94 -0
- data/ext/numo/linalg/lapack/hegvd.h +15 -0
- data/ext/numo/linalg/lapack/hegvx.c +133 -0
- data/ext/numo/linalg/lapack/hegvx.h +15 -0
- data/ext/numo/linalg/lapack/hetrf.c +68 -0
- data/ext/numo/linalg/lapack/hetrf.h +15 -0
- data/ext/numo/linalg/lapack/lange.c +66 -0
- data/ext/numo/linalg/lapack/lange.h +15 -0
- data/ext/numo/linalg/lapack/orgqr.c +79 -0
- data/ext/numo/linalg/lapack/orgqr.h +15 -0
- data/ext/numo/linalg/lapack/potrf.c +70 -0
- data/ext/numo/linalg/lapack/potrf.h +15 -0
- data/ext/numo/linalg/lapack/potri.c +70 -0
- data/ext/numo/linalg/lapack/potri.h +15 -0
- data/ext/numo/linalg/lapack/potrs.c +94 -0
- data/ext/numo/linalg/lapack/potrs.h +15 -0
- data/ext/numo/linalg/lapack/syev.c +71 -0
- data/ext/numo/linalg/lapack/syev.h +15 -0
- data/ext/numo/linalg/lapack/syevd.c +71 -0
- data/ext/numo/linalg/lapack/syevd.h +15 -0
- data/ext/numo/linalg/lapack/syevr.c +111 -0
- data/ext/numo/linalg/lapack/syevr.h +15 -0
- data/ext/numo/linalg/lapack/sygv.c +93 -0
- data/ext/numo/linalg/lapack/sygv.h +15 -0
- data/ext/numo/linalg/lapack/sygvd.c +93 -0
- data/ext/numo/linalg/lapack/sygvd.h +15 -0
- data/ext/numo/linalg/lapack/sygvx.c +133 -0
- data/ext/numo/linalg/lapack/sygvx.h +15 -0
- data/ext/numo/linalg/lapack/sytrf.c +72 -0
- data/ext/numo/linalg/lapack/sytrf.h +15 -0
- data/ext/numo/linalg/lapack/trtrs.c +99 -0
- data/ext/numo/linalg/lapack/trtrs.h +15 -0
- data/ext/numo/linalg/lapack/ungqr.c +79 -0
- data/ext/numo/linalg/lapack/ungqr.h +15 -0
- data/ext/numo/linalg/linalg.c +290 -0
- data/ext/numo/linalg/linalg.h +85 -0
- data/ext/numo/linalg/util.c +95 -0
- data/ext/numo/linalg/util.h +17 -0
- data/lib/numo/linalg/version.rb +10 -0
- data/lib/numo/linalg.rb +1309 -0
- data/vendor/tmp/.gitkeep +0 -0
- metadata +146 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_GESVD_H
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_GESVD_H 1
|
3
|
+
|
4
|
+
#include <lapacke.h>
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include <numo/narray.h>
|
9
|
+
#include <numo/template.h>
|
10
|
+
|
11
|
+
#include "../util.h"
|
12
|
+
|
13
|
+
void define_linalg_lapack_gesvd(VALUE mLapack);
|
14
|
+
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_GESVD_H */
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#include "getrf.h"
|
2
|
+
|
3
|
+
struct _getrf_option {
|
4
|
+
int matrix_layout;
|
5
|
+
};
|
6
|
+
|
7
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
8
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
9
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
10
|
+
int* ipiv = (int*)NDL_PTR(lp, 1); \
|
11
|
+
int* info = (int*)NDL_PTR(lp, 2); \
|
12
|
+
struct _getrf_option* opt = (struct _getrf_option*)(lp->opt_ptr); \
|
13
|
+
const lapack_int m = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
14
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
|
15
|
+
const lapack_int lda = n; \
|
16
|
+
const lapack_int i = LAPACKE_##fLapackFunc(opt->matrix_layout, m, n, a, lda, ipiv); \
|
17
|
+
*info = (int)i; \
|
18
|
+
} \
|
19
|
+
\
|
20
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
21
|
+
VALUE a_vnary = Qnil; \
|
22
|
+
VALUE kw_args = Qnil; \
|
23
|
+
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args); \
|
24
|
+
ID kw_table[1] = { rb_intern("order") }; \
|
25
|
+
VALUE kw_values[1] = { Qundef }; \
|
26
|
+
rb_get_kwargs(kw_args, kw_table, 0, 1, kw_values); \
|
27
|
+
const int matrix_layout = kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
|
28
|
+
\
|
29
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
30
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
31
|
+
} \
|
32
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
33
|
+
a_vnary = nary_dup(a_vnary); \
|
34
|
+
} \
|
35
|
+
\
|
36
|
+
narray_t* a_nary = NULL; \
|
37
|
+
GetNArray(a_vnary, a_nary); \
|
38
|
+
const int n_dims = NA_NDIM(a_nary); \
|
39
|
+
if (n_dims != 2) { \
|
40
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
41
|
+
return Qnil; \
|
42
|
+
} \
|
43
|
+
\
|
44
|
+
size_t m = NA_SHAPE(a_nary)[0]; \
|
45
|
+
size_t n = NA_SHAPE(a_nary)[1]; \
|
46
|
+
size_t shape[1] = { m < n ? m : n }; \
|
47
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
|
48
|
+
ndfunc_arg_out_t aout[2] = { { numo_cInt32, 1, shape }, { numo_cInt32, 0 } }; \
|
49
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 2, ain, aout }; \
|
50
|
+
struct _getrf_option opt = { matrix_layout }; \
|
51
|
+
VALUE res = na_ndloop3(&ndf, &opt, 1, a_vnary); \
|
52
|
+
\
|
53
|
+
VALUE ret = rb_ary_concat(rb_ary_new3(1, a_vnary), res); \
|
54
|
+
\
|
55
|
+
RB_GC_GUARD(a_vnary); \
|
56
|
+
return ret; \
|
57
|
+
}
|
58
|
+
|
59
|
+
DEF_LINALG_FUNC(double, numo_cDFloat, dgetrf)
|
60
|
+
DEF_LINALG_FUNC(float, numo_cSFloat, sgetrf)
|
61
|
+
DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, zgetrf)
|
62
|
+
DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cgetrf)
|
63
|
+
|
64
|
+
#undef DEF_LINALG_FUNC
|
65
|
+
|
66
|
+
void define_linalg_lapack_getrf(VALUE mLapack) {
|
67
|
+
rb_define_module_function(mLapack, "dgetrf", RUBY_METHOD_FUNC(_linalg_lapack_dgetrf), -1);
|
68
|
+
rb_define_module_function(mLapack, "sgetrf", RUBY_METHOD_FUNC(_linalg_lapack_sgetrf), -1);
|
69
|
+
rb_define_module_function(mLapack, "zgetrf", RUBY_METHOD_FUNC(_linalg_lapack_zgetrf), -1);
|
70
|
+
rb_define_module_function(mLapack, "cgetrf", RUBY_METHOD_FUNC(_linalg_lapack_cgetrf), -1);
|
71
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_GETRF_H
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_GETRF_H 1
|
3
|
+
|
4
|
+
#include <lapacke.h>
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include <numo/narray.h>
|
9
|
+
#include <numo/template.h>
|
10
|
+
|
11
|
+
#include "../util.h"
|
12
|
+
|
13
|
+
void define_linalg_lapack_getrf(VALUE mLapack);
|
14
|
+
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_GETRF_H */
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#include "getri.h"
|
2
|
+
|
3
|
+
struct _getri_option {
|
4
|
+
int matrix_layout;
|
5
|
+
};
|
6
|
+
|
7
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
8
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
9
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
10
|
+
lapack_int* ipiv = (lapack_int*)NDL_PTR(lp, 1); \
|
11
|
+
int* info = (int*)NDL_PTR(lp, 2); \
|
12
|
+
struct _getri_option* opt = (struct _getri_option*)(lp->opt_ptr); \
|
13
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
14
|
+
const lapack_int lda = n; \
|
15
|
+
const lapack_int i = LAPACKE_##fLapackFunc(opt->matrix_layout, n, a, lda, ipiv); \
|
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 ipiv_vnary = Qnil; \
|
22
|
+
VALUE kw_args = Qnil; \
|
23
|
+
rb_scan_args(argc, argv, "2:", &a_vnary, &ipiv_vnary, &kw_args); \
|
24
|
+
ID kw_table[1] = { rb_intern("order") }; \
|
25
|
+
VALUE kw_values[1] = { Qundef }; \
|
26
|
+
rb_get_kwargs(kw_args, kw_table, 0, 1, kw_values); \
|
27
|
+
const int matrix_layout = kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
|
28
|
+
\
|
29
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
30
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
31
|
+
} \
|
32
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
33
|
+
a_vnary = nary_dup(a_vnary); \
|
34
|
+
} \
|
35
|
+
if (CLASS_OF(ipiv_vnary) != numo_cInt32) { \
|
36
|
+
ipiv_vnary = rb_funcall(numo_cInt32, rb_intern("cast"), 1, ipiv_vnary); \
|
37
|
+
} \
|
38
|
+
if (!RTEST(nary_check_contiguous(ipiv_vnary))) { \
|
39
|
+
ipiv_vnary = nary_dup(ipiv_vnary); \
|
40
|
+
} \
|
41
|
+
\
|
42
|
+
narray_t* a_nary = NULL; \
|
43
|
+
GetNArray(a_vnary, a_nary); \
|
44
|
+
if (NA_NDIM(a_nary) != 2) { \
|
45
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
46
|
+
return Qnil; \
|
47
|
+
} \
|
48
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
49
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
50
|
+
return Qnil; \
|
51
|
+
} \
|
52
|
+
narray_t* ipiv_nary = NULL; \
|
53
|
+
GetNArray(ipiv_vnary, ipiv_nary); \
|
54
|
+
if (NA_NDIM(ipiv_nary) != 1) { \
|
55
|
+
rb_raise(rb_eArgError, "input array ipiv must be 1-dimensional"); \
|
56
|
+
return Qnil; \
|
57
|
+
} \
|
58
|
+
\
|
59
|
+
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 2 }, { numo_cInt32, 1 } }; \
|
60
|
+
ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
|
61
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 2, 1, ain, aout }; \
|
62
|
+
struct _getri_option opt = { matrix_layout }; \
|
63
|
+
VALUE res = na_ndloop3(&ndf, &opt, 2, a_vnary, ipiv_vnary); \
|
64
|
+
\
|
65
|
+
VALUE ret = rb_ary_new3(2, a_vnary, res); \
|
66
|
+
\
|
67
|
+
RB_GC_GUARD(a_vnary); \
|
68
|
+
RB_GC_GUARD(ipiv_vnary); \
|
69
|
+
return ret; \
|
70
|
+
}
|
71
|
+
|
72
|
+
DEF_LINALG_FUNC(double, numo_cDFloat, dgetri)
|
73
|
+
DEF_LINALG_FUNC(float, numo_cSFloat, sgetri)
|
74
|
+
DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, zgetri)
|
75
|
+
DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cgetri)
|
76
|
+
|
77
|
+
void define_linalg_lapack_getri(VALUE mLapack) {
|
78
|
+
rb_define_module_function(mLapack, "dgetri", RUBY_METHOD_FUNC(_linalg_lapack_dgetri), -1);
|
79
|
+
rb_define_module_function(mLapack, "sgetri", RUBY_METHOD_FUNC(_linalg_lapack_sgetri), -1);
|
80
|
+
rb_define_module_function(mLapack, "zgetri", RUBY_METHOD_FUNC(_linalg_lapack_zgetri), -1);
|
81
|
+
rb_define_module_function(mLapack, "cgetri", RUBY_METHOD_FUNC(_linalg_lapack_cgetri), -1);
|
82
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_GETRI_H
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_GETRI_H 1
|
3
|
+
|
4
|
+
#include <lapacke.h>
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include <numo/narray.h>
|
9
|
+
#include <numo/template.h>
|
10
|
+
|
11
|
+
#include "../util.h"
|
12
|
+
|
13
|
+
void define_linalg_lapack_getri(VALUE mLapack);
|
14
|
+
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_GETRI_H */
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#include "getrs.h"
|
2
|
+
|
3
|
+
struct _getrs_option {
|
4
|
+
int matrix_layout;
|
5
|
+
char trans;
|
6
|
+
};
|
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* ipiv = (int*)NDL_PTR(lp, 1); \
|
12
|
+
tDType* b = (tDType*)NDL_PTR(lp, 2); \
|
13
|
+
int* info = (int*)NDL_PTR(lp, 3); \
|
14
|
+
struct _getrs_option* opt = (struct _getrs_option*)(lp->opt_ptr); \
|
15
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
16
|
+
const lapack_int nrhs = lp->args[2].ndim == 1 ? 1 : (lapack_int)NDL_SHAPE(lp, 2)[1]; \
|
17
|
+
const lapack_int lda = n; \
|
18
|
+
const lapack_int ldb = nrhs; \
|
19
|
+
const lapack_int i = LAPACKE_##fLapackFunc(opt->matrix_layout, opt->trans, n, nrhs, a, lda, ipiv, 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 ipiv_vnary = Qnil; \
|
26
|
+
VALUE b_vnary = Qnil; \
|
27
|
+
VALUE kw_args = Qnil; \
|
28
|
+
rb_scan_args(argc, argv, "3:", &a_vnary, &ipiv_vnary, &b_vnary, &kw_args); \
|
29
|
+
ID kw_table[2] = { rb_intern("order"), rb_intern("trans") }; \
|
30
|
+
VALUE kw_values[2] = { Qundef, Qundef }; \
|
31
|
+
rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values); \
|
32
|
+
const int matrix_layout = kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
|
33
|
+
const char trans = kw_values[1] != Qundef ? NUM2CHR(kw_values[1]) : 'N'; \
|
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(ipiv_vnary) != numo_cInt32) { \
|
42
|
+
ipiv_vnary = rb_funcall(numo_cInt32, rb_intern("cast"), 1, ipiv_vnary); \
|
43
|
+
} \
|
44
|
+
if (!RTEST(nary_check_contiguous(ipiv_vnary))) { \
|
45
|
+
ipiv_vnary = nary_dup(ipiv_vnary); \
|
46
|
+
} \
|
47
|
+
if (CLASS_OF(b_vnary) != tNAryClass) { \
|
48
|
+
b_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, b_vnary); \
|
49
|
+
} \
|
50
|
+
if (!RTEST(nary_check_contiguous(b_vnary))) { \
|
51
|
+
b_vnary = nary_dup(b_vnary); \
|
52
|
+
} \
|
53
|
+
\
|
54
|
+
narray_t* a_nary = NULL; \
|
55
|
+
GetNArray(a_vnary, a_nary); \
|
56
|
+
const int n_dims = NA_NDIM(a_nary); \
|
57
|
+
if (n_dims != 2) { \
|
58
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
59
|
+
return Qnil; \
|
60
|
+
} \
|
61
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
62
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
63
|
+
return Qnil; \
|
64
|
+
} \
|
65
|
+
narray_t* ipiv_nary = NULL; \
|
66
|
+
GetNArray(ipiv_vnary, ipiv_nary); \
|
67
|
+
const int ipiv_n_dims = NA_NDIM(ipiv_nary); \
|
68
|
+
if (ipiv_n_dims != 1) { \
|
69
|
+
rb_raise(rb_eArgError, "input array ipiv must be 1-dimensional"); \
|
70
|
+
return Qnil; \
|
71
|
+
} \
|
72
|
+
narray_t* b_nary = NULL; \
|
73
|
+
GetNArray(b_vnary, b_nary); \
|
74
|
+
const int b_n_dims = NA_NDIM(b_nary); \
|
75
|
+
if (b_n_dims != 1 && b_n_dims != 2) { \
|
76
|
+
rb_raise(rb_eArgError, "input array b must be 1 or 2-dimensional"); \
|
77
|
+
return Qnil; \
|
78
|
+
} \
|
79
|
+
lapack_int n = (lapack_int)NA_SHAPE(a_nary)[0]; \
|
80
|
+
lapack_int nb = (lapack_int)NA_SHAPE(b_nary)[0]; \
|
81
|
+
if (n != nb) { \
|
82
|
+
rb_raise(nary_eShapeError, "shape1[0](=%d) != shape2[0](=%d)", n, nb); \
|
83
|
+
} \
|
84
|
+
\
|
85
|
+
ndfunc_arg_in_t ain[3] = { { tNAryClass, 2 }, { numo_cInt32, 1 }, { OVERWRITE, b_n_dims } }; \
|
86
|
+
ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
|
87
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 3, 1, ain, aout }; \
|
88
|
+
struct _getrs_option opt = { matrix_layout, trans }; \
|
89
|
+
VALUE info = na_ndloop3(&ndf, &opt, 3, a_vnary, ipiv_vnary, b_vnary); \
|
90
|
+
VALUE ret = rb_ary_new3(2, b_vnary, info); \
|
91
|
+
\
|
92
|
+
RB_GC_GUARD(a_vnary); \
|
93
|
+
RB_GC_GUARD(ipiv_vnary); \
|
94
|
+
RB_GC_GUARD(b_vnary); \
|
95
|
+
return ret; \
|
96
|
+
}
|
97
|
+
|
98
|
+
DEF_LINALG_FUNC(double, numo_cDFloat, dgetrs)
|
99
|
+
DEF_LINALG_FUNC(float, numo_cSFloat, sgetrs)
|
100
|
+
DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, zgetrs)
|
101
|
+
DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cgetrs)
|
102
|
+
|
103
|
+
#undef DEF_LINALG_FUNC
|
104
|
+
|
105
|
+
void define_linalg_lapack_getrs(VALUE mLapack) {
|
106
|
+
rb_define_module_function(mLapack, "dgetrs", RUBY_METHOD_FUNC(_linalg_lapack_dgetrs), -1);
|
107
|
+
rb_define_module_function(mLapack, "sgetrs", RUBY_METHOD_FUNC(_linalg_lapack_sgetrs), -1);
|
108
|
+
rb_define_module_function(mLapack, "zgetrs", RUBY_METHOD_FUNC(_linalg_lapack_zgetrs), -1);
|
109
|
+
rb_define_module_function(mLapack, "cgetrs", RUBY_METHOD_FUNC(_linalg_lapack_cgetrs), -1);
|
110
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_GETRS_H
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_GETRS_H 1
|
3
|
+
|
4
|
+
#include <lapacke.h>
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include <numo/narray.h>
|
9
|
+
#include <numo/template.h>
|
10
|
+
|
11
|
+
#include "../util.h"
|
12
|
+
|
13
|
+
void define_linalg_lapack_getrs(VALUE mLapack);
|
14
|
+
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_GETRS_H */
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#include "heev.h"
|
2
|
+
|
3
|
+
struct _heev_option {
|
4
|
+
int matrix_layout;
|
5
|
+
char jobz;
|
6
|
+
char uplo;
|
7
|
+
};
|
8
|
+
|
9
|
+
#define DEF_LINALG_FUNC(tDType, tRtDType, tNAryClass, tRtNAryClass, fLapackFunc) \
|
10
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
11
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
12
|
+
tRtDType* w = (tRtDType*)NDL_PTR(lp, 1); \
|
13
|
+
int* info = (int*)NDL_PTR(lp, 2); \
|
14
|
+
struct _heev_option* opt = (struct _heev_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 = LAPACKE_##fLapackFunc(opt->matrix_layout, opt->jobz, opt->uplo, n, a, lda, w); \
|
18
|
+
*info = (int)i; \
|
19
|
+
} \
|
20
|
+
\
|
21
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
22
|
+
VALUE a_vnary = Qnil; \
|
23
|
+
VALUE kw_args = Qnil; \
|
24
|
+
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args); \
|
25
|
+
ID kw_table[3] = { rb_intern("jobz"), rb_intern("uplo"), rb_intern("order") }; \
|
26
|
+
VALUE kw_values[3] = { Qundef, Qundef, Qundef }; \
|
27
|
+
rb_get_kwargs(kw_args, kw_table, 0, 3, kw_values); \
|
28
|
+
const char jobz = kw_values[0] != Qundef ? get_jobz(kw_values[0]) : 'V'; \
|
29
|
+
const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
|
30
|
+
const int matrix_layout = kw_values[2] != Qundef ? get_matrix_layout(kw_values[2]) : LAPACK_ROW_MAJOR; \
|
31
|
+
\
|
32
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
33
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
34
|
+
} \
|
35
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
36
|
+
a_vnary = nary_dup(a_vnary); \
|
37
|
+
} \
|
38
|
+
\
|
39
|
+
narray_t* a_nary = NULL; \
|
40
|
+
GetNArray(a_vnary, a_nary); \
|
41
|
+
if (NA_NDIM(a_nary) != 2) { \
|
42
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
43
|
+
return Qnil; \
|
44
|
+
} \
|
45
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
46
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
47
|
+
return Qnil; \
|
48
|
+
} \
|
49
|
+
\
|
50
|
+
const size_t n = NA_SHAPE(a_nary)[1]; \
|
51
|
+
size_t shape[1] = { n }; \
|
52
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
|
53
|
+
ndfunc_arg_out_t aout[2] = { { tRtNAryClass, 1, shape }, { numo_cInt32, 0 } }; \
|
54
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 2, ain, aout }; \
|
55
|
+
struct _heev_option opt = { matrix_layout, jobz, uplo }; \
|
56
|
+
VALUE res = na_ndloop3(&ndf, &opt, 1, a_vnary); \
|
57
|
+
VALUE ret = rb_ary_new3(3, a_vnary, rb_ary_entry(res, 0), rb_ary_entry(res, 1)); \
|
58
|
+
\
|
59
|
+
RB_GC_GUARD(a_vnary); \
|
60
|
+
return ret; \
|
61
|
+
}
|
62
|
+
|
63
|
+
DEF_LINALG_FUNC(lapack_complex_double, double, numo_cDComplex, numo_cDFloat, zheev)
|
64
|
+
DEF_LINALG_FUNC(lapack_complex_float, float, numo_cSComplex, numo_cSFloat, cheev)
|
65
|
+
|
66
|
+
#undef DEF_LINALG_FUNC
|
67
|
+
|
68
|
+
void define_linalg_lapack_heev(VALUE mLapack) {
|
69
|
+
rb_define_module_function(mLapack, "zheev", RUBY_METHOD_FUNC(_linalg_lapack_zheev), -1);
|
70
|
+
rb_define_module_function(mLapack, "cheev", RUBY_METHOD_FUNC(_linalg_lapack_cheev), -1);
|
71
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_HEEV_H
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_HEEV_H 1
|
3
|
+
|
4
|
+
#include <lapacke.h>
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include <numo/narray.h>
|
9
|
+
#include <numo/template.h>
|
10
|
+
|
11
|
+
#include "../util.h"
|
12
|
+
|
13
|
+
void define_linalg_lapack_heev(VALUE mLapack);
|
14
|
+
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_HEEV_H */
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#include "heevd.h"
|
2
|
+
|
3
|
+
struct _heevd_option {
|
4
|
+
int matrix_layout;
|
5
|
+
char jobz;
|
6
|
+
char uplo;
|
7
|
+
};
|
8
|
+
|
9
|
+
#define DEF_LINALG_FUNC(tDType, tRtDType, tNAryClass, tRtNAryClass, fLapackFunc) \
|
10
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
11
|
+
tDType* a = (tDType*)NDL_PTR(lp, 0); \
|
12
|
+
tRtDType* w = (tRtDType*)NDL_PTR(lp, 1); \
|
13
|
+
int* info = (int*)NDL_PTR(lp, 2); \
|
14
|
+
struct _heevd_option* opt = (struct _heevd_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 = LAPACKE_##fLapackFunc(opt->matrix_layout, opt->jobz, opt->uplo, n, a, lda, w); \
|
18
|
+
*info = (int)i; \
|
19
|
+
} \
|
20
|
+
\
|
21
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
22
|
+
VALUE a_vnary = Qnil; \
|
23
|
+
VALUE kw_args = Qnil; \
|
24
|
+
rb_scan_args(argc, argv, "1:", &a_vnary, &kw_args); \
|
25
|
+
ID kw_table[3] = { rb_intern("jobz"), rb_intern("uplo"), rb_intern("order") }; \
|
26
|
+
VALUE kw_values[3] = { Qundef, Qundef, Qundef }; \
|
27
|
+
rb_get_kwargs(kw_args, kw_table, 0, 3, kw_values); \
|
28
|
+
const char jobz = kw_values[0] != Qundef ? get_jobz(kw_values[0]) : 'V'; \
|
29
|
+
const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
|
30
|
+
const int matrix_layout = kw_values[2] != Qundef ? get_matrix_layout(kw_values[2]) : LAPACK_ROW_MAJOR; \
|
31
|
+
\
|
32
|
+
if (CLASS_OF(a_vnary) != tNAryClass) { \
|
33
|
+
a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
|
34
|
+
} \
|
35
|
+
if (!RTEST(nary_check_contiguous(a_vnary))) { \
|
36
|
+
a_vnary = nary_dup(a_vnary); \
|
37
|
+
} \
|
38
|
+
\
|
39
|
+
narray_t* a_nary = NULL; \
|
40
|
+
GetNArray(a_vnary, a_nary); \
|
41
|
+
if (NA_NDIM(a_nary) != 2) { \
|
42
|
+
rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
|
43
|
+
return Qnil; \
|
44
|
+
} \
|
45
|
+
if (NA_SHAPE(a_nary)[0] != NA_SHAPE(a_nary)[1]) { \
|
46
|
+
rb_raise(rb_eArgError, "input array a must be square"); \
|
47
|
+
return Qnil; \
|
48
|
+
} \
|
49
|
+
\
|
50
|
+
const size_t n = NA_SHAPE(a_nary)[1]; \
|
51
|
+
size_t shape[1] = { n }; \
|
52
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
|
53
|
+
ndfunc_arg_out_t aout[2] = { { tRtNAryClass, 1, shape }, { numo_cInt32, 0 } }; \
|
54
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 2, ain, aout }; \
|
55
|
+
struct _heevd_option opt = { matrix_layout, jobz, uplo }; \
|
56
|
+
VALUE res = na_ndloop3(&ndf, &opt, 1, a_vnary); \
|
57
|
+
VALUE ret = rb_ary_new3(3, a_vnary, rb_ary_entry(res, 0), rb_ary_entry(res, 1)); \
|
58
|
+
\
|
59
|
+
RB_GC_GUARD(a_vnary); \
|
60
|
+
return ret; \
|
61
|
+
}
|
62
|
+
|
63
|
+
DEF_LINALG_FUNC(lapack_complex_double, double, numo_cDComplex, numo_cDFloat, zheevd)
|
64
|
+
DEF_LINALG_FUNC(lapack_complex_float, float, numo_cSComplex, numo_cSFloat, cheevd)
|
65
|
+
|
66
|
+
#undef DEF_LINALG_FUNC
|
67
|
+
|
68
|
+
void define_linalg_lapack_heevd(VALUE mLapack) {
|
69
|
+
rb_define_module_function(mLapack, "zheevd", RUBY_METHOD_FUNC(_linalg_lapack_zheevd), -1);
|
70
|
+
rb_define_module_function(mLapack, "cheevd", RUBY_METHOD_FUNC(_linalg_lapack_cheevd), -1);
|
71
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_HEEVD_H
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_HEEVD_H 1
|
3
|
+
|
4
|
+
#include <lapacke.h>
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
|
8
|
+
#include <numo/narray.h>
|
9
|
+
#include <numo/template.h>
|
10
|
+
|
11
|
+
#include "../util.h"
|
12
|
+
|
13
|
+
void define_linalg_lapack_heevd(VALUE mLapack);
|
14
|
+
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_HEEVD_H */
|