
#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/lapack/gen/../tmpl/lib.c"
/*
  LAPACK 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_lapack.h"

static ID id_axis;
static ID id_il;
static ID id_itype;
static ID id_iu;
static ID id_jobu;
static ID id_jobvl;
static ID id_jobvr;
static ID id_jobvt;
static ID id_jobz;
static ID id_keepdims;
static ID id_norm;
static ID id_order;
static ID id_range;
static ID id_rcond;
static ID id_trans;
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/lapack/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/lapack/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/lapack/gen/../tmpl/module.c"
/*
  module definition: Numo::Linalg::Lapack
*/

#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/lapack/gen/../tmpl/module.c"
static VALUE mLapack;

static VALUE eLapackError;

#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/lapack/gen/../tmpl/def_d.c"
#include "numo/types/dfloat.h"
#define CZ 0
#define IS_COMPLEX CZ

#ifndef m_real
#define m_real(x) (x)
#endif


#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/lapack/gen/../tmpl/lange.c"
#define args_t dlange_args_t
#define func_p dlange_p

typedef struct {
    int   order;
    char  norm;
} args_t;

static dlange_t func_p = 0;

static void
iter_lapack_s_dlange(na_loop_t * const lp)
{
    dtype *a;
    rtype *norm;
    int    m, n, lda, tmp;
    args_t *g;

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

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);

    //printf("order=%d norm=%c m=%d n=%d lda=%d\n",g->order,g->norm,m,n,lda);

    *norm = (*func_p)(g->order, g->norm, m, n, a, lda);
}

/*
  @overload dlange(a, norm, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray).
  @param [String]  norm  Kind of norm: 'M',('1','O'),'I',('F','E')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [Numo::DFloat] returns dlange.

DLANGE  returns the value of the one norm,  or the Frobenius norm, or
the  infinity norm,  or the  element of  largest absolute value  of a
real matrix A.

        DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
                 (
                 ( norm1(A),         NORM = '1', 'O' or 'o'
                 (
                 ( normI(A),         NORM = 'I' or 'i'
                 (
                 ( normF(A),         NORM = 'F', 'f', 'E' or 'e'

where  norm1  denotes the  one norm of a matrix (maximum column sum),
normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
normF  denotes the  Frobenius norm of a matrix (square root of sum of
squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.

*/
static VALUE
lapack_s_dlange(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, norm, ans;
    narray_t *na1;
    ndfunc_arg_in_t ain[1] = {{cT,2}};
    ndfunc_arg_out_t aout[1] = {{cRT,0}};
    ndfunc_t ndf = {&iter_lapack_s_dlange, NO_LOOP|NDF_EXTRACT, 1, 1, ain, aout};

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

    CHECK_FUNC(func_p,"dlange");

    rb_scan_args(argc, argv, "2:", &a, &norm, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
    g.order = option_order(opts[0]);
    g.norm  = option_job(norm,'F','F');
    //reduce = nary_reduce_options(Qnil, &opts[1], 1, &a, &ndf);
    //A is DOUBLE PRECISION array, dimension (LDA,N)
    //On entry, the M-by-N matrix A.
    //COPY_OR_CAST_TO(a,cT); // not overwrite
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);

    ans = na_ndloop3(&ndf, &g, 1, a);
    return ans;
}

#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/lapack/gen/../tmpl/gesv.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/lapack/gen/../tmpl/gesv.c"
#define UPLO 0
#define IPIV 1
#define args_t dgesv_args_t
#define func_p dgesv_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dgesv_t dgesv_p = 0;

static void
iter_lapack_s_dgesv(na_loop_t * const lp)
{
    dtype *a, *b;
    int   *info;
    int    n, nrhs;
    int    lda, ldb;
    args_t *g;
#if IPIV
    int *ipiv;
    ipiv = (int*)NDL_PTR(lp,2);
    info = (int*)NDL_PTR(lp,3);
#else
    info = (int*)NDL_PTR(lp,2);
#endif
    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
    g = (args_t*)(lp->opt_ptr);

    n = NDL_SHAPE(lp,0)[0];
    lda = NDL_STEP(lp,0) / sizeof(dtype);
    if (lp->args[1].ndim == 1) {
        nrhs = 1;
        ldb = (g->order==LAPACK_COL_MAJOR) ? n : 1;
    } else {
        nrhs = NDL_SHAPE(lp,1)[1];
        ldb = NDL_STEP(lp,1) / sizeof(dtype);
    }
    //printf("order=%d n=%d nrhs=%d lda=%d ldb=%d b.ndim=%d\n",
    //       g->order,n,nrhs,lda,ldb,lp->args[1].ndim);
    *info = (*func_p)( g->order, 
                       n, nrhs, a, lda, ipiv, b, ldb );
    CHECK_ERROR(*info);
}

/*
  @overload dgesv(a, b, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed, output: lu).
  @param b [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed, output: x).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, b, ipiv, info]] Array<Numo::DFloat, Numo::DFloat, Numo::Int, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the N-by-N coefficient matrix A.
           On exit, the factors L and U from the factorization
           A = P\*L\*U; the unit diagonal elements of L are not stored.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the N-by-NRHS matrix of right hand side matrix B.
           On exit, if INFO = 0, the N-by-NRHS solution matrix X.

    - **ipiv** -- 
           IPIV is INTEGER array, dimension (N)
           The pivot indices that define the permutation matrix P;
           row i of the matrix was interchanged with row IPIV(i).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, U(i,i) is exactly zero.  The factorization
                 has been completed, but the factor U is exactly
                 singular, so the solution could not be computed.

DGESV computes the solution to a real system of linear equations

        A * X = B,

where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
The LU decomposition with partial pivoting and row interchanges is
used to factor A as

        A = P * L * U,

where P is a permutation matrix, L is unit lower triangular, and U is
upper triangular.  The factored form of A is then used to solve the
system of equations A \* X = B.

*/
static VALUE
lapack_s_dgesv(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    narray_t *na1, *na2;
    size_t n, nb, nrhs;
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{OVERWRITE,2}};
    size_t shape[2];
    ndfunc_arg_out_t aout[2] = {{cInt,1,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgesv, NO_LOOP|NDF_EXTRACT, 2,2, ain,aout};
    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[2] = {id_order,id_uplo};
    VALUE opts[2] = {Qundef,Qundef};

    CHECK_FUNC(func_p,"dgesv");

    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.order = option_order(opts[0]);
    g.uplo = option_uplo(opts[1]);

    COPY_OR_CAST_TO(a,cT);
    COPY_OR_CAST_TO(b,cT);
    GetNArray(a, na1);
    GetNArray(b, na2);
    CHECK_DIM_GE(na1, 2);
    CHECK_DIM_GE(na2, 1);
    CHECK_SQUARE("matrix a",na1);
    n = COL_SIZE(na1);
    if (NA_NDIM(na2) == 1) {
        ain[1].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col=a.row=%"SZF"u b.row=%"SZF"u", n, nb);
    }
    shape[0] = n;
    shape[1] = nrhs;
#if !IPIV
    ndf.aout++;
    ndf.nout--;
#endif

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

#if IPIV
    return rb_ary_concat(rb_assoc_new(a,b),ans);
#else
    return rb_ary_new3(3,a,b,ans);
#endif
}

#undef func_p
#undef args_t
#undef UPLO
#undef IPIV


#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/lapack/gen/../tmpl/gesv.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/lapack/gen/../tmpl/gesv.c"
#define UPLO 1
#define IPIV 1
#define args_t dsysv_args_t
#define func_p dsysv_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dsysv_t dsysv_p = 0;

static void
iter_lapack_s_dsysv(na_loop_t * const lp)
{
    dtype *a, *b;
    int   *info;
    int    n, nrhs;
    int    lda, ldb;
    args_t *g;
#if IPIV
    int *ipiv;
    ipiv = (int*)NDL_PTR(lp,2);
    info = (int*)NDL_PTR(lp,3);
#else
    info = (int*)NDL_PTR(lp,2);
#endif
    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
    g = (args_t*)(lp->opt_ptr);

    n = NDL_SHAPE(lp,0)[0];
    lda = NDL_STEP(lp,0) / sizeof(dtype);
    if (lp->args[1].ndim == 1) {
        nrhs = 1;
        ldb = (g->order==LAPACK_COL_MAJOR) ? n : 1;
    } else {
        nrhs = NDL_SHAPE(lp,1)[1];
        ldb = NDL_STEP(lp,1) / sizeof(dtype);
    }
    //printf("order=%d n=%d nrhs=%d lda=%d ldb=%d b.ndim=%d\n",
    //       g->order,n,nrhs,lda,ldb,lp->args[1].ndim);
    *info = (*func_p)( g->order, g->uplo,
                       n, nrhs, a, lda, ipiv, b, ldb );
    CHECK_ERROR(*info);
}

/*
  @overload dsysv(a, b, [uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed, output: lu).
  @param b [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed, output: x).
  @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 [[a, b, ipiv, info]] Array<Numo::DFloat, Numo::DFloat, Numo::Int, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the leading
           N-by-N upper triangular part of A contains the upper
           triangular part of the matrix A, and the strictly lower
           triangular part of A is not referenced.  If UPLO = 'L', the
           leading N-by-N lower triangular part of A contains the lower
           triangular part of the matrix A, and the strictly upper
           triangular part of A is not referenced.
           On exit, if INFO = 0, the block diagonal matrix D and the
           multipliers used to obtain the factor U or L from the
           factorization A = U\*D\*U\*\*T or A = L\*D\*L\*\*T as computed by
           DSYTRF.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the N-by-NRHS right hand side matrix B.
           On exit, if INFO = 0, the N-by-NRHS solution matrix X.

    - **ipiv** -- 
           IPIV is INTEGER array, dimension (N)
           Details of the interchanges and the block structure of D, as
           determined by DSYTRF.  If IPIV(k) > 0, then rows and columns
           k and IPIV(k) were interchanged, and D(k,k) is a 1-by-1
           diagonal block.  If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0,
           then rows and columns k-1 and -IPIV(k) were interchanged and
           D(k-1:k,k-1:k) is a 2-by-2 diagonal block.  If UPLO = 'L' and
           IPIV(k) = IPIV(k+1) < 0, then rows and columns k+1 and
           -IPIV(k) were interchanged and D(k:k+1,k:k+1) is a 2-by-2
           diagonal block.

    - **info** -- 
           INFO is INTEGER
           = 0: successful exit
           < 0: if INFO = -i, the i-th argument had an illegal value
           > 0: if INFO = i, D(i,i) is exactly zero.  The factorization
                has been completed, but the block diagonal matrix D is
                exactly singular, so the solution could not be computed.

DSYSV computes the solution to a real system of linear equations

        A * X = B,

where A is an N-by-N symmetric matrix and X and B are N-by-NRHS
matrices.
The diagonal pivoting method is used to factor A as

        A = U * D * U**T,  if UPLO = 'U', or
        A = L * D * L**T,  if UPLO = 'L',

where U (or L) is a product of permutation and unit upper (lower)
triangular matrices, and D is symmetric and block diagonal with
1-by-1 and 2-by-2 diagonal blocks.  The factored form of A is then
used to solve the system of equations A \* X = B.

*/
static VALUE
lapack_s_dsysv(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    narray_t *na1, *na2;
    size_t n, nb, nrhs;
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{OVERWRITE,2}};
    size_t shape[2];
    ndfunc_arg_out_t aout[2] = {{cInt,1,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsysv, NO_LOOP|NDF_EXTRACT, 2,2, ain,aout};
    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[2] = {id_order,id_uplo};
    VALUE opts[2] = {Qundef,Qundef};

    CHECK_FUNC(func_p,"dsysv");

    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.order = option_order(opts[0]);
    g.uplo = option_uplo(opts[1]);

    COPY_OR_CAST_TO(a,cT);
    COPY_OR_CAST_TO(b,cT);
    GetNArray(a, na1);
    GetNArray(b, na2);
    CHECK_DIM_GE(na1, 2);
    CHECK_DIM_GE(na2, 1);
    CHECK_SQUARE("matrix a",na1);
    n = COL_SIZE(na1);
    if (NA_NDIM(na2) == 1) {
        ain[1].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col=a.row=%"SZF"u b.row=%"SZF"u", n, nb);
    }
    shape[0] = n;
    shape[1] = nrhs;
#if !IPIV
    ndf.aout++;
    ndf.nout--;
#endif

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

#if IPIV
    return rb_ary_concat(rb_assoc_new(a,b),ans);
#else
    return rb_ary_new3(3,a,b,ans);
#endif
}

#undef func_p
#undef args_t
#undef UPLO
#undef IPIV


#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/lapack/gen/../tmpl/gesv.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/lapack/gen/../tmpl/gesv.c"
#define UPLO 1
#define IPIV 0
#define args_t dposv_args_t
#define func_p dposv_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dposv_t dposv_p = 0;

static void
iter_lapack_s_dposv(na_loop_t * const lp)
{
    dtype *a, *b;
    int   *info;
    int    n, nrhs;
    int    lda, ldb;
    args_t *g;
#if IPIV
    int *ipiv;
    ipiv = (int*)NDL_PTR(lp,2);
    info = (int*)NDL_PTR(lp,3);
#else
    info = (int*)NDL_PTR(lp,2);
#endif
    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
    g = (args_t*)(lp->opt_ptr);

    n = NDL_SHAPE(lp,0)[0];
    lda = NDL_STEP(lp,0) / sizeof(dtype);
    if (lp->args[1].ndim == 1) {
        nrhs = 1;
        ldb = (g->order==LAPACK_COL_MAJOR) ? n : 1;
    } else {
        nrhs = NDL_SHAPE(lp,1)[1];
        ldb = NDL_STEP(lp,1) / sizeof(dtype);
    }
    //printf("order=%d n=%d nrhs=%d lda=%d ldb=%d b.ndim=%d\n",
    //       g->order,n,nrhs,lda,ldb,lp->args[1].ndim);
    *info = (*func_p)( g->order, g->uplo,
                       n, nrhs, a, lda,  b, ldb );
    CHECK_ERROR(*info);
}

/*
  @overload dposv(a, b, [uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed, output: lu).
  @param b [Numo::DFloat]  vector (>=1-dimentional NArray, inplace allowed, output: x).
  @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 [[a, b, info]] Array<Numo::DFloat, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the leading
           N-by-N upper triangular part of A contains the upper
           triangular part of the matrix A, and the strictly lower
           triangular part of A is not referenced.  If UPLO = 'L', the
           leading N-by-N lower triangular part of A contains the lower
           triangular part of the matrix A, and the strictly upper
           triangular part of A is not referenced.
           On exit, if INFO = 0, the factor U or L from the Cholesky
           factorization A = U\*\*T\*U or A = L\*L\*\*T.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the N-by-NRHS right hand side matrix B.
           On exit, if INFO = 0, the N-by-NRHS solution matrix X.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, the leading minor of order i of A is not
                 positive definite, so the factorization could not be
                 completed, and the solution has not been computed.

DPOSV computes the solution to a real system of linear equations

        A * X = B,

where A is an N-by-N symmetric positive definite matrix and X and B
are N-by-NRHS matrices.
The Cholesky decomposition is used to factor A as

        A = U**T* U,  if UPLO = 'U', or
        A = L * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is a lower triangular
matrix.  The factored form of A is then used to solve the system of
equations A \* X = B.

*/
static VALUE
lapack_s_dposv(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    narray_t *na1, *na2;
    size_t n, nb, nrhs;
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{OVERWRITE,2}};
    size_t shape[2];
    ndfunc_arg_out_t aout[2] = {{cInt,1,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dposv, NO_LOOP|NDF_EXTRACT, 2,2, ain,aout};
    args_t g;
    VALUE kw_hash = Qnil;
    ID kw_table[2] = {id_order,id_uplo};
    VALUE opts[2] = {Qundef,Qundef};

    CHECK_FUNC(func_p,"dposv");

    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.order = option_order(opts[0]);
    g.uplo = option_uplo(opts[1]);

    COPY_OR_CAST_TO(a,cT);
    COPY_OR_CAST_TO(b,cT);
    GetNArray(a, na1);
    GetNArray(b, na2);
    CHECK_DIM_GE(na1, 2);
    CHECK_DIM_GE(na2, 1);
    CHECK_SQUARE("matrix a",na1);
    n = COL_SIZE(na1);
    if (NA_NDIM(na2) == 1) {
        ain[1].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col=a.row=%"SZF"u b.row=%"SZF"u", n, nb);
    }
    shape[0] = n;
    shape[1] = nrhs;
#if !IPIV
    ndf.aout++;
    ndf.nout--;
#endif

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

#if IPIV
    return rb_ary_concat(rb_assoc_new(a,b),ans);
#else
    return rb_ary_new3(3,a,b,ans);
#endif
}

#undef func_p
#undef args_t
#undef UPLO
#undef IPIV


#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/lapack/gen/../tmpl/gesvd.c"
//
#define SDD 0
#define args_t dgesvd_args_t
#define func_p dgesvd_p

typedef struct {
    int order;
    char jobu, jobvt, jobz;
    rtype *superb;
} args_t;

static dgesvd_t func_p = 0;

