18 int packed =
class[2] ==
'p';
20 char cl[] =
"...Matrix";
21 cl[0] = (
class[0] ==
'z') ?
'z' :
'd';
22 cl[1] = (
class[1] ==
's') ?
's' :
'g';
23 cl[2] = (
class[1] ==
's') ?
class[2] :
'e';
26 int *pdim =
DIM(from), n = pdim[1];
28 Rf_error((op_ct ==
'C')
29 ?
_(
"attempt to get skew-Hermitian part of non-square matrix")
30 :
_(
"attempt to get skew-symmetric part of non-square matrix"));
34 char ul =
'\0', ct =
'\0', nu =
'\0';
35 if (
class[1] !=
'g' && (ul =
UPLO(from)) !=
'U' &&
class[1] ==
's')
37 if (
class[1] ==
's' &&
class[0] ==
'z' && (ct =
TRANS(from)) !=
'C')
39 if (
class[1] ==
't' && (nu =
DIAG(from)) !=
'N')
44 if (
class[1] ==
's') {
51 PROTECT(x1 = Rf_allocVector(CPLXSXP, XLENGTH(x0)));
52 zvimag(COMPLEX(x1), COMPLEX(x0), (
size_t) XLENGTH(x0));
57 if ((int_fast64_t) n * n > R_XLEN_T_MAX)
58 Rf_error(
_(
"attempt to allocate vector of length exceeding %s"),
60 PROTECT(x1 = Rf_allocVector(
TYPEOF(x0), (R_xlen_t) n * n));
66 c##TYPE *px0 = c##PTR(x0), *pu0 = px0, *pl0 = px0; \
67 c##TYPE *px1 = c##PTR(x1), *pu1 = px1, *pl1 = px1; \
68 if (class[1] == 'g') { \
70 for (j = 0; j < n; ++j) { \
71 for (i = 0; i < j; ++i) { \
72 c##ASSIGN_IDEN(*pu1, *pu0); \
73 c##DECREMENT_CONJ(*pu1, *pl0); \
74 c##ASSIGN_CONJ(*pl1, *pu1); \
75 c##MULTIPLY(*pu1, 0.5); \
76 c##MULTIPLY(*pl1, -0.5); \
82 c##ASSIGN_PROJ_IMAG(*pu1, *pu0); \
89 for (j = 0; j < n; ++j) { \
90 for (i = 0; i < j; ++i) { \
91 c##ASSIGN_IDEN(*pu1, *pu0); \
92 c##DECREMENT_IDEN(*pu1, *pl0); \
93 c##ASSIGN_IDEN(*pl1, *pu1); \
94 c##MULTIPLY(*pu1, 0.5); \
95 c##MULTIPLY(*pl1, -0.5); \
109 for (j = 0; j < n; ++j) { \
110 for (i = 0; i < j; ++i) { \
111 c##ASSIGN_IDEN(*pu1, *pu0); \
112 c##ASSIGN_IDEN(*pl1, *pu0); \
113 c##MULTIPLY(*pu1, 0.5); \
114 c##MULTIPLY(*pl1, -0.5); \
119 if (nu != 'N' || op_ct != 'C') \
122 c##ASSIGN_PROJ_IMAG(*pu1, *pu0); \
132 for (j = 0; j < n; ++j) { \
137 if (nu != 'N' || op_ct != 'C') \
140 c##ASSIGN_PROJ_IMAG(*pl1, *pl0); \
144 for (i = j + 1; i < n; ++i) { \
145 c##ASSIGN_IDEN(*pl1, *pl0); \
146 c##ASSIGN_IDEN(*pu1, *pl0); \
147 c##MULTIPLY(*pl1, 0.5); \
148 c##MULTIPLY(*pu1, -0.5); \
176 char cl[] =
"...Matrix";
177 cl[0] = (
class[0] ==
'z') ?
'z' :
'd';
178 cl[1] = (
class[1] ==
's') ?
's' :
'g';
182 int *pdim =
DIM(from), n = pdim[1];
184 Rf_error((op_ct ==
'C')
185 ?
_(
"attempt to get skew-Hermitian part of non-square matrix")
186 :
_(
"attempt to get skew-symmetric part of non-square matrix"));
190 char ul =
'\0', ct =
'\0';
191 if (
class[1] !=
'g' && (ul =
UPLO(from)) !=
'U' &&
class[1] ==
's')
193 if (
class[1] ==
's' &&
class[0] ==
'z' && (ct =
TRANS(from)) !=
'C')
196 if (
class[1] ==
's' && op_ct == ct) {
197 if (
class[2] !=
'T') {
198 SEXP p1 = PROTECT(
allocZero(INTSXP, (R_xlen_t) n + 1));
206 if (
class[2] !=
'T') {
212 int *pp0 = INTEGER(p0), *pi0 = INTEGER(i0),
213 j, k, kend, nnz0 = pp0[n], nnz1;
216 if (
class[1] ==
's') {
223 SEXP x1 = PROTECT(Rf_allocVector(CPLXSXP, nnz0));
224 zvimag(COMPLEX(x1), COMPLEX(x0), (
size_t) nnz0);
231 size_t liwork = (size_t) ((int_fast64_t) n + n + 1 + nnz0);
234 int *pp0_ = iwork + n + 1, *pi0_ = iwork + n + n + 1;
235 ncsptrans(pp0_ - 1, pi0_, NULL, pp0 - 1, pi0, NULL, n, n,
'T', iwork);
236 memcpy(iwork, pp0 - 1,
sizeof(
int) * (
size_t) n);
238 SEXP p1 = PROTECT(Rf_allocVector(INTSXP, XLENGTH(p0)));
239 int *pp1 = INTEGER(p1), k_, kend_;
243 for (j = 0, k = 0, k_ = 0; j < n; ++j) {
251 while (k_ < kend_ && pi0_[k_] < pi0[k]) {
258 if (k_ < kend_ && pi0_[k_] == pi0[k])
273 for (j = 0; j < n; ++j)
274 pp1[j] += pp1[j - 1];
276 for (j = n - 1; j >= 0; --j)
279 SEXP i1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
280 x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz1));
281 int *pi1 = INTEGER(i1), l;
287 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
289 for (j = 0, k = 0, k_ = 0; j < n; ++j) { \
296 while (k_ < kend_ && pi0_[k_] < pi0[k]) { \
297 l = iwork[pi0_[k_]]++; \
298 c##ASSIGN_CONJ(px1[pp1[ j]], px0[l]); \
299 c##ASSIGN_IDEN(px1[pp1[pi0_[k_]]], px0[l]); \
300 c##MULTIPLY (px1[pp1[ j]], -0.5); \
301 c##MULTIPLY (px1[pp1[pi0_[k_]]], 0.5); \
302 pi1[pp1[ j]++] = pi0_[k_]; \
303 pi1[pp1[pi0_[k_]]++] = j; \
310 c##ASSIGN_IDEN(px1[pp1[ j]], px0[k]); \
311 c##ASSIGN_CONJ(px1[pp1[pi0[k]]], px0[k]); \
312 if (k_ < kend_ && pi0_[k_] == pi0[k]) { \
313 l = iwork[pi0[k]]++; \
314 c##DECREMENT_CONJ(px1[pp1[ j]], px0[l]); \
315 c##DECREMENT_IDEN(px1[pp1[pi0[k]]], px0[l]); \
318 c##MULTIPLY (px1[pp1[ j]], 0.5); \
319 c##MULTIPLY (px1[pp1[pi0[k]]], -0.5); \
320 pi1[pp1[ j]++] = pi0[k]; \
321 pi1[pp1[pi0[k]]++] = j; \
326 while (k_ < kend_) { \
330 l = iwork[pi0_[k_]]++; \
331 c##ASSIGN_CONJ(px1[pp1[ j]], px0[l]); \
332 c##ASSIGN_IDEN(px1[pp1[pi0_[k_]]], px0[l]); \
333 c##MULTIPLY (px1[pp1[ j]], -0.5); \
334 c##MULTIPLY (px1[pp1[pi0_[k_]]], 0.5); \
335 pi1[pp1[ j]++] = pi0_[k_]; \
336 pi1[pp1[pi0_[k_]]++] = j; \
342 for (j = 0, k = 0, k_ = 0; j < n; ++j) { \
349 while (k_ < kend_ && pi0_[k_] < pi0[k]) { \
350 l = iwork[pi0_[k_]]++; \
351 c##ASSIGN_IDEN(px1[pp1[ j]], px0[l]); \
352 c##ASSIGN_IDEN(px1[pp1[pi0_[k_]]], px0[l]); \
353 c##MULTIPLY (px1[pp1[ j]], -0.5); \
354 c##MULTIPLY (px1[pp1[pi0_[k_]]], 0.5); \
355 pi1[pp1[ j]++] = pi0_[k_]; \
356 pi1[pp1[pi0_[k_]]++] = j; \
363 c##ASSIGN_IDEN(px1[pp1[ j]], px0[k]); \
364 c##ASSIGN_IDEN(px1[pp1[pi0[k]]], px0[k]); \
365 if (k_ < kend_ && pi0_[k_] == pi0[k]) { \
366 l = iwork[pi0[k]]++; \
367 c##DECREMENT_IDEN(px1[pp1[ j]], px0[l]); \
368 c##DECREMENT_IDEN(px1[pp1[pi0[k]]], px0[l]); \
371 c##MULTIPLY (px1[pp1[ j]], 0.5); \
372 c##MULTIPLY (px1[pp1[pi0[k]]], -0.5); \
373 pi1[pp1[ j]++] = pi0[k]; \
374 pi1[pp1[pi0[k]]++] = j; \
379 while (k_ < kend_) { \
383 l = iwork[pi0_[k_]]++; \
384 c##ASSIGN_IDEN(px1[pp1[ j]], px0[l]); \
385 c##ASSIGN_IDEN(px1[pp1[pi0_[k_]]], px0[l]); \
386 c##MULTIPLY (px1[pp1[ j]], -0.5); \
387 c##MULTIPLY (px1[pp1[pi0_[k_]]], 0.5); \
388 pi1[pp1[ j]++] = pi0_[k_]; \
389 pi1[pp1[pi0_[k_]]++] = j; \
412 int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0);
413 R_xlen_t k, nnz0 = XLENGTH(i0), nnz1;
415 if (
class[1] ==
's') {
422 SEXP x1 = PROTECT(Rf_allocVector(CPLXSXP, nnz0));
423 zvimag(COMPLEX(x1), COMPLEX(x0), (
size_t) nnz0);
430 for (k = 0; k < nnz0; ++k)
431 if (pi0[k] == pj0[k])
435 SEXP i1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
436 j1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
437 x1 = PROTECT(Rf_allocVector(
TYPEOF(x0), nnz1));
438 int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1);
445 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
446 for (k = 0; k < nnz0; ++k) { \
447 if (*pi0 != *pj0) { \
450 c##ASSIGN_IDEN(*px1, *px0); \
451 c##MULTIPLY(*px1, 0.5); \
452 ++pi1; ++pj1; ++px1; \
456 c##ASSIGN_CONJ(*px1, *px0); \
458 c##ASSIGN_IDEN(*px1, *px0); \
459 c##MULTIPLY(*px1, -0.5); \
460 ++pi1; ++pj1; ++px1; \
462 ++pi0; ++pj0; ++px0; \
void ncsptrans(int *, int *, int *, const int *, const int *, const int *, int, int, char, int *)