Rev 1864 | Rev 3484 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include "dspMatrix.h"/* Note: also used for lspMatrix */SEXP dspMatrix_validate(SEXP obj){SEXP val = symmetricMatrix_validate(obj);if(isString(val))return(val);else { /* identical to the test in dtpMatrix_validate() : */int *dims = INTEGER(GET_SLOT(obj, Matrix_DimSym));if (dims[0] != packed_ncol(length(GET_SLOT(obj, Matrix_xSym))))return(mkString(_("Incorrect length of 'x' slot")));return ScalarLogical(1);}}double get_norm_sp(SEXP obj, char *typstr){char typnm[] = {'\0', '\0'};int *dims = INTEGER(GET_SLOT(obj, Matrix_DimSym));double *work = (double *) NULL;typnm[0] = norm_type(typstr);if (*typnm == 'I' || *typnm == 'O') {work = (double *) R_alloc(dims[0], sizeof(double));}return F77_CALL(dlansp)(typnm, uplo_P(obj), dims,REAL(GET_SLOT(obj, Matrix_xSym)), work);}SEXP dspMatrix_norm(SEXP obj, SEXP type){return ScalarReal(get_norm_sp(obj, CHAR(asChar(type))));}SEXP dspMatrix_rcond(SEXP obj, SEXP type){SEXP trf = dspMatrix_trf(obj);char typnm[] = {'\0', '\0'};int *dims = INTEGER(GET_SLOT(obj, Matrix_DimSym)), info;double anorm = get_norm_sp(obj, "O"), rcond;typnm[0] = rcond_type(CHAR(asChar(type)));F77_CALL(dspcon)(uplo_P(trf), dims,REAL (GET_SLOT(trf, Matrix_xSym)),INTEGER(GET_SLOT(trf, Matrix_permSym)),&anorm, &rcond,(double *) R_alloc(2*dims[0], sizeof(double)),(int *) R_alloc(dims[0], sizeof(int)), &info);return ScalarReal(rcond);}SEXP dspMatrix_solve(SEXP a){SEXP trf = dspMatrix_trf(a);SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dspMatrix")));int *dims = INTEGER(GET_SLOT(trf, Matrix_DimSym)), info;SET_SLOT(val, Matrix_uploSym, duplicate(GET_SLOT(trf, Matrix_uploSym)));SET_SLOT(val, Matrix_xSym, duplicate(GET_SLOT(trf, Matrix_xSym)));SET_SLOT(val, Matrix_DimSym, duplicate(GET_SLOT(trf, Matrix_DimSym)));F77_CALL(dsptri)(uplo_P(val), dims, REAL(GET_SLOT(val, Matrix_xSym)),INTEGER(GET_SLOT(trf, Matrix_permSym)),(double *) R_alloc((long) dims[0], sizeof(double)),&info);UNPROTECT(1);return val;}SEXP dspMatrix_matrix_solve(SEXP a, SEXP b, SEXP classedP){int classed = asLogical(classedP);SEXP trf = dspMatrix_trf(a),val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix")));int *adims = INTEGER(GET_SLOT(a, Matrix_DimSym)),*bdims = (classed ? INTEGER(GET_SLOT(b, Matrix_DimSym)) :INTEGER(getAttrib(b, R_DimSymbol)));int n = bdims[0], nrhs = bdims[1], info;int sz = n * nrhs;double *bx = (classed ? REAL(GET_SLOT(b, Matrix_xSym)) : REAL(b));if (!classed && !(isReal(b) && isMatrix(b)))error(_("Argument b must be a numeric matrix"));if (*adims != *bdims || bdims[1] < 1 || *adims < 1)error(_("Dimensions of system to be solved are inconsistent"));Memcpy(INTEGER(ALLOC_SLOT(val, Matrix_DimSym, INTSXP, 2)), bdims, 2);F77_CALL(dsptrs)(uplo_P(trf),&n, &nrhs, REAL(GET_SLOT(trf, Matrix_xSym)),INTEGER(GET_SLOT(trf, Matrix_permSym)),Memcpy(REAL(ALLOC_SLOT(val, Matrix_xSym, REALSXP, sz)),bx, sz), &n, &info);UNPROTECT(1);return val;}SEXP dspMatrix_as_dsyMatrix(SEXP from){SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dsyMatrix"))),uplo = GET_SLOT(from, Matrix_uploSym),dimP = GET_SLOT(from, Matrix_DimSym),dmnP = GET_SLOT(from, Matrix_DimNamesSym);int n = *INTEGER(dimP);SET_SLOT(val, Matrix_DimSym, duplicate(dimP));SET_SLOT(val, Matrix_DimNamesSym, duplicate(dmnP));SET_SLOT(val, Matrix_uploSym, duplicate(uplo));packed_to_full_double(REAL(ALLOC_SLOT(val, Matrix_xSym, REALSXP, n*n)),REAL(GET_SLOT(from, Matrix_xSym)), n,*CHAR(STRING_ELT(uplo, 0)) == 'U' ? UPP : LOW);UNPROTECT(1);return val;}SEXP dspMatrix_matrix_mm(SEXP a, SEXP b, SEXP classedP){int classed = asLogical(classedP);SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("dgeMatrix"))),bdimP = (classed ? GET_SLOT(b, Matrix_DimSym) :getAttrib(b, R_DimSymbol));int *bdims = INTEGER(bdimP);int i, ione = 1, n = bdims[0], nrhs = bdims[1];int sz = n * nrhs;char *uplo = uplo_P(a);double *ax = REAL(GET_SLOT(a, Matrix_xSym)), one = 1., zero = 0.,*bx = (classed ? REAL(GET_SLOT(b, Matrix_xSym)) : REAL(b)),*vx = REAL(ALLOC_SLOT(val, Matrix_xSym, REALSXP, sz));if (bdims[0] != n)error(_("Matrices are not conformable for multiplication"));if (nrhs < 1 || n < 1)error(_("Matrices with zero extents cannot be multiplied"));SET_SLOT(val, Matrix_DimSym, duplicate(bdimP));for (i = 0; i < nrhs; i++)F77_CALL(dspmv)(uplo, &n, &one, ax, bx + i * n, &ione,&zero, vx + i * n, &ione);UNPROTECT(1);return val;}SEXP dspMatrix_trf(SEXP x){SEXP val = get_factors(x, "pBunchKaufman"),dimP = GET_SLOT(x, Matrix_DimSym),uploP = GET_SLOT(x, Matrix_uploSym);int *dims = INTEGER(dimP), *perm, info;int n = dims[0];char *uplo = CHAR(STRING_ELT(uploP, 0));if (val != R_NilValue) return val;dims = INTEGER(dimP);val = PROTECT(NEW_OBJECT(MAKE_CLASS("pBunchKaufman")));SET_SLOT(val, Matrix_uploSym, duplicate(uploP));SET_SLOT(val, Matrix_diagSym, mkString("N"));SET_SLOT(val, Matrix_DimSym, duplicate(dimP));SET_SLOT(val, Matrix_xSym, duplicate(GET_SLOT(x, Matrix_xSym)));perm = INTEGER(ALLOC_SLOT(val, Matrix_permSym, INTSXP, n));F77_CALL(dsptrf)(uplo, dims, REAL(GET_SLOT(val, Matrix_xSym)), perm, &info);if (info) error(_("Lapack routine %s returned error code %d"), "dsptrf", info);UNPROTECT(1);return set_factors(x, val, "pBunchKaufman");}