static void
iter_lapack_s_dgesvd(na_loop_t * const lp)
{
    dtype *a, *u=0, *vt=0;
    rtype *s;
    int   *info;
    int    m, n, lda, ldu, ldvt, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    s = (rtype*)NDL_PTR(lp,1);
    u = (dtype*)NDL_PTR(lp,2);
    vt = (dtype*)NDL_PTR(lp,3);
    info = (int*)NDL_PTR(lp,4);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldu = NDL_STEP(lp,2) / sizeof(dtype);
    if (ldu == 0) { ldu = m; } // jobu == 'O' or 'N'
    ldvt = NDL_STEP(lp,3) / sizeof(dtype);
    if (ldvt == 0) { ldvt = n; } // jobvt == 'O' or 'N'

    //printf("order=%d jobu=%c jobvt=%c jobz=%c m=%d n=%d lda=%d ldu=%d ldvt=%d\n",g->order,g->jobu, g->jobvt,g->jobz, m,n,lda,ldu,ldvt);

    /**/
    *info = (*func_p)( g->order, g->jobu, g->jobvt, m, n, a, lda, s,
                       u, ldu, vt, ldvt , g->superb );
    CHECK_ERROR(*info);
}

/*
  @overload dgesvd(a, [jobu:'A', jobvt:'A', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed if job\*=='O').
  @param jobu [String or Symbol]  If 'A': all M columns of U are returned in array U, If 'S': the first min(m,n) columns of U (the left singular vectors) are returned in the array U, If 'O': the first min(m,n) columns of U (the left singular vectors) are overwritten on the array A, If 'N': no columns of U (no left singular vectors) are computed. (default='A')
  @param jobvt [String or Symbol]  If 'A': all N rows of V\*\*T are returned in the array VT;If 'S': the first min(m,n) rows of V\*\*T (the right singular vectors) are returned in the array VT;If 'O': the first min(m,n) rows of V\*\*T (the right singular vectors) are overwritten on the array A;If 'N': no rows of V\*\*T (no right singular vectors) are computed. (default='A')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[sigma, u, vt, info]] Array<Numo::DFloat, Numo::DFloat, Numo::DFloat, Integer>


    - **u** -- 
           U is DOUBLE PRECISION array, dimension (LDU,UCOL)
           (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
           If JOBU = 'A', U contains the M-by-M orthogonal matrix U;
           if JOBU = 'S', U contains the first min(m,n) columns of U
           (the left singular vectors, stored columnwise);
           if JOBU = 'N' or 'O', U is not referenced.

    - **vt** -- 
           VT is DOUBLE PRECISION array, dimension (LDVT,N)
           If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
           V\*\*T;
           if JOBVT = 'S', VT contains the first min(m,n) rows of
           V\*\*T (the right singular vectors, stored rowwise);
           if JOBVT = 'N' or 'O', VT is not referenced.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit.
           < 0:  if INFO = -i, the i-th argument had an illegal value.
           > 0:  if DBDSQR did not converge, INFO specifies how many
                 superdiagonals of an intermediate bidiagonal form B
                 did not converge to zero. See the description of WORK
                 above for details.

DGESVD computes the singular value decomposition (SVD) of a real
M-by-N matrix A, optionally computing the left and/or right singular
vectors. The SVD is written

        A = U * SIGMA * transpose(V)

where SIGMA is an M-by-N matrix which is zero except for its
min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA
are the singular values of A; they are real and non-negative, and
are returned in descending order.  The first min(m,n) columns of
U and V are the left and right singular vectors of A.
Note that the routine returns V\*\*T, not V.

*/
static VALUE
lapack_s_dgesvd(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#if !SDD
    VALUE tmpbuf;
#endif
    VALUE a, ans;
    int   m, n, min_mn, tmp;
    narray_t *na1;
    size_t shape_s[1], shape_u[2], shape_vt[2];
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[4] = {{cRT,1,shape_s},{cT,2,shape_u},
                                {cT,2,shape_vt},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgesvd, NO_LOOP|NDF_EXTRACT, 1, 4, ain, aout};

    args_t g;
    VALUE opts[4] = {Qundef,Qundef,Qundef,Qundef};
    VALUE kw_hash = Qnil;
    ID kw_table[4] = {id_order,id_jobu,id_jobvt,id_jobz};

    CHECK_FUNC(func_p,"dgesvd");

    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 4, opts);
    g.order = option_order(opts[0]);
#if SDD
    g.jobz = option_job(opts[3],'A','N');
    g.jobu = g.jobvt = g.jobz;
#else
    g.jobu  = option_job(opts[1],'A','N');
    g.jobvt = option_job(opts[2],'A','N');
    if (g.jobu=='O' && g.jobvt=='O') {
        rb_raise(rb_eArgError,"JOBVT and JOBU cannot both be 'O'");
    }
#endif

    if (g.jobu=='O' || g.jobvt=='O') {
        if (CLASS_OF(a) != cT) {
            rb_raise(rb_eTypeError,"type of matrix a is invalid for overwrite");
        }
    } else {
        COPY_OR_CAST_TO(a,cT);
    }

    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);

#if SDD
    if (g.jobz=='O') {
        if (m >= n) { g.jobvt='A';} else { g.jobu='A';}
    }
#endif

    // output S
    shape_s[0] = min_mn = min_(m,n);

    // output U
    switch(g.jobu){
    case 'A':
        shape_u[0] = m;
        shape_u[1] = m;
        break;
    case 'S':
        shape_u[0] = m;
        shape_u[1] = min_mn;
        SWAP_IFCOL(g.order,shape_u[0],shape_u[1]);
        break;
    case 'O':
    case 'N':
        aout[1].dim = 0; // dummy
        break;
    default:
        rb_raise(rb_eArgError,"invalid option: jobu='%c'",g.jobu);
    }
    // output VT
    switch(g.jobvt){
    case 'A':
        shape_vt[0] = n;
        shape_vt[1] = n;
        break;
    case 'S':
        shape_vt[0] = min_mn;
        shape_vt[1] = n;
        SWAP_IFCOL(g.order, shape_vt[0], shape_vt[1]);
        break;
    case 'O':
    case 'N':
        aout[2].dim = 0; // dummy
        break;
    default:
        rb_raise(rb_eArgError,"invalid option: jobvt='%c'",g.jobvt);
    }
#if !SDD
    g.superb = (rtype*)rb_alloc_tmp_buffer(&tmpbuf, min_mn*sizeof(rtype));
#endif

    ans = na_ndloop3(&ndf, &g, 1, a);

#if !SDD
    rb_free_tmp_buffer(&tmpbuf);
#endif

    if (g.jobu=='O')      { RARRAY_ASET(ans,1,a); } else
    if (aout[1].dim == 0) { RARRAY_ASET(ans,1,Qnil); }
    if (g.jobvt=='O')     { RARRAY_ASET(ans,2,a); } else
    if (aout[2].dim == 0) { RARRAY_ASET(ans,2,Qnil); }
    return ans;
}

#undef args_t
#undef func_p
#undef SDD


#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/lapack/gen/../tmpl/gesvd.c"
//
#define SDD 1
#define args_t dgesdd_args_t
#define func_p dgesdd_p

typedef struct {
    int order;
    char jobu, jobvt, jobz;
    rtype *superb;
} args_t;

static dgesdd_t func_p = 0;

static void
iter_lapack_s_dgesdd(na_loop_t * const lp)
{
    dtype *a, *u=0, *vt=0;
    rtype *s;
    int   *info;
    int    m, n, lda, ldu, ldvt, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    s = (rtype*)NDL_PTR(lp,1);
    u = (dtype*)NDL_PTR(lp,2);
    vt = (dtype*)NDL_PTR(lp,3);
    info = (int*)NDL_PTR(lp,4);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldu = NDL_STEP(lp,2) / sizeof(dtype);
    if (ldu == 0) { ldu = m; } // jobu == 'O' or 'N'
    ldvt = NDL_STEP(lp,3) / sizeof(dtype);
    if (ldvt == 0) { ldvt = n; } // jobvt == 'O' or 'N'

    //printf("order=%d jobu=%c jobvt=%c jobz=%c m=%d n=%d lda=%d ldu=%d ldvt=%d\n",g->order,g->jobu, g->jobvt,g->jobz, m,n,lda,ldu,ldvt);

    /**/
    *info = (*func_p)( g->order, g->jobz, m, n, a, lda, s,
                       u, ldu, vt, ldvt  );
    CHECK_ERROR(*info);
}

/*
  @overload dgesdd(a, [jobz:'A', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed if job\*=='O').
  @param jobz [String or Symbol]  If 'A':  all M columns of U and all N rows of V\*\*H are returned in the arrays U and VT; If 'S':  the first min(M,N) columns of U and the first min(M,N) rows of V\*\*H are returned in the arrays U and VT;If 'O':  If M >= N, the first N columns of U are overwritten in the array A and all rows of V\*\*H are returned in the array VT; otherwise, all columns of U are returned in the array U and the first M rows of V\*\*H are overwritten in the array A;If 'N':  no columns of U or rows of V\*\*H are computed. (default='A')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[sigma, u, vt, info]] Array<Numo::DFloat, Numo::DFloat, Numo::DFloat, Integer>


    - **u** -- 
           U is DOUBLE PRECISION array, dimension (LDU,UCOL)
           UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N;
           UCOL = min(M,N) if JOBZ = 'S'.
           If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M
           orthogonal matrix U;
           if JOBZ = 'S', U contains the first min(M,N) columns of U
           (the left singular vectors, stored columnwise);
           if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced.

    - **vt** -- 
           VT is DOUBLE PRECISION array, dimension (LDVT,N)
           If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the
           N-by-N orthogonal matrix V\*\*T;
           if JOBZ = 'S', VT contains the first min(M,N) rows of
           V\*\*T (the right singular vectors, stored rowwise);
           if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit.
           < 0:  if INFO = -i, the i-th argument had an illegal value.
           > 0:  DBDSDC did not converge, updating process failed.

DGESDD computes the singular value decomposition (SVD) of a real
M-by-N matrix A, optionally computing the left and right singular
vectors.  If singular vectors are desired, it uses a
divide-and-conquer algorithm.
The SVD is written

        A = U * SIGMA * transpose(V)

where SIGMA is an M-by-N matrix which is zero except for its
min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA
are the singular values of A; they are real and non-negative, and
are returned in descending order.  The first min(m,n) columns of
U and V are the left and right singular vectors of A.
Note that the routine returns VT = V\*\*T, not V.
The divide and conquer algorithm makes very mild assumptions about
floating point arithmetic. It will work on machines with a guard
digit in add/subtract, or on those binary machines without guard
digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
Cray-2. It could conceivably fail on hexadecimal or decimal machines
without guard digits, but we know of none.

*/
static VALUE
lapack_s_dgesdd(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#if !SDD
    VALUE tmpbuf;
#endif
    VALUE a, ans;
    int   m, n, min_mn, tmp;
    narray_t *na1;
    size_t shape_s[1], shape_u[2], shape_vt[2];
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[4] = {{cRT,1,shape_s},{cT,2,shape_u},
                                {cT,2,shape_vt},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgesdd, NO_LOOP|NDF_EXTRACT, 1, 4, ain, aout};

    args_t g;
    VALUE opts[4] = {Qundef,Qundef,Qundef,Qundef};
    VALUE kw_hash = Qnil;
    ID kw_table[4] = {id_order,id_jobu,id_jobvt,id_jobz};

    CHECK_FUNC(func_p,"dgesdd");

    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 4, opts);
    g.order = option_order(opts[0]);
#if SDD
    g.jobz = option_job(opts[3],'A','N');
    g.jobu = g.jobvt = g.jobz;
#else
    g.jobu  = option_job(opts[1],'A','N');
    g.jobvt = option_job(opts[2],'A','N');
    if (g.jobu=='O' && g.jobvt=='O') {
        rb_raise(rb_eArgError,"JOBVT and JOBU cannot both be 'O'");
    }
#endif

    if (g.jobu=='O' || g.jobvt=='O') {
        if (CLASS_OF(a) != cT) {
            rb_raise(rb_eTypeError,"type of matrix a is invalid for overwrite");
        }
    } else {
        COPY_OR_CAST_TO(a,cT);
    }

    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);

#if SDD
    if (g.jobz=='O') {
        if (m >= n) { g.jobvt='A';} else { g.jobu='A';}
    }
#endif

    // output S
    shape_s[0] = min_mn = min_(m,n);

    // output U
    switch(g.jobu){
    case 'A':
        shape_u[0] = m;
        shape_u[1] = m;
        break;
    case 'S':
        shape_u[0] = m;
        shape_u[1] = min_mn;
        SWAP_IFCOL(g.order,shape_u[0],shape_u[1]);
        break;
    case 'O':
    case 'N':
        aout[1].dim = 0; // dummy
        break;
    default:
        rb_raise(rb_eArgError,"invalid option: jobu='%c'",g.jobu);
    }
    // output VT
    switch(g.jobvt){
    case 'A':
        shape_vt[0] = n;
        shape_vt[1] = n;
        break;
    case 'S':
        shape_vt[0] = min_mn;
        shape_vt[1] = n;
        SWAP_IFCOL(g.order, shape_vt[0], shape_vt[1]);
        break;
    case 'O':
    case 'N':
        aout[2].dim = 0; // dummy
        break;
    default:
        rb_raise(rb_eArgError,"invalid option: jobvt='%c'",g.jobvt);
    }
#if !SDD
    g.superb = (rtype*)rb_alloc_tmp_buffer(&tmpbuf, min_mn*sizeof(rtype));
#endif

    ans = na_ndloop3(&ndf, &g, 1, a);

#if !SDD
    rb_free_tmp_buffer(&tmpbuf);
#endif

    if (g.jobu=='O')      { RARRAY_ASET(ans,1,a); } else
    if (aout[1].dim == 0) { RARRAY_ASET(ans,1,Qnil); }
    if (g.jobvt=='O')     { RARRAY_ASET(ans,2,a); } else
    if (aout[2].dim == 0) { RARRAY_ASET(ans,2,Qnil); }
    return ans;
}

#undef args_t
#undef func_p
#undef SDD


#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/lapack/gen/../tmpl/gels.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/lapack/gen/../tmpl/gels.c"
#define LSS 0
#define LSD 0
#define LSY 0
#define args_t dgels_args_t
#define func_p dgels_p

typedef struct {
    int   order;
    char  trans;
    rtype rcond;
} args_t;

static dgels_t func_p = 0;

static void
iter_lapack_s_dgels(na_loop_t * const lp)
{
    dtype *a, *b;
    int   *info;
    int    m, n, nb, nrhs, lda, ldb, tmp;
    args_t *g;
#if LSS
    
    rtype *s; // or jpvt
    int   *rank;
#endif

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if LSS
    s = (rtype*)NDL_PTR(lp,2);
    rank = (int*)NDL_PTR(lp,3);
#endif
    info = (int*)NDL_PTR(lp,2+LSS*2);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);

    if (lp->args[1].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1)[0];
        nrhs = NDL_SHAPE(lp,1)[1];
        ldb = nrhs;
        SWAP_IFCOL(g->order,nb,nrhs);
    }

    //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);

#if LSS
    *info = (*func_p)(g->order, m, n, nrhs, a, lda, b, ldb, s, g->rcond, rank);
#else
    *info = (*func_p)(g->order, g->trans, m, n, nrhs, a, lda, b, ldb);
#endif
    CHECK_ERROR(*info);
}

