numo-linalg 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/README.md +80 -0
- data/Rakefile +18 -0
- data/ext/numo/linalg/blas/blas.c +352 -0
- data/ext/numo/linalg/blas/cblas.h +575 -0
- data/ext/numo/linalg/blas/cblas_t.h +563 -0
- data/ext/numo/linalg/blas/depend.erb +23 -0
- data/ext/numo/linalg/blas/extconf.rb +67 -0
- data/ext/numo/linalg/blas/gen/cogen.rb +72 -0
- data/ext/numo/linalg/blas/gen/decl.rb +203 -0
- data/ext/numo/linalg/blas/gen/desc.rb +8138 -0
- data/ext/numo/linalg/blas/gen/erbpp2.rb +339 -0
- data/ext/numo/linalg/blas/gen/replace_cblas_h.rb +27 -0
- data/ext/numo/linalg/blas/gen/spec.rb +93 -0
- data/ext/numo/linalg/blas/numo_blas.h +41 -0
- data/ext/numo/linalg/blas/tmpl/axpy.c +75 -0
- data/ext/numo/linalg/blas/tmpl/copy.c +57 -0
- data/ext/numo/linalg/blas/tmpl/def_c.c +3 -0
- data/ext/numo/linalg/blas/tmpl/def_d.c +3 -0
- data/ext/numo/linalg/blas/tmpl/def_s.c +3 -0
- data/ext/numo/linalg/blas/tmpl/def_z.c +3 -0
- data/ext/numo/linalg/blas/tmpl/dot.c +68 -0
- data/ext/numo/linalg/blas/tmpl/ger.c +114 -0
- data/ext/numo/linalg/blas/tmpl/init_class.c +20 -0
- data/ext/numo/linalg/blas/tmpl/init_module.c +12 -0
- data/ext/numo/linalg/blas/tmpl/lib.c +40 -0
- data/ext/numo/linalg/blas/tmpl/mm.c +214 -0
- data/ext/numo/linalg/blas/tmpl/module.c +9 -0
- data/ext/numo/linalg/blas/tmpl/mv.c +194 -0
- data/ext/numo/linalg/blas/tmpl/nrm2.c +79 -0
- data/ext/numo/linalg/blas/tmpl/rot.c +65 -0
- data/ext/numo/linalg/blas/tmpl/rotm.c +82 -0
- data/ext/numo/linalg/blas/tmpl/scal.c +69 -0
- data/ext/numo/linalg/blas/tmpl/sdsdot.c +77 -0
- data/ext/numo/linalg/blas/tmpl/set_prefix.c +16 -0
- data/ext/numo/linalg/blas/tmpl/swap.c +57 -0
- data/ext/numo/linalg/blas/tmpl/syr.c +102 -0
- data/ext/numo/linalg/blas/tmpl/syr2.c +110 -0
- data/ext/numo/linalg/blas/tmpl/syr2k.c +129 -0
- data/ext/numo/linalg/blas/tmpl/syrk.c +132 -0
- data/ext/numo/linalg/lapack/depend.erb +23 -0
- data/ext/numo/linalg/lapack/extconf.rb +45 -0
- data/ext/numo/linalg/lapack/gen/cogen.rb +74 -0
- data/ext/numo/linalg/lapack/gen/desc.rb +151278 -0
- data/ext/numo/linalg/lapack/gen/replace_lapacke_h.rb +32 -0
- data/ext/numo/linalg/lapack/gen/spec.rb +104 -0
- data/ext/numo/linalg/lapack/lapack.c +387 -0
- data/ext/numo/linalg/lapack/lapacke.h +16425 -0
- data/ext/numo/linalg/lapack/lapacke_config.h +119 -0
- data/ext/numo/linalg/lapack/lapacke_mangling.h +17 -0
- data/ext/numo/linalg/lapack/lapacke_t.h +10550 -0
- data/ext/numo/linalg/lapack/numo_lapack.h +42 -0
- data/ext/numo/linalg/lapack/tmpl/def_c.c +3 -0
- data/ext/numo/linalg/lapack/tmpl/def_d.c +7 -0
- data/ext/numo/linalg/lapack/tmpl/def_s.c +7 -0
- data/ext/numo/linalg/lapack/tmpl/def_z.c +3 -0
- data/ext/numo/linalg/lapack/tmpl/fact.c +179 -0
- data/ext/numo/linalg/lapack/tmpl/geev.c +123 -0
- data/ext/numo/linalg/lapack/tmpl/gels.c +232 -0
- data/ext/numo/linalg/lapack/tmpl/gesv.c +149 -0
- data/ext/numo/linalg/lapack/tmpl/gesvd.c +189 -0
- data/ext/numo/linalg/lapack/tmpl/ggev.c +138 -0
- data/ext/numo/linalg/lapack/tmpl/gqr.c +121 -0
- data/ext/numo/linalg/lapack/tmpl/init_class.c +20 -0
- data/ext/numo/linalg/lapack/tmpl/init_module.c +12 -0
- data/ext/numo/linalg/lapack/tmpl/lange.c +79 -0
- data/ext/numo/linalg/lapack/tmpl/lib.c +40 -0
- data/ext/numo/linalg/lapack/tmpl/module.c +9 -0
- data/ext/numo/linalg/lapack/tmpl/syev.c +91 -0
- data/ext/numo/linalg/lapack/tmpl/sygv.c +104 -0
- data/ext/numo/linalg/lapack/tmpl/trf.c +276 -0
- data/ext/numo/linalg/numo_linalg.h +115 -0
- data/lib/numo/linalg.rb +3 -0
- data/lib/numo/linalg/function.rb +1008 -0
- data/lib/numo/linalg/linalg.rb +7 -0
- data/lib/numo/linalg/loader.rb +174 -0
- data/lib/numo/linalg/use/atlas.rb +3 -0
- data/lib/numo/linalg/use/lapack.rb +3 -0
- data/lib/numo/linalg/use/mkl.rb +3 -0
- data/lib/numo/linalg/use/openblas.rb +3 -0
- data/lib/numo/linalg/version.rb +5 -0
- data/numo-linalg.gemspec +26 -0
- data/spec/lapack_spec.rb +13 -0
- metadata +172 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
#define lapack_complex_float scomplex
|
2
|
+
#define lapack_complex_double dcomplex
|
3
|
+
#include "lapacke.h"
|
4
|
+
#include "lapacke_t.h"
|
5
|
+
#include "../numo_linalg.h"
|
6
|
+
|
7
|
+
typedef int blasint;
|
8
|
+
|
9
|
+
#define option_value numo_lapacke_option_value
|
10
|
+
extern int numo_lapacke_option_value(VALUE value, VALUE default_value);
|
11
|
+
|
12
|
+
#define option_order numo_lapacke_option_order
|
13
|
+
extern int numo_lapacke_option_order(VALUE order);
|
14
|
+
|
15
|
+
#define option_job numo_lapacke_option_job
|
16
|
+
extern char numo_lapacke_option_job(VALUE job, char true_char, char false_char);
|
17
|
+
|
18
|
+
#define option_trans numo_lapacke_option_trans
|
19
|
+
extern char numo_lapacke_option_trans(VALUE trans);
|
20
|
+
|
21
|
+
#define option_uplo numo_lapacke_option_uplo
|
22
|
+
extern char numo_lapacke_option_uplo(VALUE uplo);
|
23
|
+
|
24
|
+
#define option_diag numo_lapacke_option_diag
|
25
|
+
extern char numo_lapacke_option_diag(VALUE diag);
|
26
|
+
|
27
|
+
#define option_side numo_lapacke_option_side
|
28
|
+
extern char numo_lapacke_option_side(VALUE side);
|
29
|
+
|
30
|
+
#define check_func numo_lapacke_check_func
|
31
|
+
extern void numo_lapacke_check_func(void **func, const char *name);
|
32
|
+
|
33
|
+
#define CHECK_ERROR(info) \
|
34
|
+
{ if ((info)<0) { \
|
35
|
+
rb_raise(eLapackError,"LAPACK error, info=%d",(info)); \
|
36
|
+
}}
|
37
|
+
|
38
|
+
#define SWAP_IFCOL(order,a,b) \
|
39
|
+
{ if ((order)==LAPACK_COL_MAJOR) {tmp=(a);(a)=(b);(b)=tmp;} }
|
40
|
+
|
41
|
+
#define CHECK_FUNC(fptr, fname) \
|
42
|
+
{ if ((fptr)==0) { check_func((void*)(&(fptr)),fname); } }
|
@@ -0,0 +1,179 @@
|
|
1
|
+
/*<%
|
2
|
+
has_uplo = (/^.(sy|he|po)/ =~ name)
|
3
|
+
has_jpvt = (/geqp3/ =~ name)
|
4
|
+
has_tau = (/q/ =~ name || /tzrzf/ =~ name)
|
5
|
+
%>*/
|
6
|
+
<% %>
|
7
|
+
#define UPLO <%= has_uplo ? "1":"0" %>
|
8
|
+
#define JPVT <%= has_jpvt ? "1":"0" %>
|
9
|
+
#define TAU <%= has_tau ? "1":"0" %>
|
10
|
+
#define args_t <%=func_name%>_args_t
|
11
|
+
#define func_p <%=func_name%>_p
|
12
|
+
|
13
|
+
typedef struct {
|
14
|
+
int order;
|
15
|
+
char uplo;
|
16
|
+
} args_t;
|
17
|
+
|
18
|
+
static <%=func_name%>_t func_p = 0;
|
19
|
+
|
20
|
+
static void
|
21
|
+
<%=c_iter%>(na_loop_t * const lp)
|
22
|
+
{
|
23
|
+
dtype *a;
|
24
|
+
#if JPVT
|
25
|
+
int *pv;
|
26
|
+
#endif
|
27
|
+
#if TAU
|
28
|
+
dtype *tau;
|
29
|
+
#endif
|
30
|
+
int *info;
|
31
|
+
int m, n, lda, tmp;
|
32
|
+
args_t *g;
|
33
|
+
|
34
|
+
a = (dtype*)NDL_PTR(lp,0);
|
35
|
+
#if JPVT
|
36
|
+
pv = (int*)NDL_PTR(lp,1);
|
37
|
+
#endif
|
38
|
+
#if TAU
|
39
|
+
tau = (dtype*)NDL_PTR(lp,1+JPVT);
|
40
|
+
#endif
|
41
|
+
info = (int*)NDL_PTR(lp,1+JPVT+TAU);
|
42
|
+
g = (args_t*)(lp->opt_ptr);
|
43
|
+
|
44
|
+
m = NDL_SHAPE(lp,0)[0];
|
45
|
+
n = NDL_SHAPE(lp,0)[1];
|
46
|
+
SWAP_IFCOL(g->order,m,n);
|
47
|
+
#if UPLO
|
48
|
+
n = min_(m,n);
|
49
|
+
#endif
|
50
|
+
lda = NDL_STEP(lp,0) / sizeof(dtype);
|
51
|
+
|
52
|
+
//printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
|
53
|
+
|
54
|
+
/*<%
|
55
|
+
func_args = [ "g->order",
|
56
|
+
has_uplo ? "g->uplo" : "m",
|
57
|
+
"n, a, lda",
|
58
|
+
has_jpvt && "pv",
|
59
|
+
has_tau && "tau",
|
60
|
+
].select{|x| x}.join(", ")
|
61
|
+
%>*/
|
62
|
+
*info = (*func_p)(<%=func_args%>);
|
63
|
+
CHECK_ERROR(*info);
|
64
|
+
}
|
65
|
+
|
66
|
+
/*<%
|
67
|
+
args_v = [
|
68
|
+
"a",
|
69
|
+
has_jpvt && "jpvt",
|
70
|
+
].select{|x| x}.join(", ")
|
71
|
+
|
72
|
+
args_opt = [
|
73
|
+
has_uplo && "uplo:'U'",
|
74
|
+
"order:'R'",
|
75
|
+
].select{|x| x}.join(", ")
|
76
|
+
|
77
|
+
params = [
|
78
|
+
mat("a",:inplace),
|
79
|
+
has_uplo && opt("uplo"),
|
80
|
+
opt("order"),
|
81
|
+
].select{|x| x}.join("\n ")
|
82
|
+
|
83
|
+
return_type = [
|
84
|
+
class_name,
|
85
|
+
has_jpvt && "Numo::Int",
|
86
|
+
has_tau && class_name,
|
87
|
+
"Integer"
|
88
|
+
].select{|x| x}.join(", ")
|
89
|
+
|
90
|
+
return_name = [
|
91
|
+
"a",
|
92
|
+
has_jpvt && "jpvt",
|
93
|
+
has_tau && "tau",
|
94
|
+
"info"
|
95
|
+
].select{|x| x}.join(", ")
|
96
|
+
%>
|
97
|
+
@overload <%=name%>(<%=args_v%>, [<%=args_opt%>])
|
98
|
+
<%=params%>
|
99
|
+
@return [[<%=return_name%>]] Array<<%=return_type%>>
|
100
|
+
<%=outparam(return_name)%>
|
101
|
+
|
102
|
+
<%=description%>
|
103
|
+
|
104
|
+
*/
|
105
|
+
static VALUE
|
106
|
+
<%=c_func(-1)%>(int argc, VALUE const argv[], VALUE UNUSED(mod))
|
107
|
+
{
|
108
|
+
VALUE a, ans;
|
109
|
+
int m, n, tmp;
|
110
|
+
narray_t *na1;
|
111
|
+
#if JPVT
|
112
|
+
VALUE jpvt;
|
113
|
+
#endif
|
114
|
+
/*<%
|
115
|
+
ain = [ "{OVERWRITE,2}",
|
116
|
+
has_jpvt && "{OVERWRITE,1}",
|
117
|
+
].select{|x| x}.join(",")
|
118
|
+
aout = [
|
119
|
+
has_tau && "{cT,1,shape_tau}",
|
120
|
+
"{cInt,0}",
|
121
|
+
].select{|x| x}.join(",")
|
122
|
+
%>*/
|
123
|
+
#if TAU
|
124
|
+
size_t shape_tau[1];
|
125
|
+
#endif
|
126
|
+
ndfunc_arg_in_t ain[1+JPVT] = {<%=ain%>};
|
127
|
+
ndfunc_arg_out_t aout[1+TAU] = {<%=aout%>};
|
128
|
+
ndfunc_t ndf = {&<%=c_iter%>, NO_LOOP|NDF_EXTRACT,
|
129
|
+
1+JPVT, TAU+1, ain,aout};
|
130
|
+
|
131
|
+
args_t g = {0,1};
|
132
|
+
VALUE opts[2] = {Qundef,Qundef};
|
133
|
+
VALUE kw_hash = Qnil;
|
134
|
+
ID kw_table[2] = {id_order,id_uplo};
|
135
|
+
|
136
|
+
CHECK_FUNC(func_p,"<%=func_name%>");
|
137
|
+
|
138
|
+
#if JPVT
|
139
|
+
rb_scan_args(argc, argv, "2:", &a, &jpvt, &kw_hash);
|
140
|
+
#else
|
141
|
+
rb_scan_args(argc, argv, "1:", &a, &kw_hash);
|
142
|
+
#endif
|
143
|
+
rb_get_kwargs(kw_hash, kw_table, 0, 1+UPLO, opts);
|
144
|
+
g.order = option_order(opts[0]);
|
145
|
+
#if UPLO
|
146
|
+
g.uplo = option_uplo(opts[1]);
|
147
|
+
#endif
|
148
|
+
|
149
|
+
COPY_OR_CAST_TO(a,cT);
|
150
|
+
GetNArray(a, na1);
|
151
|
+
CHECK_DIM_GE(na1, 2);
|
152
|
+
m = ROW_SIZE(na1);
|
153
|
+
n = COL_SIZE(na1);
|
154
|
+
SWAP_IFCOL(g.order,m,n);
|
155
|
+
#if TAU
|
156
|
+
shape_tau[0] = min_(m,n);
|
157
|
+
#endif
|
158
|
+
|
159
|
+
#if JPVT
|
160
|
+
COPY_OR_CAST_TO(jpvt,cInt);
|
161
|
+
ans = na_ndloop3(&ndf, &g, 2, a, jpvt);
|
162
|
+
rb_ary_concat(rb_ary_assoc(a,jpvt), ans);
|
163
|
+
return ans;
|
164
|
+
#else
|
165
|
+
ans = na_ndloop3(&ndf, &g, 1, a);
|
166
|
+
#if TAU == 0
|
167
|
+
return rb_assoc_new(a, ans);
|
168
|
+
#else
|
169
|
+
rb_ary_unshift(ans, a);
|
170
|
+
return ans;
|
171
|
+
#endif
|
172
|
+
#endif
|
173
|
+
}
|
174
|
+
|
175
|
+
#undef args_t
|
176
|
+
#undef func_p
|
177
|
+
#undef UPLO
|
178
|
+
#undef JPVT
|
179
|
+
#undef TAU
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#define args_t <%=func_name%>_args_t
|
2
|
+
#define func_p <%=func_name%>_p
|
3
|
+
|
4
|
+
typedef struct {
|
5
|
+
int order;
|
6
|
+
char jobvl, jobvr;
|
7
|
+
} args_t;
|
8
|
+
|
9
|
+
static <%=func_name%>_t func_p = 0;
|
10
|
+
|
11
|
+
static void
|
12
|
+
<%=c_iter%>(na_loop_t * const lp)
|
13
|
+
{
|
14
|
+
dtype *a, *vl, *vr;
|
15
|
+
#if IS_COMPLEX
|
16
|
+
dtype *w;
|
17
|
+
#else
|
18
|
+
dtype *wr, *wi;
|
19
|
+
#endif
|
20
|
+
int *info;
|
21
|
+
int n, lda, ldvl, ldvr;
|
22
|
+
args_t *g;
|
23
|
+
|
24
|
+
a = (dtype*)NDL_PTR(lp,0);
|
25
|
+
#if IS_COMPLEX
|
26
|
+
w = (dtype*)NDL_PTR(lp,1);
|
27
|
+
#else
|
28
|
+
wr = (dtype*)NDL_PTR(lp,1);
|
29
|
+
wi = (dtype*)NDL_PTR(lp,2);
|
30
|
+
#endif
|
31
|
+
vl = (dtype*)NDL_PTR(lp,3-CZ);
|
32
|
+
vr = (dtype*)NDL_PTR(lp,4-CZ);
|
33
|
+
info = (int*)NDL_PTR(lp,5-CZ);
|
34
|
+
g = (args_t*)(lp->opt_ptr);
|
35
|
+
|
36
|
+
n = NDL_SHAPE(lp,0)[1];
|
37
|
+
lda = NDL_STEP(lp,0) / sizeof(dtype);
|
38
|
+
ldvl = NDL_STEP(lp,3-CZ) / sizeof(dtype);
|
39
|
+
if (ldvl == 0) { ldvl = n; } // jobvt == 'N'
|
40
|
+
ldvr = NDL_STEP(lp,4-CZ) / sizeof(dtype);
|
41
|
+
if (ldvr == 0) { ldvr = n; } // jobvt == 'N'
|
42
|
+
|
43
|
+
//printf("order=%d jobvl=%c jobvr=%c n=%d lda=%d ldvl=%d ldvr=%d\n",g->order,g->jobvl, g->jobvr, n, lda,ldvl,ldvr);
|
44
|
+
|
45
|
+
/*<% func_args = [
|
46
|
+
"g->order, g->jobvl, g->jobvr, n, a, lda",
|
47
|
+
is_complex ? "w" : "wr, wi",
|
48
|
+
"vl, ldvl, vr, ldvr"
|
49
|
+
].join(",") %>*/
|
50
|
+
*info = (*func_p)(<%=func_args%>);
|
51
|
+
CHECK_ERROR(*info);
|
52
|
+
}
|
53
|
+
|
54
|
+
/*<%
|
55
|
+
tp = class_name
|
56
|
+
return_type = ([tp]*(is_complex ? 3 : 4) + ["Integer"]).join(", ")
|
57
|
+
return_name = (is_complex ? "w,":"wr, wi,") + " vl, vr, info"
|
58
|
+
params = [
|
59
|
+
mat("a",:inplace),
|
60
|
+
jobe("jobvl"),
|
61
|
+
jobe("jobvr"),
|
62
|
+
opt("order"),
|
63
|
+
].select{|x| x}.join("\n ")
|
64
|
+
%>
|
65
|
+
@overload <%=name%>( a,, [jobvl:'V', jobvr:'V', order:'R'] )
|
66
|
+
<%=params%>
|
67
|
+
@return [[<%=return_name%>]] Array<<%=return_type%>>
|
68
|
+
<%=outparam(return_name)%>
|
69
|
+
|
70
|
+
<%=description%>
|
71
|
+
|
72
|
+
*/
|
73
|
+
static VALUE
|
74
|
+
<%=c_func(-1)%>(int argc, VALUE const argv[], VALUE UNUSED(mod))
|
75
|
+
{
|
76
|
+
VALUE a, ans;
|
77
|
+
int m, n;
|
78
|
+
narray_t *na1;
|
79
|
+
/*<%
|
80
|
+
aout = [
|
81
|
+
"{cT,1,shape}", !is_complex ? "{cT,1,shape}":nil,
|
82
|
+
"{cT,2,shape},{cT,2,shape},{cInt,0}"
|
83
|
+
].compact.join(",")
|
84
|
+
%>*/
|
85
|
+
size_t shape[2];
|
86
|
+
ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
|
87
|
+
ndfunc_arg_out_t aout[5-CZ] = {<%=aout%>};
|
88
|
+
ndfunc_t ndf = {&<%=c_iter%>, NO_LOOP|NDF_EXTRACT, 1, 5-CZ, ain, aout};
|
89
|
+
|
90
|
+
args_t g = {0,0,0};
|
91
|
+
VALUE opts[3] = {Qundef,Qundef,Qundef};
|
92
|
+
VALUE kw_hash = Qnil;
|
93
|
+
ID kw_table[3] = {id_order,id_jobvl,id_jobvr};
|
94
|
+
|
95
|
+
CHECK_FUNC(func_p,"<%=func_name%>");
|
96
|
+
|
97
|
+
rb_scan_args(argc, argv, "1:", &a, &kw_hash);
|
98
|
+
rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
|
99
|
+
g.order = option_order(opts[0]);
|
100
|
+
g.jobvl = option_job(opts[1],'V','N');
|
101
|
+
g.jobvr = option_job(opts[2],'V','N');
|
102
|
+
|
103
|
+
COPY_OR_CAST_TO(a,cT);
|
104
|
+
GetNArray(a, na1);
|
105
|
+
CHECK_DIM_GE(na1, 2);
|
106
|
+
m = ROW_SIZE(na1);
|
107
|
+
n = COL_SIZE(na1);
|
108
|
+
if (m != n) {
|
109
|
+
rb_raise(nary_eShapeError,"matrix must be square");
|
110
|
+
}
|
111
|
+
shape[0] = shape[1] = n;
|
112
|
+
if (g.jobvl=='N') { aout[2-CZ].dim = 0; }
|
113
|
+
if (g.jobvr=='N') { aout[3-CZ].dim = 0; }
|
114
|
+
|
115
|
+
ans = na_ndloop3(&ndf, &g, 1, a);
|
116
|
+
|
117
|
+
if (aout[3-CZ].dim == 0) { RARRAY_ASET(ans,3-CZ,Qnil); }
|
118
|
+
if (aout[2-CZ].dim == 0) { RARRAY_ASET(ans,2-CZ,Qnil); }
|
119
|
+
return ans;
|
120
|
+
}
|
121
|
+
|
122
|
+
#undef args_t
|
123
|
+
#undef func_p
|
@@ -0,0 +1,232 @@
|
|
1
|
+
/*<%
|
2
|
+
is_lss = (/gels(s|d|y)/ =~ name)
|
3
|
+
is_lsd = (/gelsd/ =~ name)
|
4
|
+
is_lsy = (/gelsy/ =~ name)
|
5
|
+
%>*/
|
6
|
+
<% %>
|
7
|
+
#define LSS <%=is_lss ? "1":"0"%>
|
8
|
+
#define LSD <%=is_lsd ? "1":"0"%>
|
9
|
+
#define LSY <%=is_lsy ? "1":"0"%>
|
10
|
+
#define args_t <%=func_name%>_args_t
|
11
|
+
#define func_p <%=func_name%>_p
|
12
|
+
|
13
|
+
typedef struct {
|
14
|
+
int order;
|
15
|
+
char trans;
|
16
|
+
rtype rcond;
|
17
|
+
} args_t;
|
18
|
+
|
19
|
+
static <%=func_name%>_t func_p = 0;
|
20
|
+
|
21
|
+
static void
|
22
|
+
<%=c_iter%>(na_loop_t * const lp)
|
23
|
+
{
|
24
|
+
dtype *a, *b;
|
25
|
+
int *info;
|
26
|
+
int m, n, nb, nrhs, lda, ldb, tmp;
|
27
|
+
args_t *g;
|
28
|
+
#if LSS
|
29
|
+
<% out_t = is_lsy ? "int" : "rtype" %>
|
30
|
+
<%=out_t%> *s; // or jpvt
|
31
|
+
int *rank;
|
32
|
+
#endif
|
33
|
+
|
34
|
+
a = (dtype*)NDL_PTR(lp,0);
|
35
|
+
b = (dtype*)NDL_PTR(lp,1);
|
36
|
+
#if LSS
|
37
|
+
s = (<%=out_t%>*)NDL_PTR(lp,2);
|
38
|
+
rank = (int*)NDL_PTR(lp,3);
|
39
|
+
#endif
|
40
|
+
info = (int*)NDL_PTR(lp,2+LSS*2);
|
41
|
+
g = (args_t*)(lp->opt_ptr);
|
42
|
+
|
43
|
+
m = NDL_SHAPE(lp,0)[0];
|
44
|
+
n = NDL_SHAPE(lp,0)[1];
|
45
|
+
SWAP_IFCOL(g->order,m,n);
|
46
|
+
lda = NDL_STEP(lp,0) / sizeof(dtype);
|
47
|
+
|
48
|
+
if (lp->args[1].ndim == 1) {
|
49
|
+
nrhs = 1;
|
50
|
+
nb = NDL_SHAPE(lp,1)[0];
|
51
|
+
ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
|
52
|
+
} else {
|
53
|
+
nb = NDL_SHAPE(lp,1)[0];
|
54
|
+
nrhs = NDL_SHAPE(lp,1)[1];
|
55
|
+
ldb = nrhs;
|
56
|
+
SWAP_IFCOL(g->order,nb,nrhs);
|
57
|
+
}
|
58
|
+
|
59
|
+
//printf("order=%d trans=%c m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,g->trans,m,n,nb,nrhs,lda,ldb);
|
60
|
+
|
61
|
+
#if LSS
|
62
|
+
*info = (*func_p)(g->order, m, n, nrhs, a, lda, b, ldb, s, g->rcond, rank);
|
63
|
+
#else
|
64
|
+
*info = (*func_p)(g->order, g->trans, m, n, nrhs, a, lda, b, ldb);
|
65
|
+
#endif
|
66
|
+
CHECK_ERROR(*info);
|
67
|
+
}
|
68
|
+
|
69
|
+
/*
|
70
|
+
<%
|
71
|
+
tp = class_name
|
72
|
+
iary = "Numo::Int"
|
73
|
+
iscal = "Integer"
|
74
|
+
if is_lsy
|
75
|
+
a = "a, b, jpvt, rcond:-1, order:'R'"
|
76
|
+
t = [tp,tp,iary,iscal,iscal]
|
77
|
+
n = "a, b, jpvt, rank, info"
|
78
|
+
elsif is_lsd
|
79
|
+
a = "a, b, rcond:-1, order:'R'"
|
80
|
+
t = [tp,tp,iscal,iscal]
|
81
|
+
n = "b, s, rank, info"
|
82
|
+
elsif is_lss
|
83
|
+
a = "a, b, rcond:-1, order:'R'"
|
84
|
+
t = [tp,tp,tp,iscal,iscal]
|
85
|
+
n = "a, b, s, rank, info"
|
86
|
+
else
|
87
|
+
a = "a, b, trans:'N', order:'R'"
|
88
|
+
t = [tp,tp,iscal]
|
89
|
+
n = "a, b, info"
|
90
|
+
end
|
91
|
+
return_type = t.join(", ")
|
92
|
+
return_name = n
|
93
|
+
args_v = a
|
94
|
+
params = [
|
95
|
+
!is_lsd && mat("a",:inplace),
|
96
|
+
mat("b",:inplace),
|
97
|
+
is_lsy && mat("jpvt",type:iary),
|
98
|
+
is_lss && "@param [Float] rcond "+
|
99
|
+
" RCOND is used to determine the effective rank of A."+
|
100
|
+
" Singular values S(i) <= RCOND*S(1) are treated as zero."+
|
101
|
+
" If RCOND < 0, machine precision is used instead.",
|
102
|
+
opt("order"),
|
103
|
+
].select{|x| x}.join("\n ")
|
104
|
+
%>
|
105
|
+
@overload <%=name%>(<%=args_v%>)
|
106
|
+
<%=params%>
|
107
|
+
@return [[<%=return_name%>]] Array<<%=return_type%>>
|
108
|
+
<%=outparam(return_name)%>
|
109
|
+
|
110
|
+
<%=description%>
|
111
|
+
|
112
|
+
*/
|
113
|
+
static VALUE
|
114
|
+
<%=c_func(-1)%>(int argc, VALUE const argv[], VALUE UNUSED(mod))
|
115
|
+
{
|
116
|
+
VALUE a, b, ans;
|
117
|
+
int m, n, nb, nrhs, tmp;
|
118
|
+
int max_mn;
|
119
|
+
narray_t *na1, *na2;
|
120
|
+
#if LSY
|
121
|
+
narray_t *na3;
|
122
|
+
VALUE jpvt;
|
123
|
+
#endif
|
124
|
+
#if LSS
|
125
|
+
size_t shape_s[1];
|
126
|
+
#endif
|
127
|
+
/*<%
|
128
|
+
ain = [
|
129
|
+
"{OVERWRITE,2},{OVERWRITE,2}", is_lss ? "{cInt,1}":nil,
|
130
|
+
].compact.join(",")
|
131
|
+
aout = [
|
132
|
+
is_lss ? "{cT,1,shape_s},{cInt,0}":nil, "{cInt,0}",
|
133
|
+
].compact.join(",")
|
134
|
+
%>*/
|
135
|
+
ndfunc_arg_in_t ain[2+LSS] = {<%=ain%>};
|
136
|
+
ndfunc_arg_out_t aout[1+LSS*2] = {<%=aout%>};
|
137
|
+
ndfunc_t ndf = {&<%=c_iter%>, NO_LOOP|NDF_EXTRACT, 2, 1+LSS*2, ain, aout};
|
138
|
+
|
139
|
+
args_t g;
|
140
|
+
VALUE opts[3] = {Qundef,Qundef,Qundef};
|
141
|
+
ID kw_table[3] = {id_order,id_trans,id_rcond};
|
142
|
+
VALUE kw_hash = Qnil;
|
143
|
+
|
144
|
+
CHECK_FUNC(func_p,"<%=func_name%>");
|
145
|
+
|
146
|
+
#if LSY
|
147
|
+
rb_scan_args(argc, argv, "3:", &a, &b, &jpvt, &kw_hash);
|
148
|
+
#else
|
149
|
+
rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
|
150
|
+
#endif
|
151
|
+
rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
|
152
|
+
g.order = option_order(opts[0]);
|
153
|
+
#if LSS
|
154
|
+
g.rcond = NUM2DBL(option_value(opts[2],DBL2NUM(-1)));
|
155
|
+
#else
|
156
|
+
g.trans = option_trans(opts[1]);
|
157
|
+
#endif
|
158
|
+
|
159
|
+
//A is DOUBLE PRECISION array, dimension (LDA,N)
|
160
|
+
//On entry, the M-by-N matrix A.
|
161
|
+
COPY_OR_CAST_TO(a,cT);
|
162
|
+
GetNArray(a, na1);
|
163
|
+
CHECK_DIM_GE(na1, 2);
|
164
|
+
|
165
|
+
//B is DOUBLE PRECISION array, dimension (LDB,NRHS)
|
166
|
+
//B is M-by-NRHS if TRANS = 'N'
|
167
|
+
// N-by-NRHS if TRANS = 'T'
|
168
|
+
COPY_OR_CAST_TO(b,cT);
|
169
|
+
GetNArray(b, na2);
|
170
|
+
CHECK_DIM_GE(na2, 1);
|
171
|
+
|
172
|
+
//The number of rows of the matrix A.
|
173
|
+
m = ROW_SIZE(na1);
|
174
|
+
//The number of columns of the matrix A.
|
175
|
+
n = COL_SIZE(na1);
|
176
|
+
max_mn = (m > n) ? m : n;
|
177
|
+
SWAP_IFCOL(g.order,m,n);
|
178
|
+
|
179
|
+
#if LSY
|
180
|
+
ndf.nin++;
|
181
|
+
ndf.nout--;
|
182
|
+
ndf.aout++;
|
183
|
+
COPY_OR_CAST_TO(jpvt,cInt);
|
184
|
+
GetNArray(jpvt, na3);
|
185
|
+
CHECK_DIM_GE(na3, 1);
|
186
|
+
{ int jpvt_sz = COL_SIZE(na3);
|
187
|
+
CHECK_INT_EQ("jpvt_size",jpvt_sz,"n",n);
|
188
|
+
}
|
189
|
+
#elif LSS
|
190
|
+
shape_s[0] = (m < n) ? m : n;
|
191
|
+
#endif
|
192
|
+
|
193
|
+
//The number of columns of the matrix B.
|
194
|
+
if (na2->ndim == 1) {
|
195
|
+
ain[1].dim = 1; // reduce dimension
|
196
|
+
nb = COL_SIZE(na2);
|
197
|
+
nrhs = 1;
|
198
|
+
} else {
|
199
|
+
//The number of rows of the matrix B.
|
200
|
+
nb = ROW_SIZE(na2);
|
201
|
+
nrhs = COL_SIZE(na2);
|
202
|
+
SWAP_IFCOL(g.order,nb,nrhs);
|
203
|
+
}
|
204
|
+
if (nb < max_mn) {
|
205
|
+
rb_raise(nary_eShapeError,
|
206
|
+
"ldb should be >= max(m,n): ldb=%d m=%d n=%d",nb,m,n);
|
207
|
+
}
|
208
|
+
|
209
|
+
// ndloop
|
210
|
+
#if LSY
|
211
|
+
ans = na_ndloop3(&ndf, &g, 3, a, b, jpvt);
|
212
|
+
#else
|
213
|
+
ans = na_ndloop3(&ndf, &g, 2, a, b);
|
214
|
+
#endif
|
215
|
+
|
216
|
+
// return
|
217
|
+
#if LSY
|
218
|
+
return rb_ary_concat(rb_ary_new3(3,a,b,jpvt),ans);
|
219
|
+
#elif LSD
|
220
|
+
rb_ary_unshift(ans,b); return ans;
|
221
|
+
#elif LSS
|
222
|
+
return rb_ary_concat(rb_ary_new3(2,a,b),ans);
|
223
|
+
#else
|
224
|
+
return rb_ary_new3(3,a,b,ans);
|
225
|
+
#endif
|
226
|
+
}
|
227
|
+
|
228
|
+
#undef func_p
|
229
|
+
#undef args_t
|
230
|
+
#undef LSS
|
231
|
+
#undef LSD
|
232
|
+
#undef LSY
|