
#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/lib.c"
/*
  BLAS wrapper for Ruby/Numo
    (C) Copyright 2017 by Masahiro TANAKA

  This program is free software.
  NO WARRANTY.
*/

#include <assert.h>
#include <ruby.h>
#include "numo/narray.h"
#include "numo/template.h"
#include "numo_blas.h"

static ID id_alpha;
static ID id_axis;
static ID id_beta;
static ID id_diag;
static ID id_keepdims;
static ID id_order;
static ID id_sb;
static ID id_side;
static ID id_trans;
static ID id_transa;
static ID id_transb;
static ID id_uplo;



#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/module.c"
/*
  module definition: Numo::Linalg
*/

#line 6 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/module.c"
static VALUE mLinalg;




#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/module.c"
/*
  module definition: Numo::Linalg::Blas
*/

#line 6 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/module.c"
static VALUE mBlas;


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/def_d.c"
#include "numo/types/dfloat.h"

#define DP(a) (a)


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/dot.c"
#define func_p ddot_p

static ddot_t func_p = 0;

#undef result_dtype
#define result_dtype double

static void
iter_blas_s_ddot(na_loop_t *const lp)
{
    char *p1, *p2, *p3;
    size_t n;
    ssize_t s1, s2;

    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);
    p3 = NDL_PTR(lp,2);
    n  = NDL_SHAPE(lp,0)[0];

  
#line 24 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/dot.c"
    *(result_dtype*)p3 = (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
                                      (dtype*)p2, s2/sizeof(dtype));
  
}

/*
  @overload ddot( x, y )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray).
  @return [Numo::DFloat] op(x) dot y

DDOT forms the dot product of two vectors.
uses unrolled loops for increments equal to one.

*/
static VALUE
blas_s_ddot(VALUE mod, VALUE x, VALUE y)
{
    VALUE     ans;
    narray_t *na1, *na2;
    size_t    nx, ny, shape[1]={1};
    ndfunc_arg_in_t ain[2] = {{cT,1},{cT,1}};
    ndfunc_arg_out_t aout[1] = {{numo_cDFloat,0,shape}};
    ndfunc_t ndf = {iter_blas_s_ddot, NDF_EXTRACT, 2,1, ain,aout};

    CHECK_FUNC(func_p,"ddot");

    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    CHECK_NON_EMPTY(na1);
    CHECK_NON_EMPTY(na2);
    nx = COL_SIZE(na1);
    ny = COL_SIZE(na2);
    CHECK_SIZE_EQ(nx,ny);

    ans = na_ndloop(&ndf, 2, x, y);

    return ans;
}
#undef func_p


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/nrm2.c"
#define func_p dnrm2_p

static dnrm2_t func_p = 0;

#undef result_dtype
#define result_dtype double

static void
iter_blas_s_dnrm2(na_loop_t *const lp)
{
    char *p1, *p2;
    size_t n;
    ssize_t s1;

    INIT_PTR(lp,0,p1,s1);
    p2 = NDL_PTR(lp,1);
    n  = NDL_SHAPE(lp,0)[0];

    *(result_dtype*)p2 = (*func_p)(n, (dtype*)p1, s1/sizeof(dtype));
}

/*

  @overload dnrm2( x )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param keepdims [String or Symbol]  
  @return [Numo::DFloat] euclidean norm of x

DNRM2 returns the euclidean norm of a vector via the function
name, so that

        DNRM2 := sqrt( x'*x )

*/
static VALUE
blas_s_dnrm2(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     x, keepdims, ans;
    narray_t *na1;
    ndfunc_arg_in_t ain[1] = {{cT,1}};
    ndfunc_arg_out_t aout[1] = {{cT,0}};
    ndfunc_t ndf = {iter_blas_s_dnrm2, NDF_EXTRACT, 1,1, ain,aout};

    VALUE opts[1] = {Qundef};
    ID    kw_table[1] = {id_keepdims};
    VALUE kw_hash = Qnil;

    CHECK_FUNC(func_p,"dnrm2");

    rb_scan_args(argc, argv, "1:", &x, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
    keepdims = option_value(opts[0],Qfalse);

    if (RTEST(keepdims)) {
        ndf.flag |= NDF_KEEP_DIM;
    }

    GetNArray(x,na1);
    CHECK_DIM_GE(na1,1);
    CHECK_NON_EMPTY(na1);

    ans = na_ndloop(&ndf, 1, x);

    return ans;
}

#undef func_p


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/nrm2.c"
#define func_p dasum_p

static dasum_t func_p = 0;

#undef result_dtype
#define result_dtype double

static void
iter_blas_s_dasum(na_loop_t *const lp)
{
    char *p1, *p2;
    size_t n;
    ssize_t s1;

    INIT_PTR(lp,0,p1,s1);
    p2 = NDL_PTR(lp,1);
    n  = NDL_SHAPE(lp,0)[0];

    *(result_dtype*)p2 = (*func_p)(n, (dtype*)p1, s1/sizeof(dtype));
}

/*

  @overload dasum( x )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param keepdims [String or Symbol]  
  @return [Numo::DFloat] euclidean norm of x

DASUM takes the sum of the absolute values.

*/
static VALUE
blas_s_dasum(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     x, keepdims, ans;
    narray_t *na1;
    ndfunc_arg_in_t ain[1] = {{cT,1}};
    ndfunc_arg_out_t aout[1] = {{cT,0}};
    ndfunc_t ndf = {iter_blas_s_dasum, NDF_EXTRACT, 1,1, ain,aout};

    VALUE opts[1] = {Qundef};
    ID    kw_table[1] = {id_keepdims};
    VALUE kw_hash = Qnil;

    CHECK_FUNC(func_p,"dasum");

    rb_scan_args(argc, argv, "1:", &x, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
    keepdims = option_value(opts[0],Qfalse);

    if (RTEST(keepdims)) {
        ndf.flag |= NDF_KEEP_DIM;
    }

    GetNArray(x,na1);
    CHECK_DIM_GE(na1,1);
    CHECK_NON_EMPTY(na1);

    ans = na_ndloop(&ndf, 1, x);

    return ans;
}

#undef func_p


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/swap.c"
#define func_p dswap_p

static dswap_t func_p = 0;

static void
iter_blas_s_dswap(na_loop_t *const lp)
{
    char *p1, *p2;
    size_t n;
    ssize_t s1, s2;

    INIT_COUNTER(lp,n);
    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);

    (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
                 (dtype*)p2, s2/sizeof(dtype));
}

/*
  @overload dswap( x, y )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray).
  @return [nil]

interchanges two vectors.
uses unrolled loops for increments equal one.

*/
static VALUE
blas_s_dswap(VALUE UNUSED(mod), VALUE x, VALUE y)
{
    narray_t *na1, *na2;
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{OVERWRITE,0}};
    ndfunc_t ndf = {iter_blas_s_dswap, STRIDE_LOOP, 2,0, ain,0};

    CHECK_FUNC(func_p,"dswap");

    CHECK_NARRAY_TYPE(x,cT);
    CHECK_NARRAY_TYPE(y,cT);
    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    CHECK_NON_EMPTY(na1);
    CHECK_NON_EMPTY(na2);
    CHECK_SAME_SHAPE(na1,na2);

    na_ndloop(&ndf, 2, x, y);

    return Qnil;
}

#undef func_p


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/copy.c"
#define func_p dcopy_p

static dcopy_t func_p = 0;

static void
iter_blas_s_dcopy(na_loop_t *const lp)
{
    char *p1, *p2;
    size_t n;
    ssize_t s1, s2;

    INIT_COUNTER(lp,n);
    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);

    (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
                 (dtype*)p2, s2/sizeof(dtype));
}

/*
  @overload dcopy( x, y )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray).
  @return [nil]

DCOPY copies a vector, x, to a vector, y.
uses unrolled loops for increments equal to one.

*/
static VALUE
blas_s_dcopy(VALUE UNUSED(mod), VALUE x, VALUE y)
{
    narray_t *na1, *na2;
    ndfunc_arg_in_t ain[2] = {{cT,0},{OVERWRITE,0}};
    ndfunc_t ndf = {iter_blas_s_dcopy, STRIDE_LOOP, 2,0, ain,0};

    CHECK_FUNC(func_p,"dcopy");

    CHECK_NARRAY_TYPE(x,cT);
    CHECK_NARRAY_TYPE(y,cT);
    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    CHECK_NON_EMPTY(na1);
    CHECK_NON_EMPTY(na2);
    CHECK_SAME_SHAPE(na1,na2);

    na_ndloop(&ndf, 2, x, y);

    return Qnil;
}

#undef func_p


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/axpy.c"
#define args_t daxpy_args_t