/*

  @overload dgels(a, b, trans:'N', order:'R')
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, b, info]] Array<Numo::DFloat, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit,
             if M >= N, A is overwritten by details of its QR
                        factorization as returned by DGEQRF;
             if M <  N, A is overwritten by details of its LQ
                        factorization as returned by DGELQF.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the matrix B of right hand side vectors, stored
           columnwise; B is M-by-NRHS if TRANS = 'N', or N-by-NRHS
           if TRANS = 'T'.
           On exit, if INFO = 0, B is overwritten by the solution
           vectors, stored columnwise:
           if TRANS = 'N' and m >= n, rows 1 to n of B contain the least
           squares solution vectors; the residual sum of squares for the
           solution in each column is given by the sum of squares of
           elements N+1 to M in that column;
           if TRANS = 'N' and m < n, rows 1 to N of B contain the
           minimum norm solution vectors;
           if TRANS = 'T' and m >= n, rows 1 to M of B contain the
           minimum norm solution vectors;
           if TRANS = 'T' and m < n, rows 1 to M of B contain the
           least squares solution vectors; the residual sum of squares
           for the solution in each column is given by the sum of
           squares of elements M+1 to N in that column.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO =  i, the i-th diagonal element of the
                 triangular factor of A is zero, so that A does not have
                 full rank; the least squares solution could not be
                 computed.

DGELS solves overdetermined or underdetermined real linear systems
involving an M-by-N matrix A, or its transpose, using a QR or LQ
factorization of A.  It is assumed that A has full rank.
The following options are provided:

1. If TRANS = 'N' and m >= n:  find the least squares solution of
   an overdetermined system, i.e., solve the least squares problem
                minimize || B - A*X ||.

2. If TRANS = 'N' and m < n:  find the minimum norm solution of
   an underdetermined system A \* X = B.

3. If TRANS = 'T' and m >= n:  find the minimum norm solution of
   an underdetermined system A\*\*T \* X = B.

4. If TRANS = 'T' and m < n:  find the least squares solution of
   an overdetermined system, i.e., solve the least squares problem
                minimize || B - A**T * X ||.

Several right hand side vectors b and solution vectors x can be
handled in a single call; they are stored as the columns of the
M-by-NRHS right hand side matrix B and the N-by-NRHS solution
matrix X.

*/
static VALUE
lapack_s_dgels(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   m, n, nb, nrhs, tmp;
    int   max_mn;
    narray_t *na1, *na2;
#if LSY
    narray_t *na3;
    VALUE jpvt;
#endif
#if LSS
    size_t shape_s[1];
#endif
    /**/
    ndfunc_arg_in_t ain[2+LSS] = {{OVERWRITE,2},{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1+LSS*2] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgels, NO_LOOP|NDF_EXTRACT, 2, 1+LSS*2, ain, aout};

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

    CHECK_FUNC(func_p,"dgels");

#if LSY
    rb_scan_args(argc, argv, "3:", &a, &b, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
#if LSS
    g.rcond = NUM2DBL(option_value(opts[2],DBL2NUM(-1)));
#else
    g.trans = option_trans(opts[1]);
#endif

    //A is DOUBLE PRECISION array, dimension (LDA,N)
    //On entry, the M-by-N matrix A.
    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);

    //B is DOUBLE PRECISION array, dimension (LDB,NRHS)
    //B is M-by-NRHS if TRANS = 'N'
    //     N-by-NRHS if TRANS = 'T'
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);

    //The number of rows of the matrix A.
    m = ROW_SIZE(na1);
    //The number of columns of the matrix A.
    n = COL_SIZE(na1);
    max_mn = (m > n) ? m : n;
    SWAP_IFCOL(g.order,m,n);

#if LSY
    ndf.nin++;
    ndf.nout--;
    ndf.aout++;
    COPY_OR_CAST_TO(jpvt,cInt);
    GetNArray(jpvt, na3);
    CHECK_DIM_GE(na3, 1);
    { int jpvt_sz = COL_SIZE(na3);
      CHECK_INT_EQ("jpvt_size",jpvt_sz,"n",n);
    }
#elif LSS
    shape_s[0] = (m < n) ? m : n;
#endif

    //The number of columns of the matrix B.
    if (na2->ndim == 1) {
        ain[1].dim = 1; // reduce dimension
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        //The number of rows of the matrix B.
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        SWAP_IFCOL(g.order,nb,nrhs);
    }
    if (nb < max_mn) {
        rb_raise(nary_eShapeError,
                 "ldb should be >= max(m,n): ldb=%d m=%d n=%d",nb,m,n);
    }

    // ndloop
#if LSY
    ans = na_ndloop3(&ndf, &g, 3, a, b, jpvt);
#else
    ans = na_ndloop3(&ndf, &g, 2, a, b);
#endif

    // return
#if LSY
    return rb_ary_concat(rb_ary_new3(3,a,b,jpvt),ans);
#elif LSD
    rb_ary_unshift(ans,b); return ans;
#elif LSS
    return rb_ary_concat(rb_ary_new3(2,a,b),ans);
#else
    return rb_ary_new3(3,a,b,ans);
#endif
}

#undef func_p
#undef args_t
#undef LSS
#undef LSD
#undef LSY


#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/lapack/gen/../tmpl/gels.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/lapack/gen/../tmpl/gels.c"
#define LSS 1
#define LSD 0
#define LSY 0
#define args_t dgelss_args_t
#define func_p dgelss_p

typedef struct {
    int   order;
    char  trans;
    rtype rcond;
} args_t;

static dgelss_t func_p = 0;

static void
iter_lapack_s_dgelss(na_loop_t * const lp)
{
    dtype *a, *b;
    int   *info;
    int    m, n, nb, nrhs, lda, ldb, tmp;
    args_t *g;
#if LSS
    
    rtype *s; // or jpvt
    int   *rank;
#endif

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if LSS
    s = (rtype*)NDL_PTR(lp,2);
    rank = (int*)NDL_PTR(lp,3);
#endif
    info = (int*)NDL_PTR(lp,2+LSS*2);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);

    if (lp->args[1].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1)[0];
        nrhs = NDL_SHAPE(lp,1)[1];
        ldb = nrhs;
        SWAP_IFCOL(g->order,nb,nrhs);
    }

    //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);

#if LSS
    *info = (*func_p)(g->order, m, n, nrhs, a, lda, b, ldb, s, g->rcond, rank);
#else
    *info = (*func_p)(g->order, g->trans, m, n, nrhs, a, lda, b, ldb);
#endif
    CHECK_ERROR(*info);
}

/*

  @overload dgelss(a, b, rcond:-1, order:'R')
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param [Float] rcond  RCOND is used to determine the effective rank of A. Singular values S(i) <= RCOND*S(1) are treated as zero. If RCOND < 0, machine precision is used instead.
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, b, s, rank, info]] Array<Numo::DFloat, Numo::DFloat, Numo::DFloat, Integer, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit, the first min(m,n) rows of A are overwritten with
           its right singular vectors, stored rowwise.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the M-by-NRHS right hand side matrix B.
           On exit, B is overwritten by the N-by-NRHS solution
           matrix X.  If m >= n and RANK = n, the residual
           sum-of-squares for the solution in the i-th column is given
           by the sum of squares of elements n+1:m in that column.

    - **s** -- 
           S is DOUBLE PRECISION array, dimension (min(M,N))
           The singular values of A in decreasing order.
           The condition number of A in the 2-norm = S(1)/S(min(m,n)).

    - **rank** -- 
           RANK is INTEGER
           The effective rank of A, i.e., the number of singular values
           which are greater than RCOND\*S(1).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value.
           > 0:  the algorithm for computing the SVD failed to converge;
                 if INFO = i, i off-diagonal elements of an intermediate
                 bidiagonal form did not converge to zero.

DGELSS computes the minimum norm solution to a real linear least
squares problem:
Minimize 2-norm(| b - A\*x |).
using the singular value decomposition (SVD) of A. A is an M-by-N
matrix which may be rank-deficient.
Several right hand side vectors b and solution vectors x can be
handled in a single call; they are stored as the columns of the
M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix
X.
The effective rank of A is determined by treating as zero those
singular values which are less than RCOND times the largest singular
value.

*/
static VALUE
lapack_s_dgelss(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   m, n, nb, nrhs, tmp;
    int   max_mn;
    narray_t *na1, *na2;
#if LSY
    narray_t *na3;
    VALUE jpvt;
#endif
#if LSS
    size_t shape_s[1];
#endif
    /**/
    ndfunc_arg_in_t ain[2+LSS] = {{OVERWRITE,2},{OVERWRITE,2},{cInt,1}};
    ndfunc_arg_out_t aout[1+LSS*2] = {{cT,1,shape_s},{cInt,0},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgelss, NO_LOOP|NDF_EXTRACT, 2, 1+LSS*2, ain, aout};

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

    CHECK_FUNC(func_p,"dgelss");

#if LSY
    rb_scan_args(argc, argv, "3:", &a, &b, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
#if LSS
    g.rcond = NUM2DBL(option_value(opts[2],DBL2NUM(-1)));
#else
    g.trans = option_trans(opts[1]);
#endif

    //A is DOUBLE PRECISION array, dimension (LDA,N)
    //On entry, the M-by-N matrix A.
    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);

    //B is DOUBLE PRECISION array, dimension (LDB,NRHS)
    //B is M-by-NRHS if TRANS = 'N'
    //     N-by-NRHS if TRANS = 'T'
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);

    //The number of rows of the matrix A.
    m = ROW_SIZE(na1);
    //The number of columns of the matrix A.
    n = COL_SIZE(na1);
    max_mn = (m > n) ? m : n;
    SWAP_IFCOL(g.order,m,n);

#if LSY
    ndf.nin++;
    ndf.nout--;
    ndf.aout++;
    COPY_OR_CAST_TO(jpvt,cInt);
    GetNArray(jpvt, na3);
    CHECK_DIM_GE(na3, 1);
    { int jpvt_sz = COL_SIZE(na3);
      CHECK_INT_EQ("jpvt_size",jpvt_sz,"n",n);
    }
#elif LSS
    shape_s[0] = (m < n) ? m : n;
#endif

    //The number of columns of the matrix B.
    if (na2->ndim == 1) {
        ain[1].dim = 1; // reduce dimension
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        //The number of rows of the matrix B.
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        SWAP_IFCOL(g.order,nb,nrhs);
    }
    if (nb < max_mn) {
        rb_raise(nary_eShapeError,
                 "ldb should be >= max(m,n): ldb=%d m=%d n=%d",nb,m,n);
    }

    // ndloop
#if LSY
    ans = na_ndloop3(&ndf, &g, 3, a, b, jpvt);
#else
    ans = na_ndloop3(&ndf, &g, 2, a, b);
#endif

    // return
#if LSY
    return rb_ary_concat(rb_ary_new3(3,a,b,jpvt),ans);
#elif LSD
    rb_ary_unshift(ans,b); return ans;
#elif LSS
    return rb_ary_concat(rb_ary_new3(2,a,b),ans);
#else
    return rb_ary_new3(3,a,b,ans);
#endif
}

#undef func_p
#undef args_t
#undef LSS
#undef LSD
#undef LSY


#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/lapack/gen/../tmpl/gels.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/lapack/gen/../tmpl/gels.c"
#define LSS 1
#define LSD 1
#define LSY 0
#define args_t dgelsd_args_t
#define func_p dgelsd_p

typedef struct {
    int   order;
    char  trans;
    rtype rcond;
} args_t;

static dgelsd_t func_p = 0;

static void
iter_lapack_s_dgelsd(na_loop_t * const lp)
{
    dtype *a, *b;
    int   *info;
    int    m, n, nb, nrhs, lda, ldb, tmp;
    args_t *g;
#if LSS
    
    rtype *s; // or jpvt
    int   *rank;
#endif

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if LSS
    s = (rtype*)NDL_PTR(lp,2);
    rank = (int*)NDL_PTR(lp,3);
#endif
    info = (int*)NDL_PTR(lp,2+LSS*2);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);

    if (lp->args[1].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1)[0];
        nrhs = NDL_SHAPE(lp,1)[1];
        ldb = nrhs;
        SWAP_IFCOL(g->order,nb,nrhs);
    }

    //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);

#if LSS
    *info = (*func_p)(g->order, m, n, nrhs, a, lda, b, ldb, s, g->rcond, rank);
#else
    *info = (*func_p)(g->order, g->trans, m, n, nrhs, a, lda, b, ldb);
#endif
    CHECK_ERROR(*info);
}

/*

  @overload dgelsd(a, b, rcond:-1, order:'R')
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param [Float] rcond  RCOND is used to determine the effective rank of A. Singular values S(i) <= RCOND*S(1) are treated as zero. If RCOND < 0, machine precision is used instead.
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[b, s, rank, info]] Array<Numo::DFloat, Numo::DFloat, Integer, Integer>

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the M-by-NRHS right hand side matrix B.
           On exit, B is overwritten by the N-by-NRHS solution
           matrix X.  If m >= n and RANK = n, the residual
           sum-of-squares for the solution in the i-th column is given
           by the sum of squares of elements n+1:m in that column.

    - **s** -- 
           S is DOUBLE PRECISION array, dimension (min(M,N))
           The singular values of A in decreasing order.
           The condition number of A in the 2-norm = S(1)/S(min(m,n)).

    - **rank** -- 
           RANK is INTEGER
           The effective rank of A, i.e., the number of singular values
           which are greater than RCOND\*S(1).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value.
           > 0:  the algorithm for computing the SVD failed to converge;
                 if INFO = i, i off-diagonal elements of an intermediate
                 bidiagonal form did not converge to zero.

DGELSD computes the minimum-norm solution to a real linear least
squares problem:

        minimize 2-norm(| b - A*x |)

using the singular value decomposition (SVD) of A. A is an M-by-N
matrix which may be rank-deficient.
Several right hand side vectors b and solution vectors x can be
handled in a single call; they are stored as the columns of the
M-by-NRHS right hand side matrix B and the N-by-NRHS solution
matrix X.
The problem is solved in three steps:

(1) Reduce the coefficient matrix A to bidiagonal form with
    Householder transformations, reducing the original problem
    into a "bidiagonal least squares problem" (BLS)

(2) Solve the BLS using a divide and conquer approach.

(3) Apply back all the Householder transformations to solve
    the original least squares problem.

The effective rank of A is determined by treating as zero those
singular values which are less than RCOND times the largest singular
value.
The divide and conquer algorithm makes very mild assumptions about
floating point arithmetic. It will work on machines with a guard
digit in add/subtract, or on those binary machines without guard
digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
Cray-2. It could conceivably fail on hexadecimal or decimal machines
without guard digits, but we know of none.

*/
static VALUE
lapack_s_dgelsd(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   m, n, nb, nrhs, tmp;
    int   max_mn;
    narray_t *na1, *na2;
#if LSY
    narray_t *na3;
    VALUE jpvt;
#endif
#if LSS
    size_t shape_s[1];
#endif
    /**/
    ndfunc_arg_in_t ain[2+LSS] = {{OVERWRITE,2},{OVERWRITE,2},{cInt,1}};
    ndfunc_arg_out_t aout[1+LSS*2] = {{cT,1,shape_s},{cInt,0},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgelsd, NO_LOOP|NDF_EXTRACT, 2, 1+LSS*2, ain, aout};

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

    CHECK_FUNC(func_p,"dgelsd");

#if LSY
    rb_scan_args(argc, argv, "3:", &a, &b, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
#if LSS
    g.rcond = NUM2DBL(option_value(opts[2],DBL2NUM(-1)));
#else
    g.trans = option_trans(opts[1]);
#endif

    //A is DOUBLE PRECISION array, dimension (LDA,N)
    //On entry, the M-by-N matrix A.
    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);

    //B is DOUBLE PRECISION array, dimension (LDB,NRHS)
    //B is M-by-NRHS if TRANS = 'N'
    //     N-by-NRHS if TRANS = 'T'
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);

    //The number of rows of the matrix A.
    m = ROW_SIZE(na1);
    //The number of columns of the matrix A.
    n = COL_SIZE(na1);
    max_mn = (m > n) ? m : n;
    SWAP_IFCOL(g.order,m,n);

#if LSY
    ndf.nin++;
    ndf.nout--;
    ndf.aout++;
    COPY_OR_CAST_TO(jpvt,cInt);
    GetNArray(jpvt, na3);
    CHECK_DIM_GE(na3, 1);
    { int jpvt_sz = COL_SIZE(na3);
      CHECK_INT_EQ("jpvt_size",jpvt_sz,"n",n);
    }
#elif LSS
    shape_s[0] = (m < n) ? m : n;
#endif

    //The number of columns of the matrix B.
    if (na2->ndim == 1) {
        ain[1].dim = 1; // reduce dimension
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        //The number of rows of the matrix B.
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        SWAP_IFCOL(g.order,nb,nrhs);
    }
    if (nb < max_mn) {
        rb_raise(nary_eShapeError,
                 "ldb should be >= max(m,n): ldb=%d m=%d n=%d",nb,m,n);
    }

    // ndloop
#if LSY
    ans = na_ndloop3(&ndf, &g, 3, a, b, jpvt);
#else
    ans = na_ndloop3(&ndf, &g, 2, a, b);
#endif

    // return
#if LSY
    return rb_ary_concat(rb_ary_new3(3,a,b,jpvt),ans);
#elif LSD
    rb_ary_unshift(ans,b); return ans;
#elif LSS
    return rb_ary_concat(rb_ary_new3(2,a,b),ans);
#else
    return rb_ary_new3(3,a,b,ans);
#endif
}

#undef func_p
#undef args_t
#undef LSS
#undef LSD
#undef LSY


#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/lapack/gen/../tmpl/gels.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/lapack/gen/../tmpl/gels.c"
#define LSS 1
#define LSD 0
#define LSY 1
#define args_t dgelsy_args_t
#define func_p dgelsy_p

typedef struct {
    int   order;
    char  trans;
    rtype rcond;
} args_t;

static dgelsy_t func_p = 0;

static void
iter_lapack_s_dgelsy(na_loop_t * const lp)
{
    dtype *a, *b;
    int   *info;
    int    m, n, nb, nrhs, lda, ldb, tmp;
    args_t *g;
#if LSS
    
    int *s; // or jpvt
    int   *rank;
#endif

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if LSS
    s = (int*)NDL_PTR(lp,2);
    rank = (int*)NDL_PTR(lp,3);
#endif
    info = (int*)NDL_PTR(lp,2+LSS*2);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);

    if (lp->args[1].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1)[0];
        nrhs = NDL_SHAPE(lp,1)[1];
        ldb = nrhs;
        SWAP_IFCOL(g->order,nb,nrhs);
    }

    //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);

#if LSS
    *info = (*func_p)(g->order, m, n, nrhs, a, lda, b, ldb, s, g->rcond, rank);
