5#define F_ND(_X_) ((_X_) ? 1 : 0)
8#define AR21_UP(i, j, m) i + j + ( j * ( j - 1)) / 2
9#define AR21_LO(i, j, m) i + (j * m + j * (m - j - 1)) / 2
15#define SUB1_START(_SEXPTYPE_) \
16 SEXPTYPE typ = _SEXPTYPE_; \
17 R_xlen_t l = 0, len = XLENGTH(w); \
18 SEXP res = allocVector(typ, len); \
23 SEXP dim = PROTECT(GET_SLOT(x, Matrix_DimSym)); \
24 int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; \
25 Matrix_int_fast64_t mn64 = (Matrix_int_fast64_t) m * n; \
28#define SUB1_START_EXTRA(_SEXPTYPE_) \
29 SUB1_START(_SEXPTYPE_); \
31 int ge = cl[1] == 'g', tr = cl[1] == 't', upper = 1, nonunit = 1; \
33 SEXP uplo = PROTECT(GET_SLOT(x, Matrix_uploSym)); \
34 upper = *CHAR(STRING_ELT(uplo, 0)) == 'U'; \
37 SEXP diag = PROTECT(GET_SLOT(x, Matrix_diagSym)); \
38 nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; \
45#define SUB1_CASES(_SUB1_N_, _SUB1_X_, _F_N_, _F_X_) \
49 _SUB1_N_(int, LOGICAL, NA_LOGICAL, 0, 1, _F_N_); \
52 _SUB1_X_(int, LOGICAL, NA_LOGICAL, 0, 1, _F_X_); \
55 _SUB1_X_(int, INTEGER, NA_INTEGER, 0, 1, _F_X_); \
58 _SUB1_X_(double, REAL, NA_REAL, 0.0, 1.0, _F_X_); \
61 _SUB1_X_(Rcomplex, COMPLEX, \
62 Matrix_zna, Matrix_zzero, Matrix_zone, _F_X_); \
69#define SUB1_N(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_) \
71 _CTYPE_ *pres = _PTR_(res); \
72 if (TYPEOF(w) == INTSXP) { \
73 int *pw = INTEGER(w); \
74 if (mn64 >= INT_MAX) { \
76 SUB1_LOOP((pw[l] == NA_INTEGER), \
77 _NA_, _ZERO_, _ONE_, _F_, Matrix_int_fast64_t); \
80 SUB1_LOOP((pw[l] == NA_INTEGER || pw[l] > mn), \
81 _NA_, _ZERO_, _ONE_, _F_, int); \
84 double *pw = REAL(w); \
85 if (mn64 >= 0x1.0p+53) \
88 SUB1_LOOP((ISNAN(pw[l]) || pw[l] >= 0x1.0p+62 || \
89 (Matrix_int_fast64_t) pw[l] > mn64), \
90 _NA_, _ZERO_, _ONE_, _F_, Matrix_int_fast64_t); \
92 double mn1a = (double) m * n + 1.0; \
93 SUB1_LOOP((ISNAN(pw[l]) || pw[l] >= mn1a), \
94 _NA_, _ZERO_, _ONE_, _F_, Matrix_int_fast64_t); \
99#define SUB1_X(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_) \
101 PROTECT(x = GET_SLOT(x, Matrix_xSym)); \
102 _CTYPE_ *px = _PTR_(x); \
103 SUB1_N(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_); \
107#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \
109 _INT_ index, i_, j_; \
110 for (l = 0; l < len; ++l) { \
111 if (_NA_SUBSCRIPT_) \
114 index = (_INT_) pw[l] - 1; \
116 pres[l] = _F_(px[index]); \
121 if ((upper) ? i_ > j_ : i_ < j_) \
123 else if (!nonunit && i_ == j_) \
126 pres[l] = _F_(px[index]); \
128 if ((upper) ? i_ > j_ : i_ < j_) \
129 pres[l] = _F_(px[i_ * m + j_]); \
131 pres[l] = _F_(px[index]); \
151#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \
153 _INT_ index, i_, j_; \
154 for (l = 0; l < len; ++l) { \
155 if (_NA_SUBSCRIPT_) \
158 index = (_INT_) pw[l] - 1; \
165 else if (!nonunit && i_ == j_) \
168 pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \
172 else if (!nonunit && i_ == j_) \
175 pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \
180 pres[l] = _F_(px[AR21_UP(j_, i_, m)]); \
182 pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \
185 pres[l] = _F_(px[AR21_LO(j_, i_, m)]); \
187 pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \
209 int *pp = INTEGER(p), *pi = INTEGER(i), i_, j_, j, k = 0, kend;
211#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \
214 if (_NA_SUBSCRIPT_) \
217 index = (_INT_) pw[l] - 1; \
218 i_ = (int) (index % m); \
219 j_ = j = (int) (index / m); \
224 while (k < kend && j_ == j) { \
231 pres[l] = _F_(px[k]); \
233 if (l == len || _NA_SUBSCRIPT_) \
236 index = (_INT_) pw[l] - 1; \
237 i_ = (int) (index % m); \
238 j_ = (int) (index / m); \
245 if (l == len || _NA_SUBSCRIPT_) \
248 index = (_INT_) pw[l] - 1; \
249 i_ = (int) (index % m); \
250 j_ = (int) (index / m); \
276 int *pp = INTEGER(p), *pj = INTEGER(j), i, i_, j_, k = 0, kend;
278#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \
281 if (_NA_SUBSCRIPT_) \
284 index = (_INT_) pw[l] - 1; \
285 i_ = i = (int) (index % m); \
286 j_ = (int) (index / m); \
291 while (k < kend && i_ == i) { \
298 pres[l] = _F_(px[k]); \
300 if (l == len || _NA_SUBSCRIPT_) \
303 index = (_INT_) pw[l] - 1; \
304 i_ = (int) (index % m); \
305 j_ = (int) (index / m); \
312 if (l == len || _NA_SUBSCRIPT_) \
315 index = (_INT_) pw[l] - 1; \
316 i_ = (int) (index % m); \
317 j_ = (int) (index / m); \
342 int nonunit = *CHAR(STRING_ELT(diag, 0)) ==
'N';
347#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \
349 for (l = 0; l < len; ++l) { \
350 if (_NA_SUBSCRIPT_) \
352 else if ((index = (Matrix_int_fast64_t) pw[l] - 1) % n1a != 0) \
357 pres[l] = _F_(px[index / n1a]); \
375 int *pperm = INTEGER(perm), i_, j_;
378 int mg = INTEGER(margin)[0] - 1;
381#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_, _INT_) \
384 for (l = 0; l < len; ++l) { \
385 if (_NA_SUBSCRIPT_) \
388 index = (_INT_) pw[l] - 1; \
389 i_ = (int) (index % m); \
390 j_ = (int) (index / m); \
392 pres[l] = j_ == pperm[i_] - 1; \
394 pres[l] = i_ == pperm[j_] - 1; \
399 SUB1_N(
int, LOGICAL, NA_LOGICAL, 0, 1, );
404#undef SUB1_START_EXTRA
414 int ivalid = R_check_class_etc(x,
valid);
418 const char *
cl =
valid[ivalid];
441 char cl_[] =
"..CMatrix";
465#define SUB1_START(_SEXPTYPE_) \
466 SEXPTYPE typ = _SEXPTYPE_; \
467 int l = 0, len = (int) (XLENGTH(w) / 2); \
468 SEXP res = allocVector(typ, len); \
472 int *pw0 = INTEGER(w), *pw1 = pw0 + len;
474#define SUB1_START_EXTRA(_SEXPTYPE_) \
475 SUB1_START(_SEXPTYPE_); \
477 SEXP dim = PROTECT(GET_SLOT(x, Matrix_DimSym)); \
478 int m = INTEGER(dim)[0]; \
481 int ge = cl[1] == 'g', tr = cl[1] == 't', upper = 1, nonunit = 1; \
483 SEXP uplo = PROTECT(GET_SLOT(x, Matrix_uploSym)); \
484 upper = *CHAR(STRING_ELT(uplo, 0)) == 'U'; \
487 SEXP diag = PROTECT(GET_SLOT(x, Matrix_diagSym)); \
488 nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; \
497#define SUB1_N(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_) \
499 _CTYPE_ *pres = _PTR_(res); \
500 SUB1_LOOP((pw0[l] == NA_INTEGER || pw1[l] == NA_INTEGER), \
501 _NA_, _ZERO_, _ONE_, _F_); \
504#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \
506 for (l = 0; l < len; ++l) { \
507 if (_NA_SUBSCRIPT_) \
513 pres[l] = _F_(px[j_ * m + i_]); \
515 if ((upper) ? i_ > j_ : i_ < j_) \
517 else if (!nonunit && i_ == j_) \
520 pres[l] = _F_(px[j_ * m + i_]); \
522 if ((upper) ? i_ > j_ : i_ < j_) \
523 pres[l] = _F_(px[i_ * m + j_]); \
525 pres[l] = _F_(px[j_ * m + i_]); \
546#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \
548 for (l = 0; l < len; ++l) { \
549 if (_NA_SUBSCRIPT_) \
558 else if (!nonunit && i_ == j_) \
561 pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \
565 else if (!nonunit && i_ == j_) \
568 pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \
573 pres[l] = _F_(px[AR21_UP(j_, i_, m)]); \
575 pres[l] = _F_(px[AR21_UP(i_, j_, m)]); \
578 pres[l] = _F_(px[AR21_LO(j_, i_, m)]); \
580 pres[l] = _F_(px[AR21_LO(i_, j_, m)]); \
602 int *pp = INTEGER(p), *pi = INTEGER(i), i_, j_, j, k = 0, kend;
604#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \
606 if (_NA_SUBSCRIPT_) \
610 j_ = j = pw1[l] - 1; \
615 while (k < kend && j_ == j) { \
622 pres[l] = _F_(px[k]); \
624 if (l == len || _NA_SUBSCRIPT_) \
635 if (l == len || _NA_SUBSCRIPT_) \
665 int *pp = INTEGER(p), *pj = INTEGER(j), i, i_, j_, k = 0, kend;
667#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \
669 if (_NA_SUBSCRIPT_) \
672 i_ = i = pw0[l] - 1; \
678 while (k < kend && i_ == i) { \
685 pres[l] = _F_(px[k]); \
687 if (l == len || _NA_SUBSCRIPT_) \
698 if (l == len || _NA_SUBSCRIPT_) \
727 int nonunit = *CHAR(STRING_ELT(diag, 0)) ==
'N';
730#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \
732 for (l = 0; l < len; ++l) { \
733 if (_NA_SUBSCRIPT_) \
735 else if (pw0[l] != pw1[l]) \
740 pres[l] = _F_(px[pw0[l] - 1]); \
758 int *pperm = INTEGER(perm);
761 int mg = INTEGER(margin)[0] - 1;
764#define SUB1_LOOP(_NA_SUBSCRIPT_, _NA_, _ZERO_, _ONE_, _F_) \
766 for (l = 0; l < len; ++l) { \
767 if (_NA_SUBSCRIPT_) \
770 pres[l] = pw1[l] == pperm[pw0[l] - 1]; \
772 pres[l] = pw0[l] == pperm[pw1[l] - 1]; \
776 SUB1_N(
int, LOGICAL, NA_LOGICAL, 0, 1, );
783#undef SUB1_START_EXTRA
795 int ivalid = R_check_class_etc(x,
valid);
799 const char *
cl =
valid[ivalid];
822 char cl_[] =
"..CMatrix";
843int keep_tr(
int *pi,
int *pj,
int n,
int upper,
int nonunit,
int checkNA)
845 int k, ident = memcmp(pi, pj, n *
sizeof(
int)) == 0;
848 for (k = 0; k < n; ++k)
849 if (pi[k] == NA_INTEGER)
852 for (k = 0; k < n; ++k)
853 if (pi[k] == NA_INTEGER || pj[k] == NA_INTEGER)
857 int r = (upper) ? 1 : -1;
863 else if (pi[0] < pi[1]) {
864 for (k = 2; k < n; ++k)
865 if (pi[k - 1] >= pi[k])
869 for (k = 2; k < n; ++k)
870 if (pi[k - 1] <= pi[k])
883 for (kj = 0; kj < n; ++kj)
884 for (ki = kj + 1, j_ = pj[kj]; ki < n; ++ki)
890 for (kj = 0; kj < n; ++kj)
891 for (ki = 0, j_ = pj[kj]; ki < kj; ++ki)
897 for (kj = 0; kj < n; ++kj)
898 for (ki = 0, j_ = pj[kj]; ki < kj; ++ki)
904 for (kj = 0; kj < n; ++kj)
905 for (ki = kj + 1, j_ = pj[kj]; ki < n; ++ki)
915int keep_sy(
int *pi,
int *pj,
int n,
int upper,
int checkNA)
917 if (memcmp(pi, pj, n *
sizeof(
int)) != 0)
919 int k, r = (upper) ? 1 : -1;
921 for (k = 0; k < n; ++k)
922 if (pi[k] == NA_INTEGER)
929 else if (pi[0] < pi[1]) {
930 for (k = 2; k < n; ++k)
931 if (pi[k - 1] >= pi[k])
935 for (k = 2; k < n; ++k)
936 if (pi[k - 1] <= pi[k])
946int keep_di(
int *pi,
int *pj,
int n,
int nonunit,
int checkNA,
int lwork)
948 int k, ident = memcmp(pi, pj, n *
sizeof(
int)) == 0;
951 for (k = 0; k < n; ++k)
952 if (pi[k] == NA_INTEGER)
955 for (k = 0; k < n; ++k)
956 if (pi[k] == NA_INTEGER || pj[k] == NA_INTEGER)
965 for (k = 0; k < n; ++k) {
972 return (nonunit) ? 1 : 2;
976 for (kj = 0; kj < n; ++kj) {
978 for (ki = 0; ki < kj; ++ki)
981 for (ki = kj + 1; ki < n; ++ki)
993 int *pdim = INTEGER(dim),
994 m = pdim[(
cl[2] ==
'C') ? 0 : 1],
995 n = pdim[(
cl[2] ==
'C') ? 1 : 0],
1002 int *pp = INTEGER(p), *pi = INTEGER(i);
1004 int i_, j_, k, kend, nnz = pp[n], *workA, *workB, *workC;
1005 size_t lwork = (size_t) m + 1 + r + nnz;
1007 workB = workA + m + 1;
1010#define SORT_LOOP(_MASK_) \
1013 for (k = 0; k < nnz; ++k) \
1017 for (i_ = 1; i_ < m; ++i_) \
1018 workA[i_] = workB[i_] = workB[i_ - 1] + workA[i_]; \
1023 for (j_ = 0; j_ < n; ++j_) { \
1025 while (k < kend) { \
1027 workC[workB[i_]] = j_; \
1028 _MASK_(workD[workB[i_]] = px[k]); \
1035 for (j_ = 0; j_ < n; ++j_) \
1036 workB[j_] = pp[j_]; \
1040 for (i_ = 0; i_ < m; ++i_) { \
1042 while (k < kend) { \
1044 pi[workB[j_]] = i_; \
1045 _MASK_(px[workB[j_]] = workD[k]); \
1053#define SORT(_CTYPE_, _PTR_) \
1055 _CTYPE_ *px = _PTR_(x), *workD; \
1056 Matrix_Calloc(workD, nnz, _CTYPE_); \
1058 Matrix_Free(workD, nnz); \
1076 SORT(Rcomplex, COMPLEX);
1092#define XIJ_GE( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1093 *(_X_ + _J_ * _M_ + _I_)
1095#define XIJ_TR_U_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1097 ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1100#define XIJ_TR_U_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1102 ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1103 : ((_I_ == _J_) ? _ONE_ : _ZERO_))
1105#define XIJ_TR_L_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1107 ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1110#define XIJ_TR_L_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1112 ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1113 : ((_I_ == _J_) ? _ONE_ : _ZERO_))
1115#define XIJ_TP_U_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1117 ? *(_X_ + AR21_UP(_I_, _J_, _M_)) \
1120#define XIJ_TP_U_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1122 ? *(_X_ + AR21_UP(_I_, _J_, _M_)) \
1123 : ((_I_ == _J_) ? _ONE_ : _ZERO_))
1125#define XIJ_TP_L_N(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1127 ? *(_X_ + AR21_LO(_I_, _J_, _M_)) \
1130#define XIJ_TP_L_U(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1132 ? *(_X_ + AR21_LO(_I_, _J_, _M_)) \
1133 : ((_I_ == _J_) ? _ONE_ : _ZERO_))
1135#define XIJ_SY_U( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1137 ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1138 : XIJ_GE(_X_, _J_, _I_, _M_, _ZERO_, _ONE_))
1140#define XIJ_SY_L( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1142 ? XIJ_GE(_X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1143 : XIJ_GE(_X_, _J_, _I_, _M_, _ZERO_, _ONE_))
1145#define XIJ_SP_U( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1147 ? *(_X_ + AR21_UP(_I_, _J_, _M_)) \
1148 : *(_X_ + AR21_UP(_J_, _I_, _M_)))
1150#define XIJ_SP_L( _X_, _I_, _J_, _M_, _ZERO_, _ONE_) \
1152 ? *(_X_ + AR21_LO(_I_, _J_, _M_)) \
1153 : *(_X_ + AR21_LO(_J_, _I_, _M_)))
1160 SEXP dim = PROTECT(GET_SLOT(x, Matrix_DimSym)); \
1161 int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1]; \
1165 mi = i == R_NilValue, \
1166 mj = j == R_NilValue, \
1167 ni = (mi) ? m : LENGTH(i), \
1168 nj = (mj) ? n : LENGTH(j), \
1169 *pi = (mi) ? NULL : INTEGER(i), \
1170 *pj = (mj) ? NULL : INTEGER(j);
1172#define SUB2_START_EXTRA(_E_, _R_, _Y_, _DENSE_) \
1175 int upper = 1, nonunit = 1, keep = 0; \
1177 if (cl[1] != 'g') { \
1178 PROTECT(uplo = GET_SLOT(x, Matrix_uploSym)); \
1179 upper = *CHAR(STRING_ELT(uplo, 0)) == 'U'; \
1181 if (cl[1] == 't') { \
1182 PROTECT(diag = GET_SLOT(x, Matrix_diagSym)); \
1183 nonunit = *CHAR(STRING_ELT(diag, 0)) == 'N'; \
1188 char cl_[] = "...Matrix"; \
1192 if (cl[1] != 'g' && !(mi || mj) && ni == nj) { \
1193 if (cl[1] == 't') { \
1194 keep = keep_tr(pi, pj, ni, upper, nonunit, _DENSE_); \
1200 keep = keep_sy(pi, pj, ni, upper, 0); \
1201 if ((_DENSE_) ? keep != 0 : keep < -1 || keep > 1) { \
1207 SEXP res = PROTECT(newObject(cl_)); \
1209 PROTECT(dim = GET_SLOT(res, Matrix_DimSym)); \
1210 pdim = INTEGER(dim); \
1215 if ((cl[1] != 's') ? keep < 0 : keep < -1) { \
1216 PROTECT(uplo = GET_SLOT(res, Matrix_uploSym)); \
1217 SEXP uplo_ = PROTECT(mkChar("L")); \
1218 SET_STRING_ELT(uplo, 0, uplo_); \
1221 if (cl[1] == 't' && (keep < -1 || keep > 1)) { \
1222 PROTECT(diag = GET_SLOT(res, Matrix_diagSym)); \
1223 SEXP diag_ = PROTECT(mkChar("U")); \
1224 SET_STRING_ELT(diag, 0, diag_); \
1230 double ninj = (double) ni * nj;
1231 if (ninj > R_XLEN_T_MAX)
1232 error(
_(
"attempt to allocate vector of length exceeding %s"),
1236 x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) ninj));
1241#define SUB2_CASES(_SUB2_) \
1246 _SUB2_(int, LOGICAL, NA_LOGICAL, 0, 1); \
1249 _SUB2_(int, INTEGER, NA_INTEGER, 0, 1); \
1252 _SUB2_(double, REAL, NA_REAL, 0.0, 1.0); \
1255 _SUB2_(Rcomplex, COMPLEX, \
1256 Matrix_zna, Matrix_zzero, Matrix_zone); \
1263#define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \
1265 _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \
1266 if (cl_[1] == 'g') { \
1268 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1269 XIJ_GE, , , _NA_, _ZERO_, _ONE_); \
1270 else if (cl[1] == 't') { \
1273 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1274 XIJ_TR_U_N, , , _NA_, _ZERO_, _ONE_); \
1276 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1277 XIJ_TR_U_U, , , _NA_, _ZERO_, _ONE_); \
1280 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1281 XIJ_TR_L_N, , , _NA_, _ZERO_, _ONE_); \
1283 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1284 XIJ_TR_L_U, , , _NA_, _ZERO_, _ONE_); \
1288 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1289 XIJ_SY_U, , , _NA_, _ZERO_, _ONE_); \
1291 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1292 XIJ_SY_L, , , _NA_, _ZERO_, _ONE_); \
1294 } else if (cl_[1] == 't') { \
1295 Matrix_memset(px1, 0, XLENGTH(x1), sizeof(_CTYPE_)); \
1299 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1300 XIJ_TR_U_N, , px1 += ni - kj - 1, \
1301 _NA_, _ZERO_, _ONE_); \
1303 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1304 XIJ_TR_U_N, px1 += kj, , \
1305 _NA_, _ZERO_, _ONE_); \
1308 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1309 XIJ_TR_U_U, , px1 += ni - kj - 1, \
1310 _NA_, _ZERO_, _ONE_); \
1312 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1313 XIJ_TR_U_U, px1 += kj, , \
1314 _NA_, _ZERO_, _ONE_); \
1319 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1320 XIJ_TR_L_N, , px1 += ni - kj - 1, \
1321 _NA_, _ZERO_, _ONE_); \
1323 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1324 XIJ_TR_L_N, px1 += kj, , \
1325 _NA_, _ZERO_, _ONE_); \
1328 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1329 XIJ_TR_L_U, , px1 += ni - kj - 1, \
1330 _NA_, _ZERO_, _ONE_); \
1332 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1333 XIJ_TR_L_U, px1 += kj, , \
1334 _NA_, _ZERO_, _ONE_); \
1338 Matrix_memset(px1, 0, XLENGTH(x1), sizeof(_CTYPE_)); \
1341 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1342 XIJ_SY_U, , px1 += ni - kj - 1, \
1343 _NA_, _ZERO_, _ONE_); \
1345 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1346 XIJ_SY_U, px1 += kj, , \
1347 _NA_, _ZERO_, _ONE_); \
1350 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1351 XIJ_SY_L, , px1 += ni - kj - 1, \
1352 _NA_, _ZERO_, _ONE_); \
1354 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1355 XIJ_SY_L, px1 += kj, , \
1356 _NA_, _ZERO_, _ONE_); \
1361#define SUB2_LOOP(_FOR_, _XIJ_, _JUMP1_, _JUMP2_, \
1362 _NA_, _ZERO_, _ONE_) \
1364 for (kj = 0; kj < nj; ++kj) { \
1369 if (j_ != NA_INTEGER) \
1386 if (i_ != NA_INTEGER) \
1393 *(px1++) = _XIJ_(px0, i_, j_, m_, _ZERO_, _ONE_); \
1414 double ninj = (double) ni * nj,
1415 ninj_ = (keep) ? 0.5 * (ninj + ni) : ninj;
1416 if (ninj_ > R_XLEN_T_MAX)
1417 error(
_(
"attempt to allocate vector of length exceeding %s"),
1421 x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) ninj_));
1426#define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \
1428 _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \
1429 if (cl_[1] == 'g') { \
1430 if (cl[1] == 't') { \
1433 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1434 XIJ_TP_U_N, , , _NA_, _ZERO_, _ONE_); \
1436 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1437 XIJ_TP_U_U, , , _NA_, _ZERO_, _ONE_); \
1440 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1441 XIJ_TP_L_N, , , _NA_, _ZERO_, _ONE_); \
1443 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1444 XIJ_TP_L_U, , , _NA_, _ZERO_, _ONE_); \
1448 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1449 XIJ_SP_U, , , _NA_, _ZERO_, _ONE_); \
1451 SUB2_LOOP(for (ki = 0; ki < ni; ++ki), \
1452 XIJ_SP_L, , , _NA_, _ZERO_, _ONE_); \
1454 } else if (cl_[1] == 't') { \
1458 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1459 XIJ_TP_U_N, , , _NA_, _ZERO_, _ONE_); \
1461 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1462 XIJ_TP_U_N, , , _NA_, _ZERO_, _ONE_); \
1465 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1466 XIJ_TP_U_U, , , _NA_, _ZERO_, _ONE_); \
1468 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1469 XIJ_TP_U_U, , , _NA_, _ZERO_, _ONE_); \
1474 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1475 XIJ_TP_L_N, , , _NA_, _ZERO_, _ONE_); \
1477 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1478 XIJ_TP_L_N, , , _NA_, _ZERO_, _ONE_); \
1481 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1482 XIJ_TP_L_U, , , _NA_, _ZERO_, _ONE_); \
1484 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1485 XIJ_TP_L_U, , , _NA_, _ZERO_, _ONE_); \
1491 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1492 XIJ_SP_U, , , _NA_, _ZERO_, _ONE_); \
1494 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1495 XIJ_SP_U, , , _NA_, _ZERO_, _ONE_); \
1498 SUB2_LOOP(for (ki = 0; ki <= kj; ++ki), \
1499 XIJ_SP_L, , , _NA_, _ZERO_, _ONE_); \
1501 SUB2_LOOP(for (ki = kj; ki < ni; ++ki), \
1502 XIJ_SP_L, , , _NA_, _ZERO_, _ONE_); \
1523 if (
cl[1] !=
'g' && cl_[1] ==
'g') {
1532 p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) nj + 1)),
1534 int *pp0 = INTEGER(p0), *pi0 = INTEGER(i0),
1535 *pp1 = INTEGER(p1), *pi1 = NULL,
1536 d, k, kend, doSort = 0;
1540#define SUB2_FINISH \
1541 if (nnz > INT_MAX) \
1542 error(_("%s too dense for %s; would have more than %s nonzero entries"), \
1543 "x[i,j]", "[CR]sparseMatrix", "2^31-1"); \
1545 PROTECT(i1 = allocVector(INTSXP, (R_xlen_t) nnz)); \
1546 pi1 = INTEGER(i1); \
1551 SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)), \
1552 x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) nnz)); \
1554 SET_SLOT(res, Matrix_xSym, x1); \
1558#define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \
1560 _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \
1566 for (kj = 0; kj < nj; ++kj) {
1567 nnz += pp0[pj[kj]] - pp0[pj[kj] - 1];
1568 pp1[kj] = (int) nnz;
1571#define SUB2_LOOP(_MASK_) \
1573 for (kj = 0; kj < nj; ++kj) { \
1574 k = pp0[pj[kj] - 1]; \
1575 kend = pp0[pj[kj]]; \
1578 Matrix_memcpy(pi1, pi0 + k, d, sizeof(int)); \
1580 _MASK_(Matrix_memcpy(px1, px0 + k, d, sizeof(*px1))); \
1592 int *workA, *workB, *workC;
1593 size_t lwork = (size_t) m + m + ni;
1603 int i_, j_, i_prev = m;
1605 for (ki = ni - 1; ki >= 0; --ki) {
1608 workC[ki] = workB[i_];
1615 for (kj = 0; kj < nj; ++kj) {
1616 j_ = (mj) ? kj : pj[kj] - 1;
1620 nnz += workA[pi0[k]];
1623 pp1[kj] = (int) nnz;
1626#define SUB2_LOOP(_MASK_) \
1628 for (kj = 0; kj < nj; ++kj) { \
1629 j_ = (mj) ? kj : pj[kj] - 1; \
1631 kend = pp0[j_ + 1]; \
1632 while (k < kend) { \
1638 _MASK_(*(px1++) = px0[k]); \
1662 if (
cl[1] ==
's' && (keep == -1 || keep == 1)) {
1676 if (
cl[1] !=
'g' && cl_[1] ==
'g') {
1685 p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) ni + 1)),
1687 int *pp0 = INTEGER(p0), *pj0 = INTEGER(j0),
1688 *pp1 = INTEGER(p1), *pj1 = NULL,
1689 d, k, kend, doSort = 0;
1693#define SUB2_FINISH \
1694 if (nnz > INT_MAX) \
1695 error(_("%s too dense for %s; would have more than %s nonzero entries"), \
1696 "x[i,j]", "[CR]sparseMatrix", "2^31-1"); \
1698 PROTECT(j1 = allocVector(INTSXP, (R_xlen_t) nnz)); \
1699 pj1 = INTEGER(j1); \
1704 SEXP x0 = PROTECT(GET_SLOT(x, Matrix_xSym)), \
1705 x1 = PROTECT(allocVector(TYPEOF(x0), (R_xlen_t) nnz)); \
1707 SET_SLOT(res, Matrix_xSym, x1); \
1713 for (ki = 0; ki < ni; ++ki) {
1714 nnz += pp0[pi[ki]] - pp0[pi[ki] - 1];
1715 pp1[ki] = (int) nnz;
1718#define SUB2_LOOP(_MASK_) \
1720 for (ki = 0; ki < ni; ++ki) { \
1721 k = pp0[pi[ki] - 1]; \
1722 kend = pp0[pi[ki]]; \
1725 Matrix_memcpy(pj1, pj0 + k, d, sizeof(int)); \
1727 _MASK_(Matrix_memcpy(px1, px0 + k, d, sizeof(*px1))); \
1739 int *workA, *workB, *workC;
1740 size_t lwork = (size_t) n + n + nj;
1750 int i_, j_, j_prev = n;
1752 for (kj = nj - 1; kj >= 0; --kj) {
1755 workC[kj] = workB[j_];
1762 for (ki = 0; ki < ni; ++ki) {
1763 i_ = (mi) ? ki : pi[ki] - 1;
1767 nnz += workA[pj0[k]];
1770 pp1[ki] = (int) nnz;
1773#define SUB2_LOOP(_MASK_) \
1775 for (ki = 0; ki < ni; ++ki) { \
1776 i_ = (mi) ? ki : pi[ki] - 1; \
1778 kend = pp0[i_ + 1]; \
1779 while (k < kend) { \
1785 _MASK_(*(px1++) = px0[k]); \
1810 if (
cl[1] ==
's' && (keep == -1 || keep == 1)) {
1824 int nonunit = 1, keep = 0;
1826 nonunit = *CHAR(STRING_ELT(diag, 0)) ==
'N';
1829 char cl_[] =
".gCMatrix";
1831 if (!(mi || mj) && ni == nj) {
1832 keep =
keep_di(pi, pj, ni, nonunit, 0, m);
1842 pdim = INTEGER(dim);
1850 SEXP diag_ = PROTECT(mkChar(
"U"));
1851 SET_STRING_ELT(diag, 0, diag_);
1854 }
else if (keep > 0) {
1857 x1 = PROTECT(allocVector(TYPEOF(x0), ni));
1860#define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \
1862 _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \
1865 (*(pi++) != (j_ = *(pj++))) \
1867 : ((nonunit) ? px0[j_ - 1] : _ONE_); \
1887#define SUB2_WORK(_CTYPE_, _PTR_, _ISNZ_) \
1889 _CTYPE_ *px0 = _PTR_(x0); \
1890 for (j_ = 0; j_ < n; ++j_) \
1891 work[j_] = _ISNZ_(px0[j_]); \
1918 SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) nj + 1));
1919 int *pp1 = INTEGER(p1);
1922 for (kj = 0; kj < nj; ++kj) {
1924 j_ = (mj) ? kj : pj[kj] - 1;
1925 if (!nonunit || work[j_]) {
1927 for (ki = 0; ki < ni; ++ki)
1931 for (ki = 0; ki < ni; ++ki)
1932 if (pi[ki] - 1 == j_)
1935 if (pp1[kj] > INT_MAX - pp1[kj - 1]) {
1938 error(
_(
"%s too dense for %s; would have more than %s nonzero entries"),
1939 "x[i,j]",
"[CR]sparseMatrix",
"2^31-1");
1942 pp1[kj] += pp1[kj-1];
1945 SEXP i1 = PROTECT(allocVector(INTSXP, pp1[nj - 1])),
1946 x1 = PROTECT(allocVector(TYPEOF(x0), pp1[nj - 1]));
1947 int *pi1 = INTEGER(i1);
1949#define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_) \
1951 _CTYPE_ *px0 = _PTR_(x0), *px1 = _PTR_(x1); \
1952 for (kj = 0; kj < nj; ++kj) { \
1953 j_ = (mj) ? kj : pj[kj] - 1; \
1954 if (!nonunit || work[j_]) { \
1955 for (ki = 0; ki < ni; ++ki) { \
1956 if (((mi) ? ki : pi[ki] - 1) == j_) { \
1958 *(px1++) = (nonunit) ? px0[j_] : _ONE_; \
1987 PROTECT_WITH_INDEX(x, &pidA);
1991 int *pperm0 = INTEGER(perm0);
1992 PROTECT_WITH_INDEX(perm0, &pidB);
1995 int mg = INTEGER(margin)[0] - 1;
1998 int *pdim = INTEGER(dim), m = pdim[mg], n = pdim[!mg];
2008 mi = i == R_NilValue,
2009 mj = j == R_NilValue,
2010 ni = (mi) ? m : LENGTH(i),
2011 nj = (mj) ? n : LENGTH(j),
2012 *pi = (mi) ? NULL : INTEGER(i),
2013 *pj = (mj) ? NULL : INTEGER(j),
2017 isP = isP && ni == m;
2022 for (ki = 0; ki < ni; ++ki) {
2033 x =
newObject((isP) ?
"pMatrix" :
"indMatrix");
2037 pdim = INTEGER(dim);
2045 SEXP perm1 = PROTECT(allocVector(INTSXP, ni));
2046 int *pperm1 = INTEGER(perm1);
2048 for (ki = 0; ki < ni; ++ki)
2049 pperm1[ki] = pperm0[pi[ki]];
2055 REPROTECT(perm0, pidB);
2061 isP = isP && nj == n;
2066 for (kj = 0; kj < nj; ++kj) {
2079 : ((!mg) ?
"ngCMatrix" :
"ngRMatrix"));
2083 pdim = INTEGER(dim);
2089 SEXP perm1 = PROTECT(allocVector(INTSXP, nj));
2090 int *pperm1 = INTEGER(perm1), *work;
2093 for (kj = 0; kj < nj; ++kj)
2094 work[pj[kj]] = kj + 1;
2095 for (kj = 0; kj < nj; ++kj)
2096 pperm1[kj] = work[pperm0[kj]];
2102 int *workA, *workB, *workC;
2103 size_t lwork = (size_t) n + n + m;
2110 SEXP p1 = PROTECT(allocVector(INTSXP, (R_xlen_t) nj + 1));
2111 int *pp1 = INTEGER(p1), k, kend;
2114 for (k = 0; k < m; ++k)
2119 for (kj = 0; kj < nj; ++kj) {
2120 pp1[kj] = workA[pj[kj]];
2121 if (pp1[kj] > INT_MAX - pp1[kj - 1])
2122 error(
_(
"%s too dense for %s; would have more than %s nonzero entries"), \
2123 "x[i,j]",
"[CR]sparseMatrix",
"2^31-1"); \
2125 pp1[kj] += pp1[kj - 1];
2130 for (k = 1; k < n; ++k) {
2131 workB[k + 1] = workB[k] + workA[k];
2132 workA[k] = workB[k];
2134 workA[n] = workB[n];
2137 for (k = 0; k < m; ++k)
2138 workC[workA[pperm0[k]]++] = k;
2140 SEXP i1 = PROTECT(allocVector(INTSXP, pp1[nj - 1]));
2141 int *pi1 = INTEGER(i1), pos;
2145 for (kj = 0; kj < nj; ++kj) {
2147 pos = workB[pj[kj]];
2149 pi1[k++] = workC[pos++];
2164#undef SUB2_START_EXTRA
2176 if (i == R_NilValue && j == R_NilValue)
2180 int ivalid = R_check_class_etc(x,
valid);
2184 const char *
cl =
valid[ivalid];
2198 static SEXP anyNA = NULL;
2200 anyNA = install(
"anyNA");
2201 SEXP call = PROTECT(lang2(anyNA, R_NilValue)), value;
2203#define ERROR_IF_ANYNA(_I_) \
2205 if ((_I_) != R_NilValue) { \
2206 SETCADR(call, _I_); \
2207 PROTECT(value = eval(call, R_BaseEnv)); \
2208 if (asLogical(value)) \
2209 error(_("NA subscripts in %s not supported for '%s' inheriting from %s"), \
2210 "x[i,j]", "x", "sparseMatrix"); \
2218#undef ERROR_IF_ANYNA
2229 char cl_[] =
"..CMatrix";
long long Matrix_int_fast64_t
#define ERROR_INVALID_CLASS(_X_, _FUNC_)
#define ISNZ_PATTERN(_X_)
#define VALID_NONVIRTUAL_MATRIX
SEXPTYPE kindToType(char)
#define ISNZ_LOGICAL(_X_)
#define Matrix_Free(_VAR_, _N_)
#define ISNZ_INTEGER(_X_)
#define SET_SLOT(x, what, value)
#define GET_SLOT(x, what)
#define Matrix_Calloc(_VAR_, _N_, _CTYPE_)
#define ISNZ_COMPLEX(_X_)
void validObject(SEXP, const char *)
SEXP newObject(const char *)
#define VALID_NONVIRTUAL_SHIFT(i, pToInd)
static const char * valid[]
SEXP sparse_as_Csparse(SEXP from, const char *class)
SEXP sparse_as_Tsparse(SEXP from, const char *class)
SEXP sparse_as_general(SEXP from, const char *class)
SEXP sparse_force_symmetric(SEXP from, const char *class, char ul)
static SEXP indMatrix_subscript_1ary_mat(SEXP x, SEXP w)
#define SORT(_CTYPE_, _PTR_)
static int keep_di(int *pi, int *pj, int n, int nonunit, int checkNA, int lwork)
static SEXP indMatrix_subscript_1ary(SEXP x, SEXP w)
#define SUB2(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_)
static SEXP unpackedMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl)
static SEXP CsparseMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl)
SEXP R_subscript_2ary(SEXP x, SEXP i, SEXP j)
static SEXP unpackedMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl)
static SEXP packedMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl)
static SEXP diagonalMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl)
static SEXP packedMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl)
#define SUB1_START(_SEXPTYPE_)
#define SUB1_N(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_)
#define SUB2_WORK(_CTYPE_, _PTR_, _ISNZ_)
static SEXP CsparseMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl)
#define SUB2_CASES(_SUB2_)
#define SUB1_CASES(_SUB1_N_, _SUB1_X_, _F_N_, _F_X_)
static SEXP indMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl)
static SEXP diagonalMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl)
#define SORT_LOOP(_MASK_)
#define SUB2_START_EXTRA(_E_, _R_, _Y_, _DENSE_)
static int keep_sy(int *pi, int *pj, int n, int upper, int checkNA)
#define ERROR_IF_ANYNA(_I_)
#define SUB1_START_EXTRA(_SEXPTYPE_)
SEXP R_subscript_1ary(SEXP x, SEXP i)
static SEXP RsparseMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl)
SEXP R_subscript_1ary_mat(SEXP x, SEXP i)
static int keep_tr(int *pi, int *pj, int n, int upper, int nonunit, int checkNA)
static void sort_cr(SEXP obj, const char *cl)
static SEXP RsparseMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl)
static SEXP packedMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl)
#define SUB1_X(_CTYPE_, _PTR_, _NA_, _ZERO_, _ONE_, _F_)
static SEXP RsparseMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl)
static SEXP CsparseMatrix_subscript_1ary(SEXP x, SEXP w, const char *cl)
static SEXP unpackedMatrix_subscript_2ary(SEXP x, SEXP i, SEXP j, const char *cl)
static SEXP diagonalMatrix_subscript_1ary_mat(SEXP x, SEXP w, const char *cl)