/* ========================================================================== */ /* === MatrixOps/cholmod_sdmult ============================================= */ /* ========================================================================== */ /* ----------------------------------------------------------------------------- * CHOLMOD/MatrixOps Module. Copyright (C) 2005-2006, Timothy A. Davis * The CHOLMOD/MatrixOps Module is licensed under Version 2.0 of the GNU * General Public License. See gpl.txt for a text of the license. * CHOLMOD is also available under other licenses; contact authors for details. * http://www.cise.ufl.edu/research/sparse * -------------------------------------------------------------------------- */ /* Sparse matrix times dense matrix: * Y = alpha*(A*X) + beta*Y or Y = alpha*(A'*X) + beta*Y, * where A is sparse and X and Y are dense. * * when using A, X has A->ncol columns and Y has A->nrow rows * when using A', X has A->nrow columns and Y has A->ncol rows * * workspace: none in Common. Temporary workspace of size 4*(X->nrow) is used * if A is stored in symmetric form and X has four columns or more. If the * workspace is not available, a slower method is used instead that requires * no workspace. * * transpose = 0: use A * otherwise, use A' (complex conjugate transpose) * * transpose is ignored if the matrix is symmetric or Hermitian. * (the array transpose A.' is not supported). * * Supports real, complex, and zomplex matrices, but the xtypes of A, X, and Y * must all match. */ #ifndef NMATRIXOPS #include "cholmod_internal.h" #include "cholmod_matrixops.h" /* ========================================================================== */ /* === TEMPLATE ============================================================= */ /* ========================================================================== */ #define REAL #include "t_cholmod_sdmult.c" #define COMPLEX #include "t_cholmod_sdmult.c" #define ZOMPLEX #include "t_cholmod_sdmult.c" /* ========================================================================== */ /* === cholmod_sdmult ======================================================= */ /* ========================================================================== */ int CHOLMOD(sdmult) ( /* ---- input ---- */ cholmod_sparse *A, /* sparse matrix to multiply */ int transpose, /* use A if 0, otherwise use A' */ double alpha [2], /* scale factor for A */ double beta [2], /* scale factor for Y */ cholmod_dense *X, /* dense matrix to multiply */ /* ---- in/out --- */ cholmod_dense *Y, /* resulting dense matrix */ /* --------------- */ cholmod_common *Common ) { double *w ; size_t nx, ny ; Int e ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ RETURN_IF_NULL_COMMON (FALSE) ; RETURN_IF_NULL (A, FALSE) ; RETURN_IF_NULL (X, FALSE) ; RETURN_IF_NULL (Y, FALSE) ; RETURN_IF_XTYPE_INVALID (A, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; RETURN_IF_XTYPE_INVALID (Y, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ; ny = transpose ? A->ncol : A->nrow ; /* required length of Y */ nx = transpose ? A->nrow : A->ncol ; /* required length of X */ if (X->nrow != nx || X->ncol != Y->ncol || Y->nrow != ny) { /* X and/or Y have the wrong dimension */ ERROR (CHOLMOD_INVALID, "X and/or Y have wrong dimensions") ; return (FALSE) ; } if (A->xtype != X->xtype || A->xtype != Y->xtype) { ERROR (CHOLMOD_INVALID, "A, X, and Y must have same xtype") ; return (FALSE) ; } Common->status = CHOLMOD_OK ; /* ---------------------------------------------------------------------- */ /* allocate workspace, if required */ /* ---------------------------------------------------------------------- */ w = NULL ; e = (A->xtype == CHOLMOD_REAL ? 1:2) ; if (A->stype && X->ncol >= 4) { w = CHOLMOD(malloc) (nx, 4*e*sizeof (double), Common) ; } if (Common->status < CHOLMOD_OK) { return (FALSE) ; /* out of memory */ } /* ---------------------------------------------------------------------- */ /* Y = alpha*op(A)*X + beta*Y via template routine */ /* ---------------------------------------------------------------------- */ ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ; DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ; DEBUG (if (IS_NONZERO (beta [0]) || (IS_NONZERO (beta [1]) && A->xtype != CHOLMOD_REAL)) CHOLMOD(dump_dense) (Y, "Y", Common)) ; switch (A->xtype) { case CHOLMOD_REAL: r_cholmod_sdmult (A, transpose, alpha, beta, X, Y, w) ; break ; case CHOLMOD_COMPLEX: c_cholmod_sdmult (A, transpose, alpha, beta, X, Y, w) ; break ; case CHOLMOD_ZOMPLEX: z_cholmod_sdmult (A, transpose, alpha, beta, X, Y, w) ; break ; } /* ---------------------------------------------------------------------- */ /* free workspace */ /* ---------------------------------------------------------------------- */ CHOLMOD(free) (4*nx, e*sizeof (double), w, Common) ; DEBUG (CHOLMOD(dump_dense) (Y, "Y", Common)) ; return (TRUE) ; } #endif