#else
    *info = (*func_p)(g->order, g->trans, m, n, nrhs, a, lda, b, ldb);
#endif
    CHECK_ERROR(*info);
}

/*

  @overload dgelsy(a, b, jpvt, rcond:-1, order:'R')
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param jpvt [Numo::Int]  matrix (>=2-dimentional NArray).
  @param [Float] rcond  RCOND is used to determine the effective rank of A. Singular values S(i) <= RCOND*S(1) are treated as zero. If RCOND < 0, machine precision is used instead.
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, b, jpvt, rank, info]] Array<Numo::DFloat, Numo::DFloat, Numo::Int, Integer, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit, A has been overwritten by details of its
           complete orthogonal factorization.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the M-by-NRHS right hand side matrix B.
           On exit, the N-by-NRHS solution matrix X.

    - **jpvt** -- 
           JPVT is INTEGER array, dimension (N)
           On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted
           to the front of AP, otherwise column i is a free column.
           On exit, if JPVT(i) = k, then the i-th column of AP
           was the k-th column of A.

    - **rank** -- 
           RANK is INTEGER
           The effective rank of A, i.e., the order of the submatrix
           R11.  This is the same as the order of the submatrix T11
           in the complete orthogonal factorization of A.

    - **info** -- 
           INFO is INTEGER
           = 0: successful exit
           < 0: If INFO = -i, the i-th argument had an illegal value.

DGELSY computes the minimum-norm solution to a real linear least
squares problem:

        minimize || A * X - B ||

using a complete orthogonal factorization of A.  A is an M-by-N
matrix which may be rank-deficient.
Several right hand side vectors b and solution vectors x can be
handled in a single call; they are stored as the columns of the
M-by-NRHS right hand side matrix B and the N-by-NRHS solution
matrix X.
The routine first computes a QR factorization with column pivoting:

        A * P = Q * [ R11 R12 ]
                    [  0  R22 ]

with R11 defined as the largest leading submatrix whose estimated
condition number is less than 1/RCOND.  The order of R11, RANK,
is the effective rank of A.
Then, R22 is considered to be negligible, and R12 is annihilated
by orthogonal transformations from the right, arriving at the
complete orthogonal factorization:

        A * P = Q * [ T11 0 ] * Z
                    [  0  0 ]

The minimum-norm solution is then

        X = P * Z**T [ inv(T11)*Q1**T*B ]
                     [        0         ]

where Q1 consists of the first RANK columns of Q.
This routine is basically identical to the original xGELSX except
three differences:

        o The call to the subroutine xGEQPF has been substituted by the
          the call to the subroutine xGEQP3. This subroutine is a Blas-3
          version of the QR factorization with column pivoting.
        o Matrix B (the right hand side) is updated with Blas-3.
        o The permutation of matrix B (the right hand side) is faster and
          more simple.

*/
static VALUE
lapack_s_dgelsy(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   m, n, nb, nrhs, tmp;
    int   max_mn;
    narray_t *na1, *na2;
#if LSY
    narray_t *na3;
    VALUE jpvt;
#endif
#if LSS
    size_t shape_s[1];
#endif
    /**/
    ndfunc_arg_in_t ain[2+LSS] = {{OVERWRITE,2},{OVERWRITE,2},{cInt,1}};
    ndfunc_arg_out_t aout[1+LSS*2] = {{cT,1,shape_s},{cInt,0},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgelsy, NO_LOOP|NDF_EXTRACT, 2, 1+LSS*2, ain, aout};

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

    CHECK_FUNC(func_p,"dgelsy");

#if LSY
    rb_scan_args(argc, argv, "3:", &a, &b, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
#if LSS
    g.rcond = NUM2DBL(option_value(opts[2],DBL2NUM(-1)));
#else
    g.trans = option_trans(opts[1]);
#endif

    //A is DOUBLE PRECISION array, dimension (LDA,N)
    //On entry, the M-by-N matrix A.
    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);

    //B is DOUBLE PRECISION array, dimension (LDB,NRHS)
    //B is M-by-NRHS if TRANS = 'N'
    //     N-by-NRHS if TRANS = 'T'
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);

    //The number of rows of the matrix A.
    m = ROW_SIZE(na1);
    //The number of columns of the matrix A.
    n = COL_SIZE(na1);
    max_mn = (m > n) ? m : n;
    SWAP_IFCOL(g.order,m,n);

#if LSY
    ndf.nin++;
    ndf.nout--;
    ndf.aout++;
    COPY_OR_CAST_TO(jpvt,cInt);
    GetNArray(jpvt, na3);
    CHECK_DIM_GE(na3, 1);
    { int jpvt_sz = COL_SIZE(na3);
      CHECK_INT_EQ("jpvt_size",jpvt_sz,"n",n);
    }
#elif LSS
    shape_s[0] = (m < n) ? m : n;
#endif

    //The number of columns of the matrix B.
    if (na2->ndim == 1) {
        ain[1].dim = 1; // reduce dimension
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        //The number of rows of the matrix B.
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        SWAP_IFCOL(g.order,nb,nrhs);
    }
    if (nb < max_mn) {
        rb_raise(nary_eShapeError,
                 "ldb should be >= max(m,n): ldb=%d m=%d n=%d",nb,m,n);
    }

    // ndloop
#if LSY
    ans = na_ndloop3(&ndf, &g, 3, a, b, jpvt);
#else
    ans = na_ndloop3(&ndf, &g, 2, a, b);
#endif

    // return
#if LSY
    return rb_ary_concat(rb_ary_new3(3,a,b,jpvt),ans);
#elif LSD
    rb_ary_unshift(ans,b); return ans;
#elif LSS
    return rb_ary_concat(rb_ary_new3(2,a,b),ans);
#else
    return rb_ary_new3(3,a,b,ans);
#endif
}

#undef func_p
#undef args_t
#undef LSS
#undef LSD
#undef LSY


#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/lapack/gen/../tmpl/geev.c"
#define args_t dgeev_args_t
#define func_p dgeev_p

typedef struct {
    int order;
    char jobvl, jobvr;
} args_t;

static dgeev_t func_p = 0;

static void
iter_lapack_s_dgeev(na_loop_t * const lp)
{
    dtype *a, *vl, *vr;
#if IS_COMPLEX
    dtype *w;
#else
    dtype *wr, *wi;
#endif
    int   *info;
    int    n, lda, ldvl, ldvr;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IS_COMPLEX
    w = (dtype*)NDL_PTR(lp,1);
#else
    wr = (dtype*)NDL_PTR(lp,1);
    wi = (dtype*)NDL_PTR(lp,2);
#endif
    vl = (dtype*)NDL_PTR(lp,3-CZ);
    vr = (dtype*)NDL_PTR(lp,4-CZ);
    info = (int*)NDL_PTR(lp,5-CZ);
    g = (args_t*)(lp->opt_ptr);

    n = NDL_SHAPE(lp,0)[1];
    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldvl = NDL_STEP(lp,3-CZ) / sizeof(dtype);
    if (ldvl == 0) { ldvl = n; } // jobvt == 'N'
    ldvr = NDL_STEP(lp,4-CZ) / sizeof(dtype);
    if (ldvr == 0) { ldvr = n; } // jobvt == 'N'

    //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);

    /**/
    *info = (*func_p)(g->order, g->jobvl, g->jobvr, n, a, lda,wr, wi,vl, ldvl, vr, ldvr);
    CHECK_ERROR(*info);
}

/*
  @overload dgeev( a,, [jobvl:'V', jobvr:'V', order:'R'] )
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param jobvl [String or Symbol]  if 'V': Compute left eigenvectors, if 'N': Not compute left eigenvectors (default='V')
  @param jobvr [String or Symbol]  if 'V': Compute right eigenvectors, if 'N': Not compute right eigenvectors (default='V')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[wr, wi, vl, vr, info]] Array<Numo::DFloat, Numo::DFloat, Numo::DFloat, Numo::DFloat, Integer>

    - **wr** -- 
           WR is DOUBLE PRECISION array, dimension (N)

    - **wi** -- 
           WI is DOUBLE PRECISION array, dimension (N)
           WR and WI contain the real and imaginary parts,
           respectively, of the computed eigenvalues.  Complex
           conjugate pairs of eigenvalues appear consecutively
           with the eigenvalue having the positive imaginary part
           first.

    - **vl** -- 
           VL is DOUBLE PRECISION array, dimension (LDVL,N)
           If JOBVL = 'V', the left eigenvectors u(j) are stored one
           after another in the columns of VL, in the same order
           as their eigenvalues.
           If JOBVL = 'N', VL is not referenced.
           If the j-th eigenvalue is real, then u(j) = VL(:,j),
           the j-th column of VL.
           If the j-th and (j+1)-st eigenvalues form a complex
           conjugate pair, then u(j) = VL(:,j) + i\*VL(:,j+1) and
           u(j+1) = VL(:,j) - i\*VL(:,j+1).

    - **vr** -- 
           VR is DOUBLE PRECISION array, dimension (LDVR,N)
           If JOBVR = 'V', the right eigenvectors v(j) are stored one
           after another in the columns of VR, in the same order
           as their eigenvalues.
           If JOBVR = 'N', VR is not referenced.
           If the j-th eigenvalue is real, then v(j) = VR(:,j),
           the j-th column of VR.
           If the j-th and (j+1)-st eigenvalues form a complex
           conjugate pair, then v(j) = VR(:,j) + i\*VR(:,j+1) and
           v(j+1) = VR(:,j) - i\*VR(:,j+1).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value.
           > 0:  if INFO = i, the QR algorithm failed to compute all the
                 eigenvalues, and no eigenvectors have been computed;
                 elements i+1:N of WR and WI contain eigenvalues which
                 have converged.

DGEEV computes for an N-by-N real nonsymmetric matrix A, the
eigenvalues and, optionally, the left and/or right eigenvectors.
The right eigenvector v(j) of A satisfies

                 A * v(j) = lambda(j) * v(j)

where lambda(j) is its eigenvalue.
The left eigenvector u(j) of A satisfies

              u(j)**H * A = lambda(j) * u(j)**H

where u(j)\*\*H denotes the conjugate-transpose of u(j).
The computed eigenvectors are normalized to have Euclidean norm
equal to 1 and largest component real.

*/
static VALUE
lapack_s_dgeev(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n;
    narray_t *na1;
    /**/
    size_t shape[2];
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[5-CZ] = {{cT,1,shape},{cT,1,shape},{cT,2,shape},{cT,2,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgeev, NO_LOOP|NDF_EXTRACT, 1, 5-CZ, ain, aout};

    args_t g = {0,0,0};
    VALUE opts[3] = {Qundef,Qundef,Qundef};
    VALUE kw_hash = Qnil;
    ID kw_table[3] = {id_order,id_jobvl,id_jobvr};

    CHECK_FUNC(func_p,"dgeev");

    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
    g.jobvl = option_job(opts[1],'V','N');
    g.jobvr = option_job(opts[2],'V','N');

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    if (m != n) {
        rb_raise(nary_eShapeError,"matrix must be square");
    }
    shape[0] = shape[1] = n;
    if (g.jobvl=='N') { aout[2-CZ].dim = 0; }
    if (g.jobvr=='N') { aout[3-CZ].dim = 0; }

    ans = na_ndloop3(&ndf, &g, 1, a);

    if (aout[3-CZ].dim == 0) { RARRAY_ASET(ans,3-CZ,Qnil); }
    if (aout[2-CZ].dim == 0) { RARRAY_ASET(ans,2-CZ,Qnil); }
    return ans;
}

#undef args_t
#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/lapack/gen/../tmpl/ggev.c"
#define args_t dggev_args_t
#define func_p dggev_p

typedef struct {
    int order;
    char jobvl, jobvr;
} args_t;

static dggev_t func_p = 0;

static void
iter_lapack_s_dggev(na_loop_t * const lp)
{
    dtype *a, *b, *beta, *vl, *vr;
#if IS_COMPLEX
    dtype *alpha;
#else
    dtype *alphar, *alphai;
#endif
    int   *info;
    int    n, lda, ldb, ldvl, ldvr;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
#if IS_COMPLEX
    alpha = (dtype*)NDL_PTR(lp,2);
#else
    alphar = (dtype*)NDL_PTR(lp,2);
    alphai = (dtype*)NDL_PTR(lp,3);
#endif
    beta = (dtype*)NDL_PTR(lp,4-CZ);
    vl = (dtype*)NDL_PTR(lp,5-CZ);
    vr = (dtype*)NDL_PTR(lp,6-CZ);
    info = (int*)NDL_PTR(lp,7-CZ);
    g = (args_t*)(lp->opt_ptr);

    n = NDL_SHAPE(lp,0)[1];
    lda = NDL_STEP(lp,0) / sizeof(dtype);
    ldb = NDL_STEP(lp,1) / sizeof(dtype);
    ldvl = NDL_STEP(lp,5-CZ) / sizeof(dtype);
    if (ldvl == 0) { ldvl = n; } // jobvl == 'N'
    ldvr = NDL_STEP(lp,6-CZ) / sizeof(dtype);
    if (ldvr == 0) { ldvr = n; } // jobvr == 'N'

    //printf("order=%d jobvl=%c jobvr=%c n=%d lda=%d ldb=%d ldvl=%d ldvr=%d\n",g->order,g->jobvl, g->jobvr, n, lda,ldb,ldvl,ldvr);

    /**/
    *info = (*func_p)(g->order, g->jobvl, g->jobvr, n, a, lda, b, ldb,alphar, alphai,beta, vl, ldvl, vr, ldvr);
    CHECK_ERROR(*info);
}

/*

  @overload dggev(a, b, [jobvl:'V', jobvr:'V', order:'R'] )
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param jobvl [String or Symbol]  if 'V': Compute left eigenvectors, if 'N': Not compute left eigenvectors (default='V')
  @param jobvr [String or Symbol]  if 'V': Compute right eigenvectors, if 'N': Not compute right eigenvectors (default='V')
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[alphar, alphai, beta, vl, vr, info]] Array<Numo::DFloat, Numo::DFloat, Numo::DFloat, Numo::DFloat, Numo::DFloat, Integer>

    - **alphar** -- 
           ALPHAR is DOUBLE PRECISION array, dimension (N)

    - **alphai** -- 
           ALPHAI is DOUBLE PRECISION array, dimension (N)

    - **beta** -- 
           BETA is DOUBLE PRECISION array, dimension (N)
           On exit, (ALPHAR(j) + ALPHAI(j)\*i)/BETA(j), j=1,...,N, will
           be the generalized eigenvalues.  If ALPHAI(j) is zero, then
           the j-th eigenvalue is real; if positive, then the j-th and
           (j+1)-st eigenvalues are a complex conjugate pair, with
           ALPHAI(j+1) negative.
           Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)
           may easily over- or underflow, and BETA(j) may even be zero.
           Thus, the user should avoid naively computing the ratio
           alpha/beta.  However, ALPHAR and ALPHAI will be always less
           than and usually comparable with norm(A) in magnitude, and
           BETA always less than and usually comparable with norm(B).

    - **vl** -- 
           VL is DOUBLE PRECISION array, dimension (LDVL,N)
           If JOBVL = 'V', the left eigenvectors u(j) are stored one
           after another in the columns of VL, in the same order as
           their eigenvalues. If the j-th eigenvalue is real, then
           u(j) = VL(:,j), the j-th column of VL. If the j-th and
           (j+1)-th eigenvalues form a complex conjugate pair, then
           u(j) = VL(:,j)+i\*VL(:,j+1) and u(j+1) = VL(:,j)-i\*VL(:,j+1).
           Each eigenvector is scaled so the largest component has
           abs(real part)+abs(imag. part)=1.
           Not referenced if JOBVL = 'N'.

    - **vr** -- 
           VR is DOUBLE PRECISION array, dimension (LDVR,N)
           If JOBVR = 'V', the right eigenvectors v(j) are stored one
           after another in the columns of VR, in the same order as
           their eigenvalues. If the j-th eigenvalue is real, then
           v(j) = VR(:,j), the j-th column of VR. If the j-th and
           (j+1)-th eigenvalues form a complex conjugate pair, then
           v(j) = VR(:,j)+i\*VR(:,j+1) and v(j+1) = VR(:,j)-i\*VR(:,j+1).
           Each eigenvector is scaled so the largest component has
           abs(real part)+abs(imag. part)=1.
           Not referenced if JOBVR = 'N'.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value.
           = 1,...,N:
                 The QZ iteration failed.  No eigenvectors have been
                 calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)
                 should be correct for j=INFO+1,...,N.
           > N:  =N+1: other than QZ iteration failed in DHGEQZ.
                 =N+2: error return from DTGEVC.

DGGEV computes for a pair of N-by-N real nonsymmetric matrices (A,B)
the generalized eigenvalues, and optionally, the left and/or right
generalized eigenvectors.
A generalized eigenvalue for a pair of matrices (A,B) is a scalar
lambda or a ratio alpha/beta = lambda, such that A - lambda\*B is
singular. It is usually represented as the pair (alpha,beta), as
there is a reasonable interpretation for beta=0, and even for both
being zero.
The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
of (A,B) satisfies

                 A * v(j) = lambda(j) * B * v(j).

The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
of (A,B) satisfies

                 u(j)**H * A  = lambda(j) * u(j)**H * B .

where u(j)\*\*H is the conjugate-transpose of u(j).

*/
static VALUE
lapack_s_dggev(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   n, nb;
    narray_t *na1, *na2;
    /**/
    size_t shape[2];
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{OVERWRITE,2}};
    ndfunc_arg_out_t aout[6-CZ] = {{cT,1,shape},{cT,1,shape},{cT,1,shape},{cT,2,shape},{cT,2,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dggev, NO_LOOP|NDF_EXTRACT, 2, 6-CZ, ain, aout};

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

    CHECK_FUNC(func_p,"dggev");

    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
    g.jobvl = option_job(opts[1],'V','N');
    g.jobvr = option_job(opts[2],'V','N');

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

    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 2);

    CHECK_SQUARE("matrix a",na1);
    n  = COL_SIZE(na1);
    CHECK_SQUARE("matrix b",na2);
    nb = COL_SIZE(na2);
    if (n != nb) {
        rb_raise(nary_eShapeError,"matrix a and b must have same size");
    }
    shape[0] = shape[1] = n;
    if (g.jobvl=='N') { aout[3-CZ].dim = 0; }
    if (g.jobvr=='N') { aout[4-CZ].dim = 0; }

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

    if (aout[4-CZ].dim == 0) { RARRAY_ASET(ans,4-CZ,Qnil); }
    if (aout[3-CZ].dim == 0) { RARRAY_ASET(ans,3-CZ,Qnil); }
    return ans;
}

