1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
/* ========================================================================== */
/* === CHOLMOD/MATLAB/resymbol mexFunction ================================== */
/* ========================================================================== */
/* -----------------------------------------------------------------------------
* CHOLMOD/MATLAB Module. Copyright (C) 2005-2006, Timothy A. Davis
* http://www.suitesparse.com
* MATLAB(tm) is a Trademark of The MathWorks, Inc.
* -------------------------------------------------------------------------- */
/* Usage:
* L = resymbol (L, A)
*
* Recompute the symbolic Cholesky factorization of the matrix A. A must be
* symmetric. Only tril(A) is used. Entries in L that are not in the Cholesky
* factorization of A are removed from L. L can be from an LL' or LDL'
* factorization. The numerical values of A are ignored; only its nonzero
* pattern is used.
*/
/* ========================================================================== */
#include "cholmod_matlab.h"
void mexFunction
(
int nargout,
mxArray *pargout [ ],
int nargin,
const mxArray *pargin [ ]
)
{
double dummy = 0 ;
double *Lx, *Lx2, *Lz, *Lz2 ;
Long *Li, *Lp, *Lnz2, *Li2, *Lp2, *ColCount ;
cholmod_sparse *A, Amatrix, *Lsparse, *S ;
cholmod_factor *L ;
cholmod_common Common, *cm ;
Long j, s, n, lnz, is_complex ;
/* ---------------------------------------------------------------------- */
/* start CHOLMOD and set parameters */
/* ---------------------------------------------------------------------- */
cm = &Common ;
cholmod_l_start (cm) ;
sputil_config (SPUMONI, cm) ;
/* ---------------------------------------------------------------------- */
/* check inputs */
/* ---------------------------------------------------------------------- */
if (nargout > 1 || nargin != 2)
{
mexErrMsgTxt ("usage: L = resymbol (L, A)\n") ;
}
n = mxGetN (pargin [0]) ;
if (!mxIsSparse (pargin [0]) || n != mxGetM (pargin [0]))
{
mexErrMsgTxt ("resymbol: L must be sparse and square") ;
}
if (n != mxGetM (pargin [1]) || n != mxGetN (pargin [1]))
{
mexErrMsgTxt ("resymbol: A and L must have same dimensions") ;
}
/* ---------------------------------------------------------------------- */
/* get the sparse matrix A */
/* ---------------------------------------------------------------------- */
A = sputil_get_sparse_pattern (pargin [1], &Amatrix, &dummy, cm) ;
S = (A == &Amatrix) ? NULL : A ;
A->stype = -1 ;
/* A = sputil_get_sparse (pargin [1], &Amatrix, &dummy, -1) ; */
/* ---------------------------------------------------------------------- */
/* construct a copy of the input sparse matrix L */
/* ---------------------------------------------------------------------- */
/* get the MATLAB L */
Lp = (Long *) mxGetJc (pargin [0]) ;
Li = (Long *) mxGetIr (pargin [0]) ;
Lx = mxGetPr (pargin [0]) ;
Lz = mxGetPi (pargin [0]) ;
is_complex = mxIsComplex (pargin [0]) ;
/* allocate the CHOLMOD symbolic L */
L = cholmod_l_allocate_factor (n, cm) ;
L->ordering = CHOLMOD_NATURAL ;
ColCount = L->ColCount ;
for (j = 0 ; j < n ; j++)
{
ColCount [j] = Lp [j+1] - Lp [j] ;
}
/* allocate space for a CHOLMOD LDL' packed factor */
/* (LL' and LDL' are treated identically) */
cholmod_l_change_factor (is_complex ? CHOLMOD_ZOMPLEX : CHOLMOD_REAL,
FALSE, FALSE, TRUE, TRUE, L, cm) ;
/* copy MATLAB L into CHOLMOD L */
Lp2 = L->p ;
Li2 = L->i ;
Lx2 = L->x ;
Lz2 = L->z ;
Lnz2 = L->nz ;
lnz = L->nzmax ;
for (j = 0 ; j <= n ; j++)
{
Lp2 [j] = Lp [j] ;
}
for (j = 0 ; j < n ; j++)
{
Lnz2 [j] = Lp [j+1] - Lp [j] ;
}
for (s = 0 ; s < lnz ; s++)
{
Li2 [s] = Li [s] ;
}
for (s = 0 ; s < lnz ; s++)
{
Lx2 [s] = Lx [s] ;
}
if (is_complex)
{
for (s = 0 ; s < lnz ; s++)
{
Lz2 [s] = Lz [s] ;
}
}
/* ---------------------------------------------------------------------- */
/* resymbolic factorization */
/* ---------------------------------------------------------------------- */
cholmod_l_resymbol (A, NULL, 0, TRUE, L, cm) ;
/* ---------------------------------------------------------------------- */
/* copy the results back to MATLAB */
/* ---------------------------------------------------------------------- */
Lsparse = cholmod_l_factor_to_sparse (L, cm) ;
/* return L as a sparse matrix */
pargout [0] = sputil_put_sparse (&Lsparse, cm) ;
/* ---------------------------------------------------------------------- */
/* free workspace and the CHOLMOD L, except for what is copied to MATLAB */
/* ---------------------------------------------------------------------- */
cholmod_l_free_factor (&L, cm) ;
cholmod_l_free_sparse (&S, cm) ;
cholmod_l_finish (cm) ;
cholmod_l_print_common (" ", cm) ;
/*
if (cm->malloc_count != 3 + mxIsComplex (pargout[0])) mexErrMsgTxt ("!") ;
*/
}
|