206 char op_ul,
char op_ct)
216 if (
class[1] ==
's' &&
class[0] ==
'z')
219 if (
class[1] ==
's' && op_ct == ct) {
224 char cl[] =
".s.Matrix";
225 cl[0] = (
class[0] ==
'z') ?
'z' :
'd';
229 int *pdim =
DIM(from), n = pdim[1];
231 Rf_error((op_ct ==
'C')
232 ?
_(
"attempt to get Hermitian part of non-square matrix")
233 :
_(
"attempt to get symmetric part of non-square matrix"));
237 char ul =
'\0', nu =
'\0';
238 if (
class[1] !=
'g' && (ul =
UPLO(from)) !=
'U')
240 if (
class[1] ==
't' && (nu =
DIAG(from)) !=
'N')
243 if (op_ul !=
'\0' && op_ul !=
'U')
245 if (op_ct !=
'\0' && op_ct !=
'C')
248 int up = (
class[0] !=
'R') == (op_ul ==
'U' || ul ==
'U');
250 if (
class[2] !=
'T') {
256 int *pp0 = INTEGER(p0), *pi0 = INTEGER(i0),
257 j, k, kend, nnz0 = pp0[n], nnz1;
260 if (
class[1] ==
'g') {
263 size_t liwork = (size_t) ((int_fast64_t) n + n + 1 + nnz0);
266 int *pp0_ = iwork + n + 1, *pi0_ = iwork + n + n + 1;
267 ncsptrans(pp0_ - 1, pi0_, NULL, pp0 - 1, pi0, NULL, n, n,
'T', iwork);
268 memcpy(iwork, pp0 - 1,
sizeof(
int) * (
size_t) n);
270 SEXP p1 = PROTECT(Rf_allocVector(INTSXP, XLENGTH(p0)));
271 int *pp1 = INTEGER(p1), k_, kend_;
275 for (j = 0, k = 0, k_ = 0; j < n; ++j) {
283 while (k_ < kend_ && pi0_[k_] < pi0[k]) {
288 if (k_ < kend_ && pi0_[k_] == pi0[k])
304 SEXP i1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
305 x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz1));
306 int *pi1 = INTEGER(i1), l;
312 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
314 for (j = 0, k = 0, k_ = 0; j < n; ++j) { \
318 if (up && pi0[k] > j) \
320 else if (!up && pi0[k] < j) \
323 while (k_ < kend_ && pi0_[k_] < pi0[k]) { \
324 l = iwork[pi0_[k_]]++; \
326 c##ASSIGN_CONJ(*px1, px0[l]); \
327 c##MULTIPLY(*px1, 0.5); \
328 ++k_; ++pi1; ++px1; \
333 c##ASSIGN_PROJ_REAL(*px1, px0[k]); \
336 c##ASSIGN_IDEN(*px1, px0[k]); \
337 if (k_ < kend_ && pi0_[k_] == pi0[k]) { \
338 l = iwork[pi0[k]]++; \
339 c##INCREMENT_CONJ(*px1, px0[l]); \
342 c##MULTIPLY(*px1, 0.5); \
347 while (k_ < kend_) { \
348 if (up && pi0_[k_] > j) \
350 else if (!up && pi0_[k_] < j) \
353 l = iwork[pi0_[k_]]++; \
355 c##ASSIGN_CONJ(*px1, px0[l]); \
356 c##MULTIPLY(*px1, 0.5); \
357 ++k_; ++pi1; ++px1; \
362 for (j = 0, k = 0, k_ = 0; j < n; ++j) { \
366 if (up && pi0[k] > j) \
368 else if (!up && pi0[k] < j) \
371 while (k_ < kend_ && pi0_[k_] < pi0[k]) { \
372 l = iwork[pi0_[k_]]++; \
374 c##ASSIGN_IDEN(*px1, px0[l]); \
375 c##MULTIPLY(*px1, 0.5); \
376 ++k_; ++pi1; ++px1; \
381 c##ASSIGN_IDEN(*px1, px0[k]); \
384 c##ASSIGN_IDEN(*px1, px0[k]); \
385 if (k_ < kend_ && pi0_[k_] == pi0[k]) { \
386 l = iwork[pi0[k]]++; \
387 c##INCREMENT_IDEN(*px1, px0[l]); \
390 c##MULTIPLY(*px1, 0.5); \
395 while (k_ < kend_) { \
396 if (up && pi0_[k_] > j) \
398 else if (!up && pi0_[k_] < j) \
401 l = iwork[pi0_[k_]]++; \
403 c##ASSIGN_IDEN(*px1, px0[l]); \
404 c##MULTIPLY(*px1, 0.5); \
405 ++k_; ++pi1; ++px1; \
418 }
else if (
class[1] ==
's') {
425 SEXP x1 = PROTECT(Rf_allocVector(CPLXSXP, nnz0));
426 zvreal(COMPLEX(x1), COMPLEX(x0), (
size_t) nnz0);
430 }
else if (nu ==
'N') {
435 SEXP x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz0));
440 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
441 for (j = 0, k = 0; j < n; ++j) { \
445 c##ASSIGN_IDEN(*px1, px0[k]); \
446 c##MULTIPLY(*px1, 0.5); \
448 else if (op_ct == 'C') \
449 c##ASSIGN_PROJ_REAL(*px1, px0[k]); \
451 c##ASSIGN_IDEN(*px1, px0[k]); \
467 SEXP p1 = PROTECT(Rf_allocVector(INTSXP, XLENGTH(p0))),
468 i1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
469 x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz1));
470 int *pp1 = INTEGER(p1), *pi1 = INTEGER(i1);
478 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
479 for (j = 0, k = 0; j < n; ++j) { \
488 c##ASSIGN_IDEN(*px1, px0[k]); \
489 c##MULTIPLY(*px1, 0.5); \
497 pp1[j] = kend + j + 1; \
516 int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0);
517 R_xlen_t k, nnz0 = XLENGTH(i0), nnz1;
519 if (
class[1] ==
'g') {
521 SEXP i1 = PROTECT(Rf_allocVector(INTSXP, nnz0)),
522 j1 = PROTECT(Rf_allocVector(INTSXP, nnz0)),
523 x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz0));
524 int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1);
531 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
533 for (k = 0; k < nnz0; ++k) { \
534 if (*pi0 != *pj0) { \
535 if ((up) ? *pi0 < *pj0 : *pi0 > *pj0) { \
538 c##ASSIGN_IDEN(*px1, *px0); \
542 c##ASSIGN_CONJ(*px1, *px0); \
544 c##MULTIPLY(*px1, 0.5); \
548 c##ASSIGN_PROJ_REAL(*px1, *px0); \
550 ++pi0; ++pi1; ++pj0; ++pj1; ++px0; ++px1; \
553 for (k = 0; k < nnz0; ++k) { \
554 if ((up) ? *pi0 <= *pj0 : *pi0 >= *pj0) { \
561 c##ASSIGN_IDEN(*px1, *px0); \
563 c##MULTIPLY(*px1, 0.5); \
564 ++pi0; ++pi1; ++pj0; ++pj1; ++px0; ++px1; \
574 }
else if (
class[1] ==
's') {
581 SEXP x1 = PROTECT(Rf_allocVector(CPLXSXP, nnz0));
582 zvreal(COMPLEX(x1), COMPLEX(x0), (
size_t) nnz0);
586 }
else if (nu ==
'N') {
591 SEXP x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz0));
596 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
597 for (k = 0; k < nnz0; ++k) { \
598 if (*pi0 != *pj0) { \
599 c##ASSIGN_IDEN(*px1, *px0); \
600 c##MULTIPLY(*px1, 0.5); \
602 else if (op_ct == 'C') \
603 c##ASSIGN_PROJ_REAL(*px1, *px0); \
605 c##ASSIGN_IDEN(*px1, *px0); \
606 ++pi0; ++pj0; ++px0; ++px1; \
620 SEXP i1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
621 j1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
622 x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz1));
623 int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1), j;
630 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
631 for (k = 0; k < nnz0; ++k) { \
634 c##ASSIGN_IDEN(*px1, *px0); \
635 c##MULTIPLY(*px1, 0.5); \
636 ++pi0; ++pi1; ++pj0; ++pj1; ++px0; ++px1; \
638 for (j = 0; j < n; ++j) { \
641 ++pi1; ++pj1; ++px1; \
void ncsptrans(int *, int *, int *, const int *, const int *, const int *, int, int, char, int *)