numo-linalg-alt 0.7.2 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 074a79c2f0a7c299dfe6332f47440698030b04546274ea93bd76907bb5cf5af7
4
- data.tar.gz: 4539bee85382917fd99ef2744673b796d4234562f6573b1441f17a51ed90552b
3
+ metadata.gz: 878a6945e58e2447673f33738b51bd5f10d61d0b4ac2237105a7f58b55da4ea3
4
+ data.tar.gz: ff8d43ac0316864b8510271561b7dca0401350fc3028e822248e19d674e6eb68
5
5
  SHA512:
6
- metadata.gz: b219e82e41d7a6b29286d2450abe548a86cff6c2bb888d0ed9e3954ef6d22153db849995feb7fbb3673f68190eba932df63ba566fce66d7d15fdef1568c35f9d
7
- data.tar.gz: a69dbd9f8f6d695949a7220ef27e56ca5591d550a1799c813d5130dd9d0985602ce658b0afb4683afb7be9a49db50e0a5b30e1739fe4fc4ca34eb0da9c921fc5
6
+ metadata.gz: d7d31594b072954acc244dcc41fde1b7a0b3ae095d9b9b1c9ce5f1af8803c5826d0ff287c56ce4447c196aa9e60f80c8f382ae1bb930368509fb4355f073f549
7
+ data.tar.gz: b319186e15031c6754497c8121d31aaa8454a690d828fdcc85bc67bbcf6c06595ca61cacbdd3e2867eb3731d076405d20d08ca044cae2e9649a6a3e936bcccf6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [[0.9.0](https://github.com/yoshoku/numo-linalg-alt/compare/v0.8.0...v0.9.0)] - 2026-02-14
2
+
3
+ - add `eigh_tridiagonal` and `eigvalsh_tridiagonal` module functions to Numo::Linalg.
4
+ - add `eig_banded` and `eigvals_banded` module functions to Numo::Linalg.
5
+ - fix CI workflow to correctly run ruby_memcheck.
6
+
7
+ ## [[0.8.0](https://github.com/yoshoku/numo-linalg-alt/compare/v0.7.2...v0.8.0)] - 2026-02-06
8
+
9
+ - relax numo-narray-alt version constraint to >= 0.9.10, < 0.11.0.
10
+ - add `diagsvd` module function to Numo::Linalg.
11
+ - add `cholesky_banded` and `cho_solve_banded` module functions to Numo::Linalg.
12
+ - add `solve_banded` and `solveh_banded` module functions to Numo::Linalg.
13
+
1
14
  ## [[0.7.2](https://github.com/yoshoku/numo-linalg-alt/compare/v0.7.1...v0.7.2)] - 2026-01-16
2
15
 
3
16
  - bump OpenBLAS from 0.3.30 to 0.3.31.
@@ -0,0 +1,92 @@
1
+ #include "gbsv.h"
2
+
3
+ struct _gbsv_option {
4
+ int matrix_layout;
5
+ int kl;
6
+ int ku;
7
+ };
8
+
9
+ #define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
10
+ static void _iter_##fLapackFunc(na_loop_t* const lp) { \
11
+ tDType* ab = (tDType*)NDL_PTR(lp, 0); \
12
+ tDType* b = (tDType*)NDL_PTR(lp, 1); \
13
+ int* ipiv = (int*)NDL_PTR(lp, 2); \
14
+ int* info = (int*)NDL_PTR(lp, 3); \
15
+ struct _gbsv_option* opt = (struct _gbsv_option*)(lp->opt_ptr); \
16
+ const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
17
+ const lapack_int nrhs = lp->args[1].ndim == 1 ? 1 : (lapack_int)NDL_SHAPE(lp, 1)[1]; \
18
+ const lapack_int ldab = n; \
19
+ const lapack_int ldb = nrhs; \
20
+ const lapack_int i = LAPACKE_##fLapackFunc( \
21
+ opt->matrix_layout, n, opt->kl, opt->ku, nrhs, ab, ldab, ipiv, b, ldb \
22
+ ); \
23
+ *info = (int)i; \
24
+ } \
25
+ \
26
+ static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
27
+ VALUE ab_vnary = Qnil; \
28
+ VALUE b_vnary = Qnil; \
29
+ VALUE kw_args = Qnil; \
30
+ rb_scan_args(argc, argv, "2:", &ab_vnary, &b_vnary, &kw_args); \
31
+ ID kw_table[3] = { rb_intern("kl"), rb_intern("ku"), rb_intern("order") }; \
32
+ VALUE kw_values[3] = { Qundef, Qundef, Qundef }; \
33
+ rb_get_kwargs(kw_args, kw_table, 2, 1, kw_values); \
34
+ const int kl = NUM2INT(kw_values[0]); \
35
+ const int ku = NUM2INT(kw_values[1]); \
36
+ const int matrix_layout = \
37
+ kw_values[2] != Qundef ? get_matrix_layout(kw_values[2]) : LAPACK_ROW_MAJOR; \
38
+ \
39
+ if (CLASS_OF(ab_vnary) != tNAryClass) { \
40
+ ab_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, ab_vnary); \
41
+ } \
42
+ if (!RTEST(nary_check_contiguous(ab_vnary))) { \
43
+ ab_vnary = nary_dup(ab_vnary); \
44
+ } \
45
+ if (CLASS_OF(b_vnary) != tNAryClass) { \
46
+ b_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, b_vnary); \
47
+ } \
48
+ if (!RTEST(nary_check_contiguous(b_vnary))) { \
49
+ b_vnary = nary_dup(b_vnary); \
50
+ } \
51
+ \
52
+ narray_t* ab_nary = NULL; \
53
+ narray_t* b_nary = NULL; \
54
+ GetNArray(ab_vnary, ab_nary); \
55
+ GetNArray(b_vnary, b_nary); \
56
+ const int ab_n_dims = NA_NDIM(ab_nary); \
57
+ const int b_n_dims = NA_NDIM(b_nary); \
58
+ if (ab_n_dims != 2) { \
59
+ rb_raise(rb_eArgError, "input array ab must be 2-dimensional"); \
60
+ return Qnil; \
61
+ } \
62
+ if (b_n_dims != 1 && b_n_dims != 2) { \
63
+ rb_raise(rb_eArgError, "input array b must be 1- or 2-dimensional"); \
64
+ return Qnil; \
65
+ } \
66
+ \
67
+ size_t shape[1] = { NA_SHAPE(ab_nary)[1] }; \
68
+ ndfunc_arg_in_t ain[2] = { { OVERWRITE, 2 }, { OVERWRITE, b_n_dims } }; \
69
+ ndfunc_arg_out_t aout[2] = { { numo_cInt32, 1, shape }, { numo_cInt32, 0 } }; \
70
+ ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 2, 2, ain, aout }; \
71
+ struct _gbsv_option opt = { matrix_layout, kl, ku }; \
72
+ VALUE res = na_ndloop3(&ndf, &opt, 2, ab_vnary, b_vnary); \
73
+ VALUE ret = rb_ary_concat(rb_assoc_new(ab_vnary, b_vnary), res); \
74
+ \
75
+ RB_GC_GUARD(ab_vnary); \
76
+ RB_GC_GUARD(b_vnary); \
77
+ return ret; \
78
+ }
79
+
80
+ DEF_LINALG_FUNC(double, numo_cDFloat, dgbsv)
81
+ DEF_LINALG_FUNC(float, numo_cSFloat, sgbsv)
82
+ DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, zgbsv)
83
+ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cgbsv)
84
+
85
+ #undef DEF_LINALG_FUNC
86
+
87
+ void define_linalg_lapack_gbsv(VALUE mLapack) {
88
+ rb_define_module_function(mLapack, "dgbsv", _linalg_lapack_dgbsv, -1);
89
+ rb_define_module_function(mLapack, "sgbsv", _linalg_lapack_sgbsv, -1);
90
+ rb_define_module_function(mLapack, "zgbsv", _linalg_lapack_zgbsv, -1);
91
+ rb_define_module_function(mLapack, "cgbsv", _linalg_lapack_cgbsv, -1);
92
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NUMO_LINALG_ALT_LAPACK_GBSV_H
2
+ #define NUMO_LINALG_ALT_LAPACK_GBSV_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 "lapack_util.h"
12
+
13
+ void define_linalg_lapack_gbsv(VALUE mLapack);
14
+
15
+ #endif /* NUMO_LINALG_ALT_LAPACK_GBSV_H */
@@ -0,0 +1,112 @@
1
+ #include "hbevx.h"
2
+
3
+ #define DEF_LINALG_FUNC(tDType, tNAryClass, tRtDType, tRtNAryClass, fLapackFunc) \
4
+ struct _hbevx_option_##tDType { \
5
+ int matrix_layout; \
6
+ char jobz; \
7
+ char range; \
8
+ char uplo; \
9
+ tRtDType vl; \
10
+ tRtDType vu; \
11
+ lapack_int il; \
12
+ lapack_int iu; \
13
+ }; \
14
+ \
15
+ static void _iter_##fLapackFunc(na_loop_t* const lp) { \
16
+ tDType* ab = (tDType*)NDL_PTR(lp, 0); \
17
+ tDType* q = (tDType*)NDL_PTR(lp, 1); \
18
+ int* m = (int*)NDL_PTR(lp, 2); \
19
+ tRtDType* w = (tRtDType*)NDL_PTR(lp, 3); \
20
+ tDType* z = (tDType*)NDL_PTR(lp, 4); \
21
+ int* ifail = (int*)NDL_PTR(lp, 5); \
22
+ int* info = (int*)NDL_PTR(lp, 6); \
23
+ struct _hbevx_option_##tDType* opt = (struct _hbevx_option_##tDType*)(lp->opt_ptr); \
24
+ const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
25
+ const lapack_int kd = (lapack_int)NDL_SHAPE(lp, 0)[0] - 1; \
26
+ const lapack_int ldab = n; \
27
+ const lapack_int ldq = n; \
28
+ const lapack_int ldz = opt->range != 'I' ? n : opt->iu - opt->il + 1; \
29
+ const tRtDType abstol = 0.0; \
30
+ const lapack_int i = LAPACKE_##fLapackFunc( \
31
+ opt->matrix_layout, opt->jobz, opt->range, opt->uplo, n, kd, ab, ldab, q, ldq, opt->vl, \
32
+ opt->vu, opt->il, opt->iu, abstol, m, w, z, ldz, ifail \
33
+ ); \
34
+ *info = (int)i; \
35
+ } \
36
+ \
37
+ static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
38
+ VALUE ab_vnary = Qnil; \
39
+ VALUE kw_args = Qnil; \
40
+ rb_scan_args(argc, argv, "1:", &ab_vnary, &kw_args); \
41
+ ID kw_table[8] = { rb_intern("jobz"), rb_intern("range"), rb_intern("uplo"), \
42
+ rb_intern("vl"), rb_intern("vu"), rb_intern("il"), \
43
+ rb_intern("iu"), rb_intern("order") }; \
44
+ VALUE kw_values[8] = { Qundef, Qundef, Qundef, Qundef, Qundef, Qundef, Qundef, Qundef }; \
45
+ rb_get_kwargs(kw_args, kw_table, 0, 8, kw_values); \
46
+ const char jobz = kw_values[0] != Qundef ? get_job(kw_values[0], "jobz") : 'V'; \
47
+ const char range = kw_values[1] != Qundef ? get_range(kw_values[1]) : 'A'; \
48
+ const char uplo = kw_values[2] != Qundef ? get_uplo(kw_values[2]) : 'U'; \
49
+ const tRtDType vl = kw_values[3] != Qundef ? NUM2DBL(kw_values[3]) : 0.0; \
50
+ const tRtDType vu = kw_values[4] != Qundef ? NUM2DBL(kw_values[4]) : 0.0; \
51
+ const lapack_int il = kw_values[5] != Qundef ? NUM2INT(kw_values[5]) : 0; \
52
+ const lapack_int iu = kw_values[6] != Qundef ? NUM2INT(kw_values[6]) : 0; \
53
+ const int matrix_layout = \
54
+ kw_values[7] != Qundef ? get_matrix_layout(kw_values[7]) : LAPACK_ROW_MAJOR; \
55
+ \
56
+ if (CLASS_OF(ab_vnary) != tNAryClass) { \
57
+ ab_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, ab_vnary); \
58
+ } \
59
+ if (!RTEST(nary_check_contiguous(ab_vnary))) { \
60
+ ab_vnary = nary_dup(ab_vnary); \
61
+ } \
62
+ \
63
+ narray_t* ab_nary = NULL; \
64
+ GetNArray(ab_vnary, ab_nary); \
65
+ if (NA_NDIM(ab_nary) != 2) { \
66
+ rb_raise(rb_eArgError, "input array ab must be 2-dimensional"); \
67
+ return Qnil; \
68
+ } \
69
+ if (range == 'V' && vu <= vl) { \
70
+ rb_raise(rb_eArgError, "vu must be greater than vl"); \
71
+ return Qnil; \
72
+ } \
73
+ const size_t n = NA_SHAPE(ab_nary)[1]; \
74
+ if (range == 'I' && (il < 1 || il > (lapack_int)n)) { \
75
+ rb_raise(rb_eArgError, "il must satisfy 1 <= il <= n"); \
76
+ return Qnil; \
77
+ } \
78
+ if (range == 'I' && (iu < 1 || iu > (lapack_int)n)) { \
79
+ rb_raise(rb_eArgError, "iu must satisfy 1 <= iu <= n"); \
80
+ return Qnil; \
81
+ } \
82
+ if (range == 'I' && iu < il) { \
83
+ rb_raise(rb_eArgError, "iu must be greater than or equal to il"); \
84
+ return Qnil; \
85
+ } \
86
+ \
87
+ size_t m = range != 'I' ? n : (size_t)(iu - il + 1); \
88
+ size_t q_shape[2] = { n, n }; \
89
+ size_t w_shape[1] = { m }; \
90
+ size_t z_shape[2] = { n, m }; \
91
+ size_t ifail_shape[1] = { m }; \
92
+ ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
93
+ ndfunc_arg_out_t aout[6] = { { tNAryClass, 2, q_shape }, { numo_cInt32, 0 }, \
94
+ { tRtNAryClass, 1, w_shape }, { tNAryClass, 2, z_shape }, \
95
+ { numo_cInt32, 1, ifail_shape }, { numo_cInt32, 0 } }; \
96
+ ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 6, ain, aout }; \
97
+ struct _hbevx_option_##tDType opt = { matrix_layout, jobz, range, uplo, vl, vu, il, iu }; \
98
+ VALUE ret = na_ndloop3(&ndf, &opt, 1, ab_vnary); \
99
+ \
100
+ RB_GC_GUARD(ab_vnary); \
101
+ return ret; \
102
+ }
103
+
104
+ DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, double, numo_cDFloat, zhbevx)
105
+ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, float, numo_cSFloat, chbevx)
106
+
107
+ #undef DEF_LINALG_FUNC
108
+
109
+ void define_linalg_lapack_hbevx(VALUE mLapack) {
110
+ rb_define_module_function(mLapack, "zhbevx", _linalg_lapack_zhbevx, -1);
111
+ rb_define_module_function(mLapack, "chbevx", _linalg_lapack_chbevx, -1);
112
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NUMO_LINALG_ALT_LAPACK_HBEVX_H
2
+ #define NUMO_LINALG_ALT_LAPACK_HBEVX_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 "lapack_util.h"
12
+
13
+ void define_linalg_lapack_hbevx(VALUE mLapack);
14
+
15
+ #endif /* NUMO_LINALG_ALT_LAPACK_HBEVX_H */
@@ -0,0 +1,88 @@
1
+ #include "pbsv.h"
2
+
3
+ struct _pbsv_option {
4
+ int matrix_layout;
5
+ char uplo;
6
+ };
7
+
8
+ #define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
9
+ static void _iter_##fLapackFunc(na_loop_t* const lp) { \
10
+ tDType* ab = (tDType*)NDL_PTR(lp, 0); \
11
+ tDType* b = (tDType*)NDL_PTR(lp, 1); \
12
+ int* info = (int*)NDL_PTR(lp, 2); \
13
+ struct _pbsv_option* opt = (struct _pbsv_option*)(lp->opt_ptr); \
14
+ const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
15
+ const lapack_int kd = (lapack_int)NDL_SHAPE(lp, 0)[0] - 1; \
16
+ const lapack_int nrhs = lp->args[1].ndim == 1 ? 1 : (lapack_int)NDL_SHAPE(lp, 1)[1]; \
17
+ const lapack_int ldab = n; \
18
+ const lapack_int ldb = nrhs; \
19
+ const lapack_int i = \
20
+ LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, kd, nrhs, ab, ldab, b, ldb); \
21
+ *info = (int)i; \
22
+ } \
23
+ \
24
+ static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
25
+ VALUE ab_vnary = Qnil; \
26
+ VALUE b_vnary = Qnil; \
27
+ VALUE kw_args = Qnil; \
28
+ rb_scan_args(argc, argv, "2:", &ab_vnary, &b_vnary, &kw_args); \
29
+ ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") }; \
30
+ VALUE kw_values[2] = { Qundef, Qundef }; \
31
+ rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values); \
32
+ const int matrix_layout = \
33
+ kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
34
+ const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
35
+ \
36
+ if (CLASS_OF(ab_vnary) != tNAryClass) { \
37
+ ab_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, ab_vnary); \
38
+ } \
39
+ if (!RTEST(nary_check_contiguous(ab_vnary))) { \
40
+ ab_vnary = nary_dup(ab_vnary); \
41
+ } \
42
+ if (CLASS_OF(b_vnary) != tNAryClass) { \
43
+ b_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, b_vnary); \
44
+ } \
45
+ if (!RTEST(nary_check_contiguous(b_vnary))) { \
46
+ b_vnary = nary_dup(b_vnary); \
47
+ } \
48
+ \
49
+ narray_t* ab_nary = NULL; \
50
+ narray_t* b_nary = NULL; \
51
+ GetNArray(ab_vnary, ab_nary); \
52
+ GetNArray(b_vnary, b_nary); \
53
+ const int ab_n_dims = NA_NDIM(ab_nary); \
54
+ const int b_n_dims = NA_NDIM(b_nary); \
55
+ if (ab_n_dims != 2) { \
56
+ rb_raise(rb_eArgError, "input array ab must be 2-dimensional"); \
57
+ return Qnil; \
58
+ } \
59
+ if (b_n_dims != 1 && b_n_dims != 2) { \
60
+ rb_raise(rb_eArgError, "input array b must be 1- or 2-dimensional"); \
61
+ return Qnil; \
62
+ } \
63
+ \
64
+ ndfunc_arg_in_t ain[2] = { { OVERWRITE, 2 }, { OVERWRITE, b_n_dims } }; \
65
+ ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
66
+ ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 2, 1, ain, aout }; \
67
+ struct _pbsv_option opt = { matrix_layout, uplo }; \
68
+ VALUE res = na_ndloop3(&ndf, &opt, 2, ab_vnary, b_vnary); \
69
+ VALUE ret = rb_ary_new3(2, b_vnary, res); \
70
+ \
71
+ RB_GC_GUARD(ab_vnary); \
72
+ RB_GC_GUARD(b_vnary); \
73
+ return ret; \
74
+ }
75
+
76
+ DEF_LINALG_FUNC(double, numo_cDFloat, dpbsv)
77
+ DEF_LINALG_FUNC(float, numo_cSFloat, spbsv)
78
+ DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, zpbsv)
79
+ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cpbsv)
80
+
81
+ #undef DEF_LINALG_FUNC
82
+
83
+ void define_linalg_lapack_pbsv(VALUE mLapack) {
84
+ rb_define_module_function(mLapack, "dpbsv", _linalg_lapack_dpbsv, -1);
85
+ rb_define_module_function(mLapack, "spbsv", _linalg_lapack_spbsv, -1);
86
+ rb_define_module_function(mLapack, "zpbsv", _linalg_lapack_zpbsv, -1);
87
+ rb_define_module_function(mLapack, "cpbsv", _linalg_lapack_cpbsv, -1);
88
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NUMO_LINALG_ALT_LAPACK_PBSV_H
2
+ #define NUMO_LINALG_ALT_LAPACK_PBSV_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 "lapack_util.h"
12
+
13
+ void define_linalg_lapack_pbsv(VALUE mLapack);
14
+
15
+ #endif /* NUMO_LINALG_ALT_LAPACK_PBSV_H */
@@ -0,0 +1,68 @@
1
+ #include "pbtrf.h"
2
+
3
+ struct _pbtrf_option {
4
+ int matrix_layout;
5
+ char uplo;
6
+ };
7
+
8
+ #define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
9
+ static void _iter_##fLapackFunc(na_loop_t* const lp) { \
10
+ tDType* ab = (tDType*)NDL_PTR(lp, 0); \
11
+ int* info = (int*)NDL_PTR(lp, 1); \
12
+ struct _pbtrf_option* opt = (struct _pbtrf_option*)(lp->opt_ptr); \
13
+ const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
14
+ const lapack_int kd = (lapack_int)NDL_SHAPE(lp, 0)[0] - 1; \
15
+ const lapack_int ldab = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
16
+ const lapack_int i = \
17
+ LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, kd, ab, ldab); \
18
+ *info = (int)i; \
19
+ } \
20
+ \
21
+ static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
22
+ VALUE ab_vnary = Qnil; \
23
+ VALUE kw_args = Qnil; \
24
+ rb_scan_args(argc, argv, "1:", &ab_vnary, &kw_args); \
25
+ ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") }; \
26
+ VALUE kw_values[2] = { Qundef, Qundef }; \
27
+ rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values); \
28
+ const int matrix_layout = \
29
+ kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
30
+ const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
31
+ \
32
+ if (CLASS_OF(ab_vnary) != tNAryClass) { \
33
+ ab_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, ab_vnary); \
34
+ } \
35
+ if (!RTEST(nary_check_contiguous(ab_vnary))) { \
36
+ ab_vnary = nary_dup(ab_vnary); \
37
+ } \
38
+ \
39
+ narray_t* ab_nary = NULL; \
40
+ GetNArray(ab_vnary, ab_nary); \
41
+ if (NA_NDIM(ab_nary) != 2) { \
42
+ rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
43
+ return Qnil; \
44
+ } \
45
+ ndfunc_arg_in_t ain[1] = { { OVERWRITE, 2 } }; \
46
+ ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
47
+ ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 1, 1, ain, aout }; \
48
+ struct _pbtrf_option opt = { matrix_layout, uplo }; \
49
+ VALUE res = na_ndloop3(&ndf, &opt, 1, ab_vnary); \
50
+ VALUE ret = rb_ary_new3(2, ab_vnary, res); \
51
+ \
52
+ RB_GC_GUARD(ab_vnary); \
53
+ return ret; \
54
+ }
55
+
56
+ DEF_LINALG_FUNC(double, numo_cDFloat, dpbtrf)
57
+ DEF_LINALG_FUNC(float, numo_cSFloat, spbtrf)
58
+ DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, zpbtrf)
59
+ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cpbtrf)
60
+
61
+ #undef DEF_LINALG_FUNC
62
+
63
+ void define_linalg_lapack_pbtrf(VALUE mLapack) {
64
+ rb_define_module_function(mLapack, "dpbtrf", _linalg_lapack_dpbtrf, -1);
65
+ rb_define_module_function(mLapack, "spbtrf", _linalg_lapack_spbtrf, -1);
66
+ rb_define_module_function(mLapack, "zpbtrf", _linalg_lapack_zpbtrf, -1);
67
+ rb_define_module_function(mLapack, "cpbtrf", _linalg_lapack_cpbtrf, -1);
68
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NUMO_LINALG_ALT_LAPACK_PBTRF_H
2
+ #define NUMO_LINALG_ALT_LAPACK_PBTRF_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 "lapack_util.h"
12
+
13
+ void define_linalg_lapack_pbtrf(VALUE mLapack);
14
+
15
+ #endif /* NUMO_LINALG_ALT_LAPACK_PBTRF_H */
@@ -0,0 +1,93 @@
1
+ #include "pbtrs.h"
2
+
3
+ struct _pbtrs_option {
4
+ int matrix_layout;
5
+ char uplo;
6
+ };
7
+
8
+ #define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
9
+ static void _iter_##fLapackFunc(na_loop_t* const lp) { \
10
+ tDType* ab = (tDType*)NDL_PTR(lp, 0); \
11
+ tDType* b = (tDType*)NDL_PTR(lp, 1); \
12
+ int* info = (int*)NDL_PTR(lp, 2); \
13
+ struct _pbtrs_option* opt = (struct _pbtrs_option*)(lp->opt_ptr); \
14
+ const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[1]; \
15
+ const lapack_int kd = (lapack_int)NDL_SHAPE(lp, 0)[0] - 1; \
16
+ const lapack_int nrhs = lp->args[1].ndim == 1 ? 1 : (lapack_int)NDL_SHAPE(lp, 1)[1]; \
17
+ const lapack_int ldab = n; \
18
+ const lapack_int ldb = nrhs; \
19
+ const lapack_int i = \
20
+ LAPACKE_##fLapackFunc(opt->matrix_layout, opt->uplo, n, kd, nrhs, ab, ldab, b, ldb); \
21
+ *info = (int)i; \
22
+ } \
23
+ \
24
+ static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
25
+ VALUE a_vnary = Qnil; \
26
+ VALUE b_vnary = Qnil; \
27
+ VALUE kw_args = Qnil; \
28
+ rb_scan_args(argc, argv, "2:", &a_vnary, &b_vnary, &kw_args); \
29
+ ID kw_table[2] = { rb_intern("order"), rb_intern("uplo") }; \
30
+ VALUE kw_values[2] = { Qundef, Qundef }; \
31
+ rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values); \
32
+ const int matrix_layout = \
33
+ kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
34
+ const char uplo = kw_values[1] != Qundef ? get_uplo(kw_values[1]) : 'U'; \
35
+ \
36
+ if (CLASS_OF(a_vnary) != tNAryClass) { \
37
+ a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
38
+ } \
39
+ if (!RTEST(nary_check_contiguous(a_vnary))) { \
40
+ a_vnary = nary_dup(a_vnary); \
41
+ } \
42
+ if (CLASS_OF(b_vnary) != tNAryClass) { \
43
+ b_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, b_vnary); \
44
+ } \
45
+ if (!RTEST(nary_check_contiguous(b_vnary))) { \
46
+ b_vnary = nary_dup(b_vnary); \
47
+ } \
48
+ \
49
+ narray_t* a_nary = NULL; \
50
+ GetNArray(a_vnary, a_nary); \
51
+ if (NA_NDIM(a_nary) != 2) { \
52
+ rb_raise(rb_eArgError, "input array a must be 2-dimensional"); \
53
+ return Qnil; \
54
+ } \
55
+ narray_t* b_nary = NULL; \
56
+ GetNArray(b_vnary, b_nary); \
57
+ const int b_n_dims = NA_NDIM(b_nary); \
58
+ if (b_n_dims != 1 && b_n_dims != 2) { \
59
+ rb_raise(rb_eArgError, "input array b must be 1- or 2-dimensional"); \
60
+ return Qnil; \
61
+ } \
62
+ \
63
+ lapack_int n = (lapack_int)NA_SHAPE(a_nary)[1]; \
64
+ lapack_int nb = (lapack_int)NA_SHAPE(b_nary)[0]; \
65
+ if (n != nb) { \
66
+ rb_raise(nary_eShapeError, "shape1[0](=%d) != shape2[0](=%d)", n, nb); \
67
+ } \
68
+ \
69
+ ndfunc_arg_in_t ain[2] = { { tNAryClass, 2 }, { OVERWRITE, b_n_dims } }; \
70
+ ndfunc_arg_out_t aout[1] = { { numo_cInt32, 0 } }; \
71
+ ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 2, 1, ain, aout }; \
72
+ struct _pbtrs_option opt = { matrix_layout, uplo }; \
73
+ VALUE res = na_ndloop3(&ndf, &opt, 2, a_vnary, b_vnary); \
74
+ VALUE ret = rb_ary_new3(2, b_vnary, res); \
75
+ \
76
+ RB_GC_GUARD(a_vnary); \
77
+ RB_GC_GUARD(b_vnary); \
78
+ return ret; \
79
+ }
80
+
81
+ DEF_LINALG_FUNC(double, numo_cDFloat, dpbtrs)
82
+ DEF_LINALG_FUNC(float, numo_cSFloat, spbtrs)
83
+ DEF_LINALG_FUNC(lapack_complex_double, numo_cDComplex, zpbtrs)
84
+ DEF_LINALG_FUNC(lapack_complex_float, numo_cSComplex, cpbtrs)
85
+
86
+ #undef DEF_LINALG_FUNC
87
+
88
+ void define_linalg_lapack_pbtrs(VALUE mLapack) {
89
+ rb_define_module_function(mLapack, "dpbtrs", _linalg_lapack_dpbtrs, -1);
90
+ rb_define_module_function(mLapack, "spbtrs", _linalg_lapack_spbtrs, -1);
91
+ rb_define_module_function(mLapack, "zpbtrs", _linalg_lapack_zpbtrs, -1);
92
+ rb_define_module_function(mLapack, "cpbtrs", _linalg_lapack_cpbtrs, -1);
93
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NUMO_LINALG_ALT_LAPACK_PBTRS_H
2
+ #define NUMO_LINALG_ALT_LAPACK_PBTRS_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 "lapack_util.h"
12
+
13
+ void define_linalg_lapack_pbtrs(VALUE mLapack);
14
+
15
+ #endif