numo-linalg-alt 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/ext/numo/linalg/lapack/gbsv.c +92 -0
- data/ext/numo/linalg/lapack/gbsv.h +15 -0
- data/ext/numo/linalg/lapack/pbsv.c +88 -0
- data/ext/numo/linalg/lapack/pbsv.h +15 -0
- data/ext/numo/linalg/lapack/pbtrf.c +68 -0
- data/ext/numo/linalg/lapack/pbtrf.h +15 -0
- data/ext/numo/linalg/lapack/pbtrs.c +93 -0
- data/ext/numo/linalg/lapack/pbtrs.h +15 -0
- data/ext/numo/linalg/linalg.c +4 -0
- data/ext/numo/linalg/linalg.h +4 -0
- data/lib/numo/linalg/version.rb +1 -1
- data/lib/numo/linalg.rb +218 -0
- metadata +18 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2a0ef106744c6982f932536daa0215fd6f8a92fff153fdc576f7de636045e820
|
|
4
|
+
data.tar.gz: 04d3a8fe78f7f47e80d19ab3efca75c329fbe9a285d9b43e260965b96eec3cfa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 782f5396ca2066b7b2b57f0ac6927675daec3e29b1544b24057b1218104363cb5f9265bee3f7d00b84ce8a1cbe42d1c8b78219341d6f9226101888361b462afd
|
|
7
|
+
data.tar.gz: 91f8471e9816bec70d8f05ebce014259d07f2a82e9989d872fc60878692cdf7a961c33024d35ba4e87446748772220bd4ccf3533f5b92cd5aa45a1f42d699822
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [[0.8.0](https://github.com/yoshoku/numo-linalg-alt/compare/v0.7.2...v0.8.0)] - 2026-02-06
|
|
2
|
+
|
|
3
|
+
- relax numo-narray-alt version constraint to >= 0.9.10, < 0.11.0.
|
|
4
|
+
- add `diagsvd` module function to Numo::Linalg.
|
|
5
|
+
- add `cholesky_banded` and `cho_solve_banded` module functions to Numo::Linalg.
|
|
6
|
+
- add `solve_banded` and `solveh_banded` module functions to Numo::Linalg.
|
|
7
|
+
|
|
1
8
|
## [[0.7.2](https://github.com/yoshoku/numo-linalg-alt/compare/v0.7.1...v0.7.2)] - 2026-01-16
|
|
2
9
|
|
|
3
10
|
- 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,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
|
data/ext/numo/linalg/linalg.c
CHANGED
|
@@ -277,10 +277,14 @@ void Init_linalg(void) {
|
|
|
277
277
|
define_linalg_lapack_getrf(rb_mLinalgLapack);
|
|
278
278
|
define_linalg_lapack_getri(rb_mLinalgLapack);
|
|
279
279
|
define_linalg_lapack_getrs(rb_mLinalgLapack);
|
|
280
|
+
define_linalg_lapack_gbsv(rb_mLinalgLapack);
|
|
280
281
|
define_linalg_lapack_trtrs(rb_mLinalgLapack);
|
|
282
|
+
define_linalg_lapack_pbsv(rb_mLinalgLapack);
|
|
281
283
|
define_linalg_lapack_potrf(rb_mLinalgLapack);
|
|
282
284
|
define_linalg_lapack_potri(rb_mLinalgLapack);
|
|
283
285
|
define_linalg_lapack_potrs(rb_mLinalgLapack);
|
|
286
|
+
define_linalg_lapack_pbtrf(rb_mLinalgLapack);
|
|
287
|
+
define_linalg_lapack_pbtrs(rb_mLinalgLapack);
|
|
284
288
|
define_linalg_lapack_syev(rb_mLinalgLapack);
|
|
285
289
|
define_linalg_lapack_heev(rb_mLinalgLapack);
|
|
286
290
|
define_linalg_lapack_syevd(rb_mLinalgLapack);
|
data/ext/numo/linalg/linalg.h
CHANGED
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
#include "blas/gemv.h"
|
|
60
60
|
#include "blas/nrm2.h"
|
|
61
61
|
|
|
62
|
+
#include "lapack/gbsv.h"
|
|
62
63
|
#include "lapack/gebal.h"
|
|
63
64
|
#include "lapack/gees.h"
|
|
64
65
|
#include "lapack/geev.h"
|
|
@@ -84,6 +85,9 @@
|
|
|
84
85
|
#include "lapack/orghr.h"
|
|
85
86
|
#include "lapack/orgqr.h"
|
|
86
87
|
#include "lapack/orgrq.h"
|
|
88
|
+
#include "lapack/pbsv.h"
|
|
89
|
+
#include "lapack/pbtrf.h"
|
|
90
|
+
#include "lapack/pbtrs.h"
|
|
87
91
|
#include "lapack/potrf.h"
|
|
88
92
|
#include "lapack/potri.h"
|
|
89
93
|
#include "lapack/potrs.h"
|
data/lib/numo/linalg/version.rb
CHANGED
data/lib/numo/linalg.rb
CHANGED
|
@@ -318,6 +318,29 @@ module Numo
|
|
|
318
318
|
end
|
|
319
319
|
end
|
|
320
320
|
|
|
321
|
+
# Computes the Cholesky decomposition of a banded symmetric / Hermitian positive-definite matrix.
|
|
322
|
+
#
|
|
323
|
+
# @param a [Numo::NArray] The banded matrix.
|
|
324
|
+
# @param uplo [String] Is the matrix form upper or lower ('U' or 'L').
|
|
325
|
+
# @return [Numo::NArray] The Cholesky factor of the banded matrix.
|
|
326
|
+
def cholesky_banded(a, uplo: 'U')
|
|
327
|
+
raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
|
|
328
|
+
|
|
329
|
+
bchr = blas_char(a)
|
|
330
|
+
raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
|
|
331
|
+
|
|
332
|
+
fnc = :"#{bchr}pbtrf"
|
|
333
|
+
c, info = Numo::Linalg::Lapack.send(fnc, a.dup, uplo: uplo)
|
|
334
|
+
raise LapackError, "the #{-info}-th argument of potrs had illegal value" if info.negative?
|
|
335
|
+
|
|
336
|
+
if info.positive?
|
|
337
|
+
raise LapackError, "the leading principal minor of order #{info} is not positive, " \
|
|
338
|
+
'and the factorization could not be completed.'
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
c
|
|
342
|
+
end
|
|
343
|
+
|
|
321
344
|
# Solves linear equation `A * x = b` or `A * X = B` for `x` with the Cholesky factorization of `A`.
|
|
322
345
|
#
|
|
323
346
|
# @example
|
|
@@ -352,6 +375,41 @@ module Numo
|
|
|
352
375
|
x
|
|
353
376
|
end
|
|
354
377
|
|
|
378
|
+
# Solves linear equation `A * x = b` or `A * X = B` for `x` with the Cholesky factorization of banded matrix `A`.
|
|
379
|
+
#
|
|
380
|
+
# @example
|
|
381
|
+
# require 'numo/linalg'
|
|
382
|
+
#
|
|
383
|
+
# a = Numo::DFloat.new(4, 4).rand - 0.5
|
|
384
|
+
# a = a.dot(a.transpose)
|
|
385
|
+
# a = a.tril(1) * a.triu(-1)
|
|
386
|
+
# ab = Numo::DFloat.zeros(2, 4)
|
|
387
|
+
# ab[0, 1...] = a[a.diag_indices(1)]
|
|
388
|
+
# ab[1, true] = a[a.diag_indices]
|
|
389
|
+
# c = Numo::Linalg.cholesky_banded(ab)
|
|
390
|
+
# b = Numo::DFloat.new(4, 2).rand
|
|
391
|
+
# x = Numo::Linalg.cho_solve_banded(c, b)
|
|
392
|
+
# pp (b - a.dot(x)).abs.max
|
|
393
|
+
# # => 1.1102230246251565e-16
|
|
394
|
+
#
|
|
395
|
+
# @param ab [Numo::NArray] The m-by-n banded cholesky factor.
|
|
396
|
+
# @param b [Numo::NArray] The n right-hand side vector, or n-by-nrhs right-hand side matrix.
|
|
397
|
+
# @param uplo [String] Whether to compute the upper- or lower-triangular Cholesky factor ('U' or 'L').
|
|
398
|
+
# @return [Numo::NArray] The solution vector or matrix `X`.
|
|
399
|
+
def cho_solve_banded(ab, b, uplo: 'U')
|
|
400
|
+
raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if ab.ndim != 2
|
|
401
|
+
raise Numo::NArray::ShapeError, "incompatible dimensions: ab.shape[1] = #{ab.shape[1]} != b.shape[0] = #{b.shape[0]}" if ab.shape[1] != b.shape[0]
|
|
402
|
+
|
|
403
|
+
bchr = blas_char(ab, b)
|
|
404
|
+
raise ArgumentError, "invalid array type: #{ab.class}" if bchr == 'n'
|
|
405
|
+
|
|
406
|
+
fnc = :"#{bchr}pbtrs"
|
|
407
|
+
x, info = Numo::Linalg::Lapack.send(fnc, ab, b.dup, uplo: uplo)
|
|
408
|
+
raise LapackError, "the #{-info}-th argument of potrs had illegal value" if info.negative?
|
|
409
|
+
|
|
410
|
+
x
|
|
411
|
+
end
|
|
412
|
+
|
|
355
413
|
# Computes the determinant of matrix.
|
|
356
414
|
#
|
|
357
415
|
# @example
|
|
@@ -906,6 +964,127 @@ module Numo
|
|
|
906
964
|
x
|
|
907
965
|
end
|
|
908
966
|
|
|
967
|
+
# Solves linear equation `A * x = b` or `A * X = B` for `x` assuming `A` is a banded matrix.
|
|
968
|
+
#
|
|
969
|
+
# @example
|
|
970
|
+
# require 'numo/linalg'
|
|
971
|
+
#
|
|
972
|
+
# # Banded matrix A:
|
|
973
|
+
# # [4 2 1 0 0]
|
|
974
|
+
# # [1 5 2 1 0]
|
|
975
|
+
# # [0 1 6 2 1]
|
|
976
|
+
# # [0 0 1 7 2]
|
|
977
|
+
# # [0 0 0 1 8]
|
|
978
|
+
# #
|
|
979
|
+
# ab = Numo::DFloat[[0, 0, 1, 1, 1],
|
|
980
|
+
# [0, 2, 2, 2, 2],
|
|
981
|
+
# [4, 5, 6, 7, 8],
|
|
982
|
+
# [1, 1, 1, 1, 0]]
|
|
983
|
+
#
|
|
984
|
+
# b = Numo::DFloat[1, 2, 3, 4, 5]
|
|
985
|
+
#
|
|
986
|
+
# x = Numo::Linalg.solve_banded([1, 2], ab, b)
|
|
987
|
+
# pp x
|
|
988
|
+
# # =>
|
|
989
|
+
# # Numo::DFloat#shape=[5]
|
|
990
|
+
# # [0.0832055, 0.211273, 0.244632, 0.371166, 0.578604]
|
|
991
|
+
#
|
|
992
|
+
# a = ab[2, true].diag + ab[0, 2...].diag(2) + ab[1, 1...].diag(1) + ab[3, 0...-1].diag(-1)
|
|
993
|
+
# pp a
|
|
994
|
+
# # =>
|
|
995
|
+
# # Numo::DFloat#shape=[5,5]
|
|
996
|
+
# # [[4, 2, 1, 0, 0],
|
|
997
|
+
# # [1, 5, 2, 1, 0],
|
|
998
|
+
# # [0, 1, 6, 2, 1],
|
|
999
|
+
# # [0, 0, 1, 7, 2],
|
|
1000
|
+
# # [0, 0, 0, 1, 8]]
|
|
1001
|
+
# pp a.dot(x)
|
|
1002
|
+
# # =>
|
|
1003
|
+
# # Numo::DFloat#shape=[5]
|
|
1004
|
+
# # [1, 2, 3, 4, 5]
|
|
1005
|
+
#
|
|
1006
|
+
# @param l_u [Array<Integer>] The number of sub-diagonals and super-diagonals of the banded matrix `A`.
|
|
1007
|
+
# @param ab [Numo::NArray] The (l + u + 1)-by-n array representing the banded matrix `A`.
|
|
1008
|
+
# @param b [Numo::NArray] The n right-hand side vector, or n-by-nrhs right-hand side matrix.
|
|
1009
|
+
# @return [Numo::NArray] The solution vector / matrix `X`.
|
|
1010
|
+
def solve_banded(l_u, ab, b)
|
|
1011
|
+
raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if ab.ndim != 2
|
|
1012
|
+
|
|
1013
|
+
unless l_u.is_a?(Array) && l_u.size == 2 && l_u.all?(Integer)
|
|
1014
|
+
raise ArgumentError, 'l_u must be an array of two integers'
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
kl, ku = l_u
|
|
1018
|
+
raise Numo::NArray::ShapeError, "ab.shape[0] must be equal to l + u + 1: #{ab.shape[0]} != #{kl} + #{ku} + 1" if ab.shape[0] != kl + ku + 1
|
|
1019
|
+
|
|
1020
|
+
bchr = blas_char(ab, b)
|
|
1021
|
+
raise ArgumentError, "invalid array type: #{a.class}, #{b.class}" if bchr == 'n'
|
|
1022
|
+
|
|
1023
|
+
gbsv = :"#{bchr}gbsv"
|
|
1024
|
+
|
|
1025
|
+
tmp = ab.class.zeros((2 * kl) + ku + 1, ab.shape[1])
|
|
1026
|
+
tmp[kl..., true] = ab
|
|
1027
|
+
_, x, _, info = Numo::Linalg::Lapack.send(gbsv, tmp, b.dup, kl: kl, ku: ku)
|
|
1028
|
+
raise LapackError, "wrong value is given to the #{-info}-th argument of #{gbsv} used internally" if info.negative?
|
|
1029
|
+
raise LapackError, 'the leading minor of the matrix is not positive definite' if info.positive?
|
|
1030
|
+
|
|
1031
|
+
x
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
# Solves linear equation `A * x = b` or `A * X = B` for `x` assuming `A` is
|
|
1035
|
+
# a symmetric/Hermitian positive-definite banded matrix.
|
|
1036
|
+
#
|
|
1037
|
+
# @example
|
|
1038
|
+
# require 'numo/linalg'
|
|
1039
|
+
#
|
|
1040
|
+
# # Banded matrix A:
|
|
1041
|
+
# # [4 2 1 0 0]
|
|
1042
|
+
# # [2 5 2 1 0]
|
|
1043
|
+
# # [1 2 6 2 1]
|
|
1044
|
+
# # [0 1 2 7 2]
|
|
1045
|
+
# # [0 0 1 2 8]
|
|
1046
|
+
# #
|
|
1047
|
+
# # The banded representation ab for lower-banded form is:
|
|
1048
|
+
# ab = Numo::DFloat[[4, 5, 6, 7, 8],
|
|
1049
|
+
# [2, 2, 2, 2, 0],
|
|
1050
|
+
# [1, 1, 1, 0, 0]]
|
|
1051
|
+
# # The banded representation ab for upper-banded form is:
|
|
1052
|
+
# # ab = Numo::DFloat[[0, 0, 1, 1, 1],
|
|
1053
|
+
# # [0, 2, 2, 2, 2],
|
|
1054
|
+
# # [4, 5, 6, 7, 8]]
|
|
1055
|
+
# b = Numo::DFloat[1, 2, 3, 4, 5]
|
|
1056
|
+
#
|
|
1057
|
+
# x = Numo::Linalg.solveh_banded(ab, b, lower: true)
|
|
1058
|
+
# pp x
|
|
1059
|
+
# # =>
|
|
1060
|
+
# # Numo::DFloat#shape=[5]
|
|
1061
|
+
# # [0.0903361, 0.210084, 0.218487, 0.331933, 0.514706]
|
|
1062
|
+
#
|
|
1063
|
+
# a = ab[0, true].diag + ab[1, 0...-1].diag(1) + ab[2, 0...-2].diag(2) +
|
|
1064
|
+
# ab[1, 0...-1].diag(-1) + ab[2, 0...-2].diag(-2)
|
|
1065
|
+
# pp a.dot(x)
|
|
1066
|
+
# # => Numo::DFloat#shape=[5]
|
|
1067
|
+
# # [1, 2, 3, 4, 5]
|
|
1068
|
+
#
|
|
1069
|
+
# @param ab [Numo::NArray] The m-by-n array representing the banded matrix `A`.
|
|
1070
|
+
# @param b [Numo::NArray] The n right-hand side vector, or n-by-k right-hand side matrix.
|
|
1071
|
+
# @param lower [Boolean] The flag indicating whether to be in the lower-banded form.
|
|
1072
|
+
# @return [Numo::NArray] The solusion vector / matrix `X`.
|
|
1073
|
+
def solveh_banded(ab, b, lower: false)
|
|
1074
|
+
raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if ab.ndim != 2
|
|
1075
|
+
|
|
1076
|
+
bchr = blas_char(ab, b)
|
|
1077
|
+
raise ArgumentError, "invalid array type: #{a.class}, #{b.class}" if bchr == 'n'
|
|
1078
|
+
|
|
1079
|
+
pbsv = :"#{bchr}pbsv"
|
|
1080
|
+
uplo = lower ? 'L' : 'U'
|
|
1081
|
+
x, info = Numo::Linalg::Lapack.send(pbsv, ab.dup, b.dup, uplo: uplo)
|
|
1082
|
+
raise LapackError, "wrong value is given to the #{info}-th argument of #{pbsv} used internally" if info.negative?
|
|
1083
|
+
raise LapackError, 'the leading minor of the matrix is not positive definite' if info.positive?
|
|
1084
|
+
|
|
1085
|
+
x
|
|
1086
|
+
end
|
|
1087
|
+
|
|
909
1088
|
# Computes the Singular Value Decomposition (SVD) of a matrix: `A = U * S * V^T`
|
|
910
1089
|
#
|
|
911
1090
|
# @example
|
|
@@ -1053,6 +1232,45 @@ module Numo
|
|
|
1053
1232
|
s
|
|
1054
1233
|
end
|
|
1055
1234
|
|
|
1235
|
+
# Creates a diagonal matrix from the given singular values.
|
|
1236
|
+
#
|
|
1237
|
+
# @example
|
|
1238
|
+
# require 'numo/linalg'
|
|
1239
|
+
#
|
|
1240
|
+
# s = Numo::DFloat[4, 2, 1]
|
|
1241
|
+
# d = Numo::Linalg.diagsvd(s, 3, 4)
|
|
1242
|
+
# pp d
|
|
1243
|
+
# # =>
|
|
1244
|
+
# # Numo::DFloat#shape=[3,4]
|
|
1245
|
+
# # [[4, 0, 0, 0],
|
|
1246
|
+
# # [0, 2, 0, 0],
|
|
1247
|
+
# # [0, 0, 1, 0]]
|
|
1248
|
+
# d = Numo::Linalg.diagsvd(s, 4, 3)
|
|
1249
|
+
# pp d
|
|
1250
|
+
# # =>
|
|
1251
|
+
# # Numo::DFloat#shape=[4,3]
|
|
1252
|
+
# # [[4, 0, 0],
|
|
1253
|
+
# # [0, 2, 0],
|
|
1254
|
+
# # [0, 0, 1],
|
|
1255
|
+
# # [0, 0, 0]]
|
|
1256
|
+
#
|
|
1257
|
+
# @param s [Numo::NArray] The singular values.
|
|
1258
|
+
# @param m [Integer] The number of rows of the constructed matrix.
|
|
1259
|
+
# @param n [Integer] The number of columns of the constructed matrix.
|
|
1260
|
+
# @return [Numo::NArray] The m-by-n diagonal matrix with the singular values on the diagonal.
|
|
1261
|
+
def diagsvd(s, m, n)
|
|
1262
|
+
sz_s = s.size
|
|
1263
|
+
raise ArgumentError, "size of s must be equal to m or n: s.size=#{sz_s}, m=#{m}, n=#{n}" if sz_s != m && sz_s != n
|
|
1264
|
+
|
|
1265
|
+
mat = s.class.zeros(m, n)
|
|
1266
|
+
if sz_s == m
|
|
1267
|
+
mat[true, 0...m] = s.diag
|
|
1268
|
+
else
|
|
1269
|
+
mat[0...n, true] = s.diag
|
|
1270
|
+
end
|
|
1271
|
+
mat
|
|
1272
|
+
end
|
|
1273
|
+
|
|
1056
1274
|
# Computes an orthonormal basis for the range of `A` using SVD.
|
|
1057
1275
|
#
|
|
1058
1276
|
# @example
|
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.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- yoshoku
|
|
@@ -13,16 +13,22 @@ dependencies:
|
|
|
13
13
|
name: numo-narray-alt
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: 0.9.10
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 0.11.0
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
28
|
version: 0.9.10
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: 0.11.0
|
|
26
32
|
description: |
|
|
27
33
|
Numo::Linalg Alternative (numo-linalg-alt) is an alternative to Numo::Linalg.
|
|
28
34
|
Unlike Numo::Linalg, numo-linalg-alt depends on Numo::NArray Alternative (numo-narray-alt).
|
|
@@ -53,6 +59,8 @@ files:
|
|
|
53
59
|
- ext/numo/linalg/blas/nrm2.c
|
|
54
60
|
- ext/numo/linalg/blas/nrm2.h
|
|
55
61
|
- ext/numo/linalg/extconf.rb
|
|
62
|
+
- ext/numo/linalg/lapack/gbsv.c
|
|
63
|
+
- ext/numo/linalg/lapack/gbsv.h
|
|
56
64
|
- ext/numo/linalg/lapack/gebal.c
|
|
57
65
|
- ext/numo/linalg/lapack/gebal.h
|
|
58
66
|
- ext/numo/linalg/lapack/gees.c
|
|
@@ -105,6 +113,12 @@ files:
|
|
|
105
113
|
- ext/numo/linalg/lapack/orgqr.h
|
|
106
114
|
- ext/numo/linalg/lapack/orgrq.c
|
|
107
115
|
- ext/numo/linalg/lapack/orgrq.h
|
|
116
|
+
- ext/numo/linalg/lapack/pbsv.c
|
|
117
|
+
- ext/numo/linalg/lapack/pbsv.h
|
|
118
|
+
- ext/numo/linalg/lapack/pbtrf.c
|
|
119
|
+
- ext/numo/linalg/lapack/pbtrf.h
|
|
120
|
+
- ext/numo/linalg/lapack/pbtrs.c
|
|
121
|
+
- ext/numo/linalg/lapack/pbtrs.h
|
|
108
122
|
- ext/numo/linalg/lapack/potrf.c
|
|
109
123
|
- ext/numo/linalg/lapack/potrf.h
|
|
110
124
|
- ext/numo/linalg/lapack/potri.c
|
|
@@ -145,7 +159,7 @@ metadata:
|
|
|
145
159
|
homepage_uri: https://github.com/yoshoku/numo-linalg-alt
|
|
146
160
|
source_code_uri: https://github.com/yoshoku/numo-linalg-alt
|
|
147
161
|
changelog_uri: https://github.com/yoshoku/numo-linalg-alt/blob/main/CHANGELOG.md
|
|
148
|
-
documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.
|
|
162
|
+
documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.8.0/
|
|
149
163
|
rubygems_mfa_required: 'true'
|
|
150
164
|
rdoc_options: []
|
|
151
165
|
require_paths:
|