#undef args_t
#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/lapack/gen/../tmpl/syev.c"
#define args_t dsyev_args_t
#define func_p dsyev_p

typedef struct {
    int order;
    char jobz, uplo;
} args_t;

static dsyev_t func_p = 0;

static void
iter_lapack_s_dsyev(na_loop_t * const lp)
{
    dtype *a;
    rtype *w;
    int   *info;
    int    n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    w = (rtype*)NDL_PTR(lp,1);
    info = (int*)NDL_PTR(lp,2);
    g = (args_t*)(lp->opt_ptr);

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

    //printf("order=%d jobz=%c uplo=%c n=%d lda=%d\n",g->order,g->jobz,g->uplo,n,lda);

    *info = (*func_p)( g->order, g->jobz, g->uplo, n, a, lda, w );
    CHECK_ERROR(*info);
}

/*
  @overload dsyev(a, [jobz:'V', uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param jobz [String or Symbol]  if 'V': Compute eigenvectors, if 'N': Not compute eigenvectors (default='V')
  @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 [[a, w, info]]  Array<Numo::DFloat,Numo::DFloat,Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA, N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the
           leading N-by-N upper triangular part of A contains the
           upper triangular part of the matrix A.  If UPLO = 'L',
           the leading N-by-N lower triangular part of A contains
           the lower triangular part of the matrix A.
           On exit, if JOBZ = 'V', then if INFO = 0, A contains the
           orthonormal eigenvectors of the matrix A.
           If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
           or the upper triangle (if UPLO='U') of A, including the
           diagonal, is destroyed.

    - **w** -- 
           W is DOUBLE PRECISION array, dimension (N)
           If INFO = 0, the eigenvalues in ascending order.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, the algorithm failed to converge; i
                 off-diagonal elements of an intermediate tridiagonal
                 form did not converge to zero.

DSYEV computes all eigenvalues and, optionally, eigenvectors of a
real symmetric matrix A.

*/
static VALUE
lapack_s_dsyev(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n;
    narray_t *na1;
    size_t shape[1];
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[2] = {{cRT,1,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsyev, NO_LOOP|NDF_EXTRACT, 1, 2, ain, aout};

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

    CHECK_FUNC(func_p,"dsyev");

    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
    g.jobz = option_job(opts[1],'V','N');
    g.uplo = option_uplo(opts[2]);

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    if (m != n) {
        rb_raise(nary_eShapeError,"matrix must be square");
    }
    shape[0] = n;

    ans = na_ndloop3(&ndf, &g, 1, a);

    return rb_ary_new3(3, a, RARRAY_AREF(ans,0), RARRAY_AREF(ans,1));
}

#undef args_t
#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/lapack/gen/../tmpl/syev.c"
#define args_t dsyevd_args_t
#define func_p dsyevd_p

typedef struct {
    int order;
    char jobz, uplo;
} args_t;

static dsyevd_t func_p = 0;

static void
iter_lapack_s_dsyevd(na_loop_t * const lp)
{
    dtype *a;
    rtype *w;
    int   *info;
    int    n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    w = (rtype*)NDL_PTR(lp,1);
    info = (int*)NDL_PTR(lp,2);
    g = (args_t*)(lp->opt_ptr);

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

    //printf("order=%d jobz=%c uplo=%c n=%d lda=%d\n",g->order,g->jobz,g->uplo,n,lda);

    *info = (*func_p)( g->order, g->jobz, g->uplo, n, a, lda, w );
    CHECK_ERROR(*info);
}

/*
  @overload dsyevd(a, [jobz:'V', uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param jobz [String or Symbol]  if 'V': Compute eigenvectors, if 'N': Not compute eigenvectors (default='V')
  @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 [[a, w, info]]  Array<Numo::DFloat,Numo::DFloat,Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA, N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the
           leading N-by-N upper triangular part of A contains the
           upper triangular part of the matrix A.  If UPLO = 'L',
           the leading N-by-N lower triangular part of A contains
           the lower triangular part of the matrix A.
           On exit, if JOBZ = 'V', then if INFO = 0, A contains the
           orthonormal eigenvectors of the matrix A.
           If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
           or the upper triangle (if UPLO='U') of A, including the
           diagonal, is destroyed.

    - **w** -- 
           W is DOUBLE PRECISION array, dimension (N)
           If INFO = 0, the eigenvalues in ascending order.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i and JOBZ = 'N', then the algorithm failed
                 to converge; i off-diagonal elements of an intermediate
                 tridiagonal form did not converge to zero;
                 if INFO = i and JOBZ = 'V', then the algorithm failed
                 to compute an eigenvalue while working on the submatrix
                 lying in rows and columns INFO/(N+1) through
                 mod(INFO,N+1).

DSYEVD computes all eigenvalues and, optionally, eigenvectors of a
real symmetric matrix A. If eigenvectors are desired, it uses a
divide and conquer algorithm.
The divide and conquer algorithm makes very mild assumptions about
floating point arithmetic. It will work on machines with a guard
digit in add/subtract, or on those binary machines without guard
digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
Cray-2. It could conceivably fail on hexadecimal or decimal machines
without guard digits, but we know of none.
Because of large use of BLAS of level 3, DSYEVD needs N\*\*2 more
workspace than DSYEVX.

*/
static VALUE
lapack_s_dsyevd(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n;
    narray_t *na1;
    size_t shape[1];
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[2] = {{cRT,1,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsyevd, NO_LOOP|NDF_EXTRACT, 1, 2, ain, aout};

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

    CHECK_FUNC(func_p,"dsyevd");

    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
    g.order = option_order(opts[0]);
    g.jobz = option_job(opts[1],'V','N');
    g.uplo = option_uplo(opts[2]);

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    if (m != n) {
        rb_raise(nary_eShapeError,"matrix must be square");
    }
    shape[0] = n;

    ans = na_ndloop3(&ndf, &g, 1, a);

    return rb_ary_new3(3, a, RARRAY_AREF(ans,0), RARRAY_AREF(ans,1));
}

#undef args_t
#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/lapack/gen/../tmpl/sygv.c"
#define args_t dsygv_args_t
#define func_p dsygv_p

typedef struct {
    int order;
    int itype;
    char jobz, uplo;
} args_t;

static dsygv_t func_p = 0;

static void
iter_lapack_s_dsygv(na_loop_t * const lp)
{
    dtype *a, *b;
    rtype *w;
    int   *info;
    int    n, lda, ldb;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
    w = (rtype*)NDL_PTR(lp,2);
    info = (int*)NDL_PTR(lp,3);
    g = (args_t*)(lp->opt_ptr);

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

    //printf("order=%d itype=%d jobz=%c uplo=%c n=%d lda=%d ldb=%d\n",g->order,g->itype,g->jobz,g->uplo,n,lda,ldb);

    *info = (*func_p)( g->order, g->itype, g->jobz, g->uplo, n, a, lda, b, ldb, w );
    CHECK_ERROR(*info);
}

/*
  @overload dsygv(a, b, [itype:1, jobz:'V', uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param [Integer] itype Specifies the problem type to be solved. If 1:  A*x = (lambda)*B*x, If 2:  A*B*x = (lambda)*x, If 3:  B*A*x = (lambda)*x.
  @param jobz [String or Symbol]  if 'V': Compute eigenvectors, if 'N': Not compute eigenvectors (default='V')
  @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 [[a, b, w, info]] Array<Numo::DFloat,Numo::DFloat,Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA, N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the
           leading N-by-N upper triangular part of A contains the
           upper triangular part of the matrix A.  If UPLO = 'L',
           the leading N-by-N lower triangular part of A contains
           the lower triangular part of the matrix A.
           On exit, if JOBZ = 'V', then if INFO = 0, A contains the
           matrix Z of eigenvectors.  The eigenvectors are normalized
           as follows:
           if ITYPE = 1 or 2, Z\*\*T\*B\*Z = I;
           if ITYPE = 3, Z\*\*T\*inv(B)\*Z = I.
           If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
           or the lower triangle (if UPLO='L') of A, including the
           diagonal, is destroyed.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB, N)
           On entry, the symmetric positive definite matrix B.
           If UPLO = 'U', the leading N-by-N upper triangular part of B
           contains the upper triangular part of the matrix B.
           If UPLO = 'L', the leading N-by-N lower triangular part of B
           contains the lower triangular part of the matrix B.
           On exit, if INFO <= N, the part of B containing the matrix is
           overwritten by the triangular factor U or L from the Cholesky
           factorization B = U\*\*T\*U or B = L\*L\*\*T.

    - **w** -- 
           W is DOUBLE PRECISION array, dimension (N)
           If INFO = 0, the eigenvalues in ascending order.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  DPOTRF or DSYEV returned an error code:
              <= N:  if INFO = i, DSYEV failed to converge;
                     i off-diagonal elements of an intermediate
                     tridiagonal form did not converge to zero;
              > N:   if INFO = N + i, for 1 <= i <= N, then the leading
                     minor of order i of B is not positive definite.
                     The factorization of B could not be completed and
                     no eigenvalues or eigenvectors were computed.

DSYGV computes all the eigenvalues, and optionally, the eigenvectors
of a real generalized symmetric-definite eigenproblem, of the form
A\*x=(lambda)\*B\*x,  A\*Bx=(lambda)\*x,  or B\*A\*x=(lambda)\*x.
Here A and B are assumed to be symmetric and B is also
positive definite.

*/
static VALUE
lapack_s_dsygv(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   n, nb;
    narray_t *na1, *na2;
    size_t shape[1];
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{OVERWRITE,2}};
    ndfunc_arg_out_t aout[2] = {{cRT,1,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsygv, NO_LOOP|NDF_EXTRACT, 2, 2, ain, aout};

    args_t g;
    VALUE opts[4] = {Qundef,Qundef,Qundef,Qundef};
    VALUE kw_hash = Qnil;
    ID kw_table[4] = {id_order,id_jobz,id_uplo,id_itype};

    CHECK_FUNC(func_p,"dsygv");

    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 4, opts);
    g.order = option_order(opts[0]);
    g.jobz = option_job(opts[1],'V','N');
    g.uplo = option_uplo(opts[2]);
    g.itype = NUM2INT(option_value(opts[3],INT2FIX(1)));

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

    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 2);

    CHECK_SQUARE("matrix a",na1);
    n  = COL_SIZE(na1);
    CHECK_SQUARE("matrix b",na2);
    nb = COL_SIZE(na2);
    if (n != nb) {
        rb_raise(nary_eShapeError,"matrix a and b must have same size");
    }
    shape[0] = n;

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

    return rb_ary_new3(4, a, b, RARRAY_AREF(ans,0), RARRAY_AREF(ans,1));
}

#undef args_t
#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/lapack/gen/../tmpl/sygv.c"
#define args_t dsygvd_args_t
#define func_p dsygvd_p

typedef struct {
    int order;
    int itype;
    char jobz, uplo;
} args_t;

static dsygvd_t func_p = 0;

static void
iter_lapack_s_dsygvd(na_loop_t * const lp)
{
    dtype *a, *b;
    rtype *w;
    int   *info;
    int    n, lda, ldb;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    b = (dtype*)NDL_PTR(lp,1);
    w = (rtype*)NDL_PTR(lp,2);
    info = (int*)NDL_PTR(lp,3);
    g = (args_t*)(lp->opt_ptr);

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

    //printf("order=%d itype=%d jobz=%c uplo=%c n=%d lda=%d ldb=%d\n",g->order,g->itype,g->jobz,g->uplo,n,lda,ldb);

    *info = (*func_p)( g->order, g->itype, g->jobz, g->uplo, n, a, lda, b, ldb, w );
    CHECK_ERROR(*info);
}

/*
  @overload dsygvd(a, b, [itype:1, jobz:'V', uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param [Integer] itype Specifies the problem type to be solved. If 1:  A*x = (lambda)*B*x, If 2:  A*B*x = (lambda)*x, If 3:  B*A*x = (lambda)*x.
  @param jobz [String or Symbol]  if 'V': Compute eigenvectors, if 'N': Not compute eigenvectors (default='V')
  @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 [[a, b, w, info]] Array<Numo::DFloat,Numo::DFloat,Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA, N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the
           leading N-by-N upper triangular part of A contains the
           upper triangular part of the matrix A.  If UPLO = 'L',
           the leading N-by-N lower triangular part of A contains
           the lower triangular part of the matrix A.
           On exit, if JOBZ = 'V', then if INFO = 0, A contains the
           matrix Z of eigenvectors.  The eigenvectors are normalized
           as follows:
           if ITYPE = 1 or 2, Z\*\*T\*B\*Z = I;
           if ITYPE = 3, Z\*\*T\*inv(B)\*Z = I.
           If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
           or the lower triangle (if UPLO='L') of A, including the
           diagonal, is destroyed.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB, N)
           On entry, the symmetric matrix B.  If UPLO = 'U', the
           leading N-by-N upper triangular part of B contains the
           upper triangular part of the matrix B.  If UPLO = 'L',
           the leading N-by-N lower triangular part of B contains
           the lower triangular part of the matrix B.
           On exit, if INFO <= N, the part of B containing the matrix is
           overwritten by the triangular factor U or L from the Cholesky
           factorization B = U\*\*T\*U or B = L\*L\*\*T.

    - **w** -- 
           W is DOUBLE PRECISION array, dimension (N)
           If INFO = 0, the eigenvalues in ascending order.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  DPOTRF or DSYEVD returned an error code:
              <= N:  if INFO = i and JOBZ = 'N', then the algorithm
                     failed to converge; i off-diagonal elements of an
                     intermediate tridiagonal form did not converge to
                     zero;
                     if INFO = i and JOBZ = 'V', then the algorithm
                     failed to compute an eigenvalue while working on
                     the submatrix lying in rows and columns INFO/(N+1)
                     through mod(INFO,N+1);
              > N:   if INFO = N + i, for 1 <= i <= N, then the leading
                     minor of order i of B is not positive definite.
                     The factorization of B could not be completed and
                     no eigenvalues or eigenvectors were computed.

DSYGVD computes all the eigenvalues, and optionally, the eigenvectors
of a real generalized symmetric-definite eigenproblem, of the form
A\*x=(lambda)\*B\*x,  A\*Bx=(lambda)\*x,  or B\*A\*x=(lambda)\*x.  Here A and
B are assumed to be symmetric and B is also positive definite.
If eigenvectors are desired, it uses a divide and conquer algorithm.
The divide and conquer algorithm makes very mild assumptions about
floating point arithmetic. It will work on machines with a guard
digit in add/subtract, or on those binary machines without guard
digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
Cray-2. It could conceivably fail on hexadecimal or decimal machines
without guard digits, but we know of none.

*/
static VALUE
lapack_s_dsygvd(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   n, nb;
    narray_t *na1, *na2;
    size_t shape[1];
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{OVERWRITE,2}};
    ndfunc_arg_out_t aout[2] = {{cRT,1,shape},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsygvd, NO_LOOP|NDF_EXTRACT, 2, 2, ain, aout};

    args_t g;
    VALUE opts[4] = {Qundef,Qundef,Qundef,Qundef};
    VALUE kw_hash = Qnil;
    ID kw_table[4] = {id_order,id_jobz,id_uplo,id_itype};

    CHECK_FUNC(func_p,"dsygvd");

    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 4, opts);
    g.order = option_order(opts[0]);
    g.jobz = option_job(opts[1],'V','N');
    g.uplo = option_uplo(opts[2]);
    g.itype = NUM2INT(option_value(opts[3],INT2FIX(1)));

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

    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 2);

    CHECK_SQUARE("matrix a",na1);
    n  = COL_SIZE(na1);
    CHECK_SQUARE("matrix b",na2);
    nb = COL_SIZE(na2);
    if (n != nb) {
        rb_raise(nary_eShapeError,"matrix a and b must have same size");
    }
    shape[0] = n;

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

    return rb_ary_new3(4, a, b, RARRAY_AREF(ans,0), RARRAY_AREF(ans,1));
}

