numo-linalg 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +80 -0
  4. data/Rakefile +18 -0
  5. data/ext/numo/linalg/blas/blas.c +352 -0
  6. data/ext/numo/linalg/blas/cblas.h +575 -0
  7. data/ext/numo/linalg/blas/cblas_t.h +563 -0
  8. data/ext/numo/linalg/blas/depend.erb +23 -0
  9. data/ext/numo/linalg/blas/extconf.rb +67 -0
  10. data/ext/numo/linalg/blas/gen/cogen.rb +72 -0
  11. data/ext/numo/linalg/blas/gen/decl.rb +203 -0
  12. data/ext/numo/linalg/blas/gen/desc.rb +8138 -0
  13. data/ext/numo/linalg/blas/gen/erbpp2.rb +339 -0
  14. data/ext/numo/linalg/blas/gen/replace_cblas_h.rb +27 -0
  15. data/ext/numo/linalg/blas/gen/spec.rb +93 -0
  16. data/ext/numo/linalg/blas/numo_blas.h +41 -0
  17. data/ext/numo/linalg/blas/tmpl/axpy.c +75 -0
  18. data/ext/numo/linalg/blas/tmpl/copy.c +57 -0
  19. data/ext/numo/linalg/blas/tmpl/def_c.c +3 -0
  20. data/ext/numo/linalg/blas/tmpl/def_d.c +3 -0
  21. data/ext/numo/linalg/blas/tmpl/def_s.c +3 -0
  22. data/ext/numo/linalg/blas/tmpl/def_z.c +3 -0
  23. data/ext/numo/linalg/blas/tmpl/dot.c +68 -0
  24. data/ext/numo/linalg/blas/tmpl/ger.c +114 -0
  25. data/ext/numo/linalg/blas/tmpl/init_class.c +20 -0
  26. data/ext/numo/linalg/blas/tmpl/init_module.c +12 -0
  27. data/ext/numo/linalg/blas/tmpl/lib.c +40 -0
  28. data/ext/numo/linalg/blas/tmpl/mm.c +214 -0
  29. data/ext/numo/linalg/blas/tmpl/module.c +9 -0
  30. data/ext/numo/linalg/blas/tmpl/mv.c +194 -0
  31. data/ext/numo/linalg/blas/tmpl/nrm2.c +79 -0
  32. data/ext/numo/linalg/blas/tmpl/rot.c +65 -0
  33. data/ext/numo/linalg/blas/tmpl/rotm.c +82 -0
  34. data/ext/numo/linalg/blas/tmpl/scal.c +69 -0
  35. data/ext/numo/linalg/blas/tmpl/sdsdot.c +77 -0
  36. data/ext/numo/linalg/blas/tmpl/set_prefix.c +16 -0
  37. data/ext/numo/linalg/blas/tmpl/swap.c +57 -0
  38. data/ext/numo/linalg/blas/tmpl/syr.c +102 -0
  39. data/ext/numo/linalg/blas/tmpl/syr2.c +110 -0
  40. data/ext/numo/linalg/blas/tmpl/syr2k.c +129 -0
  41. data/ext/numo/linalg/blas/tmpl/syrk.c +132 -0
  42. data/ext/numo/linalg/lapack/depend.erb +23 -0
  43. data/ext/numo/linalg/lapack/extconf.rb +45 -0
  44. data/ext/numo/linalg/lapack/gen/cogen.rb +74 -0
  45. data/ext/numo/linalg/lapack/gen/desc.rb +151278 -0
  46. data/ext/numo/linalg/lapack/gen/replace_lapacke_h.rb +32 -0
  47. data/ext/numo/linalg/lapack/gen/spec.rb +104 -0
  48. data/ext/numo/linalg/lapack/lapack.c +387 -0
  49. data/ext/numo/linalg/lapack/lapacke.h +16425 -0
  50. data/ext/numo/linalg/lapack/lapacke_config.h +119 -0
  51. data/ext/numo/linalg/lapack/lapacke_mangling.h +17 -0
  52. data/ext/numo/linalg/lapack/lapacke_t.h +10550 -0
  53. data/ext/numo/linalg/lapack/numo_lapack.h +42 -0
  54. data/ext/numo/linalg/lapack/tmpl/def_c.c +3 -0
  55. data/ext/numo/linalg/lapack/tmpl/def_d.c +7 -0
  56. data/ext/numo/linalg/lapack/tmpl/def_s.c +7 -0
  57. data/ext/numo/linalg/lapack/tmpl/def_z.c +3 -0
  58. data/ext/numo/linalg/lapack/tmpl/fact.c +179 -0
  59. data/ext/numo/linalg/lapack/tmpl/geev.c +123 -0
  60. data/ext/numo/linalg/lapack/tmpl/gels.c +232 -0
  61. data/ext/numo/linalg/lapack/tmpl/gesv.c +149 -0
  62. data/ext/numo/linalg/lapack/tmpl/gesvd.c +189 -0
  63. data/ext/numo/linalg/lapack/tmpl/ggev.c +138 -0
  64. data/ext/numo/linalg/lapack/tmpl/gqr.c +121 -0
  65. data/ext/numo/linalg/lapack/tmpl/init_class.c +20 -0
  66. data/ext/numo/linalg/lapack/tmpl/init_module.c +12 -0
  67. data/ext/numo/linalg/lapack/tmpl/lange.c +79 -0
  68. data/ext/numo/linalg/lapack/tmpl/lib.c +40 -0
  69. data/ext/numo/linalg/lapack/tmpl/module.c +9 -0
  70. data/ext/numo/linalg/lapack/tmpl/syev.c +91 -0
  71. data/ext/numo/linalg/lapack/tmpl/sygv.c +104 -0
  72. data/ext/numo/linalg/lapack/tmpl/trf.c +276 -0
  73. data/ext/numo/linalg/numo_linalg.h +115 -0
  74. data/lib/numo/linalg.rb +3 -0
  75. data/lib/numo/linalg/function.rb +1008 -0
  76. data/lib/numo/linalg/linalg.rb +7 -0
  77. data/lib/numo/linalg/loader.rb +174 -0
  78. data/lib/numo/linalg/use/atlas.rb +3 -0
  79. data/lib/numo/linalg/use/lapack.rb +3 -0
  80. data/lib/numo/linalg/use/mkl.rb +3 -0
  81. data/lib/numo/linalg/use/openblas.rb +3 -0
  82. data/lib/numo/linalg/version.rb +5 -0
  83. data/numo-linalg.gemspec +26 -0
  84. data/spec/lapack_spec.rb +13 -0
  85. metadata +172 -0
