numo-linalg-alt 0.8.0 → 0.9.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 +11 -0
- data/ext/numo/linalg/extconf.rb +2 -2
- data/ext/numo/linalg/lapack/hbevx.c +112 -0
- data/ext/numo/linalg/lapack/hbevx.h +15 -0
- data/ext/numo/linalg/lapack/sbevx.c +112 -0
- data/ext/numo/linalg/lapack/sbevx.h +15 -0
- data/ext/numo/linalg/lapack/stevx.c +122 -0
- data/ext/numo/linalg/lapack/stevx.h +15 -0
- data/ext/numo/linalg/linalg.c +20 -0
- data/ext/numo/linalg/linalg.h +3 -0
- data/lib/numo/linalg/version.rb +1 -1
- data/lib/numo/linalg.rb +157 -0
- metadata +9 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2be058f70990035c731689a4784185d6eef5ce44f27269dac0069ab463837cf1
|
|
4
|
+
data.tar.gz: 395d611376e5b39da69ee641834d60386caa5903354afa5c2a6374ca7b4e12b2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7d848848e62683dd518a043f941bb45c7f9d9b99d92943e08664c4fee6cff7fc8b3838a1aaeeed65bdd3cfb7218adfc085e3523f8e6d24f75d7f41e5cbebbc69
|
|
7
|
+
data.tar.gz: 3cb5325539e038a528e576532e2442fbc99da21031a20428051a4803e6f44d83f135d2c05e9abb2b844639a6378770f2ba80f5cf913f53014ba0834eaec70e15
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## [[0.9.1](https://github.com/yoshoku/numo-linalg-alt/compare/v0.9.0...v0.9.1)] - 2026-04-26
|
|
2
|
+
|
|
3
|
+
- bump OpenBLAS from 0.3.30 to 0.3.33.
|
|
4
|
+
- add `ilaver` module function to Numo::Linalg::Lapack.
|
|
5
|
+
|
|
6
|
+
## [[0.9.0](https://github.com/yoshoku/numo-linalg-alt/compare/v0.8.0...v0.9.0)] - 2026-02-14
|
|
7
|
+
|
|
8
|
+
- add `eigh_tridiagonal` and `eigvalsh_tridiagonal` module functions to Numo::Linalg.
|
|
9
|
+
- add `eig_banded` and `eigvals_banded` module functions to Numo::Linalg.
|
|
10
|
+
- fix CI workflow to correctly run ruby_memcheck.
|
|
11
|
+
|
|
1
12
|
## [[0.8.0](https://github.com/yoshoku/numo-linalg-alt/compare/v0.7.2...v0.8.0)] - 2026-02-06
|
|
2
13
|
|
|
3
14
|
- relax numo-narray-alt version constraint to >= 0.9.10, < 0.11.0.
|
data/ext/numo/linalg/extconf.rb
CHANGED
|
@@ -71,8 +71,8 @@ if build_openblas
|
|
|
71
71
|
|
|
72
72
|
VENDOR_DIR = File.expand_path("#{__dir__}/../../../vendor")
|
|
73
73
|
LINALG_DIR = File.expand_path("#{__dir__}/../../../lib/numo/linalg")
|
|
74
|
-
OPENBLAS_VER = '0.3.
|
|
75
|
-
OPENBLAS_KEY = '
|
|
74
|
+
OPENBLAS_VER = '0.3.33'
|
|
75
|
+
OPENBLAS_KEY = '96c5cd9013013faefc294bc57830c77d'
|
|
76
76
|
OPENBLAS_URI = "https://github.com/OpenMathLib/OpenBLAS/archive/v#{OPENBLAS_VER}.tar.gz"
|
|
77
77
|
OPENBLAS_TGZ = "#{VENDOR_DIR}/tmp/openblas.tgz"
|
|
78
78
|
|
|
@@ -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,112 @@
|
|
|
1
|
+
#include "sbevx.h"
|
|
2
|
+
|
|
3
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
|
4
|
+
struct _sbevx_option_##tDType { \
|
|
5
|
+
int matrix_layout; \
|
|
6
|
+
char jobz; \
|
|
7
|
+
char range; \
|
|
8
|
+
char uplo; \
|
|
9
|
+
tDType vl; \
|
|
10
|
+
tDType 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
|
+
tDType* w = (tDType*)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 _sbevx_option_##tDType* opt = (struct _sbevx_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 tDType 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 tDType vl = kw_values[3] != Qundef ? NUM2DBL(kw_values[3]) : 0.0; \
|
|
50
|
+
const tDType 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
|
+
{ tNAryClass, 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 _sbevx_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(double, numo_cDFloat, dsbevx)
|
|
105
|
+
DEF_LINALG_FUNC(float, numo_cSFloat, ssbevx)
|
|
106
|
+
|
|
107
|
+
#undef DEF_LINALG_FUNC
|
|
108
|
+
|
|
109
|
+
void define_linalg_lapack_sbevx(VALUE mLapack) {
|
|
110
|
+
rb_define_module_function(mLapack, "dsbevx", _linalg_lapack_dsbevx, -1);
|
|
111
|
+
rb_define_module_function(mLapack, "ssbevx", _linalg_lapack_ssbevx, -1);
|
|
112
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_SBEVX_H
|
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_SBEVX_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_sbevx(VALUE mLapack);
|
|
14
|
+
|
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_SBEVX_H */
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#include "stevx.h"
|
|
2
|
+
|
|
3
|
+
#define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
|
|
4
|
+
struct _stevx_option_##tDType { \
|
|
5
|
+
int matrix_layout; \
|
|
6
|
+
char jobz; \
|
|
7
|
+
char range; \
|
|
8
|
+
tDType vl; \
|
|
9
|
+
tDType vu; \
|
|
10
|
+
lapack_int il; \
|
|
11
|
+
lapack_int iu; \
|
|
12
|
+
}; \
|
|
13
|
+
\
|
|
14
|
+
static void _iter_##fLapackFunc(na_loop_t* const lp) { \
|
|
15
|
+
tDType* d = (tDType*)NDL_PTR(lp, 0); \
|
|
16
|
+
tDType* e = (tDType*)NDL_PTR(lp, 1); \
|
|
17
|
+
int* m = (int*)NDL_PTR(lp, 2); \
|
|
18
|
+
tDType* w = (tDType*)NDL_PTR(lp, 3); \
|
|
19
|
+
tDType* z = (tDType*)NDL_PTR(lp, 4); \
|
|
20
|
+
int* ifail = (int*)NDL_PTR(lp, 5); \
|
|
21
|
+
int* info = (int*)NDL_PTR(lp, 6); \
|
|
22
|
+
struct _stevx_option_##tDType* opt = (struct _stevx_option_##tDType*)(lp->opt_ptr); \
|
|
23
|
+
const lapack_int n = (lapack_int)NDL_SHAPE(lp, 0)[0]; \
|
|
24
|
+
const tDType abstol = 0.0; \
|
|
25
|
+
const lapack_int ldz = opt->range != 'I' ? n : opt->iu - opt->il + 1; \
|
|
26
|
+
const lapack_int i = LAPACKE_##fLapackFunc( \
|
|
27
|
+
opt->matrix_layout, opt->jobz, opt->range, n, d, e, opt->vl, opt->vu, opt->il, opt->iu, \
|
|
28
|
+
abstol, m, w, z, ldz, ifail \
|
|
29
|
+
); \
|
|
30
|
+
*info = (int)i; \
|
|
31
|
+
} \
|
|
32
|
+
\
|
|
33
|
+
static VALUE _linalg_lapack_##fLapackFunc(int argc, VALUE* argv, VALUE self) { \
|
|
34
|
+
VALUE d_vnary = Qnil; \
|
|
35
|
+
VALUE e_vnary = Qnil; \
|
|
36
|
+
VALUE kw_args = Qnil; \
|
|
37
|
+
rb_scan_args(argc, argv, "2:", &d_vnary, &e_vnary, &kw_args); \
|
|
38
|
+
ID kw_table[7] = { rb_intern("jobz"), rb_intern("range"), rb_intern("vl"), \
|
|
39
|
+
rb_intern("vu"), rb_intern("il"), rb_intern("iu"), \
|
|
40
|
+
rb_intern("order") }; \
|
|
41
|
+
VALUE kw_values[7] = { Qundef, Qundef, Qundef, Qundef, Qundef, Qundef, Qundef }; \
|
|
42
|
+
rb_get_kwargs(kw_args, kw_table, 0, 7, kw_values); \
|
|
43
|
+
const char jobz = kw_values[0] != Qundef ? get_job(kw_values[0], "jobz") : 'V'; \
|
|
44
|
+
const char range = kw_values[1] != Qundef ? get_range(kw_values[1]) : 'A'; \
|
|
45
|
+
const tDType vl = kw_values[2] != Qundef ? NUM2DBL(kw_values[2]) : 0.0; \
|
|
46
|
+
const tDType vu = kw_values[3] != Qundef ? NUM2DBL(kw_values[3]) : 0.0; \
|
|
47
|
+
const lapack_int il = kw_values[4] != Qundef ? NUM2INT(kw_values[4]) : 0; \
|
|
48
|
+
const lapack_int iu = kw_values[5] != Qundef ? NUM2INT(kw_values[5]) : 0; \
|
|
49
|
+
const int matrix_layout = \
|
|
50
|
+
kw_values[6] != Qundef ? get_matrix_layout(kw_values[6]) : LAPACK_ROW_MAJOR; \
|
|
51
|
+
\
|
|
52
|
+
if (CLASS_OF(d_vnary) != tNAryClass) { \
|
|
53
|
+
d_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, d_vnary); \
|
|
54
|
+
} \
|
|
55
|
+
if (!RTEST(nary_check_contiguous(d_vnary))) { \
|
|
56
|
+
d_vnary = nary_dup(d_vnary); \
|
|
57
|
+
} \
|
|
58
|
+
if (CLASS_OF(e_vnary) != tNAryClass) { \
|
|
59
|
+
e_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, e_vnary); \
|
|
60
|
+
} \
|
|
61
|
+
if (!RTEST(nary_check_contiguous(e_vnary))) { \
|
|
62
|
+
e_vnary = nary_dup(e_vnary); \
|
|
63
|
+
} \
|
|
64
|
+
\
|
|
65
|
+
narray_t* d_nary = NULL; \
|
|
66
|
+
GetNArray(d_vnary, d_nary); \
|
|
67
|
+
if (NA_NDIM(d_nary) != 1) { \
|
|
68
|
+
rb_raise(rb_eArgError, "input array d must be 1-dimensional"); \
|
|
69
|
+
return Qnil; \
|
|
70
|
+
} \
|
|
71
|
+
narray_t* e_nary = NULL; \
|
|
72
|
+
GetNArray(e_vnary, e_nary); \
|
|
73
|
+
if (NA_NDIM(e_nary) != 1) { \
|
|
74
|
+
rb_raise(rb_eArgError, "input array e must be 1-dimensional"); \
|
|
75
|
+
return Qnil; \
|
|
76
|
+
} \
|
|
77
|
+
if (range == 'V' && vu <= vl) { \
|
|
78
|
+
rb_raise(rb_eArgError, "vu must be greater than vl"); \
|
|
79
|
+
return Qnil; \
|
|
80
|
+
} \
|
|
81
|
+
const size_t n = NA_SHAPE(d_nary)[0]; \
|
|
82
|
+
if (range == 'I' && (il < 1 || il > (lapack_int)n)) { \
|
|
83
|
+
rb_raise(rb_eArgError, "il must satisfy 1 <= il <= n"); \
|
|
84
|
+
return Qnil; \
|
|
85
|
+
} \
|
|
86
|
+
if (range == 'I' && (iu < 1 || iu > (lapack_int)n)) { \
|
|
87
|
+
rb_raise(rb_eArgError, "iu must satisfy 1 <= iu <= n"); \
|
|
88
|
+
return Qnil; \
|
|
89
|
+
} \
|
|
90
|
+
if (range == 'I' && iu < il) { \
|
|
91
|
+
rb_raise(rb_eArgError, "iu must be greater than or equal to il"); \
|
|
92
|
+
return Qnil; \
|
|
93
|
+
} \
|
|
94
|
+
\
|
|
95
|
+
size_t m = range != 'I' ? n : (size_t)(iu - il + 1); \
|
|
96
|
+
size_t w_shape[1] = { m }; \
|
|
97
|
+
size_t z_shape[2] = { n, m }; \
|
|
98
|
+
size_t ifail_shape[1] = { m }; \
|
|
99
|
+
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 1 }, { OVERWRITE, 1 } }; \
|
|
100
|
+
ndfunc_arg_out_t aout[5] = { { numo_cInt32, 0 }, \
|
|
101
|
+
{ tNAryClass, 1, w_shape }, \
|
|
102
|
+
{ tNAryClass, 2, z_shape }, \
|
|
103
|
+
{ numo_cInt32, 1, ifail_shape }, \
|
|
104
|
+
{ numo_cInt32, 0 } }; \
|
|
105
|
+
ndfunc_t ndf = { _iter_##fLapackFunc, NO_LOOP | NDF_EXTRACT, 2, 5, ain, aout }; \
|
|
106
|
+
struct _stevx_option_##tDType opt = { matrix_layout, jobz, range, vl, vu, il, iu }; \
|
|
107
|
+
VALUE ret = na_ndloop3(&ndf, &opt, 2, d_vnary, e_vnary); \
|
|
108
|
+
\
|
|
109
|
+
RB_GC_GUARD(d_vnary); \
|
|
110
|
+
RB_GC_GUARD(e_vnary); \
|
|
111
|
+
return ret; \
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
DEF_LINALG_FUNC(double, numo_cDFloat, dstevx)
|
|
115
|
+
DEF_LINALG_FUNC(float, numo_cSFloat, sstevx)
|
|
116
|
+
|
|
117
|
+
#undef DEF_LINALG_FUNC
|
|
118
|
+
|
|
119
|
+
void define_linalg_lapack_stevx(VALUE mLapack) {
|
|
120
|
+
rb_define_module_function(mLapack, "dstevx", _linalg_lapack_dstevx, -1);
|
|
121
|
+
rb_define_module_function(mLapack, "sstevx", _linalg_lapack_sstevx, -1);
|
|
122
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#ifndef NUMO_LINALG_ALT_LAPACK_STEVX_H
|
|
2
|
+
#define NUMO_LINALG_ALT_LAPACK_STEVX_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_stevx(VALUE mLapack);
|
|
14
|
+
|
|
15
|
+
#endif /* NUMO_LINALG_ALT_LAPACK_STEVX_H */
|
data/ext/numo/linalg/linalg.c
CHANGED
|
@@ -202,6 +202,16 @@ static VALUE linalg_dot(VALUE self, VALUE a_, VALUE b_) {
|
|
|
202
202
|
return ret;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
static VALUE linalg_lapack_ilaver(VALUE self) {
|
|
206
|
+
lapack_int vers_major;
|
|
207
|
+
lapack_int vers_minor;
|
|
208
|
+
lapack_int vers_patch;
|
|
209
|
+
LAPACKE_ilaver(&vers_major, &vers_minor, &vers_patch);
|
|
210
|
+
VALUE version_arr =
|
|
211
|
+
rb_ary_new3(3, INT2NUM(vers_major), INT2NUM(vers_minor), INT2NUM(vers_patch));
|
|
212
|
+
return version_arr;
|
|
213
|
+
}
|
|
214
|
+
|
|
205
215
|
void Init_linalg(void) {
|
|
206
216
|
rb_require("numo/narray");
|
|
207
217
|
|
|
@@ -256,6 +266,13 @@ void Init_linalg(void) {
|
|
|
256
266
|
* Numo::Linalg::Blas.call(:gemv, a, b)
|
|
257
267
|
*/
|
|
258
268
|
rb_define_singleton_method(rb_mLinalgBlas, "call", linalg_blas_call, -1);
|
|
269
|
+
/**
|
|
270
|
+
* Returns the version of LAPACKE used in background library.
|
|
271
|
+
*
|
|
272
|
+
* @overload ilaver() -> Array<Integer>
|
|
273
|
+
* @return [Array<Integer>] [major, minor, patch]
|
|
274
|
+
*/
|
|
275
|
+
rb_define_module_function(rb_mLinalgLapack, "ilaver", linalg_lapack_ilaver, 0);
|
|
259
276
|
|
|
260
277
|
define_linalg_blas_dot(rb_mLinalgBlas);
|
|
261
278
|
define_linalg_blas_dot_sub(rb_mLinalgBlas);
|
|
@@ -291,6 +308,9 @@ void Init_linalg(void) {
|
|
|
291
308
|
define_linalg_lapack_heevd(rb_mLinalgLapack);
|
|
292
309
|
define_linalg_lapack_syevr(rb_mLinalgLapack);
|
|
293
310
|
define_linalg_lapack_heevr(rb_mLinalgLapack);
|
|
311
|
+
define_linalg_lapack_sbevx(rb_mLinalgLapack);
|
|
312
|
+
define_linalg_lapack_hbevx(rb_mLinalgLapack);
|
|
313
|
+
define_linalg_lapack_stevx(rb_mLinalgLapack);
|
|
294
314
|
define_linalg_lapack_sygv(rb_mLinalgLapack);
|
|
295
315
|
define_linalg_lapack_hegv(rb_mLinalgLapack);
|
|
296
316
|
define_linalg_lapack_sygvd(rb_mLinalgLapack);
|
data/ext/numo/linalg/linalg.h
CHANGED
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
#include "lapack/getri.h"
|
|
75
75
|
#include "lapack/getrs.h"
|
|
76
76
|
#include "lapack/gges.h"
|
|
77
|
+
#include "lapack/hbevx.h"
|
|
77
78
|
#include "lapack/heev.h"
|
|
78
79
|
#include "lapack/heevd.h"
|
|
79
80
|
#include "lapack/heevr.h"
|
|
@@ -91,6 +92,8 @@
|
|
|
91
92
|
#include "lapack/potrf.h"
|
|
92
93
|
#include "lapack/potri.h"
|
|
93
94
|
#include "lapack/potrs.h"
|
|
95
|
+
#include "lapack/sbevx.h"
|
|
96
|
+
#include "lapack/stevx.h"
|
|
94
97
|
#include "lapack/syev.h"
|
|
95
98
|
#include "lapack/syevd.h"
|
|
96
99
|
#include "lapack/syevr.h"
|
data/lib/numo/linalg/version.rb
CHANGED
data/lib/numo/linalg.rb
CHANGED
|
@@ -1699,6 +1699,163 @@ module Numo
|
|
|
1699
1699
|
eigh(a, b, vals_only: true, vals_range: vals_range, uplo: uplo, turbo: turbo)[0]
|
|
1700
1700
|
end
|
|
1701
1701
|
|
|
1702
|
+
# Computes the eigenvalues and eigenvectors of a symmetric / Hermitian banded matrix.
|
|
1703
|
+
#
|
|
1704
|
+
# @example
|
|
1705
|
+
# require 'numo/linalg'
|
|
1706
|
+
#
|
|
1707
|
+
# # Banded matrix A:
|
|
1708
|
+
# # [4 2 1 0 0]
|
|
1709
|
+
# # [2 5 2 1 0]
|
|
1710
|
+
# # [1 2 6 2 1]
|
|
1711
|
+
# # [0 1 2 7 2]
|
|
1712
|
+
# # [0 0 1 2 8]
|
|
1713
|
+
# #
|
|
1714
|
+
# ab = Numo::DFloat[[0, 0, 1, 1, 1],
|
|
1715
|
+
# [0, 2, 2, 2, 2],
|
|
1716
|
+
# [4, 5, 6, 7, 8]]
|
|
1717
|
+
#
|
|
1718
|
+
# w, v = Numo::Linalg.eig_banded(ab)
|
|
1719
|
+
#
|
|
1720
|
+
# b = v.dot(w.diag).dot(v.transpose)
|
|
1721
|
+
# b[b<1e-10] = 0.0
|
|
1722
|
+
# pp b
|
|
1723
|
+
# # =>
|
|
1724
|
+
# # Numo::DFloat#shape=[5,5]
|
|
1725
|
+
# # [[4, 2, 1, 0, 0],
|
|
1726
|
+
# # [2, 5, 2, 1, 0],
|
|
1727
|
+
# # [1, 2, 6, 2, 1],
|
|
1728
|
+
# # [0, 1, 2, 7, 2],
|
|
1729
|
+
# # [0, 0, 1, 2, 8]]
|
|
1730
|
+
#
|
|
1731
|
+
# @param ab [Numo::NArray] The (kd+1)-by-n array representing the banded matrix.
|
|
1732
|
+
# @param vals_only [Boolean] The flag indicating whether to compute only eigenvalues.
|
|
1733
|
+
# @param vals_range [Range/Array]
|
|
1734
|
+
# The range of indices of the eigenvalues (in ascending order) and corresponding eigenvectors to be returned.
|
|
1735
|
+
# If nil, all eigenvalues and eigenvectors are computed.
|
|
1736
|
+
# @param lower [Boolean] The flag indicating whether to be in the lower-banded form.
|
|
1737
|
+
# @return [Array<Numo::NArray>] The eigenvalues and eigenvectors.
|
|
1738
|
+
def eig_banded(ab, vals_only: false, vals_range: nil, lower: false)
|
|
1739
|
+
raise Numo::NArray::ShapeError, 'input array ab must be 2-dimensional' if ab.ndim != 2
|
|
1740
|
+
|
|
1741
|
+
bchr = blas_char(ab)
|
|
1742
|
+
raise ArgumentError, "invalid array type: #{ab.class}" if bchr == 'n'
|
|
1743
|
+
|
|
1744
|
+
jobz = vals_only ? 'N' : 'V'
|
|
1745
|
+
uplo = lower ? 'L' : 'U'
|
|
1746
|
+
fnc = %w[d s].include?(bchr) ? "#{bchr}sbevx" : "#{bchr}hbevx"
|
|
1747
|
+
|
|
1748
|
+
if vals_range.nil?
|
|
1749
|
+
_, _, vals, vecs, _, info = Numo::Linalg::Lapack.send(fnc.to_sym, ab.dup, range: 'A', jobz: jobz, uplo: uplo)
|
|
1750
|
+
else
|
|
1751
|
+
il = vals_range.first(1)[0] + 1
|
|
1752
|
+
iu = vals_range.last(1)[0] + 1
|
|
1753
|
+
_, _, vals, vecs, _, info = Numo::Linalg::Lapack.send(fnc.to_sym, ab.dup,
|
|
1754
|
+
range: 'I', jobz: jobz, uplo: uplo, il: il, iu: iu)
|
|
1755
|
+
end
|
|
1756
|
+
|
|
1757
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1758
|
+
|
|
1759
|
+
vecs = nil if vals_only
|
|
1760
|
+
|
|
1761
|
+
[vals, vecs]
|
|
1762
|
+
end
|
|
1763
|
+
|
|
1764
|
+
# Computes the eigenvalues a symmetric / Hermitian banded matrix.
|
|
1765
|
+
#
|
|
1766
|
+
# @param ab [Numo::NArray] The (kd+1)-by-n array representing the banded matrix.
|
|
1767
|
+
# @param vals_range [Range/Array]
|
|
1768
|
+
# The range of indices of the eigenvalues (in ascending order) to be returned.
|
|
1769
|
+
# If nil, all eigenvalues are computed.
|
|
1770
|
+
# @param lower [Boolean] The flag indicating whether to be in the lower-banded form.
|
|
1771
|
+
# @return [Numo::NArray] The eigenvalues.
|
|
1772
|
+
def eigvals_banded(ab, vals_range: nil, lower: false)
|
|
1773
|
+
eig_banded(ab, vals_only: true, vals_range: vals_range, lower: lower)[0]
|
|
1774
|
+
end
|
|
1775
|
+
|
|
1776
|
+
# Computes the eigenvalues and eigenvectors of a real symmetric tridiagonal matrix.
|
|
1777
|
+
#
|
|
1778
|
+
# @example
|
|
1779
|
+
# require 'numo/linalg'
|
|
1780
|
+
#
|
|
1781
|
+
# # symmetric tridiagonal matrix A:
|
|
1782
|
+
# # [4 2 0 0 0]
|
|
1783
|
+
# # [2 5 2 0 0]
|
|
1784
|
+
# # [0 2 6 2 0]
|
|
1785
|
+
# # [0 0 2 7 2]
|
|
1786
|
+
# # [0 0 0 2 8]
|
|
1787
|
+
# d = Numo::DFloat[4, 5, 6, 7, 8]
|
|
1788
|
+
# e = Numo::DFloat[2, 2, 2, 2]
|
|
1789
|
+
#
|
|
1790
|
+
# w, v = Numo::Linalg.eigh_tridiagonal(d, e)
|
|
1791
|
+
#
|
|
1792
|
+
# b = v.dot(w.diag).dot(v.transpose)
|
|
1793
|
+
# b[b<1e-10] = 0.0
|
|
1794
|
+
# pp b
|
|
1795
|
+
# # =>
|
|
1796
|
+
# # Numo::DFloat#shape=[5,5]
|
|
1797
|
+
# # [[4, 2, 0, 0, 0],
|
|
1798
|
+
# # [2, 5, 2, 0, 0],
|
|
1799
|
+
# # [0, 2, 6, 2, 0],
|
|
1800
|
+
# # [0, 0, 2, 7, 2],
|
|
1801
|
+
# # [0, 0, 0, 2, 8]]
|
|
1802
|
+
#
|
|
1803
|
+
# @param d [Numo::NArray] The 1-dimensional array of length n representing the diagonal elements of the matrix.
|
|
1804
|
+
# @param e [Numo::NArray] The 1-dimensional array of length n-1 representing the off-diagonal elements of the matrix.
|
|
1805
|
+
# @param vals_only [Boolean] The flag indicating whether to compute only eigenvalues.
|
|
1806
|
+
# @param vals_range [Range/Array]
|
|
1807
|
+
# The range of indices of the eigenvalues (in ascending order) and corresponding eigenvectors to be returned.
|
|
1808
|
+
# If nil, all eigenvalues and eigenvectors are computed.
|
|
1809
|
+
# @return [Array<Numo::NArray>] The eigenvalues and eigenvectors.
|
|
1810
|
+
def eigh_tridiagonal(d, e, vals_only: false, vals_range: nil) # rubocop:disable Metrics/AbcSize
|
|
1811
|
+
raise Numo::NArray::ShapeError, 'input array d must be 1-dimensional' if d.ndim != 1
|
|
1812
|
+
raise Numo::NArray::ShapeError, 'input array e must be 1-dimensional' if e.ndim != 1
|
|
1813
|
+
|
|
1814
|
+
if d.shape[0] != e.shape[0] + 1
|
|
1815
|
+
raise Numo::NArray::ShapeError,
|
|
1816
|
+
"incompatible dimensions: d.shape[0] (#{d.shape[0]}) != e.shape[0] + 1 (#{e.shape[0] + 1})"
|
|
1817
|
+
end
|
|
1818
|
+
|
|
1819
|
+
if d.is_a?(Numo::DComplex) || d.is_a?(Numo::SComplex) || e.is_a?(Numo::DComplex) || e.is_a?(Numo::SComplex)
|
|
1820
|
+
raise ArgumentError, 'eigh_tridiagonal does not support complex arrays'
|
|
1821
|
+
end
|
|
1822
|
+
|
|
1823
|
+
bchr = blas_char(d)
|
|
1824
|
+
raise ArgumentError, "invalid array type: #{d.class}" if bchr == 'n'
|
|
1825
|
+
|
|
1826
|
+
jobz = vals_only ? 'N' : 'V'
|
|
1827
|
+
fnc = "#{bchr}stevx"
|
|
1828
|
+
|
|
1829
|
+
e_w_zero = e.concatenate(0)
|
|
1830
|
+
|
|
1831
|
+
if vals_range.nil?
|
|
1832
|
+
_, vals, vecs, _, info = Numo::Linalg::Lapack.send(fnc.to_sym, d.dup, e_w_zero, range: 'A', jobz: jobz)
|
|
1833
|
+
else
|
|
1834
|
+
il = vals_range.first(1)[0] + 1
|
|
1835
|
+
iu = vals_range.last(1)[0] + 1
|
|
1836
|
+
_, vals, vecs, _, info = Numo::Linalg::Lapack.send(fnc.to_sym, d.dup, e_w_zero,
|
|
1837
|
+
range: 'I', jobz: jobz, il: il, iu: iu)
|
|
1838
|
+
end
|
|
1839
|
+
|
|
1840
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1841
|
+
|
|
1842
|
+
vecs = nil if vals_only
|
|
1843
|
+
|
|
1844
|
+
[vals, vecs]
|
|
1845
|
+
end
|
|
1846
|
+
|
|
1847
|
+
# Computes the eigenvalues of a real symmetric tridiagonal matrix.
|
|
1848
|
+
#
|
|
1849
|
+
# @param d [Numo::NArray] The 1-dimensional array of length n representing the diagonal elements of the matrix.
|
|
1850
|
+
# @param e [Numo::NArray] The 1-dimensional array of length n-1 representing the off-diagonal elements of the matrix.
|
|
1851
|
+
# @param vals_range [Range/Array]
|
|
1852
|
+
# The range of indices of the eigenvalues (in ascending order) and corresponding eigenvectors to be returned.
|
|
1853
|
+
# If nil, all eigenvalues and eigenvectors are computed.
|
|
1854
|
+
# @return [Numo::NArray] The eigenvalues.
|
|
1855
|
+
def eigvalsh_tridiagonal(d, e, vals_range: nil)
|
|
1856
|
+
eigh_tridiagonal(d, e, vals_only: true, vals_range: vals_range)[0]
|
|
1857
|
+
end
|
|
1858
|
+
|
|
1702
1859
|
# Computes the Bunch-Kaufman decomposition of a symmetric / Hermitian matrix.
|
|
1703
1860
|
# The factorization has the form `A = U * D * U^T` or `A = L * D * L^T`,
|
|
1704
1861
|
# where `U` (or `L`) is a product of permutation and unit upper
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: numo-linalg-alt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- yoshoku
|
|
@@ -89,6 +89,8 @@ files:
|
|
|
89
89
|
- ext/numo/linalg/lapack/getrs.h
|
|
90
90
|
- ext/numo/linalg/lapack/gges.c
|
|
91
91
|
- ext/numo/linalg/lapack/gges.h
|
|
92
|
+
- ext/numo/linalg/lapack/hbevx.c
|
|
93
|
+
- ext/numo/linalg/lapack/hbevx.h
|
|
92
94
|
- ext/numo/linalg/lapack/heev.c
|
|
93
95
|
- ext/numo/linalg/lapack/heev.h
|
|
94
96
|
- ext/numo/linalg/lapack/heevd.c
|
|
@@ -125,6 +127,10 @@ files:
|
|
|
125
127
|
- ext/numo/linalg/lapack/potri.h
|
|
126
128
|
- ext/numo/linalg/lapack/potrs.c
|
|
127
129
|
- ext/numo/linalg/lapack/potrs.h
|
|
130
|
+
- ext/numo/linalg/lapack/sbevx.c
|
|
131
|
+
- ext/numo/linalg/lapack/sbevx.h
|
|
132
|
+
- ext/numo/linalg/lapack/stevx.c
|
|
133
|
+
- ext/numo/linalg/lapack/stevx.h
|
|
128
134
|
- ext/numo/linalg/lapack/syev.c
|
|
129
135
|
- ext/numo/linalg/lapack/syev.h
|
|
130
136
|
- ext/numo/linalg/lapack/syevd.c
|
|
@@ -159,7 +165,7 @@ metadata:
|
|
|
159
165
|
homepage_uri: https://github.com/yoshoku/numo-linalg-alt
|
|
160
166
|
source_code_uri: https://github.com/yoshoku/numo-linalg-alt
|
|
161
167
|
changelog_uri: https://github.com/yoshoku/numo-linalg-alt/blob/main/CHANGELOG.md
|
|
162
|
-
documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.
|
|
168
|
+
documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.9.1/
|
|
163
169
|
rubygems_mfa_required: 'true'
|
|
164
170
|
rdoc_options: []
|
|
165
171
|
require_paths:
|
|
@@ -175,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
175
181
|
- !ruby/object:Gem::Version
|
|
176
182
|
version: '0'
|
|
177
183
|
requirements: []
|
|
178
|
-
rubygems_version: 4.0.
|
|
184
|
+
rubygems_version: 4.0.6
|
|
179
185
|
specification_version: 4
|
|
180
186
|
summary: Numo::Linalg Alternative (numo-linalg-alt) is an alternative to Numo::Linalg.
|
|
181
187
|
test_files: []
|