/* ========================================================================== */
/* === Partition/cholmod_ccolamd ============================================ */
/* ========================================================================== */
/* -----------------------------------------------------------------------------
* CHOLMOD/Partition Module.
* Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis
* The CHOLMOD/Partition Module is licensed under Version 2.1 of the GNU
* Lesser General Public License. See lesser.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
* -------------------------------------------------------------------------- */
/* CHOLMOD interface to the CCOLAMD ordering routine. Finds a permutation
* p such that the Cholesky factorization of PAA'P' is sparser than AA'.
* The column etree is found and postordered, and the ccolamd ordering is then
* combined with its postordering. A must be unsymmetric.
*
* workspace: Iwork (MAX (nrow,ncol))
* Allocates a copy of its input matrix, which is
* then used as CCOLAMD's workspace.
*
* Supports any xtype (pattern, real, complex, or zomplex).
*/
#ifndef NPARTITION
#include "cholmod_internal.h"
#include "ccolamd.h"
#include "cholmod_partition.h"
#if (CCOLAMD_VERSION < CCOLAMD_VERSION_CODE (2,5))
#error "CCOLAMD v2.0 or later is required"
#endif
/* ========================================================================== */
/* === ccolamd_interface ==================================================== */
/* ========================================================================== */
/* Order with ccolamd */
static int ccolamd_interface
(
cholmod_sparse *A,
size_t alen,
Int *Perm,
Int *Cmember,
Int *fset,
Int fsize,
cholmod_sparse *C,
cholmod_common *Common
)
{
double knobs [CCOLAMD_KNOBS] ;
Int *Cp = NULL ;
Int ok, k, nrow, ncol, stats [CCOLAMD_STATS] ;
nrow = A->nrow ;
ncol = A->ncol ;
/* ---------------------------------------------------------------------- */
/* copy (and transpose) the input matrix A into the ccolamd workspace */
/* ---------------------------------------------------------------------- */
/* C = A (:,f)', which also packs A if needed. */
/* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset non-NULL) */
ok = CHOLMOD(transpose_unsym) (A, 0, NULL, fset, fsize, C, Common) ;
/* ---------------------------------------------------------------------- */
/* order the matrix (destroys the contents of C->i and C->p) */
/* ---------------------------------------------------------------------- */
/* get parameters */
#ifdef LONG
ccolamd_l_set_defaults (knobs) ;
#else
ccolamd_set_defaults (knobs) ;
#endif
if (Common->current < 0 || Common->current >= CHOLMOD_MAXMETHODS)
{
/* this is the CHOLMOD default, not the CCOLAMD default */
knobs [CCOLAMD_DENSE_ROW] = -1 ;
}
else
{
/* get the knobs from the Common parameters */
knobs [CCOLAMD_DENSE_COL] =Common->method[Common->current].prune_dense ;
knobs [CCOLAMD_DENSE_ROW] =Common->method[Common->current].prune_dense2;
knobs [CCOLAMD_AGGRESSIVE]=Common->method[Common->current].aggressive ;
knobs [CCOLAMD_LU] =Common->method[Common->current].order_for_lu;
}
if (ok)
{
#ifdef LONG
ccolamd_l (ncol, nrow, alen, C->i, C->p, knobs, stats, Cmember) ;
#else
ccolamd (ncol, nrow, alen, C->i, C->p, knobs, stats, Cmember) ;
#endif
ok = stats [CCOLAMD_STATUS] ;
ok = (ok == CCOLAMD_OK || ok == CCOLAMD_OK_BUT_JUMBLED) ;
/* permutation returned in C->p, if the ordering succeeded */
Cp = C->p ;
for (k = 0 ; k < nrow ; k++)
{
Perm [k] = Cp [k] ;
}
}
return (ok) ;
}
/* ========================================================================== */
/* === cholmod_ccolamd ====================================================== */
/* ========================================================================== */
/* Order AA' or A(:,f)*A(:,f)' using CCOLAMD. */
int CHOLMOD(ccolamd)
(
/* ---- input ---- */
cholmod_sparse *A, /* matrix to order */
Int *fset, /* subset of 0:(A->ncol)-1 */
size_t fsize, /* size of fset */
Int *Cmember, /* size A->nrow. Cmember [i] = c if row i is in the
* constraint set c. c must be >= 0. The # of
* constraint sets is max (Cmember) + 1. If Cmember is
* NULL, then it is interpretted as Cmember [i] = 0 for
* all i */
/* ---- output --- */
Int *Perm, /* size A->nrow, output permutation */
/* --------------- */
cholmod_common *Common
)
{
cholmod_sparse *C ;
Int ok, nrow, ncol ;
size_t alen ;
/* ---------------------------------------------------------------------- */
/* check inputs */
/* ---------------------------------------------------------------------- */
RETURN_IF_NULL_COMMON (FALSE) ;
RETURN_IF_NULL (A, FALSE) ;
RETURN_IF_NULL (Perm, FALSE) ;
RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ;
if (A->stype != 0)
{
ERROR (CHOLMOD_INVALID, "matrix must be unsymmetric") ;
return (FALSE) ;
}
Common->status = CHOLMOD_OK ;
/* ---------------------------------------------------------------------- */
/* get inputs */
/* ---------------------------------------------------------------------- */
nrow = A->nrow ;
ncol = A->ncol ;
/* ---------------------------------------------------------------------- */
/* allocate workspace */
/* ---------------------------------------------------------------------- */
#ifdef LONG
alen = ccolamd_l_recommended (A->nzmax, ncol, nrow) ;
#else
alen = ccolamd_recommended (A->nzmax, ncol, nrow) ;
#endif
if (alen == 0)
{
ERROR (CHOLMOD_TOO_LARGE, "matrix invalid or too large") ;
return (FALSE) ;
}
CHOLMOD(allocate_work) (0, MAX (nrow,ncol), 0, Common) ;
if (Common->status < CHOLMOD_OK)
{
return (FALSE) ;
}
C = CHOLMOD(allocate_sparse) (ncol, nrow, alen, TRUE, TRUE, 0,
CHOLMOD_PATTERN, Common) ;
/* ---------------------------------------------------------------------- */
/* order with ccolamd */
/* ---------------------------------------------------------------------- */
ok = ccolamd_interface (A, alen, Perm, Cmember, fset, fsize, C, Common) ;
/* ---------------------------------------------------------------------- */
/* free the workspace and return result */
/* ---------------------------------------------------------------------- */
CHOLMOD(free_sparse) (&C, Common) ;
return (ok) ;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1