typedef struct {
    dtype alpha;
} args_t;

#define func_p daxpy_p
static daxpy_t func_p = 0;

static void
iter_blas_s_daxpy(na_loop_t *const lp)
{
    char   *p1, *p2;
    size_t  n;
    ssize_t s1, s2;
    dtype  *g;

    INIT_COUNTER(lp,n);
    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);
    g = (dtype*)(lp->opt_ptr);

    (*func_p)(n, DP(*g), (dtype*)p1, s1/sizeof(dtype),
                         (dtype*)p2, s2/sizeof(dtype));
}

/*
  @overload daxpy( x, y, [alpha:1] )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @return [Numo::DFloat] y = alpha * x + y

DAXPY constant times a vector plus a vector.
uses unrolled loops for increments equal to one.

*/
static VALUE
blas_s_daxpy(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE x, y, alpha;
    narray_t *na1, *na2;
    ndfunc_arg_in_t ain[2] = {{cT,0},{OVERWRITE,0}};
    ndfunc_t ndf = {iter_blas_s_daxpy, STRIDE_LOOP, 2, 0, ain, 0};

    dtype g;
    VALUE kw_hash = Qnil;
    ID kw_table[1] = {id_alpha};
    VALUE opts[1] = {Qundef};

    CHECK_FUNC(func_p,"daxpy");

    rb_scan_args(argc, argv, "2:", &x, &y, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
    alpha = option_value(opts[0],Qnil);
    g     = RTEST(alpha) ? m_num_to_data(alpha) : m_one;

    COPY_OR_CAST_TO(y,cT);
    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    CHECK_NON_EMPTY(na1);
    CHECK_NON_EMPTY(na2);
    CHECK_SAME_SHAPE(na1,na2);

    na_ndloop3(&ndf, &g, 2, x, y);
    return y;
}

#undef func_p
#undef args_t


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/rot.c"
#define func_p drot_p

static drot_t func_p = 0;

static void
iter_blas_s_drot(na_loop_t *const lp)
{
    char *p1, *p2;
    size_t n;
    ssize_t s1, s2;
    rtype  *g;

    INIT_COUNTER(lp,n);
    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);
    g = (rtype*)(lp->opt_ptr);

    (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
                 (dtype*)p2, s2/sizeof(dtype), g[0], g[1]);
}

/*
  @overload drot( x, y, c, s )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed).
  @param [Float] c
  @param [Float] s
  @return [Array<Numo::DFloat,Numo::DFloat>] returns [x,y]

DROT applies a plane rotation.

*/
static VALUE
blas_s_drot(VALUE UNUSED(mod), VALUE x, VALUE y, VALUE c, VALUE s)
{
    rtype g[2] = {0,0};
    narray_t *na1, *na2;
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{OVERWRITE,0}};
    ndfunc_t ndf = {iter_blas_s_drot, STRIDE_LOOP, 2,0, ain,0};

    CHECK_FUNC(func_p,"drot");

    if (RTEST(c)) {g[0] = NUM2DBL(c);}
    if (RTEST(s)) {g[1] = NUM2DBL(s);}

    COPY_OR_CAST_TO(x,cT);
    COPY_OR_CAST_TO(y,cT);
    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    CHECK_NON_EMPTY(na1);
    CHECK_NON_EMPTY(na2);
    CHECK_SAME_SHAPE(na1,na2);

    na_ndloop3(&ndf, g, 2, x, y);

    return rb_assoc_new(x,y);
}

#undef func_p


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/rotm.c"
#define func_p drotm_p

static drotm_t func_p = 0;

static void
iter_blas_s_drotm(na_loop_t *const lp)
{
    char *p1, *p2;
    size_t n;
    ssize_t s1, s2;
    dtype  *g;

    INIT_COUNTER(lp,n);
    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);
    g = (dtype*)(lp->opt_ptr);

    (*func_p)(n, (dtype*)p1, s1/sizeof(dtype),
                 (dtype*)p2, s2/sizeof(dtype), g);
}

/*
  @overload drotm( x, y, param )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed).
  @param param [Numo::DFloat]  array of [FLAG,H11,H21,H12,H22]
  @return [Array<Numo::DFloat,Numo::DFloat>] returns [x,y]

Apply the modified givens transformation, H,
to the 2 by N matrix (X\*\*T), where \*\*T indicates transpose.
The elements of X are in (Y\*\*T)

X(LX+I\*INCX), I = 0 to N-1, where LX = 1 if INCX .GE. 0, else
LX = (-INCX)\*N, and similarly for Y using LY and INCY.
With PARAM(1)=FLAG, H has one of the following forms..

        FLAG=-1.0     FLAG=0.0        FLAG=1.0     FLAG=-2.0

          (H11  H12)    (1.0  H12)    (H11  1.0)    (1.0  0.0)
        H=(        )    (        )    (        )    (        )
          (H21  H22),   (H21  1.0),   (-1.0 H22),   (0.0  1.0).

see DROTMG for a description of data storage in param.

 */
static VALUE
blas_s_drotm(VALUE UNUSED(mod), VALUE x, VALUE y, VALUE param)
{
    dtype *g;
    narray_t *na1, *na2, *nap;
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{OVERWRITE,0}};
    ndfunc_t ndf = {iter_blas_s_drotm, STRIDE_LOOP, 2,0, ain,0};

    CHECK_FUNC(func_p,"drotm");

    COPY_OR_CAST_TO(x,cT);
    COPY_OR_CAST_TO(y,cT);
    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    CHECK_NON_EMPTY(na1);
    CHECK_NON_EMPTY(na2);
    CHECK_SAME_SHAPE(na1,na2);

    param = rb_funcall(cT,rb_intern("cast"),1,param);
    GetNArray(param,nap);
    CHECK_DIM_EQ(nap,1);
    CHECK_SIZE_GE(nap,5);
    g = (dtype*)nary_get_pointer_for_read(param);

    na_ndloop3(&ndf, g, 2, x, y);

    RB_GC_GUARD(param);
    return rb_assoc_new(x,y);
}

#undef func_p


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/scal.c"
#define func_p dscal_p

static dscal_t func_p = 0;

#line 8 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/scal.c"
#define scal_t dtype

#line 11 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/scal.c"
static void
iter_blas_s_dscal(na_loop_t *const lp)
{
    char *p1;
    size_t n;
    ssize_t s1;
    scal_t *g;

    INIT_COUNTER(lp,n);
    INIT_PTR(lp,0,p1,s1);
    g = (scal_t*)(lp->opt_ptr);

  
#line 26 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/scal.c"
    (*func_p)(n, *g, (dtype*)p1, s1/sizeof(dtype));
  
}

/*
  @overload dscal( a, x )
  @param [Float]        a  scale factor
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @return [Numo::DFloat] returns a*x.

DSCAL scales a vector by a constant.
uses unrolled loops for increment equal to one.

 */
static VALUE
blas_s_dscal(VALUE mod, VALUE a, VALUE x)
{
    scal_t g[1];
    narray_t *na1;
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,0}};
    ndfunc_t ndf = {iter_blas_s_dscal, STRIDE_LOOP, 1,0, ain,0};

    CHECK_FUNC(func_p,"dscal");

  
#line 56 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/scal.c"
    if (RTEST(a)) {g[0] = m_num_to_data(a);} else {g[0]=m_one;}
  
    COPY_OR_CAST_TO(x,cT);
    GetNArray(x,na1);
    CHECK_DIM_GE(na1,1);
    CHECK_NON_EMPTY(na1);

    na_ndloop3(&ndf, g, 1, x);

    return x;
}

#undef func_p
#undef scal_t


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mv.c"
/**/
#line 6 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mv.c"
#define GE 1
#define TR 0
#define args_t dgemv_args_t

typedef struct {
  enum CBLAS_ORDER order;
  enum CBLAS_TRANSPOSE trans;
  enum CBLAS_UPLO uplo;
  enum CBLAS_DIAG diag;
  dtype alpha, beta;
  blasint m, n;
} args_t;

#define func_p dgemv_p

static dgemv_t func_p = 0;

static void
iter_blas_s_dgemv(na_loop_t *const lp)
{
    dtype *a;
    char *p1;
    ssize_t s1;
#if !TR
    char *p2;
    ssize_t s2;
#endif
#if !GE
    int n;
#endif
    int lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    INIT_PTR(lp,1,p1,s1);
#if !TR
    INIT_PTR(lp,2,p2,s2);
#endif
    g = (args_t*)(lp->opt_ptr);

#if !GE
    n = NDL_SHAPE(lp,0)[1];
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

#if GE
    (*func_p)( g->order, g->trans, g->m, g->n,
        DP(g->alpha), a, lda, (dtype*)p1, s1/sizeof(dtype),
        DP(g->beta), (dtype*)p2, s2/sizeof(dtype) );
#elif TR
    (*func_p)( g->order, g->uplo, g->trans, g->diag, n, a, lda,
        (dtype*)p1, s1/sizeof(dtype) );
#else // SY,HE
    (*func_p)( g->order, g->uplo, n,
        DP(g->alpha), a, lda, (dtype*)p1, s1/sizeof(dtype),
        DP(g->beta), (dtype*)p2, s2/sizeof(dtype) );
#endif
}