#undef args_t
#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/lapack/gen/../tmpl/sygvx.c"
#define args_t dsygvx_args_t
#define func_p dsygvx_p

typedef struct {
    int order;
    int itype;
    char jobz;
    char uplo;
    char range;
    int il;
    int iu;
} args_t;

static dsygvx_t func_p = 0;

static void
iter_lapack_s_dsygvx(na_loop_t * const lp)
{
    dtype *a, *b, *z;
    rtype *w;
    int   *ifail;
    int   *info;
    int    m, n, lda, ldb, ldz;
    rtype  vl = 0, vu = 0;
    rtype  abstol = 0;

    args_t *g;

    a = (dtype*)NDL_PTR(lp, 0);
    b = (dtype*)NDL_PTR(lp, 1);
    w = (rtype*)NDL_PTR(lp, 2);
    z = (dtype*)NDL_PTR(lp, 3);
    ifail = (int*)NDL_PTR(lp, 4);
    info = (int*)NDL_PTR(lp, 5);
    g = (args_t*)(lp->opt_ptr);

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

    *info = (*func_p)( g->order, g->itype, g->jobz, g->range, g->uplo, n, a, lda, b, ldb,
                       vl, vu, g->il, g->iu, abstol, &m, w, z, ldz, ifail );

    CHECK_ERROR(*info);
}

/*

  @overload dsygvx(a, b, [itype:1, jobz:'V', uplo:'U', order:'R', range:'I', il: 1, il: 2])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param [Integer] itype Specifies the problem type to be solved.  If 1:  A*x = (lambda)*B*x, If 2:  A*B*x = (lambda)*x, If 3:  B*A*x = (lambda)*x.
  @param jobz [String or Symbol]  if 'V': Compute eigenvectors, if 'N': Not compute eigenvectors (default='V')
  @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')
  @param [String or Symbol] range If 'A': Compute all eigenvalues, if 'I': Compute eigenvalues with indices il to iu (default='A')
  @param [Integer] il Specifies the index of the smallest eigenvalue in ascending order to be returned. If range = 'A', il is not referenced.
  @param [Integer] iu Specifies the index of the largest eigenvalue in ascending order to be returned. Constraint: 1<=il<=iu<=N. If range = 'A', iu is not referenced.
  @return [[a, b, w, z, ifail, info]]
    Array<Numo::DFloat,Numo::DFloat,Numo::DFloat,Numo::DFloat,Numo::DFloat,Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA, N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the
           leading N-by-N upper triangular part of A contains the
           upper triangular part of the matrix A.  If UPLO = 'L',
           the leading N-by-N lower triangular part of A contains
           the lower triangular part of the matrix A.
           On exit, the lower triangle (if UPLO='L') or the upper
           triangle (if UPLO='U') of A, including the diagonal, is
           destroyed.

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB, N)
           On entry, the symmetric matrix B.  If UPLO = 'U', the
           leading N-by-N upper triangular part of B contains the
           upper triangular part of the matrix B.  If UPLO = 'L',
           the leading N-by-N lower triangular part of B contains
           the lower triangular part of the matrix B.
           On exit, if INFO <= N, the part of B containing the matrix is
           overwritten by the triangular factor U or L from the Cholesky
           factorization B = U\*\*T\*U or B = L\*L\*\*T.

    - **w** -- 
           W is DOUBLE PRECISION array, dimension (N)
           On normal exit, the first M elements contain the selected
           eigenvalues in ascending order.

    - **z** -- 
           Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))
           If JOBZ = 'N', then Z is not referenced.
           If JOBZ = 'V', then if INFO = 0, the first M columns of Z
           contain the orthonormal eigenvectors of the matrix A
           corresponding to the selected eigenvalues, with the i-th
           column of Z holding the eigenvector associated with W(i).
           The eigenvectors are normalized as follows:
           if ITYPE = 1 or 2, Z\*\*T\*B\*Z = I;
           if ITYPE = 3, Z\*\*T\*inv(B)\*Z = I.
           If an eigenvector fails to converge, then that column of Z
           contains the latest approximation to the eigenvector, and the
           index of the eigenvector is returned in IFAIL.
           Note: the user must ensure that at least max(1,M) columns are
           supplied in the array Z; if RANGE = 'V', the exact value of M
           is not known in advance and an upper bound must be used.

    - **ifail** -- 
           IFAIL is INTEGER array, dimension (N)
           If JOBZ = 'V', then if INFO = 0, the first M elements of
           IFAIL are zero.  If INFO > 0, then IFAIL contains the
           indices of the eigenvectors that failed to converge.
           If JOBZ = 'N', then IFAIL is not referenced.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  DPOTRF or DSYEVX returned an error code:
              <= N:  if INFO = i, DSYEVX failed to converge;
                     i eigenvectors failed to converge.  Their indices
                     are stored in array IFAIL.
              > N:   if INFO = N + i, for 1 <= i <= N, then the leading
                     minor of order i of B is not positive definite.
                     The factorization of B could not be completed and
                     no eigenvalues or eigenvectors were computed.

DSYGVX computes selected eigenvalues, and optionally, eigenvectors
of a real generalized symmetric-definite eigenproblem, of the form
A\*x=(lambda)\*B\*x,  A\*Bx=(lambda)\*x,  or B\*A\*x=(lambda)\*x.  Here A
and B are assumed to be symmetric and B is also positive definite.
Eigenvalues and eigenvectors can be selected by specifying either a
range of values or a range of indices for the desired eigenvalues.
*/

static VALUE
lapack_s_dsygvx(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, b, ans;
    int   n, nb, m;
    narray_t *na1, *na2;
    size_t w_shape[1];
    size_t z_shape[2];
    size_t ifail_shape[1];

    ndfunc_arg_in_t ain[2] = {{OVERWRITE, 2}, {OVERWRITE, 2}};
    ndfunc_arg_out_t aout[4] = {{cRT, 1, w_shape}, {cT, 2, z_shape}, {cI, 1, ifail_shape}, {cInt, 0}};
    ndfunc_t ndf = {&iter_lapack_s_dsygvx, NO_LOOP | NDF_EXTRACT, 2, 4, ain, aout};

    args_t g;
    VALUE opts[7] = {Qundef, Qundef, Qundef, Qundef, Qundef, Qundef, Qundef};
    VALUE kw_hash = Qnil;
    ID kw_table[7] = {id_order, id_jobz, id_uplo, id_itype, id_range, id_il, id_iu};

    CHECK_FUNC(func_p,"dsygvx");

    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 7, opts);
    g.order = option_order(opts[0]);
    g.jobz = option_job(opts[1], 'V', 'N');
    g.uplo = option_uplo(opts[2]);
    g.itype = NUM2INT(option_value(opts[3], INT2FIX(1)));
    g.range = option_range(opts[4], 'A', 'I');
    g.il = NUM2INT(option_value(opts[5], INT2FIX(1)));
    g.iu = NUM2INT(option_value(opts[6], INT2FIX(1)));

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

    COPY_OR_CAST_TO(b, cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 2);
    CHECK_SQUARE("matrix a", na1);
    n  = COL_SIZE(na1);
    CHECK_SQUARE("matrix b", na2);
    nb = COL_SIZE(na2);
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix a and b must have same size");
    }

    m = g.range == 'I' ? g.iu - g.il + 1 : n;
    w_shape[0] = m;
    z_shape[0] = n;
    z_shape[1] = m;
    ifail_shape[0] = m;

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

    return rb_ary_new3(6, a, b, RARRAY_AREF(ans, 0), RARRAY_AREF(ans, 1), RARRAY_AREF(ans, 2), RARRAY_AREF(ans, 3));
}

#undef args_t
#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/lapack/gen/../tmpl/fact.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/lapack/gen/../tmpl/fact.c"
#define UPLO 0
#define JPVT 0
#define TAU  1
#define args_t dgeqrf_args_t
#define func_p dgeqrf_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dgeqrf_t func_p = 0;

static void
iter_lapack_s_dgeqrf(na_loop_t * const lp)
{
    dtype *a;
#if JPVT
    int   *pv;
#endif
#if TAU
    dtype *tau;
#endif
    int   *info;
    int    m, n, lda, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if JPVT
    pv = (int*)NDL_PTR(lp,1);
#endif
#if TAU
    tau = (dtype*)NDL_PTR(lp,1+JPVT);
#endif
    info = (int*)NDL_PTR(lp,1+JPVT+TAU);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
#if UPLO
    n = min_(m,n);
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

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

    /**/
    *info = (*func_p)(g->order, m, n, a, lda, tau);
    CHECK_ERROR(*info);
}

/*
  @overload dgeqrf(a, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, tau, info]] Array<Numo::DFloat, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit, the elements on and above the diagonal of the array
           contain the min(M,N)-by-N upper trapezoidal matrix R (R is
           upper triangular if m >= n); the elements below the diagonal,
           with the array TAU, represent the orthogonal matrix Q as a
           product of min(m,n) elementary reflectors (see Further
           Details).

    - **tau** -- 
           TAU is DOUBLE PRECISION array, dimension (min(M,N))
           The scalar factors of the elementary reflectors (see Further
           Details).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DGEQRF computes a QR factorization of a real M-by-N matrix A:
A = Q \* R.

*/
static VALUE
lapack_s_dgeqrf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n, tmp;
    narray_t *na1;
#if JPVT
    VALUE jpvt;
#endif
    /**/
#if TAU
    size_t shape_tau[1];
#endif
    ndfunc_arg_in_t ain[1+JPVT] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1+TAU] = {{cT,1,shape_tau},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgeqrf, NO_LOOP|NDF_EXTRACT,
                    1+JPVT, TAU+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgeqrf");

#if JPVT
    rb_scan_args(argc, argv, "2:", &a, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 1+UPLO, opts);
    g.order = option_order(opts[0]);
#if UPLO
    g.uplo = option_uplo(opts[1]);
#endif

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);
#if TAU
    shape_tau[0] = min_(m,n);
#endif

#if JPVT
    COPY_OR_CAST_TO(jpvt,cInt);
    ans = na_ndloop3(&ndf, &g, 2, a, jpvt);
    rb_ary_concat(rb_ary_assoc(a,jpvt), ans);
    return ans;
#else
    ans = na_ndloop3(&ndf, &g, 1, a);
#if TAU == 0
    return rb_assoc_new(a, ans);
#else
    rb_ary_unshift(ans, a);
    return ans;
#endif
#endif
}

#undef args_t
#undef func_p
#undef UPLO
#undef JPVT
#undef TAU


#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/lapack/gen/../tmpl/fact.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/lapack/gen/../tmpl/fact.c"
#define UPLO 0
#define JPVT 0
#define TAU  1
#define args_t dgerqf_args_t
#define func_p dgerqf_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dgerqf_t func_p = 0;

static void
iter_lapack_s_dgerqf(na_loop_t * const lp)
{
    dtype *a;
#if JPVT
    int   *pv;
#endif
#if TAU
    dtype *tau;
#endif
    int   *info;
    int    m, n, lda, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if JPVT
    pv = (int*)NDL_PTR(lp,1);
#endif
#if TAU
    tau = (dtype*)NDL_PTR(lp,1+JPVT);
#endif
    info = (int*)NDL_PTR(lp,1+JPVT+TAU);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
#if UPLO
    n = min_(m,n);
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

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

    /**/
    *info = (*func_p)(g->order, m, n, a, lda, tau);
    CHECK_ERROR(*info);
}

/*
  @overload dgerqf(a, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, tau, info]] Array<Numo::DFloat, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit,
           if m <= n, the upper triangle of the subarray
           A(1:m,n-m+1:n) contains the M-by-M upper triangular matrix R;
           if m >= n, the elements on and above the (m-n)-th subdiagonal
           contain the M-by-N upper trapezoidal matrix R;
           the remaining elements, with the array TAU, represent the
           orthogonal matrix Q as a product of min(m,n) elementary
           reflectors (see Further Details).

    - **tau** -- 
           TAU is DOUBLE PRECISION array, dimension (min(M,N))
           The scalar factors of the elementary reflectors (see Further
           Details).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DGERQF computes an RQ factorization of a real M-by-N matrix A:
A = R \* Q.

*/
static VALUE
lapack_s_dgerqf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n, tmp;
    narray_t *na1;
#if JPVT
    VALUE jpvt;
#endif
    /**/
#if TAU
    size_t shape_tau[1];
#endif
    ndfunc_arg_in_t ain[1+JPVT] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1+TAU] = {{cT,1,shape_tau},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgerqf, NO_LOOP|NDF_EXTRACT,
                    1+JPVT, TAU+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgerqf");

#if JPVT
    rb_scan_args(argc, argv, "2:", &a, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 1+UPLO, opts);
    g.order = option_order(opts[0]);
#if UPLO
    g.uplo = option_uplo(opts[1]);
#endif

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);
#if TAU
    shape_tau[0] = min_(m,n);
#endif

#if JPVT
    COPY_OR_CAST_TO(jpvt,cInt);
    ans = na_ndloop3(&ndf, &g, 2, a, jpvt);
    rb_ary_concat(rb_ary_assoc(a,jpvt), ans);
    return ans;
#else
    ans = na_ndloop3(&ndf, &g, 1, a);
#if TAU == 0
    return rb_assoc_new(a, ans);
#else
    rb_ary_unshift(ans, a);
    return ans;
#endif
#endif
}

#undef args_t
#undef func_p
#undef UPLO
#undef JPVT
#undef TAU


#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/lapack/gen/../tmpl/fact.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/lapack/gen/../tmpl/fact.c"
#define UPLO 0
#define JPVT 0
#define TAU  1
#define args_t dgeqlf_args_t
#define func_p dgeqlf_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dgeqlf_t func_p = 0;

static void
iter_lapack_s_dgeqlf(na_loop_t * const lp)
{
    dtype *a;
#if JPVT
    int   *pv;
#endif
#if TAU
    dtype *tau;
#endif
    int   *info;
    int    m, n, lda, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if JPVT
    pv = (int*)NDL_PTR(lp,1);
#endif
#if TAU
    tau = (dtype*)NDL_PTR(lp,1+JPVT);
#endif
    info = (int*)NDL_PTR(lp,1+JPVT+TAU);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
#if UPLO
    n = min_(m,n);
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

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

    /**/
    *info = (*func_p)(g->order, m, n, a, lda, tau);
    CHECK_ERROR(*info);
}

/*
  @overload dgeqlf(a, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, tau, info]] Array<Numo::DFloat, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit,
           if m >= n, the lower triangle of the subarray
           A(m-n+1:m,1:n) contains the N-by-N lower triangular matrix L;
           if m <= n, the elements on and below the (n-m)-th
           superdiagonal contain the M-by-N lower trapezoidal matrix L;
           the remaining elements, with the array TAU, represent the
           orthogonal matrix Q as a product of elementary reflectors
           (see Further Details).

    - **tau** -- 
           TAU is DOUBLE PRECISION array, dimension (min(M,N))
           The scalar factors of the elementary reflectors (see Further
           Details).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DGEQLF computes a QL factorization of a real M-by-N matrix A:
A = Q \* L.

*/
static VALUE
lapack_s_dgeqlf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n, tmp;
    narray_t *na1;
#if JPVT
    VALUE jpvt;
#endif
    /**/
#if TAU
    size_t shape_tau[1];
#endif
    ndfunc_arg_in_t ain[1+JPVT] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1+TAU] = {{cT,1,shape_tau},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgeqlf, NO_LOOP|NDF_EXTRACT,
                    1+JPVT, TAU+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgeqlf");

#if JPVT
    rb_scan_args(argc, argv, "2:", &a, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 1+UPLO, opts);
    g.order = option_order(opts[0]);
#if UPLO
    g.uplo = option_uplo(opts[1]);
#endif

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);
#if TAU
    shape_tau[0] = min_(m,n);
#endif

#if JPVT
    COPY_OR_CAST_TO(jpvt,cInt);
    ans = na_ndloop3(&ndf, &g, 2, a, jpvt);
    rb_ary_concat(rb_ary_assoc(a,jpvt), ans);
    return ans;
#else
    ans = na_ndloop3(&ndf, &g, 1, a);
#if TAU == 0
    return rb_assoc_new(a, ans);
#else
    rb_ary_unshift(ans, a);
    return ans;
#endif
#endif
}

#undef args_t
#undef func_p
#undef UPLO
#undef JPVT
#undef TAU


#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/lapack/gen/../tmpl/fact.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/lapack/gen/../tmpl/fact.c"
#define UPLO 0
#define JPVT 0
#define TAU  1
#define args_t dgelqf_args_t
#define func_p dgelqf_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dgelqf_t func_p = 0;

