Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_cholmod_l_colamd.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Cholesky/cholmod_colamd ============================================== */
3 /* ========================================================================== */
4 
5 /* -----------------------------------------------------------------------------
6  * CHOLMOD/Cholesky Module. Copyright (C) 2005-2006, Timothy A. Davis
7  * The CHOLMOD/Cholesky Module is licensed under Version 2.1 of the GNU
8  * Lesser General Public License. See lesser.txt for a text of the license.
9  * CHOLMOD is also available under other licenses; contact authors for details.
10  * http://www.cise.ufl.edu/research/sparse
11  * -------------------------------------------------------------------------- */
12 
13 /* CHOLMOD interface to the COLAMD ordering routine (version 2.4 or later).
14  * Finds a permutation p such that the Cholesky factorization of PAA'P' is
15  * sparser than AA' using colamd. If the postorder input parameter is TRUE,
16  * the column etree is found and postordered, and the colamd ordering is then
17  * combined with its postordering. A must be unsymmetric.
18  *
19  * There can be no duplicate entries in f.
20  * f can be length 0 to n if A is m-by-n.
21  *
22  * workspace: Iwork (4*nrow+ncol), Head (nrow+1), Flag (nrow)
23  * Allocates a copy of its input matrix, which
24  * is then used as CCOLAMD's workspace.
25  *
26  * Supports any xtype (pattern, real, complex, or zomplex)
27  */
28 
29 #ifndef NCHOLESKY
30 
31 /* This file should make the long int version of CHOLMOD */
32 #define DLONG 1
33 
35 #include "amesos_colamd.h"
37 
38 #if (!defined (COLAMD_VERSION) || (COLAMD_VERSION < COLAMD_VERSION_CODE (2,5)))
39 #error "COLAMD v2.5 or later is required"
40 #endif
41 
42 /* ========================================================================== */
43 /* === cholmod_colamd ======================================================= */
44 /* ========================================================================== */
45 
46 int CHOLMOD(colamd)
47 (
48  /* ---- input ---- */
49  cholmod_sparse *A, /* matrix to order */
50  Int *fset, /* subset of 0:(A->ncol)-1 */
51  size_t fsize, /* size of fset */
52  int postorder, /* if TRUE, follow with a coletree postorder */
53  /* ---- output --- */
54  Int *Perm, /* size A->nrow, output permutation */
55  /* --------------- */
56  cholmod_common *Common
57 )
58 {
59  double knobs [COLAMD_KNOBS] ;
60  cholmod_sparse *C ;
61  Int *NewPerm, *Parent, *Post, *Work2n ;
62  Int k, nrow, ncol ;
63  size_t s, alen ;
64  int ok = TRUE ;
65 
66  /* ---------------------------------------------------------------------- */
67  /* check inputs */
68  /* ---------------------------------------------------------------------- */
69 
71  RETURN_IF_NULL (A, FALSE) ;
72  RETURN_IF_NULL (Perm, FALSE) ;
74  if (A->stype != 0)
75  {
76  ERROR (CHOLMOD_INVALID, "matrix must be unsymmetric") ;
77  return (FALSE) ;
78  }
79  Common->status = CHOLMOD_OK ;
80 
81  /* ---------------------------------------------------------------------- */
82  /* get inputs */
83  /* ---------------------------------------------------------------------- */
84 
85  nrow = A->nrow ;
86  ncol = A->ncol ;
87 
88  /* ---------------------------------------------------------------------- */
89  /* allocate workspace */
90  /* ---------------------------------------------------------------------- */
91 
92  /* Note: this is less than the space used in cholmod_analyze, so if
93  * cholmod_colamd is being called by that routine, no space will be
94  * allocated.
95  */
96 
97  /* s = 4*nrow + ncol */
98  s = CHOLMOD(mult_size_t) (nrow, 4, &ok) ;
99  s = CHOLMOD(add_size_t) (s, ncol, &ok) ;
100 
101 #ifdef LONG
102  alen = amesos_colamd_l_recommended (A->nzmax, ncol, nrow) ;
104 #else
105  alen = amesos_colamd_recommended (A->nzmax, ncol, nrow) ;
107 #endif
108 
109  if (!ok || alen == 0)
110  {
111  ERROR (CHOLMOD_TOO_LARGE, "matrix invalid or too large") ;
112  return (FALSE) ;
113  }
114 
115  CHOLMOD(allocate_work) (0, s, 0, Common) ;
116  if (Common->status < CHOLMOD_OK)
117  {
118  return (FALSE) ;
119  }
120 
121  /* ---------------------------------------------------------------------- */
122  /* allocate COLAMD workspace */
123  /* ---------------------------------------------------------------------- */
124 
125  /* colamd_printf is only available in colamd v2.4 or later */
126  amesos_colamd_printf = Common->print_function ;
127 
128  C = CHOLMOD(allocate_sparse) (ncol, nrow, alen, TRUE, TRUE, 0,
129  CHOLMOD_PATTERN, Common) ;
130 
131  /* ---------------------------------------------------------------------- */
132  /* copy (and transpose) the input matrix A into the colamd workspace */
133  /* ---------------------------------------------------------------------- */
134 
135  /* C = A (:,f)', which also packs A if needed. */
136  /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset) */
137  ok = CHOLMOD(transpose_unsym) (A, 0, NULL, fset, fsize, C, Common) ;
138 
139  /* ---------------------------------------------------------------------- */
140  /* order the matrix (destroys the contents of C->i and C->p) */
141  /* ---------------------------------------------------------------------- */
142 
143  /* get parameters */
144  if (Common->current < 0 || Common->current >= CHOLMOD_MAXMETHODS)
145  {
146  /* this is the CHOLMOD default, not the COLAMD default */
147  knobs [COLAMD_DENSE_ROW] = -1 ;
148  }
149  else
150  {
151  /* get the knobs from the Common parameters */
152  knobs [COLAMD_DENSE_COL] = Common->method[Common->current].prune_dense ;
153  knobs [COLAMD_DENSE_ROW] = Common->method[Common->current].prune_dense2;
154  knobs [COLAMD_AGGRESSIVE] = Common->method[Common->current].aggressive ;
155  }
156 
157  if (ok)
158  {
159  Int *Cp ;
160  Int stats [COLAMD_STATS] ;
161  Cp = C->p ;
162 
163 #ifdef LONG
164  amesos_colamd_l (ncol, nrow, alen, C->i, Cp, knobs, stats) ;
165 #else
166  amesos_colamd (ncol, nrow, alen, C->i, Cp, knobs, stats) ;
167 #endif
168 
169  ok = stats [COLAMD_STATUS] ;
170  ok = (ok == COLAMD_OK || ok == COLAMD_OK_BUT_JUMBLED) ;
171  /* permutation returned in C->p, if the ordering succeeded */
172  for (k = 0 ; k < nrow ; k++)
173  {
174  Perm [k] = Cp [k] ;
175  }
176  }
177 
178  CHOLMOD(free_sparse) (&C, Common) ;
179 
180  /* ---------------------------------------------------------------------- */
181  /* column etree postordering */
182  /* ---------------------------------------------------------------------- */
183 
184  if (postorder)
185  {
186  /* use the last 2*n space in Iwork for Parent and Post */
187  Work2n = Common->Iwork ;
188  Work2n += 2*((size_t) nrow) + ncol ;
189  Parent = Work2n ; /* size nrow (i/i/l) */
190  Post = Work2n + nrow ; /* size nrow (i/i/l) */
191 
192  /* workspace: Iwork (2*nrow+ncol), Flag (nrow), Head (nrow+1) */
193  ok = ok && CHOLMOD(analyze_ordering) (A, CHOLMOD_COLAMD, Perm, fset,
194  fsize, Parent, Post, NULL, NULL, NULL, Common) ;
195 
196  /* combine the colamd permutation with its postordering */
197  if (ok)
198  {
199  NewPerm = Common->Iwork ; /* size nrow (i/i/l) */
200  for (k = 0 ; k < nrow ; k++)
201  {
202  NewPerm [k] = Perm [Post [k]] ;
203  }
204  for (k = 0 ; k < nrow ; k++)
205  {
206  Perm [k] = NewPerm [k] ;
207  }
208  }
209  }
210 
211  return (ok) ;
212 }
213 #endif
#define CHOLMOD_TOO_LARGE
int CHOLMOD() transpose_unsym(cholmod_sparse *A, int values, Int *Perm, Int *fset, size_t fsize, cholmod_sparse *F, cholmod_common *Common)
#define Int
size_t CHOLMOD() add_size_t(size_t a, size_t b, int *ok)
#define COLAMD_KNOBS
Definition: amesos_colamd.h:97
#define FALSE
UF_long amesos_colamd_l(UF_long n_row, UF_long n_col, UF_long Alen, UF_long A[], UF_long p[], double knobs[COLAMD_KNOBS], UF_long stats[COLAMD_STATS])
#define RETURN_IF_NULL_COMMON(result)
int CHOLMOD() colamd(cholmod_sparse *A, Int *fset, size_t fsize, int postorder, Int *Perm, cholmod_common *Common)
size_t CHOLMOD() mult_size_t(size_t a, size_t k, int *ok)
#define COLAMD_STATUS
#define CHOLMOD_PATTERN
#define CHOLMOD(name)
#define COLAMD_OK_BUT_JUMBLED
#define COLAMD_AGGRESSIVE
int CHOLMOD() free_sparse(cholmod_sparse **AHandle, cholmod_common *Common)
#define NULL
size_t amesos_colamd_l_recommended(UF_long nnz, UF_long n_row, UF_long n_col)
#define COLAMD_OK
#define COLAMD_STATS
#define CHOLMOD_INVALID
#define CHOLMOD_OK
EXTERN int(* amesos_colamd_printf)(const char *,...)
int amesos_colamd(int n_row, int n_col, int Alen, int A[], int p[], double knobs[COLAMD_KNOBS], int stats[COLAMD_STATS])
void amesos_colamd_l_set_defaults(double knobs[COLAMD_KNOBS])
size_t amesos_colamd_recommended(int nnz, int n_row, int n_col)
cholmod_sparse *CHOLMOD() allocate_sparse(size_t nrow, size_t ncol, size_t nzmax, int sorted, int packed, int stype, int xtype, cholmod_common *Common)
int CHOLMOD() allocate_work(size_t nrow, size_t iworksize, size_t xworksize, cholmod_common *Common)
#define CHOLMOD_MAXMETHODS
#define COLAMD_DENSE_ROW
int CHOLMOD() analyze_ordering(cholmod_sparse *A, int ordering, Int *Perm, Int *fset, size_t fsize, Int *Parent, Int *Post, Int *ColCount, Int *First, Int *Level, cholmod_common *Common)
#define RETURN_IF_NULL(A, result)
#define CHOLMOD_COLAMD
#define ERROR(status, msg)
#define TRUE
#define RETURN_IF_XTYPE_INVALID(A, xtype1, xtype2, result)
#define CHOLMOD_ZOMPLEX
#define COLAMD_DENSE_COL
void amesos_colamd_set_defaults(double knobs[COLAMD_KNOBS])