/*
  @overload dgemv(a, x, [y, alpha:1, beta:0, trans:'N', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray, optional, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param trans [String or Symbol]  if 'N': Not transpose , if 'T': Transpose . (default='N')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns y = alpha*op(A)\*x + beta\*y.

DGEMV  performs one of the matrix-vector operations

        y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,

where alpha and beta are scalars, x and y are vectors and A is an
m by n matrix.

*/
static VALUE
blas_s_dgemv(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     a, x, y=Qnil, alpha, beta;
    narray_t *na1, *na2;
    blasint   ma, na, nx;
#if GE
    blasint   tmp;
#endif
    size_t    shape[1];
    ndfunc_arg_in_t ain[4] = {{cT,2},{cT,1},{OVERWRITE,1},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,1,shape}};
    ndfunc_t ndf = {iter_blas_s_dgemv, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
#if GE
    ID kw_table[4] = {id_alpha,id_beta,id_order,id_trans};
#elif TR
    ID kw_table[6] = {id_alpha,id_beta,id_order,id_uplo,id_trans,id_diag};
#else
    ID kw_table[4] = {id_alpha,id_beta,id_order,id_uplo};
#endif
    VALUE opts[6] = {Qundef,Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dgemv");

    rb_scan_args(argc, argv, "21:", &a, &x, &y, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 4+2*TR, opts);
    alpha   = option_value(opts[0],Qnil);
    g.alpha = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    beta    = option_value(opts[1],Qnil);
    g.beta  = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
    g.order = option_order(opts[2]);
#if GE
    g.trans = option_trans(opts[3]);
#else
    g.uplo  = option_uplo(opts[3]);
#endif
#if TR
    g.trans = option_trans(opts[4]);
    g.diag  = option_diag(opts[5]);
#endif

    GetNArray(a,na1);
    CHECK_DIM_GE(na1,2);
    ma = ROW_SIZE(na1);
    na = COL_SIZE(na1);

    GetNArray(x,na2);
    CHECK_DIM_GE(na2,1);
    nx = COL_SIZE(na2);
#if GE
    SWAP_IFCOL(g.order, ma, na, tmp);
    g.m = ma;
    g.n = na;
    SWAP_IFTRANS(g.trans, ma, na, tmp);
#else
    CHECK_SQUARE("a",na1);
#endif
    CHECK_INT_EQ("na",na,"nx",nx);
    shape[0] = ma;

#if TR
    if (y != Qnil) {
        rb_raise(rb_eArgError,"wrong number of arguments (3 for 2)");
    }
    COPY_OR_CAST_TO(x,cT);
    ndf.nin = 2;
    na_ndloop3(&ndf, &g, 2, a, x);
    return x;

#else // GE,SY,HE

    if (y == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[2] = ain[3];
        y = INT2FIX(0);
        shape[0] = ma;
    } else {
        narray_t *na3;
        COPY_OR_CAST_TO(y,cT);
        GetNArray(y,na3);
        CHECK_DIM_GE(na3,1);
        CHECK_SIZE_GE(na3,nx);
    }
    {
        VALUE ans;
        ans = na_ndloop3(&ndf, &g, 3, a, x, y);

        if (ndf.nout == 1) { // c is not given.
            return ans;
        } else {
            return y;
        }
    }
#endif
}

#undef func_p
#undef args_t
#undef GE
#undef TR


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mv.c"
/**/
#line 6 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mv.c"
#define GE 0
#define TR 1
#define args_t dtrmv_args_t

typedef struct {
  enum CBLAS_ORDER order;
  enum CBLAS_TRANSPOSE trans;
  enum CBLAS_UPLO uplo;
  enum CBLAS_DIAG diag;
  dtype alpha, beta;
  blasint m, n;
} args_t;

#define func_p dtrmv_p

static dtrmv_t func_p = 0;

static void
iter_blas_s_dtrmv(na_loop_t *const lp)
{
    dtype *a;
    char *p1;
    ssize_t s1;
#if !TR
    char *p2;
    ssize_t s2;
#endif
#if !GE
    int n;
#endif
    int lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    INIT_PTR(lp,1,p1,s1);
#if !TR
    INIT_PTR(lp,2,p2,s2);
#endif
    g = (args_t*)(lp->opt_ptr);

#if !GE
    n = NDL_SHAPE(lp,0)[1];
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

#if GE
    (*func_p)( g->order, g->trans, g->m, g->n,
        DP(g->alpha), a, lda, (dtype*)p1, s1/sizeof(dtype),
        DP(g->beta), (dtype*)p2, s2/sizeof(dtype) );
#elif TR
    (*func_p)( g->order, g->uplo, g->trans, g->diag, n, a, lda,
        (dtype*)p1, s1/sizeof(dtype) );
#else // SY,HE
    (*func_p)( g->order, g->uplo, n,
        DP(g->alpha), a, lda, (dtype*)p1, s1/sizeof(dtype),
        DP(g->beta), (dtype*)p2, s2/sizeof(dtype) );
#endif
}

/*
  @overload dtrmv(a, x, [uplo:'U', trans:'N', diag:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param side [String or Symbol]  if 'L': op(A)\*B (left-side op), if 'R': B\*op(A) (right-side op). (default='L')
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param trans [String or Symbol]  if 'N': Not transpose , if 'T': Transpose . (default='N')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns y = alpha*op(A)\*x + beta\*y.

DTRMV  performs one of the matrix-vector operations

        x := A*x,   or   x := A**T*x,

where x is an n element vector and  A is an n by n unit, or non-unit,
upper or lower triangular matrix.

*/
static VALUE
blas_s_dtrmv(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     a, x, y=Qnil, alpha, beta;
    narray_t *na1, *na2;
    blasint   ma, na, nx;
#if GE
    blasint   tmp;
#endif
    size_t    shape[1];
    ndfunc_arg_in_t ain[4] = {{cT,2},{cT,1},{OVERWRITE,1},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,1,shape}};
    ndfunc_t ndf = {iter_blas_s_dtrmv, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
#if GE
    ID kw_table[4] = {id_alpha,id_beta,id_order,id_trans};
#elif TR
    ID kw_table[6] = {id_alpha,id_beta,id_order,id_uplo,id_trans,id_diag};
#else
    ID kw_table[4] = {id_alpha,id_beta,id_order,id_uplo};
#endif
    VALUE opts[6] = {Qundef,Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dtrmv");

    rb_scan_args(argc, argv, "21:", &a, &x, &y, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 4+2*TR, opts);
    alpha   = option_value(opts[0],Qnil);
    g.alpha = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    beta    = option_value(opts[1],Qnil);
    g.beta  = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
    g.order = option_order(opts[2]);
#if GE
    g.trans = option_trans(opts[3]);
#else
    g.uplo  = option_uplo(opts[3]);
#endif
#if TR
    g.trans = option_trans(opts[4]);
    g.diag  = option_diag(opts[5]);
#endif

    GetNArray(a,na1);
    CHECK_DIM_GE(na1,2);
    ma = ROW_SIZE(na1);
    na = COL_SIZE(na1);

    GetNArray(x,na2);
    CHECK_DIM_GE(na2,1);
    nx = COL_SIZE(na2);
#if GE
    SWAP_IFCOL(g.order, ma, na, tmp);
    g.m = ma;
    g.n = na;
    SWAP_IFTRANS(g.trans, ma, na, tmp);
#else
    CHECK_SQUARE("a",na1);
#endif
    CHECK_INT_EQ("na",na,"nx",nx);
    shape[0] = ma;

#if TR
    if (y != Qnil) {
        rb_raise(rb_eArgError,"wrong number of arguments (3 for 2)");
    }
    COPY_OR_CAST_TO(x,cT);
    ndf.nin = 2;
    na_ndloop3(&ndf, &g, 2, a, x);
    return x;

#else // GE,SY,HE

    if (y == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[2] = ain[3];
        y = INT2FIX(0);
        shape[0] = ma;
    } else {
        narray_t *na3;
        COPY_OR_CAST_TO(y,cT);
        GetNArray(y,na3);
        CHECK_DIM_GE(na3,1);
        CHECK_SIZE_GE(na3,nx);
    }
    {
        VALUE ans;
        ans = na_ndloop3(&ndf, &g, 3, a, x, y);

        if (ndf.nout == 1) { // c is not given.
            return ans;
        } else {
            return y;
        }
    }
#endif
}

#undef func_p
#undef args_t
#undef GE
#undef TR


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mv.c"
/**/
#line 6 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mv.c"
#define GE 0
#define TR 0
#define args_t dsymv_args_t

typedef struct {
  enum CBLAS_ORDER order;
  enum CBLAS_TRANSPOSE trans;
  enum CBLAS_UPLO uplo;
  enum CBLAS_DIAG diag;
  dtype alpha, beta;
  blasint m, n;
} args_t;

#define func_p dsymv_p

static dsymv_t func_p = 0;

static void
iter_blas_s_dsymv(na_loop_t *const lp)
{
    dtype *a;
    char *p1;
    ssize_t s1;
#if !TR
    char *p2;
    ssize_t s2;
#endif
#if !GE
    int n;
#endif
    int lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    INIT_PTR(lp,1,p1,s1);
#if !TR
    INIT_PTR(lp,2,p2,s2);
#endif
    g = (args_t*)(lp->opt_ptr);

#if !GE
    n = NDL_SHAPE(lp,0)[1];
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

#if GE
    (*func_p)( g->order, g->trans, g->m, g->n,
        DP(g->alpha), a, lda, (dtype*)p1, s1/sizeof(dtype),
        DP(g->beta), (dtype*)p2, s2/sizeof(dtype) );
#elif TR
    (*func_p)( g->order, g->uplo, g->trans, g->diag, n, a, lda,
        (dtype*)p1, s1/sizeof(dtype) );
#else // SY,HE
    (*func_p)( g->order, g->uplo, n,
        DP(g->alpha), a, lda, (dtype*)p1, s1/sizeof(dtype),
        DP(g->beta), (dtype*)p2, s2/sizeof(dtype) );
#endif
}

/*
  @overload dsymv(a, x, [y, alpha:1, beta:0, uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray, optional, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param side [String or Symbol]  if 'L': op(A)\*B (left-side op), if 'R': B\*op(A) (right-side op). (default='L')
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns y = alpha*op(A)\*x + beta\*y.

DSYMV  performs the matrix-vector  operation

        y := alpha*A*x + beta*y,

where alpha and beta are scalars, x and y are n element vectors and
A is an n by n symmetric matrix.

*/
static VALUE
blas_s_dsymv(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     a, x, y=Qnil, alpha, beta;
    narray_t *na1, *na2;
    blasint   ma, na, nx;
#if GE
    blasint   tmp;
#endif
    size_t    shape[1];
    ndfunc_arg_in_t ain[4] = {{cT,2},{cT,1},{OVERWRITE,1},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,1,shape}};
    ndfunc_t ndf = {iter_blas_s_dsymv, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
#if GE
    ID kw_table[4] = {id_alpha,id_beta,id_order,id_trans};
#elif TR
    ID kw_table[6] = {id_alpha,id_beta,id_order,id_uplo,id_trans,id_diag};
#else
    ID kw_table[4] = {id_alpha,id_beta,id_order,id_uplo};
#endif
    VALUE opts[6] = {Qundef,Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dsymv");

    rb_scan_args(argc, argv, "21:", &a, &x, &y, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 4+2*TR, opts);
    alpha   = option_value(opts[0],Qnil);
    g.alpha = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    beta    = option_value(opts[1],Qnil);
    g.beta  = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
    g.order = option_order(opts[2]);
#if GE
    g.trans = option_trans(opts[3]);
#else
    g.uplo  = option_uplo(opts[3]);
#endif
#if TR
    g.trans = option_trans(opts[4]);
    g.diag  = option_diag(opts[5]);
#endif

    GetNArray(a,na1);
    CHECK_DIM_GE(na1,2);
    ma = ROW_SIZE(na1);
    na = COL_SIZE(na1);

    GetNArray(x,na2);
    CHECK_DIM_GE(na2,1);
    nx = COL_SIZE(na2);
#if GE
    SWAP_IFCOL(g.order, ma, na, tmp);
    g.m = ma;
    g.n = na;
    SWAP_IFTRANS(g.trans, ma, na, tmp);
#else
    CHECK_SQUARE("a",na1);
#endif
    CHECK_INT_EQ("na",na,"nx",nx);
    shape[0] = ma;

#if TR
    if (y != Qnil) {
        rb_raise(rb_eArgError,"wrong number of arguments (3 for 2)");
    }
    COPY_OR_CAST_TO(x,cT);
    ndf.nin = 2;
    na_ndloop3(&ndf, &g, 2, a, x);
    return x;

#else // GE,SY,HE

    if (y == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[2] = ain[3];
        y = INT2FIX(0);
        shape[0] = ma;
    } else {
        narray_t *na3;
        COPY_OR_CAST_TO(y,cT);
        GetNArray(y,na3);
        CHECK_DIM_GE(na3,1);
        CHECK_SIZE_GE(na3,nx);
    }
    {
        VALUE ans;
        ans = na_ndloop3(&ndf, &g, 3, a, x, y);

        if (ndf.nout == 1) { // c is not given.
            return ans;
        } else {
            return y;
        }
    }
#endif
}

#undef func_p
#undef args_t
#undef GE
#undef TR


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syr.c"
#define args_t dsyr_args_t

typedef struct {
    enum CBLAS_ORDER order;
    enum CBLAS_UPLO uplo;
    rtype alpha;
} args_t;

#define func_p dsyr_p

static dsyr_t func_p = 0;

static void
iter_blas_s_dsyr(na_loop_t *const lp)
{
    dtype *a;
    char *p1;
    ssize_t s1;
    args_t *g;
    blasint n, lda;

    INIT_PTR(lp,0,p1,s1);
    a = (dtype*)NDL_PTR(lp,1);
    g = (args_t*)(lp->opt_ptr);

    n = NDL_SHAPE(lp,0)[0];
    lda = NDL_STEP(lp,1) / sizeof(dtype);

    (*func_p)(g->order, g->uplo, n, g->alpha,
              (dtype*)p1, s1/sizeof(dtype), a, lda);
}

/*
  @overload dsyr( x, [a, alpha:1, uplo:'U', order:'R'] )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] return a
DSYR   performs the symmetric rank 1 operation

        A := alpha*x*x**T + A,

where alpha is a real scalar, x is an n element vector and A is an
n by n symmetric matrix.

 */
static VALUE
blas_s_dsyr(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     ans;
    VALUE     x, a, alpha;
    narray_t *na1, *na3;
    blasint   nx, na;
    size_t    shape[2];
    ndfunc_arg_in_t ain[3] = {{cT,1},{OVERWRITE,2},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dsyr, NO_LOOP, 2, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[3] = {id_alpha,id_order,id_uplo};
    VALUE opts[3] = {Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dsyr");

    rb_scan_args(argc, argv, "11:", &x, &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    alpha   = option_value(opts[0],Qnil);
    g.alpha = RTEST(alpha) ? NUM2DBL(alpha) : 1;
    g.order = option_order(opts[1]);
    g.uplo  = option_uplo(opts[2]);

    GetNArray(x,na1);
    CHECK_DIM_GE(na1,1);
    nx = COL_SIZE(na1); // n

    if (a == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[1] = ain[2];
        a = INT2FIX(0);
        shape[0] = shape[1] = nx;
    } else {
        COPY_OR_CAST_TO(a,cT);
        GetNArray(a,na3);
        CHECK_DIM_GE(na3,2);
        CHECK_SQUARE("a",na3);
        na = COL_SIZE(na3); // n (lda)
        CHECK_SIZE_EQ(na,nx);
    }

    ans = na_ndloop3(&ndf, &g, 2, x, a);

    if (ndf.nout == 1) { // a is not given.
        return ans;
    } else {
        return a;
    }
}

#undef func_p
#undef args_t


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/ger.c"
#define args_t dger_args_t

typedef struct {
    enum CBLAS_ORDER order;
    dtype alpha;
    blasint m, n;
} args_t;

#define func_p dger_p

static dger_t func_p = 0;

static void
iter_blas_s_dger(na_loop_t *const lp)
{
    dtype *a;
    char *p1, *p2;
    ssize_t s1, s2;
    args_t *g;
    int lda;

    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);
    a = (dtype*)NDL_PTR(lp,2);
    g = (args_t*)(lp->opt_ptr);

    lda = NDL_STEP(lp,2) / sizeof(dtype);

    (*func_p)(g->order, g->m, g->n,
              DP(g->alpha), (dtype*)p1, s1/sizeof(dtype),
              (dtype*)p2, s2/sizeof(dtype), a, lda);
}

/*
  @overload dger( x, y, [a, alpha:1, order:'R'] )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, m-by-n symmetric matrix, optional, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns a.

  DGER   performs the rank 1 operation

        A := alpha*x*y**T + A,

where alpha is a scalar, x is an m element vector, y is an n element
vector and A is an m by n matrix.


 */
static VALUE
blas_s_dger(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     ans;
    VALUE     x, y, a=Qnil, alpha;
    narray_t *na1, *na2;
    blasint   mx, ny, tmp;
    size_t    shape[2];
    ndfunc_arg_in_t ain[4] = {{cT,1},{cT,1},{OVERWRITE,2},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dger, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[2] = {id_alpha,id_order};
    VALUE opts[2] = {Qundef};

    CHECK_FUNC(func_p,"dger");

    rb_scan_args(argc, argv, "21:", &x, &y, &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    alpha   = option_value(opts[0],Qnil);
    g.alpha = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    g.order = option_order(opts[1]);

    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    mx = COL_SIZE(na1); // m
    ny = COL_SIZE(na2); // n
    g.m = mx;
    g.n = ny;

    SWAP_IFCOL(g.order, mx,ny, tmp);

    if (a == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[2] = ain[3];
        a = INT2FIX(0);
        shape[0] = mx;
        shape[1] = ny;
    } else {
        narray_t  *na3;
        blasint    ma, na;
        COPY_OR_CAST_TO(a,cT);
        GetNArray(a,na3);
        CHECK_DIM_GE(na3,2);
        ma = ROW_SIZE(na3); // m
        na = COL_SIZE(na3); // n (lda)
        CHECK_SIZE_EQ(ma,mx);
        CHECK_SIZE_EQ(na,ny);
    }

    ans = na_ndloop3(&ndf, &g, 3, x, y, a);

    if (ndf.nout = 1) { // a is not given.
        return ans;
    } else {
        return a;
    }
}

#undef func_p
#undef args_t


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syr2.c"
#define args_t dsyr2_args_t

typedef struct {
    enum CBLAS_ORDER order;
    enum CBLAS_UPLO uplo;
    dtype alpha;
} args_t;

#define func_p dsyr2_p

static dsyr2_t func_p = 0;

static void
iter_blas_s_dsyr2(na_loop_t *const lp)
{
    dtype *a;
    char *p1, *p2;
    ssize_t s1, s2;
    args_t *g;
    blasint n, lda;

    INIT_PTR(lp,0,p1,s1);
    INIT_PTR(lp,1,p2,s2);
    a = (dtype*)NDL_PTR(lp,2);
    g = (args_t*)(lp->opt_ptr);

    n = NDL_SHAPE(lp,0)[0];
    lda = NDL_STEP(lp,2) / sizeof(dtype);

    (*func_p)(g->order, g->uplo, n,
              DP(g->alpha), (dtype*)p1, s1/sizeof(dtype),
              (dtype*)p2, s2/sizeof(dtype), a, lda);
}

/*
  @overload dsyr2( x, y, [a, alpha:1, uplo:'U', order:'R'] )
  @param x [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param y [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns a.

DSYR2  performs the symmetric rank 2 operation

        A := alpha*x*y**T + alpha*y*x**T + A,

where alpha is a scalar, x and y are n element vectors and A is an n
by n symmetric matrix.

*/
static VALUE
blas_s_dsyr2(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     ans;
    VALUE     x, y, a, alpha;
    narray_t *na1, *na2, *na3;
    blasint   nx, ny, na;
    size_t    shape[2];
    ndfunc_arg_in_t ain[4] = {{cT,1},{cT,1},{OVERWRITE,2},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dsyr2, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[3] = {id_alpha,id_order,id_uplo};
    VALUE opts[3] = {Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dsyr2");

    rb_scan_args(argc, argv, "21:", &x, &y, &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    alpha   = option_value(opts[0],Qnil);
    g.alpha = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    g.order = option_order(opts[1]);
    g.uplo  = option_uplo(opts[2]);

    GetNArray(x,na1);
    GetNArray(y,na2);
    CHECK_DIM_GE(na1,1);
    CHECK_DIM_GE(na2,1);
    nx = COL_SIZE(na1); // n
    ny = COL_SIZE(na2); // n
    CHECK_INT_EQ("nx",nx,"ny",ny);

    if (a == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[2] = ain[3];
        a = INT2FIX(0);
        shape[0] = shape[1] = nx;
    } else {
        COPY_OR_CAST_TO(a,cT);
        GetNArray(a,na3);
        CHECK_DIM_GE(na3,2);
        CHECK_SQUARE("a",na3);
        na = COL_SIZE(na3); // n (lda)
        CHECK_SIZE_EQ(na,nx);
    }

    ans = na_ndloop3(&ndf, &g, 3, x, y, a);

    if (ndf.nout == 1) { // a is not given.
        return ans;
    } else {
        return a;
    }
}

#undef func_p
#undef args_t


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mm.c"
/**/
#line 7 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mm.c"
#define GE 1
#define TR 0
#define args_t dgemm_args_t

typedef struct {
  enum CBLAS_ORDER order;
  enum CBLAS_TRANSPOSE transa, transb;
  enum CBLAS_SIDE side;
  enum CBLAS_UPLO uplo;
  enum CBLAS_DIAG diag;
  dtype alpha, beta;
  blasint m, n, k;
} args_t;

#define func_p dgemm_p

static dgemm_t func_p = 0;

static void
iter_blas_s_dgemm(na_loop_t *const lp)
{
    dtype *a, *b;
    int    lda, ldb;
#if !TR
    dtype *c;
    int    ldc;
#endif
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if !TR
    c = (dtype*)NDL_PTR(lp,2);
#endif
    g = (args_t*)(lp->opt_ptr);

    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldb = NDL_STEP(lp,1) / sizeof(dtype);
#if !TR
    ldc = NDL_STEP(lp,2) / sizeof(dtype);
#endif

    //printf("m=%d n=%d k=%d\n",g->m,g->n,g->k);

#if GE
    (*func_p)( g->order, g->transa, g->transb, g->m, g->n, g->k,
              DP(g->alpha), a, lda, b, ldb, DP(g->beta), c, ldc);
#elif TR
    (*func_p)( g->order, g->side, g->uplo, g->transa, g->diag, g->m, g->n,
               DP(g->alpha), a, lda, b, ldb);
#else // SY,HE
    (*func_p)( g->order, g->side, g->uplo, g->m, g->n,
               DP(g->alpha), a, lda, b, ldb, DP(g->beta), c, ldc);
#endif
}

/*

  @overload dgemm(a, b, [c, alpha:1, beta:0, transa:'N', transb:'N', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param c [Numo::DFloat]  matrix (>=2-dimentional NArray, optional, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param transa [String or Symbol]  if 'N': Not transpose a, if 'T': Transpose a. (default='N')
  @param transb [String or Symbol]  if 'N': Not transpose b, if 'T': Transpose b. (default='N')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns c = alpha\*op( A )\*op( B ) + beta\*C.
DGEMM  performs one of the matrix-matrix operations

        C := alpha*op( A )*op( B ) + beta*C,

where  op( X ) is one of

        op( X ) = X   or   op( X ) = X**T,

alpha and beta are scalars, and A, B and C are matrices, with op( A )
an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.

*/
static VALUE
blas_s_dgemm(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     a, b, c=Qnil, alpha, beta;
    narray_t *na1, *na2;
    blasint   ma, ka, kb, nb, tmp;
    size_t    shape[2];
    ndfunc_arg_in_t ain[3] = {{cT,2},{cT,2},{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dgemm, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
#if GE
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_transa,id_transb};
#elif TR
    ID kw_table[7] = {id_alpha,id_beta,id_order,id_side,id_uplo,id_transa,id_diag};
#else
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_side,id_uplo};
#endif
    VALUE opts[7] = {Qundef,Qundef,Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dgemm");

    rb_scan_args(argc, argv, "21:", &a, &b, &c, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 5+TR*2, opts);
    alpha    = option_value(opts[0],Qnil);
    g.alpha  = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    beta     = option_value(opts[1],Qnil);
    g.beta   = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
    g.order  = option_order(opts[2]);
#if GE
    g.transa = option_trans(opts[3]);
    g.transb = option_trans(opts[4]);
#else
    g.side   = option_side(opts[3]);
    g.uplo   = option_uplo(opts[4]);
#endif
#if TR
    g.transa = option_trans(opts[5]);
    g.diag   = option_diag(opts[6]);
#endif

    GetNArray(a,na1);
    GetNArray(b,na2);
    CHECK_DIM_GE(na1,2);
    CHECK_DIM_GE(na2,2);
    ma = ROW_SIZE(na1); // m
    ka = COL_SIZE(na1); // k (lda)
    kb = ROW_SIZE(na2); // k
    nb = COL_SIZE(na2); // n (ldb)

#if GE
    SWAP_IFCOLTR(g.order,g.transa, ma,ka, tmp);
    SWAP_IFCOLTR(g.order,g.transb, kb,nb, tmp);
    CHECK_INT_EQ("ka",ka,"kb",kb);
    g.m = ma;
    g.n = nb;
    g.k = ka;
#else
    CHECK_SQUARE("a",na1); // ma == ka
    SWAP_IFCOL(g.order, kb,nb, tmp);
    // row major             L    R
    //ma = ROW_SIZE(na1); // m or n
    //ka = COL_SIZE(na1); // m or n (lda)
    g.m = kb; // m
    g.n = nb; // n (ldb)
    if (g.side == CblasLeft) {
        CHECK_SIZE_EQ(ka, g.m);
    } else {
        CHECK_SIZE_EQ(ka, g.n);
    }
#endif

    SWAP_IFROW(g.order, ma,nb, tmp);

#if TR
    if (c != Qnil) {
        rb_raise(rb_eArgError,"wrong number of arguments (3 for 2)");
    }
    COPY_OR_CAST_TO(b,cT);
    ndf.nin = 2;

    na_ndloop3(&ndf, &g, 2, a, b);
    return b;
#else

    if (c == Qnil) { // c is not given.
        ndfunc_arg_in_t ain_init = {sym_init,0};
        ain[2] = ain_init;
        ndf.nout = 1;
        c = INT2FIX(0);
        shape[0] = nb;
        shape[1] = ma;
    } else {
        narray_t *na3;
        int nc;
        COPY_OR_CAST_TO(c,cT);
        GetNArray(c,na3);
        CHECK_DIM_GE(na3,2);
        nc = ROW_SIZE(na3);
        if (nc < nb) {
            rb_raise(nary_eShapeError,"nc=%d must be >= nb=%d",nc,nb);
        }
        //CHECK_LEADING_GE("ldc",g.ldc,"m",ma);
    }
    {
        VALUE ans = na_ndloop3(&ndf, &g, 3, a, b, c);

        if (ndf.nout == 1) { // c is not given.
            return ans;
        } else {
            return c;
        }
    }
#endif
}

#undef func_p
#undef args_t
#undef GE
#undef TR


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mm.c"
/**/
#line 7 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mm.c"
#define GE 0
#define TR 0
#define args_t dsymm_args_t

typedef struct {
  enum CBLAS_ORDER order;
  enum CBLAS_TRANSPOSE transa, transb;
  enum CBLAS_SIDE side;
  enum CBLAS_UPLO uplo;
  enum CBLAS_DIAG diag;
  dtype alpha, beta;
  blasint m, n, k;
} args_t;

#define func_p dsymm_p

static dsymm_t func_p = 0;

static void
iter_blas_s_dsymm(na_loop_t *const lp)
{
    dtype *a, *b;
    int    lda, ldb;
#if !TR
    dtype *c;
    int    ldc;
#endif
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if !TR
    c = (dtype*)NDL_PTR(lp,2);
#endif
    g = (args_t*)(lp->opt_ptr);

    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldb = NDL_STEP(lp,1) / sizeof(dtype);
#if !TR
    ldc = NDL_STEP(lp,2) / sizeof(dtype);
#endif

    //printf("m=%d n=%d k=%d\n",g->m,g->n,g->k);

#if GE
    (*func_p)( g->order, g->transa, g->transb, g->m, g->n, g->k,
              DP(g->alpha), a, lda, b, ldb, DP(g->beta), c, ldc);
#elif TR
    (*func_p)( g->order, g->side, g->uplo, g->transa, g->diag, g->m, g->n,
               DP(g->alpha), a, lda, b, ldb);
#else // SY,HE
    (*func_p)( g->order, g->side, g->uplo, g->m, g->n,
               DP(g->alpha), a, lda, b, ldb, DP(g->beta), c, ldc);
#endif
}

/*

  @overload dsymm(a, b, [c, alpha:1, beta:0, side:'L', uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param c [Numo::DFloat]  matrix (>=2-dimentional NArray, optional, inplace allowed).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param side [String or Symbol]  if 'L': op(A)\*B (left-side op), if 'R': B\*op(A) (right-side op). (default='L')
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns c = alpha\*op( A )\*op( B ) + beta\*C.
DSYMM  performs one of the matrix-matrix operations

        C := alpha*A*B + beta*C,

or

        C := alpha*B*A + beta*C,

where alpha and beta are scalars,  A is a symmetric matrix and  B and
C are  m by n matrices.

*/
static VALUE
blas_s_dsymm(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     a, b, c=Qnil, alpha, beta;
    narray_t *na1, *na2;
    blasint   ma, ka, kb, nb, tmp;
    size_t    shape[2];
    ndfunc_arg_in_t ain[3] = {{cT,2},{cT,2},{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dsymm, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
#if GE
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_transa,id_transb};
#elif TR
    ID kw_table[7] = {id_alpha,id_beta,id_order,id_side,id_uplo,id_transa,id_diag};
#else
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_side,id_uplo};
#endif
    VALUE opts[7] = {Qundef,Qundef,Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dsymm");

    rb_scan_args(argc, argv, "21:", &a, &b, &c, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 5+TR*2, opts);
    alpha    = option_value(opts[0],Qnil);
    g.alpha  = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    beta     = option_value(opts[1],Qnil);
    g.beta   = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
    g.order  = option_order(opts[2]);
#if GE
    g.transa = option_trans(opts[3]);
    g.transb = option_trans(opts[4]);
#else
    g.side   = option_side(opts[3]);
    g.uplo   = option_uplo(opts[4]);
#endif
#if TR
    g.transa = option_trans(opts[5]);
    g.diag   = option_diag(opts[6]);
#endif

    GetNArray(a,na1);
    GetNArray(b,na2);
    CHECK_DIM_GE(na1,2);
    CHECK_DIM_GE(na2,2);
    ma = ROW_SIZE(na1); // m
    ka = COL_SIZE(na1); // k (lda)
    kb = ROW_SIZE(na2); // k
    nb = COL_SIZE(na2); // n (ldb)

#if GE
    SWAP_IFCOLTR(g.order,g.transa, ma,ka, tmp);
    SWAP_IFCOLTR(g.order,g.transb, kb,nb, tmp);
    CHECK_INT_EQ("ka",ka,"kb",kb);
    g.m = ma;
    g.n = nb;
    g.k = ka;
#else
    CHECK_SQUARE("a",na1); // ma == ka
    SWAP_IFCOL(g.order, kb,nb, tmp);
    // row major             L    R
    //ma = ROW_SIZE(na1); // m or n
    //ka = COL_SIZE(na1); // m or n (lda)
    g.m = kb; // m
    g.n = nb; // n (ldb)
    if (g.side == CblasLeft) {
        CHECK_SIZE_EQ(ka, g.m);
    } else {
        CHECK_SIZE_EQ(ka, g.n);
    }
#endif

    SWAP_IFROW(g.order, ma,nb, tmp);

#if TR
    if (c != Qnil) {
        rb_raise(rb_eArgError,"wrong number of arguments (3 for 2)");
    }
    COPY_OR_CAST_TO(b,cT);
    ndf.nin = 2;

    na_ndloop3(&ndf, &g, 2, a, b);
    return b;
#else

    if (c == Qnil) { // c is not given.
        ndfunc_arg_in_t ain_init = {sym_init,0};
        ain[2] = ain_init;
        ndf.nout = 1;
        c = INT2FIX(0);
        shape[0] = nb;
        shape[1] = ma;
    } else {
        narray_t *na3;
        int nc;
        COPY_OR_CAST_TO(c,cT);
        GetNArray(c,na3);
        CHECK_DIM_GE(na3,2);
        nc = ROW_SIZE(na3);
        if (nc < nb) {
            rb_raise(nary_eShapeError,"nc=%d must be >= nb=%d",nc,nb);
        }
        //CHECK_LEADING_GE("ldc",g.ldc,"m",ma);
    }
    {
        VALUE ans = na_ndloop3(&ndf, &g, 3, a, b, c);

        if (ndf.nout == 1) { // c is not given.
            return ans;
        } else {
            return c;
        }
    }
#endif
}

#undef func_p
#undef args_t
#undef GE
#undef TR


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mm.c"
/**/
#line 7 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/mm.c"
#define GE 0
#define TR 1
#define args_t dtrmm_args_t

typedef struct {
  enum CBLAS_ORDER order;
  enum CBLAS_TRANSPOSE transa, transb;
  enum CBLAS_SIDE side;
  enum CBLAS_UPLO uplo;
  enum CBLAS_DIAG diag;
  dtype alpha, beta;
  blasint m, n, k;
} args_t;

#define func_p dtrmm_p

static dtrmm_t func_p = 0;

static void
iter_blas_s_dtrmm(na_loop_t *const lp)
{
    dtype *a, *b;
    int    lda, ldb;
#if !TR
    dtype *c;
    int    ldc;
#endif
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if !TR
    c = (dtype*)NDL_PTR(lp,2);
#endif
    g = (args_t*)(lp->opt_ptr);

    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldb = NDL_STEP(lp,1) / sizeof(dtype);
#if !TR
    ldc = NDL_STEP(lp,2) / sizeof(dtype);
#endif

    //printf("m=%d n=%d k=%d\n",g->m,g->n,g->k);

#if GE
    (*func_p)( g->order, g->transa, g->transb, g->m, g->n, g->k,
              DP(g->alpha), a, lda, b, ldb, DP(g->beta), c, ldc);
#elif TR
    (*func_p)( g->order, g->side, g->uplo, g->transa, g->diag, g->m, g->n,
               DP(g->alpha), a, lda, b, ldb);
#else // SY,HE
    (*func_p)( g->order, g->side, g->uplo, g->m, g->n,
               DP(g->alpha), a, lda, b, ldb, DP(g->beta), c, ldc);
#endif
}

/*

  @overload dtrmm(a, b, [alpha:1, side:'L', uplo:'U', transa:'N', diag:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param side [String or Symbol]  if 'L': op(A)\*B (left-side op), if 'R': B\*op(A) (right-side op). (default='L')
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param transa [String or Symbol]  if 'N': Not transpose a, if 'T': Transpose a. (default='N')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns c = alpha\*op( A )\*op( B ) + beta\*C.
DTRMM  performs one of the matrix-matrix operations

        B := alpha*op( A )*B,   or   B := alpha*B*op( A ),

where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
non-unit,  upper or lower triangular matrix  and  op( A )  is one  of

        op( A ) = A   or   op( A ) = A**T.

*/
static VALUE
blas_s_dtrmm(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     a, b, c=Qnil, alpha, beta;
    narray_t *na1, *na2;
    blasint   ma, ka, kb, nb, tmp;
    size_t    shape[2];
    ndfunc_arg_in_t ain[3] = {{cT,2},{cT,2},{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dtrmm, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
#if GE
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_transa,id_transb};
#elif TR
    ID kw_table[7] = {id_alpha,id_beta,id_order,id_side,id_uplo,id_transa,id_diag};
#else
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_side,id_uplo};
#endif
    VALUE opts[7] = {Qundef,Qundef,Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dtrmm");

    rb_scan_args(argc, argv, "21:", &a, &b, &c, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 5+TR*2, opts);
    alpha    = option_value(opts[0],Qnil);
    g.alpha  = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    beta     = option_value(opts[1],Qnil);
    g.beta   = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
    g.order  = option_order(opts[2]);
#if GE
    g.transa = option_trans(opts[3]);
    g.transb = option_trans(opts[4]);
#else
    g.side   = option_side(opts[3]);
    g.uplo   = option_uplo(opts[4]);
#endif
#if TR
    g.transa = option_trans(opts[5]);
    g.diag   = option_diag(opts[6]);
#endif

    GetNArray(a,na1);
    GetNArray(b,na2);
    CHECK_DIM_GE(na1,2);
    CHECK_DIM_GE(na2,2);
    ma = ROW_SIZE(na1); // m
    ka = COL_SIZE(na1); // k (lda)
    kb = ROW_SIZE(na2); // k
    nb = COL_SIZE(na2); // n (ldb)

#if GE
    SWAP_IFCOLTR(g.order,g.transa, ma,ka, tmp);
    SWAP_IFCOLTR(g.order,g.transb, kb,nb, tmp);
    CHECK_INT_EQ("ka",ka,"kb",kb);
    g.m = ma;
    g.n = nb;
    g.k = ka;
#else
    CHECK_SQUARE("a",na1); // ma == ka
    SWAP_IFCOL(g.order, kb,nb, tmp);
    // row major             L    R
    //ma = ROW_SIZE(na1); // m or n
    //ka = COL_SIZE(na1); // m or n (lda)
    g.m = kb; // m
    g.n = nb; // n (ldb)
    if (g.side == CblasLeft) {
        CHECK_SIZE_EQ(ka, g.m);
    } else {
        CHECK_SIZE_EQ(ka, g.n);
    }
#endif

    SWAP_IFROW(g.order, ma,nb, tmp);

#if TR
    if (c != Qnil) {
        rb_raise(rb_eArgError,"wrong number of arguments (3 for 2)");
    }
    COPY_OR_CAST_TO(b,cT);
    ndf.nin = 2;

    na_ndloop3(&ndf, &g, 2, a, b);
    return b;
#else

    if (c == Qnil) { // c is not given.
        ndfunc_arg_in_t ain_init = {sym_init,0};
        ain[2] = ain_init;
        ndf.nout = 1;
        c = INT2FIX(0);
        shape[0] = nb;
        shape[1] = ma;
    } else {
        narray_t *na3;
        int nc;
        COPY_OR_CAST_TO(c,cT);
        GetNArray(c,na3);
        CHECK_DIM_GE(na3,2);
        nc = ROW_SIZE(na3);
        if (nc < nb) {
            rb_raise(nary_eShapeError,"nc=%d must be >= nb=%d",nc,nb);
        }
        //CHECK_LEADING_GE("ldc",g.ldc,"m",ma);
    }
    {
        VALUE ans = na_ndloop3(&ndf, &g, 3, a, b, c);

        if (ndf.nout == 1) { // c is not given.
            return ans;
        } else {
            return c;
        }
    }
#endif
}

#undef func_p
#undef args_t
#undef GE
#undef TR


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syrk.c"
/**/
#line 8 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syrk.c"
#define P(a) DP(a)

#line 11 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syrk.c"
#define args_t dsyrk_args_t

typedef struct {
    enum CBLAS_ORDER order;
    enum CBLAS_UPLO uplo;
    enum CBLAS_TRANSPOSE trans;
    dtype alpha, beta;
    blasint n, k;
} args_t;

#define func_p dsyrk_p

static dsyrk_t func_p = 0;

static void
iter_blas_s_dsyrk(na_loop_t *const lp)
{
    dtype *a, *c;
    args_t *g;
    blasint lda, ldc;

    a = (dtype*)NDL_PTR(lp,0);
    c = (dtype*)NDL_PTR(lp,1);
    g = (args_t*)(lp->opt_ptr);

    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldc = NDL_STEP(lp,1) / sizeof(dtype);

    (*func_p)(g->order, g->uplo, g->trans, g->n, g->k,
              P(g->alpha), a, lda, P(g->beta), c, ldc);
}

/*
  @overload dsyrk( a, [c, alpha:1, beta:0, uplo:'U', trans:'N', order:'R'] )
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, n-by-k, inpace).
  @param c [Numo::DFloat]  matrix (>=2-dimentional NArray, n-by-n, optional, inpace).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param trans [String or Symbol]  if 'N': Not transpose , if 'T': Transpose . (default='N')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns c.

DSYRK  performs one of the symmetric rank k operations

        C := alpha*A*A**T + beta*C,

or

        C := alpha*A**T*A + beta*C,

where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
and  A  is an  n by k  matrix in the first case and a  k by n  matrix
in the second case.

 */
static VALUE
blas_s_dsyrk(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     ans;
    VALUE     a, c, alpha, beta;
    narray_t *na1, *na3;
    blasint   na, ka, nc, tmp;
    size_t    shape[2];
    ndfunc_arg_in_t ain[3] = {{cT,2},{OVERWRITE,2},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dsyrk, NO_LOOP, 2, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_uplo,id_trans};
    VALUE opts[5] = {Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dsyrk");

    rb_scan_args(argc, argv, "11:", &a, &c, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 5, opts);
    alpha   = option_value(opts[0],Qnil);
    beta    = option_value(opts[1],Qnil);
#line 88 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syrk.c"
    g.alpha = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    g.beta  = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
#line 91 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syrk.c"
    g.order = option_order(opts[2]);
    g.uplo  = option_uplo(opts[3]);
    g.trans = option_trans(opts[4]);

    GetNArray(a,na1);
    CHECK_DIM_GE(na1,2);

    na = ROW_SIZE(na1); // n
    ka = COL_SIZE(na1); // k (lda)
    SWAP_IFCOLTR(g.order,g.trans, na,ka, tmp);
    g.n = na;
    g.k = ka;

    if (c == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[1] = ain[2];
        c = INT2FIX(0);
        shape[0] = na;
        shape[1] = na;
    } else {
        COPY_OR_CAST_TO(c,cT);
        GetNArray(c,na3);
        CHECK_DIM_GE(na3,2);
        nc = ROW_SIZE(na3);
        if (nc < na) {
            rb_raise(nary_eShapeError,"nc=%d must be >= na=%d",nc,na);
        }
        //CHECK_LEADING_GE("ldc",g.ldc,"n",na);
    }

    ans = na_ndloop3(&ndf, &g, 2, a, c);

    if (ndf.nout == 1) { // c is not given.
        return ans;
    } else {
        return c;
    }
}

#undef func_p
#undef args_t
#undef P


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/syr2k.c"
#define args_t dsyr2k_args_t

typedef struct {
    enum CBLAS_ORDER order;
    enum CBLAS_UPLO uplo;
    enum CBLAS_TRANSPOSE trans;
    dtype alpha, beta;
    blasint n, k;
} args_t;

#define func_p dsyr2k_p

static dsyr2k_t func_p = 0;

static void
iter_blas_s_dsyr2k(na_loop_t *const lp)
{
    dtype *a, *b, *c;
    blasint lda, ldb, ldc;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
    c = (dtype*)NDL_PTR(lp,2);
    g = (args_t*)(lp->opt_ptr);

    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldb = NDL_STEP(lp,1) / sizeof(dtype);
    ldc = NDL_STEP(lp,2) / sizeof(dtype);

    (*func_p)(g->order, g->uplo, g->trans, g->n, g->k,
              DP(g->alpha), a, lda, b, ldb, DP(g->beta), c, ldc);
}

/*
  @overload dsyr2k( a, b, [c, alpha:1, beta:0, uplo:'U', trans:'N', order:'R'] )
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, n-by-k).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, n-by-k).
  @param c [Numo::DFloat]  matrix (>=2-dimentional NArray, n-by-n, optional, inpace).
  @param alpha [Float]  (default=1.0)
  @param beta [Float]  (default=0.0)
  @param uplo [String or Symbol]  if 'U': Upper triangle, if 'L': Lower triangle. (default='U')
  @param trans [String or Symbol]  if 'N': Not transpose , if 'T': Transpose . (default='N')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns c.

DSYR2K  performs one of the symmetric rank 2k operations

        C := alpha*A*B**T + alpha*B*A**T + beta*C,

or

        C := alpha*A**T*B + alpha*B**T*A + beta*C,

where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
and  A and B  are  n by k  matrices  in the  first  case  and  k by n
matrices in the second case.

 */
static VALUE
blas_s_dsyr2k(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE     ans;
    VALUE     a, b, c=Qnil, alpha, beta;
    narray_t *na1, *na2, *na3;
    blasint   na, ka, kb, nb, nc, tmp;
    size_t    shape[2];
    ndfunc_arg_in_t ain[4] = {{cT,2},{cT,2},{OVERWRITE,2},{sym_init,0}};
    ndfunc_arg_out_t aout[1] = {{cT,2,shape}};
    ndfunc_t ndf = {iter_blas_s_dsyr2k, NO_LOOP, 3, 0, ain, aout};

    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[5] = {id_alpha,id_beta,id_order,id_uplo,id_trans};
    VALUE opts[5] = {Qundef,Qundef,Qundef,Qundef,Qundef};

    CHECK_FUNC(func_p,"dsyr2k");

    rb_scan_args(argc, argv, "21:", &a, &b, &c, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 5, opts);
    alpha    = option_value(opts[0],Qnil);
    g.alpha  = RTEST(alpha) ? m_num_to_data(alpha) : m_one;
    beta     = option_value(opts[1],Qnil);
    g.beta   = RTEST(beta)  ? m_num_to_data(beta)  : m_zero;
    g.order  = option_order(opts[2]);
    g.uplo   = option_uplo(opts[3]);
    g.trans  = option_trans(opts[4]);

    GetNArray(a,na1);
    GetNArray(b,na2);
    CHECK_DIM_GE(na1,2);
    CHECK_DIM_GE(na2,2);

    na = ROW_SIZE(na1); // n
    ka = COL_SIZE(na1); // k (lda)
    SWAP_IFCOLTR(g.order, g.trans, na, ka, tmp);

    nb = ROW_SIZE(na2); // n
    kb = COL_SIZE(na2); // k (ldb)
    SWAP_IFCOLTR(g.order, g.trans, kb, nb, tmp);
    CHECK_INT_EQ("na",na,"nb",nb);
    CHECK_INT_EQ("ka",ka,"kb",kb);
    g.n = nb;
    g.k = kb;

    SWAP_IFROW(g.order, na, nb, tmp);

    if (c == Qnil) { // c is not given.
        ndf.nout = 1;
        ain[2] = ain[3];
        c = INT2FIX(0);
        shape[0] = nb;
        shape[1] = na;
    } else {
        COPY_OR_CAST_TO(c,cT);
        GetNArray(c,na3);
        CHECK_DIM_GE(na3,2);
        nc = ROW_SIZE(na3); // n
        if (nc < nb) {
            rb_raise(nary_eShapeError,"nc=%d must be >= nb=%d",nc,nb);
        }
        //CHECK_LEADING_GE("ldc",g.ldc,"n",na);
    }

    ans = na_ndloop3(&ndf, &g, 3, a, b, c);

    if (ndf.nout = 1) { // c is not given.
        return ans;
    } else {
        return c;
    }
}

#undef func_p
#undef args_t



#line 27 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/lib.c"
void
Init_numo_linalg_blas_d(void)
{
    VALUE mN;

    mN = rb_define_module("Numo");

    
    id_alpha = rb_intern("alpha");
    id_axis = rb_intern("axis");
    id_beta = rb_intern("beta");
    id_diag = rb_intern("diag");
    id_keepdims = rb_intern("keepdims");
    id_order = rb_intern("order");
    id_sb = rb_intern("sb");
    id_side = rb_intern("side");
    id_trans = rb_intern("trans");
    id_transa = rb_intern("transa");
    id_transb = rb_intern("transb");
    id_uplo = rb_intern("uplo");


#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/init_module.c"
    /*
      Document-module: Numo::Linalg
      
    */
    
    mLinalg = rb_define_module_under(mN, "Linalg");
    
    

#line 11 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/init_module.c"
    //  how to do this?
    //rb_extend_object(cT, mTM);

#line 1 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/init_module.c"
    /*
      Document-module: Numo::Linalg::Blas
      
    */
    
    mBlas = rb_define_module_under(mLinalg, "Blas");
    
    
    
    rb_define_module_function(mBlas, "ddot", blas_s_ddot, 2);
    rb_define_module_function(mBlas, "dnrm2", blas_s_dnrm2, -1);
    rb_define_module_function(mBlas, "dasum", blas_s_dasum, -1);
    rb_define_module_function(mBlas, "dswap", blas_s_dswap, 2);
    rb_define_module_function(mBlas, "dcopy", blas_s_dcopy, 2);
    rb_define_module_function(mBlas, "daxpy", blas_s_daxpy, -1);
    rb_define_module_function(mBlas, "drot", blas_s_drot, 4);
    rb_define_module_function(mBlas, "drotm", blas_s_drotm, 3);
    rb_define_module_function(mBlas, "dscal", blas_s_dscal, 2);
    rb_define_module_function(mBlas, "dgemv", blas_s_dgemv, -1);
    rb_define_module_function(mBlas, "dtrmv", blas_s_dtrmv, -1);
    rb_define_module_function(mBlas, "dsymv", blas_s_dsymv, -1);
    rb_define_module_function(mBlas, "dsyr", blas_s_dsyr, -1);
    rb_define_module_function(mBlas, "dger", blas_s_dger, -1);
    rb_define_module_function(mBlas, "dsyr2", blas_s_dsyr2, -1);
    rb_define_module_function(mBlas, "dgemm", blas_s_dgemm, -1);
    rb_define_module_function(mBlas, "dsymm", blas_s_dsymm, -1);
    rb_define_module_function(mBlas, "dtrmm", blas_s_dtrmm, -1);
    rb_define_module_function(mBlas, "dsyrk", blas_s_dsyrk, -1);
    rb_define_module_function(mBlas, "dsyr2k", blas_s_dsyr2k, -1);

#line 11 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/init_module.c"
    //  how to do this?
    //rb_extend_object(cT, mTM);
#line 40 "/opt/local/var/macports/build/rb31-numo-linalg-003c080d/work/destroot/opt/local/lib/ruby3.1/gems/3.1.0/gems/numo-linalg-0.1.7/ext/numo/linalg/blas/gen/../tmpl/lib.c"
}
