11void matmultDim(SEXP x, SEXP y,
int *xtrans,
int *ytrans,
int *ztrans,
12 int *m,
int *n,
int *v)
14 *xtrans = (*xtrans) ? 1 : 0;
15 *ytrans = (*ytrans) ? 1 : 0;
16 *ztrans = (*ztrans) ? 1 : 0;
17 if (y == R_NilValue) {
19 xdim = (TYPEOF(x) == S4SXP)
21 if (TYPEOF(xdim) == INTSXP && LENGTH(xdim) == 2) {
23 *m = *n = INTEGER(xdim)[(*xtrans) ? 1 : 0];
24 }
else if (XLENGTH(x) <= INT_MAX) {
26 *m = *n = (*xtrans) ? 1 : LENGTH(x);
28 error(
_(
"dimensions cannot exceed %s"),
"2^31-1");
29 *ytrans = (*xtrans) ? 0 : 1;
33 int tmp = !(*xtrans); *xtrans = !(*ytrans); *ytrans = tmp;
34 SEXP s = x; x = y; y = s;
37 xdim = (TYPEOF(x) == S4SXP)
39 ydim = (TYPEOF(y) == S4SXP)
41 int xm, xn, ym, yn, x2, y2;
42 xm = xn = ym = yn = -1;
43 x2 = TYPEOF(xdim) == INTSXP && LENGTH(xdim) == 2;
44 y2 = TYPEOF(ydim) == INTSXP && LENGTH(ydim) == 2;
46 int *pxdim = INTEGER(xdim);
49 }
else if (XLENGTH(x) > INT_MAX)
50 error(
_(
"dimensions cannot exceed %s"),
"2^31-1");
52 int *pydim = INTEGER(ydim);
55 }
else if (XLENGTH(y) > INT_MAX)
56 error(
_(
"dimensions cannot exceed %s"),
"2^31-1");
61 *v = (*ztrans) ? 2 : 1;
62 int k = (*ytrans) ? yn : ym, xl = LENGTH(x);
63 if (k == xl || (k == 1 && !(*xtrans))) {
66 *xtrans = (k == xl) ? 1 : 0;
69 *v = (*ztrans) ? 1 : 2;
70 int k = (*xtrans) ? xm : xn, yl = LENGTH(y);
72 if (xm == 1 || xn == 1) {
75 *ytrans = (((*xtrans) ? xn : xm) == 1) ? 0 : 1;
78 if (k == yl || k == 1) {
81 *ytrans = (k == yl) ? 0 : 1;
86 int xl = LENGTH(x), yl = LENGTH(y);
102 ym = (xl == 1) ? 1 : yl;
103 yn = (xl == 1) ? yl : 1;
106 if (((*xtrans) ? xm : xn) != ((*ytrans) ? yn : ym))
107 error(
_(
"non-conformable arguments"));
108 *m = (*xtrans) ? xn : xm;
109 *n = (*ytrans) ? ym : yn;
111 int tmp = !(*xtrans); *xtrans = !(*ytrans); *ytrans = tmp;
112 tmp = *m; *m = *n; *n = tmp;
119void matmultDN(SEXP dest, SEXP asrc,
int ai, SEXP bsrc,
int bi) {
121 if (!isNull(s = VECTOR_ELT(asrc, ai)))
122 SET_VECTOR_ELT(dest, 0, s);
123 if (!isNull(s = VECTOR_ELT(bsrc, bi)))
124 SET_VECTOR_ELT(dest, 1, s);
125 PROTECT(asrc = getAttrib(asrc, R_NamesSymbol));
126 PROTECT(bsrc = getAttrib(bsrc, R_NamesSymbol));
127 if (!isNull(asrc) || !isNull(bsrc)) {
128 SEXP destnms = PROTECT(allocVector(STRSXP, 2));
129 if (!isNull(asrc) && *CHAR(s = STRING_ELT(asrc, ai)) !=
'\0')
130 SET_STRING_ELT(destnms, 0, s);
131 if (!isNull(bsrc) && *CHAR(s = STRING_ELT(bsrc, bi)) !=
'\0')
132 SET_STRING_ELT(destnms, 1, s);
133 setAttrib(dest, R_NamesSymbol, destnms);
145 int *padim = INTEGER(adim), am = padim[0], an = padim[1],
146 rm = (atrans) ? an : am, rk = (atrans) ? am : an;
148 if (b == R_NilValue) {
151 error(
_(
"attempt to allocate vector of length exceeding %s"),
156 char rcl[] =
".poMatrix";
157 rcl[0] = (TYPEOF(ax) == CPLXSXP) ?
'z' :
'd';
161 int *prdim = INTEGER(rdim);
162 prdim[0] = prdim[1] = rm;
166 symDN(rdimnames, adimnames, (atrans) ? 1 : 0);
170 SEXP rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rm));
171#ifdef MATRIX_ENABLE_ZMATRIX
172 if (TYPEOF(ax) == CPLXSXP) {
173 Rcomplex *prx = COMPLEX(rx);
176 Rcomplex *pax = COMPLEX(ax),
179 "U", (atrans) ?
"T" :
"N", &rm, &rk,
184 double *prx = REAL(rx);
187 double *pax = REAL(ax),
188 zero = 0.0, one = 1.0;
190 "U", (atrans) ?
"T" :
"N", &rm, &rk,
193#ifdef MATRIX_ENABLE_ZMATRIX
206 int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1],
207 rn = (btrans) ? bm : bn;
209 if (rk != ((btrans) ? bn : bm))
210 error(
_(
"non-conformable arguments"));
212 error(
_(
"attempt to allocate vector of length exceeding %s"),
217 char rcl[] =
".geMatrix";
218 rcl[0] = (TYPEOF(ax) == CPLXSXP) ?
'z' :
'd';
222 int *prdim = INTEGER(rdim);
230 adimnames, (atrans) ? 1 : 0,
231 bdimnames, (btrans) ? 0 : 1);
234 if (rm > 0 && rn > 0) {
235 SEXP rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rn));
236#ifdef MATRIX_ENABLE_ZMATRIX
237 if (TYPEOF(ax) == CPLXSXP) {
238 Rcomplex *prx = COMPLEX(rx);
243 Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx),
246 (atrans) ?
"T" :
"N", (btrans) ?
"T" :
"N", &rm, &rn, &rk,
247 &one, pax, &am, pbx, &bm, &zero, prx, &rm
FCONE FCONE);
252 double *prx = REAL(rx);
257 double *pax = REAL(ax), *pbx = REAL(bx),
258 zero = 0.0, one = 1.0;
260 (atrans) ?
"T" :
"N", (btrans) ?
"T" :
"N", &rm, &rn, &rk,
261 &one, pax, &am, pbx, &bm, &zero, prx, &rm
FCONE FCONE);
264#ifdef MATRIX_ENABLE_ZMATRIX
282 int rk = INTEGER(adim)[0];
285 int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1],
286 rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn;
288 if (rk != ((aleft == btrans) ? bn : bm))
289 error(
_(
"non-conformable arguments"));
291 error(
_(
"attempt to allocate vector of length exceeding %s"),
296 char rcl[] =
".geMatrix";
297 rcl[0] = (TYPEOF(ax) == CPLXSXP) ?
'z' :
'd';
301 int *prdim = INTEGER(rdim);
309 matmultDN(rdimnames, adimnames, 0, bdimnames, !btrans);
311 matmultDN(rdimnames, bdimnames, btrans, adimnames, 1);
314 if (rm > 0 && rn > 0) {
317 rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rn));
318 char aul = *CHAR(STRING_ELT(auplo, 0));
319 int i, d = (aleft) ? rn : rm,
320 binc = (aleft) ? bm : 1, bincp = (aleft) ? 1 : bm,
321 rinc = (aleft) ? 1 : rm, rincp = (aleft) ? rm : 1;
322#ifdef MATRIX_ENABLE_ZMATRIX
323 if (TYPEOF(ax) == CPLXSXP) {
324 Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx),
328 (aleft) ?
"L" :
"R", &aul, &rm, &rn,
329 &one, pax, &rk, pbx, &bm, &zero, prx, &rm
FCONE FCONE);
331 for (i = 0; i < d; ++i) {
333 &aul, &rk, &one, pax, &rk, pbx, &binc, &zero, prx, &rinc
FCONE);
340 double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx),
341 zero = 0.0, one = 1.0;
344 (aleft) ?
"L" :
"R", &aul, &rm, &rn,
345 &one, pax, &rk, pbx, &bm, &zero, prx, &rm
FCONE FCONE);
347 for (i = 0; i < d; ++i) {
349 &aul, &rk, &one, pax, &rk, pbx, &binc, &zero, prx, &rinc
FCONE);
354#ifdef MATRIX_ENABLE_ZMATRIX
370 int rk = INTEGER(adim)[0];
373 int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1],
374 rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn;
376 if (rk != ((aleft == btrans) ? bn : bm))
377 error(
_(
"non-conformable arguments"));
379 error(
_(
"attempt to allocate vector of length exceeding %s"),
384 char rcl[] =
".geMatrix";
385 rcl[0] = (TYPEOF(ax) == CPLXSXP) ?
'z' :
'd';
389 int *prdim = INTEGER(rdim);
397 matmultDN(rdimnames, adimnames, 0, bdimnames, !btrans);
399 matmultDN(rdimnames, bdimnames, btrans, adimnames, 1);
402 if (rm > 0 && rn > 0) {
405 rx = PROTECT(allocVector(REALSXP, (R_xlen_t) rm * rn));
406 char aul = *CHAR(STRING_ELT(auplo, 0));
407 int i, d = (aleft) ? rn : rm,
408 binc = (aleft == btrans) ? bm : 1, bincp = (aleft == btrans) ? 1 : bm,
409 rinc = (aleft ) ? 1 : rm, rincp = (aleft ) ? rm : 1;
410#ifdef MATRIX_ENABLE_ZMATRIX
411 if (TYPEOF(ax) == CPLXSXP) {
412 Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx),
414 for (i = 0; i < d; ++i) {
416 &aul, &rk, &one, pax, pbx, &binc, &zero, prx, &rinc
FCONE);
422 double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx),
423 zero = 0.0, one = 1.0;
424 for (i = 0; i < d; ++i) {
426 &aul, &rk, &one, pax, pbx, &binc, &zero, prx, &rinc
FCONE);
430#ifdef MATRIX_ENABLE_ZMATRIX
447 int rk = INTEGER(adim)[0];
450 int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1],
451 rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn;
453 if (rk != ((aleft == btrans) ? bn : bm))
454 error(
_(
"non-conformable arguments"));
456 error(
_(
"attempt to allocate vector of length exceeding %s"),
461 char rcl[] =
"...Matrix";
462 rcl[0] = (TYPEOF(ax) == CPLXSXP) ?
'z' :
'd';
463 rcl[1] = (triangular > 0) ?
't' :
'g';
464 rcl[2] = (triangular > 0) ?
'r' :
'e';
468 int *prdim = INTEGER(rdim);
476 matmultDN(rdimnames, adimnames, atrans, bdimnames, !btrans);
478 matmultDN(rdimnames, bdimnames, btrans, adimnames, !atrans);
482 char aul = *CHAR(STRING_ELT(auplo, 0));
483 if (triangular > 0 && ((atrans) ? aul ==
'U' : aul !=
'U')) {
485 auplo = mkString(
"L");
492 char adi = *CHAR(STRING_ELT(adiag, 0));
493 if (triangular > 1 && adi !=
'N') {
499 if (rm > 0 && rn > 0) {
501 rx = PROTECT(allocVector(TYPEOF(ax), (R_xlen_t) rm * rn));
502#ifdef MATRIX_ENABLE_ZMATRIX
503 if (TYPEOF(ax) == CPLXSXP) {
504 Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx),
507 Matrix_memcpy(prx, pbx, (R_xlen_t) bm * bn,
sizeof(Rcomplex));
509 ztranspose2(prx, pbx, bm, bn);
511 (aleft) ?
"L" :
"R", &aul, (atrans) ?
"T" :
"N", &adi, &rm, &rn,
515 double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx),
520 dtranspose2(prx, pbx, bm, bn);
522 (aleft) ?
"L" :
"R", &aul, (atrans) ?
"T" :
"N", &adi, &rm, &rn,
524#ifdef MATRIX_ENABLE_ZMATRIX
541 int rk = INTEGER(adim)[0];
544 int *pbdim = INTEGER(bdim), bm = pbdim[0], bn = pbdim[1],
545 rm = (btrans) ? bn : bm, rn = (btrans) ? bm : bn;
547 if (rk != ((aleft == btrans) ? bn : bm))
548 error(
_(
"non-conformable arguments"));
550 error(
_(
"attempt to allocate vector of length exceeding %s"),
555 char rcl[] =
"...Matrix";
556 rcl[0] = (TYPEOF(ax) == CPLXSXP) ?
'z' :
'd';
557 rcl[1] = (triangular > 0) ?
't' :
'g';
558 rcl[2] = (triangular > 0) ?
'r' :
'e';
562 int *prdim = INTEGER(rdim);
570 matmultDN(rdimnames, adimnames, atrans, bdimnames, !btrans);
572 matmultDN(rdimnames, bdimnames, btrans, adimnames, !atrans);
576 char aul = *CHAR(STRING_ELT(auplo, 0));
577 if (triangular > 0 && ((atrans) ? aul ==
'U' : aul !=
'U')) {
579 auplo = mkString(
"L");
586 char adi = *CHAR(STRING_ELT(adiag, 0));
587 if (triangular > 1 && adi !=
'N') {
593 if (rm > 0 && rn > 0) {
595 rx = PROTECT(allocVector(REALSXP, (R_xlen_t) rm * rn));
596 int i, rinc = (aleft) ? 1 : rm, rincp = (aleft) ? rm : 1;
597#ifdef MATRIX_ENABLE_ZMATRIX
598 if (TYPEOF(ax) == CPLXSXP) {
599 Rcomplex *pax = COMPLEX(ax), *pbx = COMPLEX(bx), *prx = COMPLEX(rx);
601 Matrix_memcpy(prx, pbx, (R_xlen_t) bm * bn,
sizeof(Rcomplex));
603 ztranspose2(prx, pbx, bm, bn);
604 for (i = 0; i < rn; ++i) {
606 &aul, (aleft == atrans) ?
"T" :
"N", &adi, &rk,
612 double *pax = REAL(ax), *pbx = REAL(bx), *prx = REAL(rx);
616 dtranspose2(prx, pbx, bm, bn);
617 for (i = 0; i < rn; ++i) {
619 &aul, (aleft == atrans) ?
"T" :
"N", &adi, &rk,
623#ifdef MATRIX_ENABLE_ZMATRIX
636 int xtrans_ = LOGICAL(xtrans)[0], ytrans_ = LOGICAL(ytrans)[0],
637 ztrans_ = 0, m, n, v;
638 matmultDim(x, y, &xtrans_, &ytrans_, &ztrans_, &m, &n, &v);
640 PROTECT_INDEX xpid, ypid;
641 PROTECT_WITH_INDEX(x, &xpid);
642 PROTECT_WITH_INDEX(y, &ypid);
644 if (TYPEOF(x) != S4SXP) {
645 REPROTECT(x =
matrix_as_dense(x,
",ge",
'\0',
'\0', xtrans_, 0), xpid);
649 (xtrans_) ? 1 : 0, R_NilValue);
653 if (TYPEOF(y) != S4SXP && y != R_NilValue) {
654 REPROTECT(y =
matrix_as_dense(y,
",ge",
'\0',
'\0', ytrans_, 0), ypid);
658 (ytrans_) ? 1 : 0, R_NilValue);
664 const char *xcl = NULL, *ycl = NULL;
666 ivalid = R_check_class_etc(x,
valid);
670 if (y != R_NilValue) {
671 ivalid = R_check_class_etc(y,
valid);
677 char kind = (xcl[0] ==
'z' || (y != R_NilValue && ycl[0] ==
'z'))
679 if (xcl[0] != kind) {
683 if (y != R_NilValue) {
684 if (ycl[0] != kind) {
690 if (y == R_NilValue) {
693 }
else if (xcl[1] ==
'g' && ycl[1] ==
'g') {
695 }
else if (xcl[1] ==
'g' || ycl[1] ==
'g') {
711 }
else if (xcl[1] ==
's' && ycl[1] ==
's') {
712 if (xcl[2] ==
'p' && ycl[2] ==
'p') {
715 }
else if (xcl[2] ==
'p') {
722 }
else if (xcl[1] ==
's' || ycl[1] ==
's') {
741 xul = *CHAR(STRING_ELT(xuplo, 0)),
742 yul = *CHAR(STRING_ELT(yuplo, 0)),
743 xdi = *CHAR(STRING_ELT(xdiag, 0)),
744 ydi = *CHAR(STRING_ELT(ydiag, 0));
746 xul = (xul ==
'U') ?
'L' :
'U';
748 yul = (yul ==
'U') ?
'L' :
'U';
749 int triangular = (xul != yul) ? 0 : ((xdi != ydi || xdi ==
'N') ? 1 : 2);
752 if (xcl[2] ==
'p' && ycl[2] ==
'p') {
755 }
else if (xcl[2] ==
'p') {
772 int ztrans,
int triangular,
int boolean)
776 char zcl[] =
"..CMatrix";
777 zcl[0] = (boolean) ?
'n' :
'd';
778 if (y == R_NilValue) {
780 cholmod_sparse *X =
M2CHS(x, !
boolean);
781 if (X->xtype == CHOLMOD_COMPLEX)
782 error(
_(
"'%s' does not support complex matrices"),
"cholmod_aat");
784 X = cholmod_transpose(X, !
boolean, &
c);
785 cholmod_sparse *Z = cholmod_aat(X, (
int *) NULL, 0, !
boolean, &
c);
787 cholmod_free_sparse(&X, &
c);
790 X = cholmod_copy(Z, (ztrans) ? -1 : 1, 1, &
c);
791 cholmod_free_sparse(&Z, &
c);
793 PROTECT_WITH_INDEX(z =
CHS2M(Z, !
boolean, zcl[1]), &zpid);
794 cholmod_free_sparse(&Z, &
c);
797 symDN(zdimnames, xdimnames, (xtrans) ? 1 : 0);
800 SEXP uplo = PROTECT(mkString(
"L"));
805 zcl[1] = (triangular != 0) ?
't' :
'g';
807 *X =
M2CHS(x, !
boolean),
808 *Y =
M2CHS(y, !
boolean);
809 if (X->xtype == CHOLMOD_COMPLEX || Y->xtype == CHOLMOD_COMPLEX)
810 error(
_(
"'%s' does not support complex matrices"),
"cholmod_ssmult");
811 if (((xtrans) ? X->nrow : X->ncol) != ((ytrans) ? Y->ncol : Y->nrow))
812 error(
_(
"non-conformable arguments"));
814 X = cholmod_transpose(X, !
boolean, &
c);
816 Y = cholmod_transpose(Y, !
boolean, &
c);
817 cholmod_sparse *Z = cholmod_ssmult(X, Y, 0, !
boolean, 1, &
c);
819 cholmod_free_sparse(&X, &
c);
821 cholmod_free_sparse(&Y, &
c);
822 PROTECT_WITH_INDEX(z =
CHS2M(Z, !
boolean, zcl[1]), &zpid);
823 cholmod_free_sparse(&Z, &
c);
828 xdimnames, (xtrans) ? 1 : 0,
829 ydimnames, (ytrans) ? 0 : 1);
831 if (triangular < 0) {
832 SEXP uplo = PROTECT(mkString(
"L"));
836 if (triangular < -1 || triangular > 1)
848 int ztrans,
int triangular,
int symmetric)
851 char zcl[] =
"...Matrix";
852 cholmod_sparse *X =
M2CHS(x, 1);
853 cholmod_dense *Y =
M2CHD(y, ytrans);
854 zcl[0] = (X->xtype == CHOLMOD_COMPLEX || Y->xtype == CHOLMOD_COMPLEX)
856 zcl[1] = (triangular) ?
't' :
'g';
857 zcl[2] = (triangular) ?
'r' :
'e';
858 X->stype = symmetric;
859 if (((xtrans) ? X->nrow : X->ncol) != Y->nrow) {
862 error(
_(
"non-conformable arguments"));
864 int m = (int) ((xtrans) ? X->ncol : X->nrow), n = (
int) Y->ncol;
868 error(
_(
"attempt to allocate vector of length exceeding %s"),
871 cholmod_dense *Z = (cholmod_dense *) R_alloc(1,
sizeof(cholmod_dense));
872 memset(Z, 0,
sizeof(cholmod_dense));
873 Z->nrow = (size_t) m;
874 Z->ncol = (size_t) n;
876 Z->nzmax = Z->nrow * Z->ncol;
879 double alpha[2] = { 1.0, 0.0 }, beta[2] = { 0.0, 0.0 };
881 if (Z->xtype == CHOLMOD_COMPLEX)
882 Z->x = R_Calloc(Z->nzmax, Rcomplex);
884 Z->x = R_Calloc(Z->nzmax,
double);
885 cholmod_sdmult(X, xtrans, alpha, beta, Y, Z, &
c);
886 PROTECT(z =
CHD2M(Z, ztrans, zcl[1]));
891 INTEGER(zdim)[0] = m;
892 INTEGER(zdim)[1] = n;
894 if (Z->xtype == CHOLMOD_COMPLEX) {
895 PROTECT(zx = allocVector(CPLXSXP, (R_xlen_t) m * n));
898 PROTECT(zx = allocVector(REALSXP, (R_xlen_t) m * n));
901 cholmod_sdmult(X, xtrans, alpha, beta, Y, Z, &
c);
907 SEXP xdimnames = (symmetric)
914 ydimnames, (ytrans) ? 0 : 1,
915 xdimnames, (xtrans) ? 1 : 0);
918 xdimnames, (xtrans) ? 1 : 0,
919 ydimnames, (ytrans) ? 0 : 1);
921 if (triangular != 0 && ztrans == (triangular > 0)) {
922 SEXP uplo = PROTECT(mkString(
"L"));
926 if (triangular < -1 || triangular > 1) {
927 SEXP diag = PROTECT(mkString(
"U"));
938 if (TYPEOF(
boolean) != LGLSXP || LENGTH(
boolean) < 1)
939 error(
_(
"invalid '%s' to '%s'"),
"boolean", __func__);
940 int boolean_ = LOGICAL(
boolean)[0];
942 int xtrans_ = LOGICAL(xtrans)[0], ytrans_ = LOGICAL(ytrans)[0],
943 ztrans_ = LOGICAL(ztrans)[0], m, n, v;
944 matmultDim(x, y, &xtrans_, &ytrans_, &ztrans_, &m, &n, &v);
946 PROTECT_INDEX xpid, ypid;
947 PROTECT_WITH_INDEX(x, &xpid);
948 PROTECT_WITH_INDEX(y, &ypid);
950 if (TYPEOF(x) != S4SXP) {
951 if (boolean_ == NA_LOGICAL || !boolean_)
952 REPROTECT(x =
matrix_as_dense( x,
",ge",
'\0',
'\0', xtrans_, 0), xpid);
960 (xtrans_) ? 1 : 0, R_NilValue);
964 if (TYPEOF(y) != S4SXP && y != R_NilValue) {
965 if (boolean_ == NA_LOGICAL || !boolean_)
966 REPROTECT(y =
matrix_as_dense( y,
",ge",
'\0',
'\0', ytrans_, 0), ypid);
974 (ytrans_) ? 1 : 0, R_NilValue);
979 static const char *
valid[] = {
981 const char *xcl = NULL, *ycl = NULL;
983 ivalid = R_check_class_etc(x,
valid);
987 if (y != R_NilValue) {
988 ivalid = R_check_class_etc(y,
valid);
993 if (boolean_ == NA_LOGICAL)
994 boolean_ = xcl[0] ==
'n' && (y == R_NilValue || ycl[0] ==
'n');
995 char kind = (boolean_) ?
'n' :
996 ((xcl[0] ==
'z' || (y != R_NilValue && ycl[0] ==
'z')) ?
'z' :
'd');
998 if (xcl[2] !=
'C' && xtrans_) {
999 if (xcl[2] !=
'R' && xcl[2] !=
'T') {
1003 if (xcl[1] !=
's' || xcl[1] !=
'T') {
1009 if (xcl[2] !=
'C') {
1010 if (xcl[2] !=
'R' && xcl[2] !=
'T')
1018 if (xcl[0] != kind) {
1027 if (y == R_NilValue) {
1030 x, y, xtrans_, !xtrans_, ztrans_, 0, boolean_);
1036 if (xcl[1] ==
't' && ycl[1] ==
't') {
1043 xul = *CHAR(STRING_ELT(xuplo, 0)),
1044 yul = *CHAR(STRING_ELT(yuplo, 0)),
1045 xdi = *CHAR(STRING_ELT(xdiag, 0)),
1046 ydi = *CHAR(STRING_ELT(ydiag, 0));
1048 xul = (xul ==
'U') ?
'L' :
'U';
1050 yul = (yul ==
'U') ?
'L' :
'U';
1051 triangular = (xul != yul) ? 0 : ((xdi != ydi || xdi ==
'N') ? 1 : 2);
1053 triangular = -triangular;
1057 if (!boolean_ && ycl[2] !=
'C' && ycl[2] !=
'R' && ycl[2] !=
'T') {
1058 int symmetric = xcl[1] ==
's';
1061 char xul = *CHAR(STRING_ELT(xuplo, 0));
1066 if (ycl[0] != kind) {
1074 x, y, xtrans_, ytrans_, ztrans_, triangular, symmetric);
1079 if (ycl[2] !=
'C' && ytrans_) {
1080 if (ycl[2] !=
'R' && ycl[2] !=
'T') {
1084 if (ycl[1] !=
's' || ycl[1] !=
'T') {
1090 if (ycl[2] !=
'C') {
1091 if (ycl[2] !=
'R' && ycl[2] !=
'T')
1099 if (ycl[0] != kind) {
1111 x, y, xtrans_, ytrans_, ztrans_, triangular, boolean_);
1116#define MULTIPLY_COMPLEX(_X_, _D_) \
1119 (_X_).r = tmp.r * (_D_).r - tmp.i * (_D_).i; \
1120 (_X_).i = tmp.r * (_D_).i + tmp.i * (_D_).r; \
1122#define MULTIPLY_REAL(_X_, _D_) \
1123 (_X_) = (_X_) * (_D_)
1124#define MULTIPLY_LOGICAL(_X_, _D_) \
1125 (_X_) = (_X_) && (_D_)
1127#define SCALE_CASES(_J_) \
1129 switch (TYPEOF(d)) { \
1133 SCALE(Rcomplex, COMPLEX, MULTIPLY_COMPLEX, _J_); \
1137 SCALE(double, REAL, MULTIPLY_REAL, _J_); \
1140 SCALE(int, LOGICAL, MULTIPLY_LOGICAL, _J_); \
1149 int i, j, packed = XLENGTH(x) < (R_xlen_t) m * n;
1151#define SCALE(_CTYPE_, _PTR_, _OP_, _J_) \
1153 _CTYPE_ *px = _PTR_(x), *pd = _PTR_(d); \
1154 if (uplo == '\0') { \
1155 for (j = 0; j < n; ++j) { \
1156 for (i = 0; i < m; ++i) { \
1157 _OP_(*px, pd[_J_]); \
1161 } else if (uplo == 'U') { \
1162 for (j = 0; j < n; ++j) { \
1163 for (i = 0; i <= j; ++i) { \
1164 _OP_(*px, pd[_J_]); \
1171 for (j = 0; j < n; ++j) { \
1174 for (i = j; i < m; ++i) { \
1175 _OP_(*px, pd[_J_]); \
1180 if (diag != '\0' && diag != 'N') { \
1183 R_xlen_t m1a = (R_xlen_t) m + 1; \
1184 for (j = 0; j < n; ++j, px += m1a, pd += 1) \
1186 } else if (uplo == 'U') { \
1187 for (j = 0; j < n; px += (++j)+1, pd += 1) \
1190 for (j = 0; j < n; px += m-(j++), pd += 1) \
1204 int i, j, packed = XLENGTH(x) < (R_xlen_t) m * n;
1219 int *pp = INTEGER(p) + 1, n = (int) (XLENGTH(p) - 1), j, k = 0, kend;
1222#define SCALE(_CTYPE_, _PTR_, _OP_, _J_) \
1224 _CTYPE_ *px = _PTR_(x), *pd = _PTR_(d); \
1225 for (j = 0; j < n; ++j) { \
1227 while (k < kend) { \
1251 int *pi = INTEGER(i), k, nnz = INTEGER(p)[XLENGTH(p) - 1];
1254#define SCALE(_CTYPE_, _PTR_, _OP_, _J_) \
1256 _CTYPE_ *px = _PTR_(x), *pd = _PTR_(d); \
1257 for (k = 0; k < nnz; ++k) { \
1258 _OP_(*px, pd[*pi]); \
1275 int *pi = INTEGER(i);
1276 R_xlen_t k, nnz = XLENGTH(i);
1288 SEXP x_ = x, y_ = y;
1290 if (TYPEOF(
boolean) != LGLSXP || LENGTH(
boolean) < 1)
1291 error(
_(
"invalid '%s' to '%s'"),
"boolean", __func__);
1292 int boolean_ = LOGICAL(
boolean)[0];
1294 int xtrans_ = LOGICAL(xtrans)[0], ytrans_ = LOGICAL(ytrans)[0],
1295 ztrans_ = 0, m, n, v;
1296 matmultDim(x, y, &xtrans_, &ytrans_, &ztrans_, &m, &n, &v);
1298 PROTECT_INDEX xpid, ypid;
1299 PROTECT_WITH_INDEX(x, &xpid);
1300 PROTECT_WITH_INDEX(y, &ypid);
1302 if (TYPEOF(x) != S4SXP) {
1303 if (boolean_ == NA_LOGICAL || !boolean_)
1304 REPROTECT(x =
matrix_as_dense(x,
",ge",
'\0',
'\0', xtrans_, 2), xpid);
1306 REPROTECT(x =
matrix_as_dense(x,
"nge",
'\0',
'\0', xtrans_, 2), xpid);
1310 (xtrans_) ? 1 : 0, R_NilValue);
1314 if (TYPEOF(y) != S4SXP) {
1315 if (boolean_ == NA_LOGICAL || !boolean_)
1316 REPROTECT(y =
matrix_as_dense(y,
",ge",
'\0',
'\0', ytrans_, 2), ypid);
1318 REPROTECT(y =
matrix_as_dense(y,
"nge",
'\0',
'\0', ytrans_, 2), ypid);
1322 (ytrans_) ? 1 : 0, R_NilValue);
1327 static const char *
valid[] = {
1330 const char *xcl = NULL, *ycl = NULL;
1332 ivalid = R_check_class_etc(x,
valid);
1335 xcl =
valid[ivalid];
1338 ivalid = R_check_class_etc(y,
valid);
1341 ycl =
valid[ivalid];
1344 if (boolean_ == NA_LOGICAL)
1345 boolean_ = xcl[0] ==
'n' && ycl[0] ==
'n';
1346 char kind = (boolean_) ?
'n' :
1347 ((xcl[0] ==
'z' || ycl[0] ==
'z') ?
'z' :
'd');
1349 int margin = -1, unit = -1;
1350 if (xcl[2] ==
'i') {
1353 }
else if (ycl[2] ==
'i') {
1357 error(
_(
"should never happen ..."));
1359 char ks = (boolean_) ?
'l' : kind, kd = kind;
1362 if (!unit && xcl[0] != ks) {
1374 if (!unit && xcl[1] ==
's') {
1377 }
else if (!unit && xcl[1] ==
't')
1389 if (!unit && xcl[1] ==
's') {
1401 if (!unit && ycl[0] != ks) {
1413 if (!unit && ycl[1] ==
's') {
1416 }
else if (!unit && ycl[1] ==
't')
1428 if (!unit && ycl[1] ==
's') {
1441 const char *zcl = (margin == 0) ? ycl : xcl;
1442 PROTECT_WITH_INDEX(z =
newObject(zcl), &zpid);
1445 int *pzdim = INTEGER(zdim);
1454 xdimnames, (xtrans_) ? 1 : 0,
1455 ydimnames, (ytrans_) ? 0 : 1);
1458 char ul =
'\0', di =
'\0';
1459 if (zcl[1] !=
'g') {
1461 ul = *CHAR(STRING_ELT(uplo, 0));
1466 if (zcl[1] ==
't') {
1468 di = *CHAR(STRING_ELT(diag, 0));
1469 if (di !=
'N' && unit)
1475 if (zcl[2] ==
'C' || zcl[2] ==
'R' || zcl[2] ==
'T') {
1476 if (zcl[2] !=
'T') {
1481 if (zcl[2] !=
'R') {
1486 if (zcl[2] !=
'C') {
1494 if (unit || ((margin == 0) ? y != y_ : x != x_))
1497 SEXP x1 = PROTECT(allocVector(TYPEOF(x0), XLENGTH(x0)));
1500 Matrix_memcpy(COMPLEX(x1), COMPLEX(x0), XLENGTH(x0),
sizeof(Rcomplex));
1503 Matrix_memcpy( REAL(x1), REAL(x0), XLENGTH(x0),
sizeof(
double));
1506 Matrix_memcpy(LOGICAL(x1), LOGICAL(x0), XLENGTH(x0),
sizeof(
int));
1545 if (boolean_ && (zcl[2] ==
'C' || zcl[2] ==
'R' || zcl[2] ==
'T')) {
long long Matrix_int_fast64_t
#define ERROR_INVALID_CLASS(_X_, _FUNC_)
#define SET_SLOT(x, what, value)
#define GET_SLOT(x, what)
SEXP newObject(const char *)
SEXP get_symmetrized_DimNames(SEXP obj, int J)
void symDN(SEXP dest, SEXP src, int J)
static const char * valid[]
SEXP CHD2M(cholmod_dense *A, int trans, char shape)
cholmod_sparse * M2CHS(SEXP obj, int values)
SEXP CHS2M(cholmod_sparse *A, int values, char shape)
cholmod_dense * M2CHD(SEXP obj, int trans)
SEXP sparse_as_Csparse(SEXP from, const char *class)
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 diagonal_as_kind(SEXP from, const char *class, char kind)
SEXP matrix_as_dense(SEXP from, const char *zzz, char ul, char di, int trans, int new)
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 dense_transpose(SEXP from, const char *class)
SEXP R_diagonal_matmult(SEXP x, SEXP y, SEXP xtrans, SEXP ytrans, SEXP boolean)
static void Tsparse_rowscale(SEXP obj, SEXP d, SEXP iSym)
static void matmultDN(SEXP dest, SEXP asrc, int ai, SEXP bsrc, int bi)
SEXP R_sparse_matmult(SEXP x, SEXP y, SEXP xtrans, SEXP ytrans, SEXP ztrans, SEXP boolean)
static SEXP dsyMatrix_matmult(SEXP a, SEXP b, int aleft, int btrans)
static SEXP dgCMatrix_dgeMatrix_matmult(SEXP x, SEXP y, int xtrans, int ytrans, int ztrans, int triangular, int symmetric)
static void Csparse_rowscale(SEXP obj, SEXP d, SEXP iSym)
static SEXP dgCMatrix_dgCMatrix_matmult(SEXP x, SEXP y, int xtrans, int ytrans, int ztrans, int triangular, int boolean)
static void Csparse_colscale(SEXP obj, SEXP d)
static void dense_rowscale(SEXP obj, SEXP d, int m, int n, char uplo, char diag)
static void dense_colscale(SEXP obj, SEXP d, int m, int n, char uplo, char diag)
static SEXP dspMatrix_matmult(SEXP a, SEXP b, int aleft, int btrans)
static SEXP dgeMatrix_matmult(SEXP a, SEXP b, int atrans, int btrans)
static void matmultDim(SEXP x, SEXP y, int *xtrans, int *ytrans, int *ztrans, int *m, int *n, int *v)
static SEXP dtrMatrix_matmult(SEXP a, SEXP b, int aleft, int atrans, int btrans, int triangular)
SEXP R_dense_matmult(SEXP x, SEXP y, SEXP xtrans, SEXP ytrans)
static SEXP dtpMatrix_matmult(SEXP a, SEXP b, int aleft, int atrans, int btrans, int triangular)
SEXP sparse_diag_N2U(SEXP from, const char *class)
SEXP sparse_diag_U2N(SEXP from, const char *class)
SEXP sparse_transpose(SEXP from, const char *class, int lazy)
SEXP sparse_drop0(SEXP from, const char *class, double tol)
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)