The R Project SVN R-packages

Rev

Rev 4963 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

            /* Sparse symmetric matrices in triplet format */
#include "TMatrix_as.h"

#define MAYBE_DECLARE_AND_GET_X_SLOT(__T__, __S__)  \
          DECLARE_AND_GET_X_SLOT(__T__, __S__)

#define Matrix_T_as_DENSE(_C_TYPE_, _SEXP_, _SEXPTYPE_)         \
    SEXP dimP = GET_SLOT(x, Matrix_DimSym),             \
      xiP = GET_SLOT(x, Matrix_iSym);               \
    int k, n = INTEGER(dimP)[0], nnz = length(xiP);         \
    int *xi = INTEGER(xiP), *xj = INTEGER(GET_SLOT(x, Matrix_jSym)),    \
    sz = n * n;                         \
    _C_TYPE_ *tx = _SEXP_(ALLOC_SLOT(val, Matrix_xSym, _SEXPTYPE_, sz)); \
    MAYBE_DECLARE_AND_GET_X_SLOT(_C_TYPE_, _SEXP_);         \
                                    \
    SET_SLOT(val, Matrix_DimSym, duplicate(dimP));          \
    SET_DimNames(val, x);                       \
    slot_dup(val, x, Matrix_uploSym)

#define Matrix_T_as_DENSE_FINISH(_X_k_)     \
    AZERO(tx, sz);              \
    for (k = 0; k < nnz; k++)           \
    tx[xi[k] + xj[k] * n] = _X_k_;      \
    UNPROTECT(1);               \
    return val


SEXP dsTMatrix_as_dsyMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dsyMatrix")));

    Matrix_T_as_DENSE(double, REAL, REALSXP);
    Matrix_T_as_DENSE_FINISH(xx[k]);
}

SEXP lsTMatrix_as_lsyMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("lsyMatrix")));

    Matrix_T_as_DENSE(int, LOGICAL, LGLSXP);
    Matrix_T_as_DENSE_FINISH(xx[k]);
}

/* ---- Now the triangular ones --  have an extra  'diag'  slot : ------ */

SEXP dtTMatrix_as_dtrMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dtrMatrix")));

    Matrix_T_as_DENSE(double, REAL, REALSXP);
    slot_dup(val, x, Matrix_diagSym);
    Matrix_T_as_DENSE_FINISH(xx[k]);
}

SEXP ltTMatrix_as_ltrMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("ltrMatrix")));

    Matrix_T_as_DENSE(int, LOGICAL, LGLSXP);
    slot_dup(val, x, Matrix_diagSym);
    Matrix_T_as_DENSE_FINISH(xx[k]);
}

/*===================== Coercion to  gTMatrix ================================*/

#undef  MAYBE_DECLARE_AND_GET_X_SLOT
#define MAYBE_DECLARE_AND_GET_X_SLOT(__T__, __S__)      \
          DECLARE_AND_GET_X_SLOT(__T__, __S__), *vx

#define ALLOC_val_x_SLOT(__SEXP__, __S_TYPE__)          \
    vx = __SEXP__(ALLOC_SLOT(val, Matrix_xSym,__S_TYPE__, nv))

#define MAYBE_ALLOC_val_x_SLOT(_S1_, _S2_)  \
          ALLOC_val_x_SLOT(_S1_, _S2_)

#define MEMCPY_x_SLOT       Memcpy(&vx[nv], xx, nnz)
#define MAYBE_MEMCPY_x_SLOT     MEMCPY_x_SLOT

#define SET_x_SLOT      vx[nv] = xx[i]
#define MAYBE_SET_x_SLOT    SET_x_SLOT

#define Matrix_T_as_GENERAL(_C_TYPE_, _SEXP_, _SEXPTYPE_)       \
    SEXP xiP = GET_SLOT(x, Matrix_iSym);                \
    /* , uplo = GET_SLOT(x, Matrix_uploSym); */             \
    int i, nnz = length(xiP), n0d, nv,                  \
    *xi = INTEGER(xiP),                     \
    *xj = INTEGER(GET_SLOT(x, Matrix_jSym)),            \
    *vi, *vj;                           \
    MAYBE_DECLARE_AND_GET_X_SLOT(_C_TYPE_, _SEXP_);         \
                                    \
    /* Find *length* of result slots: */                \
    /*  = 2 * nnz - n0d; n0d := #{non-0 diagonals} :*/          \
    for(i = 0, n0d = 0; i < nnz; i++)                   \
    if(xi[i] == xj[i]) n0d++ ;                  \
    nv = 2 * nnz - n0d;                         \
                                    \
    vi = INTEGER(ALLOC_SLOT(val, Matrix_iSym, INTSXP, nv));     \
    vj = INTEGER(ALLOC_SLOT(val, Matrix_jSym, INTSXP, nv));     \
    MAYBE_ALLOC_val_x_SLOT(_SEXP_, _SEXPTYPE_);             \
                                    \
    slot_dup(val, x, Matrix_DimSym); \
    SET_DimNames(val, x);                       \
    /* copy the upper/lower triangle (including the diagonal)*/     \
    /* "at end" ([nv]): */                      \
    nv = nnz - n0d;                         \
    Memcpy(&vi[nv], xi, nnz);                       \
    Memcpy(&vj[nv], xj, nnz);                       \
    MAYBE_MEMCPY_x_SLOT;                        \
                                    \
    for(i = 0, nv = 0; i < nnz; i++) { /* copy the other triangle */    \
    if(xi[i] != xj[i]) { /* but not the diagonal */         \
        vi[nv] = xj[i];                     \
        vj[nv] = xi[i];                     \
        MAYBE_SET_x_SLOT;                       \
        nv++;                           \
    }                               \
    }                                   \
                                    \
    UNPROTECT(1);                           \
    return val


/* this corresponds to changing 'stype' of a cholmod_triplet;
 * seems not available there */
SEXP dsTMatrix_as_dgTMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgTMatrix")));
    Matrix_T_as_GENERAL(double, REAL, REALSXP);
}


SEXP lsTMatrix_as_lgTMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("lgTMatrix")));
    Matrix_T_as_GENERAL(int, LOGICAL, LGLSXP);
}

/* Now the 'nsparseMatrix' ones where input has no 'x' slot : ---------------*/

#undef  MAYBE_DECLARE_AND_GET_X_SLOT
#define MAYBE_DECLARE_AND_GET_X_SLOT(__T__, __S__)
#undef  MAYBE_ALLOC_val_x_SLOT
#define MAYBE_ALLOC_val_x_SLOT(_S1_, _S2_)
#undef  MAYBE_MEMCPY_x_SLOT
#define MAYBE_MEMCPY_x_SLOT
#undef  MAYBE_SET_x_SLOT
#define MAYBE_SET_x_SLOT

SEXP nsTMatrix_as_nsyMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("nsyMatrix")));

    Matrix_T_as_DENSE(int, LOGICAL, LGLSXP);
    Matrix_T_as_DENSE_FINISH(1);
}

SEXP ntTMatrix_as_ntrMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("ntrMatrix")));

    Matrix_T_as_DENSE(int, LOGICAL, LGLSXP);
    slot_dup(val, x, Matrix_diagSym);
    Matrix_T_as_DENSE_FINISH(1);
}

SEXP nsTMatrix_as_ngTMatrix(SEXP x)
{
    SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("ngTMatrix")));
    Matrix_T_as_GENERAL(int, LOGICAL, LGLSXP);
}