static void
iter_lapack_s_dgelqf(na_loop_t * const lp)
{
    dtype *a;
#if JPVT
    int   *pv;
#endif
#if TAU
    dtype *tau;
#endif
    int   *info;
    int    m, n, lda, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if JPVT
    pv = (int*)NDL_PTR(lp,1);
#endif
#if TAU
    tau = (dtype*)NDL_PTR(lp,1+JPVT);
#endif
    info = (int*)NDL_PTR(lp,1+JPVT+TAU);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
#if UPLO
    n = min_(m,n);
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

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

    /**/
    *info = (*func_p)(g->order, m, n, a, lda, tau);
    CHECK_ERROR(*info);
}

/*
  @overload dgelqf(a, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, tau, info]] Array<Numo::DFloat, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit, the elements on and below the diagonal of the array
           contain the m-by-min(m,n) lower trapezoidal matrix L (L is
           lower triangular if m <= n); the elements above the diagonal,
           with the array TAU, represent the orthogonal matrix Q as a
           product of elementary reflectors (see Further Details).

    - **tau** -- 
           TAU is DOUBLE PRECISION array, dimension (min(M,N))
           The scalar factors of the elementary reflectors (see Further
           Details).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DGELQF computes an LQ factorization of a real M-by-N matrix A:
A = L \* Q.

*/
static VALUE
lapack_s_dgelqf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n, tmp;
    narray_t *na1;
#if JPVT
    VALUE jpvt;
#endif
    /**/
#if TAU
    size_t shape_tau[1];
#endif
    ndfunc_arg_in_t ain[1+JPVT] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1+TAU] = {{cT,1,shape_tau},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgelqf, NO_LOOP|NDF_EXTRACT,
                    1+JPVT, TAU+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgelqf");

#if JPVT
    rb_scan_args(argc, argv, "2:", &a, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 1+UPLO, opts);
    g.order = option_order(opts[0]);
#if UPLO
    g.uplo = option_uplo(opts[1]);
#endif

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);
#if TAU
    shape_tau[0] = min_(m,n);
#endif

#if JPVT
    COPY_OR_CAST_TO(jpvt,cInt);
    ans = na_ndloop3(&ndf, &g, 2, a, jpvt);
    rb_ary_concat(rb_ary_assoc(a,jpvt), ans);
    return ans;
#else
    ans = na_ndloop3(&ndf, &g, 1, a);
#if TAU == 0
    return rb_assoc_new(a, ans);
#else
    rb_ary_unshift(ans, a);
    return ans;
#endif
#endif
}

#undef args_t
#undef func_p
#undef UPLO
#undef JPVT
#undef TAU


#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/lapack/gen/../tmpl/fact.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/lapack/gen/../tmpl/fact.c"
#define UPLO 0
#define JPVT 1
#define TAU  1
#define args_t dgeqp3_args_t
#define func_p dgeqp3_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dgeqp3_t func_p = 0;

static void
iter_lapack_s_dgeqp3(na_loop_t * const lp)
{
    dtype *a;
#if JPVT
    int   *pv;
#endif
#if TAU
    dtype *tau;
#endif
    int   *info;
    int    m, n, lda, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if JPVT
    pv = (int*)NDL_PTR(lp,1);
#endif
#if TAU
    tau = (dtype*)NDL_PTR(lp,1+JPVT);
#endif
    info = (int*)NDL_PTR(lp,1+JPVT+TAU);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
#if UPLO
    n = min_(m,n);
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

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

    /**/
    *info = (*func_p)(g->order, m, n, a, lda, pv, tau);
    CHECK_ERROR(*info);
}

/*
  @overload dgeqp3(a, jpvt, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, jpvt, tau, info]] Array<Numo::DFloat, Numo::Int, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix A.
           On exit, the upper triangle of the array contains the
           min(M,N)-by-N upper trapezoidal matrix R; the elements below
           the diagonal, together with the array TAU, represent the
           orthogonal matrix Q as a product of min(M,N) elementary
           reflectors.

    - **jpvt** -- 
           JPVT is INTEGER array, dimension (N)
           On entry, if JPVT(J).ne.0, the J-th column of A is permuted
           to the front of A\*P (a leading column); if JPVT(J)=0,
           the J-th column of A is a free column.
           On exit, if JPVT(J)=K, then the J-th column of A\*P was the
           the K-th column of A.

    - **tau** -- 
           TAU is DOUBLE PRECISION array, dimension (min(M,N))
           The scalar factors of the elementary reflectors.

    - **info** -- 
           INFO is INTEGER
           = 0: successful exit.
           < 0: if INFO = -i, the i-th argument had an illegal value.

DGEQP3 computes a QR factorization with column pivoting of a
matrix A:  A\*P = Q\*R  using Level 3 BLAS.

*/
static VALUE
lapack_s_dgeqp3(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n, tmp;
    narray_t *na1;
#if JPVT
    VALUE jpvt;
#endif
    /**/
#if TAU
    size_t shape_tau[1];
#endif
    ndfunc_arg_in_t ain[1+JPVT] = {{OVERWRITE,2},{OVERWRITE,1}};
    ndfunc_arg_out_t aout[1+TAU] = {{cT,1,shape_tau},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgeqp3, NO_LOOP|NDF_EXTRACT,
                    1+JPVT, TAU+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgeqp3");

#if JPVT
    rb_scan_args(argc, argv, "2:", &a, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 1+UPLO, opts);
    g.order = option_order(opts[0]);
#if UPLO
    g.uplo = option_uplo(opts[1]);
#endif

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);
#if TAU
    shape_tau[0] = min_(m,n);
#endif

#if JPVT
    COPY_OR_CAST_TO(jpvt,cInt);
    ans = na_ndloop3(&ndf, &g, 2, a, jpvt);
    rb_ary_concat(rb_ary_assoc(a,jpvt), ans);
    return ans;
#else
    ans = na_ndloop3(&ndf, &g, 1, a);
#if TAU == 0
    return rb_assoc_new(a, ans);
#else
    rb_ary_unshift(ans, a);
    return ans;
#endif
#endif
}

#undef args_t
#undef func_p
#undef UPLO
#undef JPVT
#undef TAU


#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/lapack/gen/../tmpl/fact.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/lapack/gen/../tmpl/fact.c"
#define UPLO 0
#define JPVT 0
#define TAU  1
#define args_t dtzrzf_args_t
#define func_p dtzrzf_p

typedef struct {
    int order;
    char uplo;
} args_t;

static dtzrzf_t func_p = 0;

static void
iter_lapack_s_dtzrzf(na_loop_t * const lp)
{
    dtype *a;
#if JPVT
    int   *pv;
#endif
#if TAU
    dtype *tau;
#endif
    int   *info;
    int    m, n, lda, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if JPVT
    pv = (int*)NDL_PTR(lp,1);
#endif
#if TAU
    tau = (dtype*)NDL_PTR(lp,1+JPVT);
#endif
    info = (int*)NDL_PTR(lp,1+JPVT+TAU);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    SWAP_IFCOL(g->order,m,n);
#if UPLO
    n = min_(m,n);
#endif
    lda = NDL_STEP(lp,0) / sizeof(dtype);

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

    /**/
    *info = (*func_p)(g->order, m, n, a, lda, tau);
    CHECK_ERROR(*info);
}

/*
  @overload dtzrzf(a, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, tau, info]] Array<Numo::DFloat, Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the leading M-by-N upper trapezoidal part of the
           array A must contain the matrix to be factorized.
           On exit, the leading M-by-M upper triangular part of A
           contains the upper triangular matrix R, and elements M+1 to
           N of the first M rows of A, with the array TAU, represent the
           orthogonal matrix Z as a product of M elementary reflectors.

    - **tau** -- 
           TAU is DOUBLE PRECISION array, dimension (M)
           The scalar factors of the elementary reflectors.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DTZRZF reduces the M-by-N ( M<=N ) real upper trapezoidal matrix A
to upper triangular form by means of orthogonal transformations.
The upper trapezoidal matrix A is factored as

        A = ( R  0 ) * Z,

where Z is an N-by-N orthogonal matrix and R is an M-by-M upper
triangular matrix.

*/
static VALUE
lapack_s_dtzrzf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, ans;
    int   m, n, tmp;
    narray_t *na1;
#if JPVT
    VALUE jpvt;
#endif
    /**/
#if TAU
    size_t shape_tau[1];
#endif
    ndfunc_arg_in_t ain[1+JPVT] = {{OVERWRITE,2}};
    ndfunc_arg_out_t aout[1+TAU] = {{cT,1,shape_tau},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dtzrzf, NO_LOOP|NDF_EXTRACT,
                    1+JPVT, TAU+1, ain,aout};

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

    CHECK_FUNC(func_p,"dtzrzf");

#if JPVT
    rb_scan_args(argc, argv, "2:", &a, &jpvt, &kw_hash);
#else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
#endif
    rb_get_kwargs(kw_hash, kw_table, 0, 1+UPLO, opts);
    g.order = option_order(opts[0]);
#if UPLO
    g.uplo = option_uplo(opts[1]);
#endif

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);
    SWAP_IFCOL(g.order,m,n);
#if TAU
    shape_tau[0] = min_(m,n);
#endif

#if JPVT
    COPY_OR_CAST_TO(jpvt,cInt);
    ans = na_ndloop3(&ndf, &g, 2, a, jpvt);
    rb_ary_concat(rb_ary_assoc(a,jpvt), ans);
    return ans;
#else
    ans = na_ndloop3(&ndf, &g, 1, a);
#if TAU == 0
    return rb_assoc_new(a, ans);
#else
    rb_ary_unshift(ans, a);
    return ans;
#endif
#endif
}

#undef args_t
#undef func_p
#undef UPLO
#undef JPVT
#undef TAU


#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/lapack/gen/../tmpl/gqr.c"
/**/
#line 4 "/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/lapack/gen/../tmpl/gqr.c"
#define args_t dorgqr_args_t
#define func_p dorgqr_p

typedef struct {
    int order;
} args_t;

static dorgqr_t func_p = 0;

static void
iter_lapack_s_dorgqr(na_loop_t * const lp)
{
    dtype *a;
    dtype *tau;
    int   *info;
    int    m, n, k, lda, tmp;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
    tau = (dtype*)NDL_PTR(lp,1);
    info = (int*)NDL_PTR(lp,2);
    g = (args_t*)(lp->opt_ptr);

    m = NDL_SHAPE(lp,0)[0];
    n = NDL_SHAPE(lp,0)[1];
    k = NDL_SHAPE(lp,1)[0];
    SWAP_IFCOL(g->order,m,n);
    lda = NDL_STEP(lp,0) / sizeof(dtype);

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

    *info = (*func_p)(g->order, m, n, k, a, lda, tau);
    CHECK_ERROR(*info);
}

/*
  @overload dorgqr(a, tau, order:'R')
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param tau [Numo::DFloat]  vector (>=1-dimentional NArray).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, info]] Array<Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the i-th column must contain the vector which
           defines the elementary reflector H(i), for i = 1,2,...,k, as
           returned by DGEQRF in the first k columns of its array
           argument A.
           On exit, the M-by-N matrix Q.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument has an illegal value

DORGQR generates an M-by-N real matrix Q with orthonormal columns,
which is defined as the first N columns of a product of K elementary
reflectors of order M

        Q  =  H(1) H(2) . . . H(k)

as returned by DGEQRF.

*/
static VALUE
lapack_s_dorgqr(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
    VALUE a, tau, ans;
    int   m, n, k, tmp;
    narray_t *na1, *na2;
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cT,1}};
    ndfunc_arg_out_t aout[1] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dorgqr, NO_LOOP|NDF_EXTRACT, 2,1, ain,aout};

    args_t g = {0};
    VALUE opts[1] = {Qundef};
    VALUE kw_hash = Qnil;
    ID kw_table[1] = {id_order};

    CHECK_FUNC(func_p,"dorgqr");

    rb_scan_args(argc, argv, "2:", &a, &tau, &kw_hash);
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
    g.order = option_order(opts[0]);

    COPY_OR_CAST_TO(a,cT);
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
    m = ROW_SIZE(na1);
    n = COL_SIZE(na1);

    GetNArray(tau, na2);
    CHECK_DIM_GE(na2, 1);
    k = COL_SIZE(na2);
    if (m < n) {
        rb_raise(nary_eShapeError,
                 "a row length (m) must be >= a column length (n): m=%d n=%d",
                 m,n);
    }
    if (n < k) {
        rb_raise(nary_eShapeError,
                 "a column length (n) must be >= tau length (k): n=%d, k=%d",
                 k,n);
    }
    SWAP_IFCOL(g.order,m,n);

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

    return rb_assoc_new(a, ans);
}

#undef args_t
#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  0
#define TRANS 0
#define UPLO 0
#define IPIV 1
#define IPIV_OUT 1
#define IPIV_IN 0
#define SYM  0
#define args_t dgetrf_args_t
#define func_p dgetrf_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dgetrf_t func_p = 0;

static void
iter_lapack_s_dgetrf(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, n, m, a, lda, pv);
    CHECK_ERROR(*info);
}

/*
  @overload dgetrf(a, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, ipiv, info]] Array<Numo::DFloat, Numo::Int, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the M-by-N matrix to be factored.
           On exit, the factors L and U from the factorization
           A = P\*L\*U; the unit diagonal elements of L are not stored.

    - **ipiv** -- 
           IPIV is INTEGER array, dimension (min(M,N))
           The pivot indices; for 1 <= i <= min(M,N), row i of the
           matrix was interchanged with row IPIV(i).

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, U(i,i) is exactly zero. The factorization
                 has been completed, but the factor U is exactly
                 singular, and division by zero will occur if it is used
                 to solve a system of equations.

DGETRF computes an LU factorization of a general M-by-N matrix A
using partial pivoting with row interchanges.
The factorization has the form

        A = P * L * U

where P is a permutation matrix, L is lower triangular with unit
diagonal elements (lower trapezoidal if m > n), and U is upper
triangular (upper trapezoidal if m < n).
This is the right-looking Level 3 BLAS version of the algorithm.

*/
static VALUE
lapack_s_dgetrf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,1,shape_piv},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgetrf, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgetrf");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  0
#define TRANS 0
#define UPLO 0
#define IPIV 1
#define IPIV_OUT 0
#define IPIV_IN 1
#define SYM  1
#define args_t dgetri_args_t
#define func_p dgetri_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dgetri_t func_p = 0;

static void
iter_lapack_s_dgetri(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, n, a, lda, pv);
    CHECK_ERROR(*info);
}

/*
  @overload dgetri(a, ipiv, [order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param ipiv [Numo::Int] pivot computed by dgetrf
  @param order [String or Symbol]  if 'R': Row-major, if 'C': Column-major. (default='R')
  @return [[a, info]] Array<Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the factors L and U from the factorization
           A = P\*L\*U as computed by DGETRF.
           On exit, if INFO = 0, the inverse of the original matrix A.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, U(i,i) is exactly zero; the matrix is
                 singular and its inverse could not be computed.

DGETRI computes the inverse of a matrix using the LU factorization
computed by DGETRF.
This method inverts U and then computes inv(A) by solving the system
inv(A)\*L = inv(U) for inv(A).

*/
static VALUE
lapack_s_dgetri(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgetri, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgetri");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  1
#define TRANS 1
#define UPLO 0
#define IPIV 1
#define IPIV_OUT 0
#define IPIV_IN 1
#define SYM  1
#define args_t dgetrs_args_t
#define func_p dgetrs_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dgetrs_t func_p = 0;

static void
iter_lapack_s_dgetrs(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, g->trans, n, nrhs, a, lda, pv, b, ldb);
    CHECK_ERROR(*info);
}

/*
  @overload dgetrs(a, ipiv, b, [trans:'N', order:'R'])
  @param a [Numo::DFloat] LU matrix computed by dgetrf
  @param ipiv [Numo::Int] pivot computed by dgetrf
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @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 [[b, info]] Array<Numo::DFloat, Integer>

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the right hand side matrix B.
           On exit, the solution matrix X.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DGETRS solves a system of linear equations

        A * X = B  or  A**T * X = B

with a general N-by-N matrix A using the LU factorization computed
by DGETRF.

*/
static VALUE
lapack_s_dgetrs(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dgetrs, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dgetrs");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  0
#define TRANS 0
#define UPLO 1
#define IPIV 1
#define IPIV_OUT 1
#define IPIV_IN 0
#define SYM  1
#define args_t dsytrf_args_t
#define func_p dsytrf_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dsytrf_t func_p = 0;

static void
iter_lapack_s_dsytrf(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, g->uplo, n, a, lda, pv);
    CHECK_ERROR(*info);
}

