10void scanArgs(SEXP args, SEXP exprs,
int margin,
int level,
11 int *rdim,
int *rdimnames,
char *kind,
char *repr)
14 int nS4 = 0, nDense = 0,
15 anyCsparse = 0, anyRsparse = 0, anyTsparse = 0, anyDiagonal = 0,
16 anyN = 0, anyL = 0, anyI = 0, anyD = 0, anyZ = 0,
23 rdimnames[0] = rdimnames[1] = 0;
25 for (a = args; a != R_NilValue; a = CDR(a)) {
29 if (TYPEOF(s) == S4SXP) {
31 ivalid = R_check_class_etc(s,
valid);
42 if (rdim[!margin] < 0)
43 rdim[!margin] = sdim[!margin];
44 else if (sdim[!margin] != rdim[!margin]) {
46 error(
_(
"number of rows of matrices must match"));
48 error(
_(
"number of columns of matrices must match"));
50 if (sdim[margin] > INT_MAX - rdim[margin])
51 error(
_(
"dimensions cannot exceed %s"),
"2^31-1");
52 rdim[margin] += sdim[margin];
54 if (!rdimnames[0] || !rdimnames[1]) {
57 if (VECTOR_ELT(tmp, 0) != R_NilValue ||
58 VECTOR_ELT(tmp, 1) != R_NilValue)
59 rdimnames[0] = rdimnames[1] = 1;
61 for (i = 0; i < 2; ++i)
63 VECTOR_ELT(tmp, i) != R_NilValue)
146 tmp = getAttrib(s, R_DimSymbol);
147 if (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2) {
149 if (rdim[!margin] < 0)
150 rdim[!margin] = sdim[!margin];
151 else if (rdim[!margin] != sdim[!margin]) {
153 error(
_(
"number of rows of matrices must match"));
155 error(
_(
"number of columns of matrices must match"));
157 if (sdim[margin] > INT_MAX - rdim[margin])
158 error(
_(
"dimensions cannot exceed %s"),
"2^31-1");
159 rdim[margin] += sdim[margin];
161 if (!rdimnames[0] || !rdimnames[1]) {
162 tmp = getAttrib(s, R_DimNamesSymbol);
163 if (tmp != R_NilValue)
164 for (i = 0; i < 2; ++i)
166 VECTOR_ELT(tmp, i) != R_NilValue)
173 if (rdim[!margin] < 0) {
175 R_xlen_t maxlen = -1;
176 for (a = args; a != R_NilValue; a = CDR(a)) {
182 error(
_(
"dimensions cannot exceed %s"),
"2^31-1");
183 else if (slen > maxlen)
189 rdim[!margin] = (int) maxlen;
192 for (a = args, e = exprs; a != R_NilValue; a = CDR(a), e = CDR(e)) {
194 if ((s == R_NilValue && rdim[!margin] > 0) || TYPEOF(s) == S4SXP)
199 tmp = getAttrib(s, R_DimSymbol);
200 if (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2)
203 if (slen == 0 && rdim[!margin] > 0)
205 if (rdim[margin] == INT_MAX)
206 error(
_(
"dimensions cannot exceed %s"),
"2^31-1");
208 if (slen > rdim[!margin] || rdim[!margin] % (
int) slen) {
210 warning(
_(
"number of rows of result is not a multiple of vector length"));
212 warning(
_(
"number of columns of result is not a multiple of vector length"));
214 if (!rdimnames[!margin] && slen == rdim[!margin]) {
215 tmp = getAttrib(s, R_NamesSymbol);
216 if (tmp != R_NilValue)
217 rdimnames[!margin] = 1;
220 if (!rdimnames[margin]) {
221 if (TAG(a) != R_NilValue ||
222 level == 2 || (level == 1 && TYPEOF(CAR(e)) == SYMSXP))
223 rdimnames[margin] = 1;
229#ifndef MATRIX_ENABLE_IMATRIX
230 else if (anyD || anyI)
247 else if (nDense == 0) {
248 if (anyCsparse && anyRsparse)
249 *repr = (margin) ?
'C' :
'R';
256 else if (anyDiagonal)
257 *repr = (margin) ?
'C' :
'R';
266 for (a = args; a != R_NilValue && nnz < INT_MAX; a = CDR(a)) {
268 if (TYPEOF(s) != S4SXP)
270 ivalid = R_check_class_etc(s,
valid);
282 snnz = (scl[1] !=
't') ? slen : ((slen + sdim[0]) / 2);
288 int *pp = INTEGER(p), n = sdim[(scl[2] ==
'C') ? 1 : 0];
293 int *pi = INTEGER(i), j;
296 for (j = 0; j < n; ++j)
297 if (pp[j] < pp[j + 1] && pi[pp[j + 1] - 1] == j)
300 for (j = 0; j < n; ++j)
301 if (pp[j] < pp[j + 1] && pi[pp[j]] == j)
316 int *pi = INTEGER(i), *pj = INTEGER(j);
317 R_xlen_t k = XLENGTH(i);
320 if (*(pi++) == *(pj++))
343 if (nnz > INT_MAX || nnz > len / 2)
345 else if (anyCsparse && anyRsparse)
346 *repr = (margin) ?
'C' :
'R';
354 *repr = (margin) ?
'C' :
'R';
362 int *rdim,
char kind,
char repr)
366 char scl_[] =
"...Matrix";
369 for (a = args; a != R_NilValue; a = CDR(a)) {
372 SET_TAG(a, R_NilValue);
376 PROTECT_WITH_INDEX(s, &pid);
377 if (TYPEOF(s) == S4SXP) {
378 ivalid = R_check_class_etc(s,
valid);
388 scl_[0] = kind; scl_[1] = scl[1]; scl_[2] = scl[2];
396 scl_[0] = scl[0]; scl_[1] = scl[1]; scl_[2] = repr;
409 scl_[0] = kind; scl_[1] = scl[1]; scl_[2] = scl[2];
461 tmp = getAttrib(s, R_DimSymbol);
462 isM = TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2;
464 if (rdim[!margin] > 0 && XLENGTH(s) == 0) {
471 REPROTECT(s = coerceVector(s,
kindToType(kind)), pid);
473 if (!isM && XLENGTH(s) != rdim[!margin]) {
474 static SEXP replen = NULL;
476 replen = install(
"rep_len");
477 SEXP lengthout = PROTECT(ScalarInteger(rdim[!margin])),
478 call = PROTECT(lang3(replen, s, lengthout));
479 REPROTECT(s = eval(call, R_GlobalEnv), pid);
496 int *rdim,
char kind,
char repr)
500#define BIND_CASES(_BIND_) \
504 _BIND_(int, LOGICAL, SHOW); \
507 _BIND_(int, INTEGER, SHOW); \
510 _BIND_(double, REAL, SHOW); \
513 _BIND_(Rcomplex, COMPLEX, SHOW); \
522 if (rdim[0] == 0 || rdim[1] == 0)
525 int k, m = rdim[0], n = rdim[1];
526 R_xlen_t mn = (R_xlen_t) m * n;
527 SEXP x = PROTECT(allocVector(
kindToType(kind), mn)), tmp;
530#define BIND_E(_CTYPE_, _PTR_, _MASK_) \
532 _CTYPE_ *px = _PTR_(x), *ps; \
533 for (a = args; a != R_NilValue; a = CDR(a)) { \
535 if (s == R_NilValue) \
537 if (TYPEOF(s) != S4SXP) \
538 tmp = getAttrib(s, R_DimSymbol); \
540 s = GET_SLOT(s, Matrix_xSym); \
546 if (!tmp || (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2)) { \
547 Matrix_memcpy(px, ps, mn, sizeof(_CTYPE_)); \
549 } else if (mn >= m) { \
550 Matrix_memcpy(px, ps, m , sizeof(_CTYPE_)); \
552 } else if (mn == 1) { \
554 for (k = 0; k < m; ++k) \
557 int mn_ = (int) mn; \
558 for (k = 0; k < rdim[0]; ++k) \
559 *(px++) = ps[k % mn_]; \
563 if (!tmp || (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2)) { \
564 m = (int) (mn / n); \
565 for (k = 0; k < n; ++k) { \
566 Matrix_memcpy(py, ps, m, sizeof(_CTYPE_)); \
571 } else if (mn >= n) { \
572 for (k = 0; k < n; ++k) { \
578 } else if (mn == 1) { \
580 for (k = 0; k < n; ++k) { \
586 int mn_ = (int) mn; \
587 for (k = 0; k < n; ++k) { \
603 }
else if ((repr ==
'C' && margin) || (repr ==
'R' && !margin)) {
605 SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) rdim[margin] + 1));
606 int *pp = INTEGER(p);
609 if (rdim[0] == 0 || rdim[1] == 0) {
610 Matrix_memset(pp, 0, (R_xlen_t) rdim[margin] + 1,
sizeof(
int));
616 int *psp, j, n, nnz = 0;
618 for (a = args; a != R_NilValue; a = CDR(a)) {
624 n = (int) (XLENGTH(sp) - 1);
625 if (psp[n] > INT_MAX - nnz)
626 error(
_(
"%s cannot exceed %s"),
"p[length(p)]",
"2^31-1");
627 for (j = 0; j < n; ++j)
628 *(pp++) = nnz = nnz + (psp[j + 1] - psp[j]);
631 SEXP i = PROTECT(allocVector(INTSXP, nnz)), si,
633 int *pi = INTEGER(i), *psi;
636#define BIND_C1R0(_CTYPE_, _PTR_, _MASK_) \
638 _MASK_(_CTYPE_ *px = _PTR_(x), *psx); \
639 for (a = args; a != R_NilValue; a = CDR(a)) { \
641 if (s == R_NilValue) \
643 PROTECT(sp = GET_SLOT(s, Matrix_pSym)); \
644 PROTECT(si = GET_SLOT(s, iSym)); \
645 _MASK_(PROTECT(sx = GET_SLOT(s, Matrix_xSym))); \
648 _MASK_(psx = _PTR_(sx)); \
649 n = (int) (XLENGTH(sp) - 1); \
650 Matrix_memcpy(pi, psi, psp[n], sizeof(int)); \
651 _MASK_(Matrix_memcpy(px, psx, psp[n], sizeof(_CTYPE_))); \
653 _MASK_(px += psp[n]); \
654 _MASK_(UNPROTECT(1)); \
662 SEXP x = PROTECT(allocVector(
kindToType(kind), nnz)), sx;
669 }
else if ((repr ==
'C' && !margin) || (repr ==
'R' && margin)) {
671 SEXP p = PROTECT(allocVector(INTSXP, (R_xlen_t) rdim[!margin] + 1));
672 int *pp = INTEGER(p);
674 Matrix_memset(pp, 0, (R_xlen_t) rdim[!margin] + 1,
sizeof(
int));
676 if (rdim[0] == 0 || rdim[1] == 0) {
682 int *psp, j, n = rdim[!margin];
684 for (a = args; a != R_NilValue; a = CDR(a)) {
689 psp = INTEGER(sp) + 1;
690 if (n > 0 && psp[n - 1] > INT_MAX - pp[n - 1])
691 error(
_(
"%s cannot exceed %s"),
"p[length(p)]",
"2^31-1");
692 for (j = 0; j < n; ++j)
698 SEXP i = PROTECT(allocVector(INTSXP, nnz)), si,
700 int *pi = INTEGER(i), *psi, *work, k, kend, pos = 0;
705#define BIND_C0R1(_CTYPE_, _PTR_, _MASK_) \
707 _MASK_(_CTYPE_ *px = _PTR_(x), *psx); \
708 for (a = args; a != R_NilValue; a = CDR(a)) { \
710 if (s == R_NilValue) \
712 PROTECT(sp = GET_SLOT(s, Matrix_pSym)); \
713 PROTECT(si = GET_SLOT(s, iSym)); \
714 _MASK_(PROTECT(sx = GET_SLOT(s, Matrix_xSym))); \
717 _MASK_(psx = _PTR_(sx)); \
718 for (j = 0, k = 0; j < n; ++j) { \
721 pi[work[j]] = *(psi++) + pos; \
722 _MASK_(px[work[j]] = *(psx++)); \
727 _MASK_(UNPROTECT(1)); \
729 pos += INTEGER(GET_SLOT(s, Matrix_DimSym))[margin]; \
736 SEXP x = PROTECT(allocVector(
kindToType(kind), nnz)), sx;
744 }
else if (repr ==
'T') {
746 if (rdim[0] == 0 || rdim[1] == 0)
750 for (a = args; a != R_NilValue; a = CDR(a)) {
755 if (k > R_XLEN_T_MAX - nnz)
756 error(
_(
"attempt to allocate vector of length exceeding %s"),
762 i = PROTECT(allocVector(INTSXP, nnz)),
763 j = PROTECT(allocVector(INTSXP, nnz));
764 int *psi, *psj, *pi = INTEGER(i), *pj = INTEGER(j), pos = 0;
768#define BIND_T(_CTYPE_, _PTR_, _MASK_) \
770 _MASK_(_CTYPE_ *px = _PTR_(x), *psx); \
771 for (a = args; a != R_NilValue; a = CDR(a)) { \
773 if (s == R_NilValue) \
775 PROTECT(si = GET_SLOT(s, Matrix_iSym)); \
776 PROTECT(sj = GET_SLOT(s, Matrix_jSym)); \
777 _MASK_(PROTECT(sx = GET_SLOT(s, Matrix_xSym))); \
780 _MASK_(psx = _PTR_(sx)); \
784 *(pi++) = *(psi++); \
785 *(pj++) = *(psj++) + pos; \
786 _MASK_(*(px++) = *(psx++)); \
790 *(pi++) = *(psi++) + pos; \
791 *(pj++) = *(psj++); \
792 _MASK_(*(px++) = *(psx++)); \
795 _MASK_(UNPROTECT(1)); \
797 pos += INTEGER(GET_SLOT(s, Matrix_DimSym))[margin]; \
804 SEXP x = PROTECT(allocVector(
kindToType(kind), nnz)), sx;
813 SEXP p = PROTECT(allocVector(INTSXP, rdim[margin])), sp;
814 int *pp = INTEGER(p);
815 for (a = args; a != R_NilValue; a = CDR(a)) {
840SEXP
bind(SEXP args, SEXP exprs,
int margin,
int level)
845 int rdim[2], rdimnames[2];
846 char kind =
'\0', repr =
'\0';
847 scanArgs(args, exprs, margin, level,
848 rdim, rdimnames, &kind, &repr);
849 if (rdim[!margin] < 0)
853 error(
_(
"attempt to allocate vector of length exceeding %s"),
855 char rcl[] =
"...Matrix";
856 if (kind ==
'\0' || repr ==
'\0') {
858 error(
_(
"should never happen ..."));
869 bindArgs(args, margin, res, rdim, kind, repr);
872 INTEGER(dim)[0] = rdim[0];
873 INTEGER(dim)[1] = rdim[1];
876 if (rdimnames[0] || rdimnames[1]) {
878 marnames = R_NilValue, nms[2], nms_, a, e, s, tmp;
879 int i, ivalid, r = -1, pos = 0, nprotect = 1;
881 if (rdimnames[margin]) {
882 PROTECT(marnames = allocVector(STRSXP, rdim[margin]));
884 SET_VECTOR_ELT(dimnames, margin, marnames);
886 for (a = args, e = exprs; a != R_NilValue; a = CDR(a), e = CDR(e)) {
888 if (s == R_NilValue && rdim[!margin] > 0)
890 nms[0] = nms[1] = R_NilValue;
891 if (TYPEOF(s) == S4SXP) {
892 ivalid = R_check_class_etc(s,
valid);
895 r = INTEGER(tmp)[margin];
898 if ((nms_ = VECTOR_ELT(tmp, 1)) != R_NilValue ||
899 (nms_ = VECTOR_ELT(tmp, 0)) != R_NilValue)
900 nms[0] = nms[1] = nms_;
902 for (i = 0; i < 2; ++i)
903 nms[i] = VECTOR_ELT(tmp, i);
905 tmp = getAttrib(s, R_DimSymbol);
906 if (TYPEOF(tmp) == INTSXP && LENGTH(tmp) == 2) {
907 r = INTEGER(tmp)[margin];
908 tmp = getAttrib(s, R_DimNamesSymbol);
909 if (tmp != R_NilValue)
910 for (i = 0; i < 2; ++i)
911 nms[i] = VECTOR_ELT(tmp, i);
912 }
else if (rdim[!margin] == 0 || XLENGTH(s) > 0) {
914 if (rdim[!margin] > 0 && XLENGTH(s) == rdim[!margin])
915 nms[!margin] = getAttrib(s, R_NamesSymbol);
918 if (TAG(a) != R_NilValue) {
920 nms[margin] = coerceVector(TAG(a), STRSXP);
921 else if (level == 2) {
922 PROTECT(nms_ = allocVector(EXPRSXP, 1));
923 SET_VECTOR_ELT(nms_, 0, CAR(e));
924 nms[margin] = coerceVector(nms_, STRSXP);
926 }
else if (level == 1 && TYPEOF(CAR(e)) == SYMSXP)
927 nms[margin] = coerceVector(CAR(e), STRSXP);
929 if (rdimnames[!margin] && nms[!margin] != R_NilValue) {
930 SET_VECTOR_ELT(dimnames, !margin, nms[!margin]);
931 rdimnames[!margin] = 0;
932 if (!rdimnames[margin])
935 if (rdimnames[ margin] && nms[ margin] != R_NilValue)
936 for (i = 0; i < r; ++i)
937 SET_STRING_ELT(marnames, pos + i,
938 STRING_ELT(nms[margin], i));
950 SEXP level, margin, exprs;
951 args = CDR(args); level = CAR(args);
952 args = CDR(args); margin = CAR(args);
953 args = CDR(args); exprs = CAR(args);
954 return bind(CDR(args), CDR(exprs), asInteger(margin), asInteger(level));
long long Matrix_int_fast64_t
#define ERROR_INVALID_CLASS(_X_, _FUNC_)
#define VALID_NONVIRTUAL_MATRIX
SEXPTYPE kindToType(char)
#define ERROR_INVALID_TYPE(_X_, _FUNC_)
#define Matrix_Free(_VAR_, _N_)
#define SET_SLOT(x, what, value)
#define GET_SLOT(x, what)
#define Matrix_Calloc(_VAR_, _N_, _CTYPE_)
SEXP newObject(const char *)
#define VALID_NONVIRTUAL_SHIFT(i, pToInd)
static void coerceArgs(SEXP args, int margin, int *rdim, char kind, char repr)
#define BIND_C0R1(_CTYPE_, _PTR_, _MASK_)
static const char * valid[]
#define BIND_CASES(_BIND_)
#define BIND_E(_CTYPE_, _PTR_, _MASK_)
#define BIND_T(_CTYPE_, _PTR_, _MASK_)
#define BIND_C1R0(_CTYPE_, _PTR_, _MASK_)
static void bindArgs(SEXP args, int margin, SEXP res, int *rdim, char kind, char repr)
static void scanArgs(SEXP args, SEXP exprs, int margin, int level, int *rdim, int *rdimnames, char *kind, char *repr)
static SEXP bind(SEXP args, SEXP exprs, int margin, int level)
SEXP sparse_as_Csparse(SEXP from, const char *class)
SEXP sparse_as_Rsparse(SEXP from, const char *class)
SEXP diagonal_as_sparse(SEXP from, const char *class, char kind, char shape, char repr, char ul)
SEXP sparse_as_dense(SEXP from, const char *class, int packed)
SEXP dense_as_sparse(SEXP from, const char *class, char repr)
SEXP sparse_as_kind(SEXP from, const char *class, char kind)
SEXP dense_as_kind(SEXP from, const char *class, char kind, int new)
SEXP index_as_dense(SEXP from, const char *class, char kind)
SEXP sparse_as_Tsparse(SEXP from, const char *class)
SEXP matrix_as_sparse(SEXP from, const char *zzz, char ul, char di, int trans)
SEXP dense_as_general(SEXP from, const char *class, int new)
SEXP sparse_as_general(SEXP from, const char *class)
SEXP diagonal_as_dense(SEXP from, const char *class, char kind, char shape, int packed, char ul)
SEXP index_as_sparse(SEXP from, const char *class, char kind, char repr)
SEXP Tsparse_aggregate(SEXP from)
void * Matrix_memset(void *dest, int ch, R_xlen_t length, size_t size)
void * Matrix_memcpy(void *dest, const void *src, R_xlen_t length, size_t size)