@@ -0,0 +1,65 @@
1
+ #define func_p <%=func_name%>_p
2
+
3
+ static <%=func_name%>_t func_p = 0;
4
+
5
+ static void
6
+ <%=c_iter%>(na_loop_t *const lp)
7
+ {
8
+ char *p1, *p2;
9
+ size_t n;
10
+ ssize_t s1, s2;
11
+ rtype *g;
12
+
13
+ INIT_COUNTER(lp,n);
14
+ INIT_PTR(lp,0,p1,s1);
15
+ INIT_PTR(lp,1,p2,s2);
16
+ g = (rtype*)(lp->opt_ptr);
17
+
18
+ (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
19
+ (dtype*)p2, s2/sizeof(dtype), g[0], g[1]);
20
+ }
21
+
22
+ /*<%
23
+ params = [
24
+ vec("x",:inplace),
25
+ vec("y",:inplace),
26
+ ].select{|x| x}.join("\n ")
27
+ %>
28
+ @overload <%=name%>( x, y, c, s )
29
+ <%=params%>
30
+ @param [Float] c
31
+ @param [Float] s
32
+ @return [Array<<%=class_name%>,<%=class_name%>>] returns [x,y]
33
+
34
+ <%=description%>
35
+
36
+ */
37
+ static VALUE
38
+ <%=c_func(4)%>(VALUE UNUSED(mod), VALUE x, VALUE y, VALUE c, VALUE s)
39
+ {
40
+ rtype g[2] = {0,0};
41
+ narray_t *na1, *na2;
42
+ ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{OVERWRITE,0}};
43
+ ndfunc_t ndf = {<%=c_iter%>, STRIDE_LOOP, 2,0, ain,0};
44
+
45
+ CHECK_FUNC(func_p,"<%=func_name%>");
46
+
47
+ if (RTEST(c)) {g[0] = NUM2DBL(c);}
48
+ if (RTEST(s)) {g[1] = NUM2DBL(s);}
49
+
50
+ COPY_OR_CAST_TO(x,cT);
51
+ COPY_OR_CAST_TO(y,cT);
52
+ GetNArray(x,na1);
53
+ GetNArray(y,na2);
54
+ CHECK_DIM_GE(na1,1);
55
+ CHECK_DIM_GE(na2,1);
56
+ CHECK_NON_EMPTY(na1);
57
+ CHECK_NON_EMPTY(na2);
58
+ CHECK_SAME_SHAPE(na1,na2);
59
+
60
+ na_ndloop3(&ndf, g, 2, x, y);
61
+
62
+ return rb_assoc_new(x,y);
63
+ }
64
+
65
+ #undef func_p
@@ -0,0 +1,82 @@
1
+ #define func_p <%=func_name%>_p
2
+
3
+ static <%=func_name%>_t func_p = 0;
4
+
5
+ static void
6
+ <%=c_iter%>(na_loop_t *const lp)
7
+ {
8
+ char *p1, *p2;
9
+ size_t n;
10
+ ssize_t s1, s2;
11
+ dtype *g;
12
+
13
+ INIT_COUNTER(lp,n);
14
+ INIT_PTR(lp,0,p1,s1);
15
+ INIT_PTR(lp,1,p2,s2);
16
+ g = (dtype*)(lp->opt_ptr);
17
+
18
+ (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
19
+ (dtype*)p2, s2/sizeof(dtype), g);
20
+ }
21
+
22
+ /*<%
23
+ params = [
24
+ vec("x",:inplace),
25
+ vec("y",:inplace),
26
+ ].select{|x| x}.join("\n ")
27
+ %>
28
+ @overload <%=name%>( x, y, param )
29
+ <%=params%>
30
+ @param param [<%=class_name%>] array of [FLAG,H11,H21,H12,H22]
31
+ @return [Array<<%=class_name%>,<%=class_name%>>] returns [x,y]
32
+
33
+ Apply the modified givens transformation, H,
34
+ to the 2 by N matrix (X\*\*T), where \*\*T indicates transpose.
35
+ The elements of X are in (Y\*\*T)
36
+
37
+ X(LX+I\*INCX), I = 0 to N-1, where LX = 1 if INCX .GE. 0, else
38
+ LX = (-INCX)\*N, and similarly for Y using LY and INCY.
39
+ With PARAM(1)=FLAG, H has one of the following forms..
40
+
41
+ FLAG=-1.0 FLAG=0.0 FLAG=1.0 FLAG=-2.0
42
+
43
+ (H11 H12) (1.0 H12) (H11 1.0) (1.0 0.0)
44
+ H=( ) ( ) ( ) ( )
45
+ (H21 H22), (H21 1.0), (-1.0 H22), (0.0 1.0).
46
+
47
+ see <%=name.upcase%>G for a description of data storage in param.
48
+
49
+ */
50
+ static VALUE
51
+ <%=c_func(3)%>(VALUE UNUSED(mod), VALUE x, VALUE y, VALUE param)
52
+ {
53
+ dtype *g;
54
+ narray_t *na1, *na2, *nap;
55
+ ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{OVERWRITE,0}};
56
+ ndfunc_t ndf = {<%=c_iter%>, STRIDE_LOOP, 2,0, ain,0};
57
+
58
+ CHECK_FUNC(func_p,"<%=func_name%>");
59
+
60
+ COPY_OR_CAST_TO(x,cT);
61
+ COPY_OR_CAST_TO(y,cT);
62
+ GetNArray(x,na1);
63
+ GetNArray(y,na2);
64
+ CHECK_DIM_GE(na1,1);
65
+ CHECK_DIM_GE(na2,1);
66
+ CHECK_NON_EMPTY(na1);
67
+ CHECK_NON_EMPTY(na2);
68
+ CHECK_SAME_SHAPE(na1,na2);
69
+
70
+ param = rb_funcall(cT,rb_intern("cast"),1,param);
71
+ GetNArray(param,nap);
72
+ CHECK_DIM_EQ(nap,1);
73
+ CHECK_SIZE_GE(nap,5);
74
+ g = (dtype*)nary_get_pointer_for_read(param);
75
+
76
+ na_ndloop3(&ndf, g, 2, x, y);
77
+
78
+ RB_GC_GUARD(param);
79
+ return rb_assoc_new(x,y);
80
+ }
81
+
82
+ #undef func_p
@@ -0,0 +1,69 @@
1
+ #define func_p <%=func_name%>_p
2
+
3
+ static <%=func_name%>_t func_p = 0;
4
+
5
+ <% if /^(cs|zd)scal/ =~ name %>
6
+ #define scal_t rtype
7
+ <% else %>
8
+ #define scal_t dtype
9
+ <% end %>
10
+
11
+ static void
12
+ <%=c_iter%>(na_loop_t *const lp)
13
+ {
14
+ char *p1;
15
+ size_t n;
16
+ ssize_t s1;
17
+ scal_t *g;
18
+
19
+ INIT_COUNTER(lp,n);
20
+ INIT_PTR(lp,0,p1,s1);
21
+ g = (scal_t*)(lp->opt_ptr);
22
+
23
+ <% if /^[cz]scal/ =~ name %>
24
+ (*func_p)(n, g, (dtype*)p1, s1/sizeof(dtype));
25
+ <% else %>
26
+ (*func_p)(n, *g, (dtype*)p1, s1/sizeof(dtype));
27
+ <% end %>
28
+ }
29
+
30
+ /*<%
31
+ params = [
32
+ vec("x"),
33
+ ].select{|x| x}.join("\n ")
34
+ %>
35
+ @overload <%=name%>( a, x )
36
+ @param [Float] a scale factor
37
+ <%=params%>
38
+ @return [<%=class_name%>] returns a*x.
39
+
40
+ <%=description%>
41
+
42
+ */
43
+ static VALUE
44
+ <%=c_func(2)%>(VALUE mod, VALUE a, VALUE x)
45
+ {
46
+ scal_t g[1];
47
+ narray_t *na1;
48
+ ndfunc_arg_in_t ain[1] = {{OVERWRITE,0}};
49
+ ndfunc_t ndf = {<%=c_iter%>, STRIDE_LOOP, 1,0, ain,0};
50
+
51
+ CHECK_FUNC(func_p,"<%=func_name%>");
52
+
53
+ <% if /^(cs|zd)scal/ =~ name %>
54
+ if (RTEST(a)) {g[0] = NUM2DBL(a);} else {g[0]=1;}
55
+ <% else %>
56
+ if (RTEST(a)) {g[0] = m_num_to_data(a);} else {g[0]=m_one;}
57
+ <% end %>
58
+ COPY_OR_CAST_TO(x,cT);
59
+ GetNArray(x,na1);
60
+ CHECK_DIM_GE(na1,1);
61
+ CHECK_NON_EMPTY(na1);
62
+
63
+ na_ndloop3(&ndf, g, 1, x);
64
+
65
+ return x;
66
+ }
67
+
68
+ #undef func_p
69
+ #undef scal_t
@@ -0,0 +1,77 @@
1
+ #define func_p <%=func_name%>_p
2
+
3
+ static <%=func_name%>_t func_p = 0;
4
+
5
+ static void
6
+ <%=c_iter%>(na_loop_t *const lp)
7
+ {
8
+ char *p1, *p2, *p3;
9
+ size_t n;
10
+ ssize_t s1, s2;
11
+ dtype *g;
12
+
13
+ INIT_PTR(lp,0,p1,s1);
14
+ INIT_PTR(lp,1,p2,s2);
15
+ p3 = NDL_PTR(lp,2);
16
+ n = NDL_SHAPE(lp,0)[0];
17
+ g = (dtype*)(lp->opt_ptr);
18
+
19
+ *(dtype*)p3 = (*func_p)(n, *g, (dtype*)p1, s1/sizeof(dtype),
20
+ (dtype*)p2, s2/sizeof(dtype));
21
+ }
22
+
23
+ /*<%
24
+ params = [
25
+ vec("sx"),
26
+ vec("sy",:inplace),
27
+ ].select{|x| x}.join("\n ")
28
+ %>
29
+ @overload <%=name%>( sx, sy, [sb:0] )
30
+ <%=params%>
31
+ @param [Float] sb
32
+ @return [<%=class_name%>] returns inner product.
33
+
34
+ Compute the inner product of two vectors with extended
35
+ precision accumulation.
36
+
37
+ Returns S.P. result with dot product accumulated in D.P.
38
+ SDSDOT = SB + sum for I = 0 to N-1 of SX(LX+I*INCX)*SY(LY+I*INCY),
39
+ where LX = 1 if INCX .GE. 0, else LX = 1+(1-N)*INCX, and LY is
40
+ defined in a similar way using INCY.
41
+
42
+ */
43
+ static VALUE
44
+ <%=c_func(-1)%>(int argc, VALUE const argv[], VALUE UNUSED(mod))
45
+ {
46
+ VALUE x, y, sb;
47
+ dtype g[1];
48
+ narray_t *na1, *na2;
49
+ size_t nx, ny;
50
+ ndfunc_arg_in_t ain[2] = {{cT,1},{cT,1}};
51
+ ndfunc_arg_out_t aout[1] = {{cT,0}};
52
+ ndfunc_t ndf = {<%=c_iter%>, NDF_EXTRACT, 2,1, ain,aout};
53
+
54
+ VALUE kw_hash = Qnil;
55
+ ID kw_table[1] = {id_sb};
56
+ VALUE opts[1] = {Qundef};
57
+
58
+ CHECK_FUNC(func_p,"<%=func_name%>");
59
+
60
+ rb_scan_args(argc, argv, "2:", &x, &y, &kw_hash);
61
+ rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
62
+ sb = option_value(opts[0],Qnil);
63
+ g[0] = RTEST(sb) ? m_num_to_data(sb) : m_zero;
64
+
65
+ GetNArray(x,na1);
66
+ GetNArray(y,na2);
67
+ CHECK_DIM_GE(na1,1);
68
+ CHECK_DIM_GE(na2,1);
69
+ CHECK_NON_EMPTY(na1);
70
+ CHECK_NON_EMPTY(na2);
71
+ nx = na1->shape[na1->ndim-1];
72
+ ny = na2->shape[na2->ndim-1];
73
+ CHECK_SIZE_EQ(nx,ny);
74
+
75
+ return na_ndloop3(&ndf, g, 2, x, y);
76
+ }
77
+ #undef func_p
@@ -0,0 +1,16 @@
1
+ static VALUE
2
+ <%=c_func(1)%>(VALUE mod, VALUE prefix)
3
+ {
4
+ long len;
5
+
6
+ if (TYPE(prefix) != T_STRING) {
7
+ rb_raise(rb_eTypeError,"argument must be string");
8
+ }
9
+ if (blas_prefix) {
10
+ free(blas_prefix);
11
+ }
12
+ len = RSTRING_LEN(prefix);
13
+ blas_prefix = malloc(len+1);
14
+ strcpy(blas_prefix, StringValueCStr(prefix));
15
+ return prefix;
16
+ }
@@ -0,0 +1,57 @@
1
+ #define func_p <%=func_name%>_p
2
+
3
+ static <%=func_name%>_t func_p = 0;
4
+
5
+ static void
6
+ <%=c_iter%>(na_loop_t *const lp)
7
+ {
8
+ char *p1, *p2;
9
+ size_t n;
10
+ ssize_t s1, s2;
11
+
12
+ INIT_COUNTER(lp,n);
13
+ INIT_PTR(lp,0,p1,s1);
14
+ INIT_PTR(lp,1,p2,s2);
15
+
16
+ (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
17
+ (dtype*)p2, s2/sizeof(dtype));
18
+ }
19
+
20
+ /*<%
21
+ params = [
22
+ vec("x"),
23
+ vec("y"),
24
+ ].select{|x| x}.join("\n ")
25
+ %>
26
+ @overload <%=name%>( x, y )
27
+ <%=params%>
28
+ @return [nil]
29
+
30
+ <%=description%>
31
+
32
+ */
33
+ static VALUE
34
+ <%=c_func(2)%>(VALUE UNUSED(mod), VALUE x, VALUE y)
35
+ {
36
+ narray_t *na1, *na2;
37
+ ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{OVERWRITE,0}};
38
+ ndfunc_t ndf = {<%=c_iter%>, STRIDE_LOOP, 2,0, ain,0};
39
+
40
+ CHECK_FUNC(func_p,"<%=func_name%>");
41
+
42
+ CHECK_NARRAY_TYPE(x,cT);
43
+ CHECK_NARRAY_TYPE(y,cT);
44
+ GetNArray(x,na1);
45
+ GetNArray(y,na2);
46
+ CHECK_DIM_GE(na1,1);
47
+ CHECK_DIM_GE(na2,1);
48
+ CHECK_NON_EMPTY(na1);
49
+ CHECK_NON_EMPTY(na2);
50
+ CHECK_SAME_SHAPE(na1,na2);
51
+
52
+ na_ndloop(&ndf, 2, x, y);
53
+
54
+ return Qnil;
55
+ }
56
+
57
+ #undef func_p
@@ -0,0 +1,102 @@
1
+ #define args_t <%=name%>_args_t
2
+
3
+ typedef struct {
4
+ enum CBLAS_ORDER order;
5
+ enum CBLAS_UPLO uplo;
6
+ rtype alpha;
7
+ } args_t;
8
+
9
+ #define func_p <%=func_name%>_p
10
+
11
+ static <%=func_name%>_t func_p = 0;
12
+
13
+ static void
14
+ <%=c_iter%>(na_loop_t *const lp)
15
+ {
16
+ dtype *a;
17
+ char *p1;
18
+ ssize_t s1;
19
+ args_t *g;
20
+ blasint n, lda;
21
+
22
+ INIT_PTR(lp,0,p1,s1);
23
+ a = (dtype*)NDL_PTR(lp,1);
24
+ g = (args_t*)(lp->opt_ptr);
25
+
26
+ n = NDL_SHAPE(lp,0)[0];
27
+ lda = NDL_STEP(lp,1) / sizeof(dtype);
28
+
29
+ (*func_p)(g->order, g->uplo, n, g->alpha,
30
+ (dtype*)p1, s1/sizeof(dtype), a, lda);
31
+ }
32
+
33
+ /*<%
34
+ params = [
35
+ vec("x"),
36
+ mat("a",:inplace),
37
+ opt("alpha"),
38
+ opt("uplo"),
39
+ opt("order")
40
+ ].select{|x| x}.join("\n ")
41
+ %>
42
+ @overload <%=name%>( x, [a, alpha:1, uplo:'U', order:'R'] )
43
+ <%=params%>
44
+ @return [<%=class_name%>] return a
45
+ <%=description%>
46
+
47
+ */
48
+ static VALUE
49
+ <%=c_func(-1)%>(int argc, VALUE const argv[], VALUE UNUSED(mod))
50
+ {
51
+ VALUE ans;
52
+ VALUE x, a, alpha;
53
+ narray_t *na1, *na3;
54
+ blasint nx, na;
55
+ size_t shape[2];
56
+ ndfunc_arg_in_t ain[3] = {{cT,1},{OVERWRITE,2},{sym_init,0}};
57
+ ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
58
+ ndfunc_t ndf = {<%=c_iter%>, NO_LOOP, 2, 0, ain, aout};
59
+
60
+ args_t g;
61
+ VALUE kw_hash = Qnil;
62
+ ID kw_table[3] = {id_alpha,id_order,id_uplo};
63
+ VALUE opts[3] = {Qundef,Qundef,Qundef};
64
+
65
+ CHECK_FUNC(func_p,"<%=func_name%>");
66
+
67
+ rb_scan_args(argc, argv, "11:", &x, &a, &kw_hash);
68
+ rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
69
+ alpha = option_value(opts[0],Qnil);
70
+ g.alpha = RTEST(alpha) ? NUM2DBL(alpha) : 1;
71
+ g.order = option_order(opts[1]);
72
+ g.uplo = option_uplo(opts[2]);
73
+
74
+ GetNArray(x,na1);
75
+ CHECK_DIM_GE(na1,1);
76
+ nx = COL_SIZE(na1); // n
77
+
78
+ if (a == Qnil) { // c is not given.
79
+ ndf.nout = 1;
80
+ ain[1] = ain[2];
81
+ a = INT2FIX(0);
82
+ shape[0] = shape[1] = nx;
83
+ } else {
84
+ COPY_OR_CAST_TO(a,cT);
85
+ GetNArray(a,na3);
86
+ CHECK_DIM_GE(na3,2);
87
+ CHECK_SQUARE("a",na3);
88
+ na = COL_SIZE(na3); // n (lda)
89
+ CHECK_SIZE_EQ(na,nx);
90
+ }
91
+
92
+ ans = na_ndloop3(&ndf, &g, 2, x, a);
93
+
94
+ if (ndf.nout == 1) { // a is not given.
95
+ return ans;
96
+ } else {
97
+ return a;
98
+ }
99
+ }
100
+
101
+ #undef func_p
102
+ #undef args_t