/*
  @overload dsytrf(a, [uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @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 [[a, ipiv, info]] Array<Numo::DFloat, Numo::Int, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the leading
           N-by-N upper triangular part of A contains the upper
           triangular part of the matrix A, and the strictly lower
           triangular part of A is not referenced.  If UPLO = 'L', the
           leading N-by-N lower triangular part of A contains the lower
           triangular part of the matrix A, and the strictly upper
           triangular part of A is not referenced.
           On exit, the block diagonal matrix D and the multipliers used
           to obtain the factor U or L (see below for further details).

    - **ipiv** -- 
           IPIV is INTEGER array, dimension (N)
           Details of the interchanges and the block structure of D.
           If IPIV(k) > 0, then rows and columns k and IPIV(k) were
           interchanged and D(k,k) is a 1-by-1 diagonal block.
           If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and
           columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)
           is a 2-by-2 diagonal block.  If UPLO = 'L' and IPIV(k) =
           IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were
           interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, D(i,i) is exactly zero.  The factorization
                 has been completed, but the block diagonal matrix D is
                 exactly singular, and division by zero will occur if it
                 is used to solve a system of equations.

DSYTRF computes the factorization of a real symmetric matrix A using
the Bunch-Kaufman diagonal pivoting method.  The form of the
factorization is

        A = U*D*U**T  or  A = L*D*L**T

where U (or L) is a product of permutation and unit upper (lower)
triangular matrices, and D is symmetric and block diagonal with
1-by-1 and 2-by-2 diagonal blocks.
This is the blocked version of the algorithm, calling Level 3 BLAS.

*/
static VALUE
lapack_s_dsytrf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,1,shape_piv},{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsytrf, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dsytrf");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  0
#define TRANS 0
#define UPLO 1
#define IPIV 1
#define IPIV_OUT 0
#define IPIV_IN 1
#define SYM  1
#define args_t dsytri_args_t
#define func_p dsytri_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dsytri_t func_p = 0;

static void
iter_lapack_s_dsytri(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, g->uplo, n, a, lda, pv);
    CHECK_ERROR(*info);
}

/*
  @overload dsytri(a, ipiv, [uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @param ipiv [Numo::Int] pivot computed by dsytrf
  @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 [[a, info]] Array<Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the block diagonal matrix D and the multipliers
           used to obtain the factor U or L as computed by DSYTRF.
           On exit, if INFO = 0, the (symmetric) inverse of the original
           matrix.  If UPLO = 'U', the upper triangular part of the
           inverse is formed and the part of A below the diagonal is not
           referenced; if UPLO = 'L' the lower triangular part of the
           inverse is formed and the part of A above the diagonal is
           not referenced.

    - **info** -- 
           INFO is INTEGER
           = 0: successful exit
           < 0: if INFO = -i, the i-th argument had an illegal value
           > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its
                inverse could not be computed.

DSYTRI computes the inverse of a real symmetric indefinite matrix
A using the factorization A = U\*D\*U\*\*T or A = L\*D\*L\*\*T computed by
DSYTRF.

*/
static VALUE
lapack_s_dsytri(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsytri, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dsytri");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  1
#define TRANS 0
#define UPLO 1
#define IPIV 1
#define IPIV_OUT 0
#define IPIV_IN 1
#define SYM  1
#define args_t dsytrs_args_t
#define func_p dsytrs_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dsytrs_t func_p = 0;

static void
iter_lapack_s_dsytrs(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, g->uplo, n, nrhs, a, lda, pv, b, ldb);
    CHECK_ERROR(*info);
}

/*
  @overload dsytrs(a, ipiv, b, [uplo:'U', order:'R'])
  @param a [Numo::DFloat] LU matrix computed by dsytrf
  @param ipiv [Numo::Int] pivot computed by dsytrf
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @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 [[b, info]] Array<Numo::DFloat, Integer>

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the right hand side matrix B.
           On exit, the solution matrix X.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DSYTRS solves a system of linear equations A\*X = B with a real
symmetric matrix A using the factorization A = U\*D\*U\*\*T or
A = L\*D\*L\*\*T computed by DSYTRF.

*/
static VALUE
lapack_s_dsytrs(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dsytrs, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dsytrs");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  0
#define TRANS 0
#define UPLO 1
#define IPIV 0
#define IPIV_OUT 0
#define IPIV_IN 0
#define SYM  1
#define args_t dpotrf_args_t
#define func_p dpotrf_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dpotrf_t func_p = 0;

static void
iter_lapack_s_dpotrf(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, g->uplo, n, a, lda);
    CHECK_ERROR(*info);
}

/*
  @overload dpotrf(a, [uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @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 [[a, info]] Array<Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the symmetric matrix A.  If UPLO = 'U', the leading
           N-by-N upper triangular part of A contains the upper
           triangular part of the matrix A, and the strictly lower
           triangular part of A is not referenced.  If UPLO = 'L', the
           leading N-by-N lower triangular part of A contains the lower
           triangular part of the matrix A, and the strictly upper
           triangular part of A is not referenced.
           On exit, if INFO = 0, the factor U or L from the Cholesky
           factorization A = U\*\*T\*U or A = L\*L\*\*T.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, the leading minor of order i is not
                 positive definite, and the factorization could not be
                 completed.

DPOTRF computes the Cholesky factorization of a real symmetric
positive definite matrix A.
The factorization has the form

        A = U**T * U,  if UPLO = 'U', or
        A = L  * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is lower triangular.
This is the block version of the algorithm, calling Level 3 BLAS.

*/
static VALUE
lapack_s_dpotrf(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dpotrf, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dpotrf");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  0
#define TRANS 0
#define UPLO 1
#define IPIV 0
#define IPIV_OUT 0
#define IPIV_IN 0
#define SYM  1
#define args_t dpotri_args_t
#define func_p dpotri_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dpotri_t func_p = 0;

static void
iter_lapack_s_dpotri(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, g->uplo, n, a, lda);
    CHECK_ERROR(*info);
}

/*
  @overload dpotri(a, [uplo:'U', order:'R'])
  @param a [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @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 [[a, info]] Array<Numo::DFloat, Integer>

    - **a** -- 
           A is DOUBLE PRECISION array, dimension (LDA,N)
           On entry, the triangular factor U or L from the Cholesky
           factorization A = U\*\*T\*U or A = L\*L\*\*T, as computed by
           DPOTRF.
           On exit, the upper or lower triangle of the (symmetric)
           inverse of A, overwriting the input factor U or L.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value
           > 0:  if INFO = i, the (i,i) element of the factor U or L is
                 zero, and the inverse could not be computed.

DPOTRI computes the inverse of a real symmetric positive definite
matrix A using the Cholesky factorization A = U\*\*T\*U or A = L\*L\*\*T
computed by DPOTRF.

*/
static VALUE
lapack_s_dpotri(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dpotri, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dpotri");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM


#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/lapack/gen/../tmpl/trf.c"

#line 10 "/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/lapack/gen/../tmpl/trf.c"
#define RHS  1
#define TRANS 0
#define UPLO 1
#define IPIV 0
#define IPIV_OUT 0
#define IPIV_IN 0
#define SYM  1
#define args_t dpotrs_args_t
#define func_p dpotrs_p

typedef struct {
    int order;
    char uplo;
    char trans;
} args_t;

static dpotrs_t func_p = 0;

static void
iter_lapack_s_dpotrs(na_loop_t * const lp)
{
    dtype *a;
#if RHS
    dtype *b;
    int    nb, nrhs, ldb;
#endif
#if IPIV
    int   *pv;
#endif
    int   *info;
    int    m, n, lda;
    args_t *g;

    a = (dtype*)NDL_PTR(lp,0);
#if IPIV
    pv = (int*)NDL_PTR(lp,1);
#endif
#if RHS
    b = (dtype*)NDL_PTR(lp,1+IPIV);
#endif
    info = (int*)NDL_PTR(lp,1+IPIV+RHS);
    g = (args_t*)(lp->opt_ptr);

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

#if RHS
    // same as gels.c
    if (lp->args[1+IPIV].ndim == 1) {
        nrhs = 1;
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        ldb = (g->order==LAPACK_COL_MAJOR) ? nb : 1;
    } else {
        nb = NDL_SHAPE(lp,1+IPIV)[0];
        nrhs = NDL_SHAPE(lp,1+IPIV)[1];
        ldb = nrhs;
        { int tmp; SWAP_IFCOL(g->order,nb,nrhs); }
    }
    //printf("order=%d m=%d n=%d nb=%d nrhs=%d lda=%d ldb=%d\n",g->order,m,n,nb,nrhs,lda,ldb);
#else
    //printf("order=%d m=%d n=%d lda=%d \n",g->order,m,n,lda);
#endif

#if SYM
    n = min_(m,n);
#else
    { int tmp; SWAP_IFCOL(g->order,m,n); }
#endif

    
#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/lapack/gen/../tmpl/trf.c"
    *info = (*func_p)(g->order, g->uplo, n, nrhs, a, lda, b, ldb);
    CHECK_ERROR(*info);
}

/*
  @overload dpotrs(a, b, [uplo:'U', order:'R'])
  @param a [Numo::DFloat] LU matrix computed by dpotrf
  @param b [Numo::DFloat]  matrix (>=2-dimentional NArray, inplace allowed).
  @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 [[b, info]] Array<Numo::DFloat, Integer>

    - **b** -- 
           B is DOUBLE PRECISION array, dimension (LDB,NRHS)
           On entry, the right hand side matrix B.
           On exit, the solution matrix X.

    - **info** -- 
           INFO is INTEGER
           = 0:  successful exit
           < 0:  if INFO = -i, the i-th argument had an illegal value

DPOTRS solves a system of linear equations A\*X = B with a symmetric
positive definite matrix A using the Cholesky factorization
A = U\*\*T\*U or A = L\*L\*\*T computed by DPOTRF.

*/
static VALUE
lapack_s_dpotrs(int argc, VALUE const argv[], VALUE UNUSED(mod))
{
#line 144 "/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/lapack/gen/../tmpl/trf.c"
    VALUE a, ans;
#if IPIV_IN
    VALUE ipiv;
#endif
#if RHS
    VALUE b;
    size_t n, nb, nrhs;
    narray_t *na2;
#endif
    narray_t *na1;
    
#line 160 "/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/lapack/gen/../tmpl/trf.c"
#if IPIV_OUT
    size_t shape_piv[1];
#endif
#if IPIV_IN
# if RHS
    ndfunc_arg_in_t ain[3] = {{cT,2},{cInt,1},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[2] = {{OVERWRITE,2},{cInt,1}};
# endif
#else
# if RHS
    ndfunc_arg_in_t ain[2] = {{cT,2},{OVERWRITE,2}};
# else
    ndfunc_arg_in_t ain[1] = {{OVERWRITE,2}};
# endif
#endif
    ndfunc_arg_out_t aout[1+IPIV_OUT] = {{cInt,0}};
    ndfunc_t ndf = {&iter_lapack_s_dpotrs, NO_LOOP|NDF_EXTRACT,
                    1+IPIV_IN+RHS, IPIV_OUT+1, ain,aout};

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

    CHECK_FUNC(func_p,"dpotrs");

#if IPIV_IN
# if RHS
    rb_scan_args(argc, argv, "3:", &a, &ipiv, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "2:", &a, &ipiv, &kw_hash);
# endif
#else
# if RHS
    rb_scan_args(argc, argv, "2:", &a, &b, &kw_hash);
# else
    rb_scan_args(argc, argv, "1:", &a, &kw_hash);
# endif
#endif
#if TRANS
    kw_table[1] = id_trans;
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.trans = option_trans(opts[1]);
#elif UPLO
    rb_get_kwargs(kw_hash, kw_table, 0, 2, opts);
    g.uplo = option_uplo(opts[1]);
#else
    rb_get_kwargs(kw_hash, kw_table, 0, 1, opts);
#endif
    g.order = option_order(opts[0]);

#if !RHS
    COPY_OR_CAST_TO(a,cT);
#endif
    GetNArray(a, na1);
    CHECK_DIM_GE(na1, 2);
#if IPIV_OUT
    shape_piv[0] = min_(ROW_SIZE(na1),COL_SIZE(na1));
#endif

#if RHS
    COPY_OR_CAST_TO(b,cT);
    GetNArray(b, na2);
    CHECK_DIM_GE(na2, 1);
    n = COL_SIZE(na1);
#if SYM
    n = min_(n,ROW_SIZE(na1));
#endif
    // same as gesv.c
    if (NA_NDIM(na2) == 1) {
        ain[1+IPIV_IN].dim = 1;
        nb = COL_SIZE(na2);
        nrhs = 1;
    } else {
        nb = ROW_SIZE(na2);
        nrhs = COL_SIZE(na2);
        { int tmp; SWAP_IFCOL(g.order,nb,nrhs); }
    }
    if (n != nb) {
        rb_raise(nary_eShapeError, "matrix dimension mismatch: "
                 "a.col(or a.row)=%"SZF"u b.row=%"SZF"u", n, nb);
    }
#endif

#if IPIV_IN
# if RHS
    ans = na_ndloop3(&ndf, &g, 3, a, ipiv, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 2, a, ipiv);
    return rb_assoc_new(a, ans);
# endif
#else
# if RHS
    ans = na_ndloop3(&ndf, &g, 2, a, b);
    return rb_assoc_new(b, ans);
# else
    ans = na_ndloop3(&ndf, &g, 1, a);
#  if IPIV_OUT
    return rb_ary_unshift(ans, a);
#  else
    return rb_assoc_new(a, ans);
#  endif
# endif
#endif
}

#undef args_t
#undef func_p
#undef RHS
#undef TRANS
#undef UPLO
#undef IPIV
#undef IPIV_OUT
#undef IPIV_IN
#undef SYM



#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/lapack/gen/../tmpl/lib.c"
void
Init_numo_linalg_lapack_d(void)
{
    VALUE mN;

    mN = rb_define_module("Numo");

    
    id_axis = rb_intern("axis");
    id_il = rb_intern("il");
    id_itype = rb_intern("itype");
    id_iu = rb_intern("iu");
    id_jobu = rb_intern("jobu");
    id_jobvl = rb_intern("jobvl");
    id_jobvr = rb_intern("jobvr");
    id_jobvt = rb_intern("jobvt");
    id_jobz = rb_intern("jobz");
    id_keepdims = rb_intern("keepdims");
    id_norm = rb_intern("norm");
    id_order = rb_intern("order");
    id_range = rb_intern("range");
    id_rcond = rb_intern("rcond");
    id_trans = rb_intern("trans");
    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/lapack/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/lapack/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/lapack/gen/../tmpl/init_module.c"
    /*
      Document-module: Numo::Linalg::Lapack
      
    */
    
    mLapack = rb_define_module_under(mLinalg, "Lapack");
    
    
    /**/
    eLapackError = rb_define_class_under(mLinalg,"LapackError",rb_eStandardError);
    
    rb_define_module_function(mLapack, "dlange", lapack_s_dlange, -1);
    rb_define_module_function(mLapack, "dgesv", lapack_s_dgesv, -1);
    rb_define_module_function(mLapack, "dsysv", lapack_s_dsysv, -1);
    rb_define_module_function(mLapack, "dposv", lapack_s_dposv, -1);
    rb_define_module_function(mLapack, "dgesvd", lapack_s_dgesvd, -1);
    rb_define_module_function(mLapack, "dgesdd", lapack_s_dgesdd, -1);
    rb_define_module_function(mLapack, "dgels", lapack_s_dgels, -1);
    rb_define_module_function(mLapack, "dgelss", lapack_s_dgelss, -1);
    rb_define_module_function(mLapack, "dgelsd", lapack_s_dgelsd, -1);
    rb_define_module_function(mLapack, "dgelsy", lapack_s_dgelsy, -1);
    rb_define_module_function(mLapack, "dgeev", lapack_s_dgeev, -1);
    rb_define_module_function(mLapack, "dggev", lapack_s_dggev, -1);
    rb_define_module_function(mLapack, "dsyev", lapack_s_dsyev, -1);
    rb_define_module_function(mLapack, "dsyevd", lapack_s_dsyevd, -1);
    rb_define_module_function(mLapack, "dsygv", lapack_s_dsygv, -1);
    rb_define_module_function(mLapack, "dsygvd", lapack_s_dsygvd, -1);
    rb_define_module_function(mLapack, "dsygvx", lapack_s_dsygvx, -1);
    rb_define_module_function(mLapack, "dgeqrf", lapack_s_dgeqrf, -1);
    rb_define_module_function(mLapack, "dgerqf", lapack_s_dgerqf, -1);
    rb_define_module_function(mLapack, "dgeqlf", lapack_s_dgeqlf, -1);
    rb_define_module_function(mLapack, "dgelqf", lapack_s_dgelqf, -1);
    rb_define_module_function(mLapack, "dgeqp3", lapack_s_dgeqp3, -1);
    rb_define_module_function(mLapack, "dtzrzf", lapack_s_dtzrzf, -1);
    rb_define_module_function(mLapack, "dorgqr", lapack_s_dorgqr, -1);
    rb_define_module_function(mLapack, "dgetrf", lapack_s_dgetrf, -1);
    rb_define_module_function(mLapack, "dgetri", lapack_s_dgetri, -1);
    rb_define_module_function(mLapack, "dgetrs", lapack_s_dgetrs, -1);
    rb_define_module_function(mLapack, "dsytrf", lapack_s_dsytrf, -1);
    rb_define_module_function(mLapack, "dsytri", lapack_s_dsytri, -1);
    rb_define_module_function(mLapack, "dsytrs", lapack_s_dsytrs, -1);
    rb_define_module_function(mLapack, "dpotrf", lapack_s_dpotrf, -1);
    rb_define_module_function(mLapack, "dpotri", lapack_s_dpotri, -1);
    rb_define_module_function(mLapack, "dpotrs", lapack_s_dpotrs, -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/lapack/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/lapack/gen/../tmpl/lib.c"
}
