Amesos Package Browser (Single Doxygen Collection)  Development
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_cholmod_l_band.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Core/cholmod_band ==================================================== */
3 /* ========================================================================== */
4 
5 /* -----------------------------------------------------------------------------
6  * CHOLMOD/Core Module. Copyright (C) 2005-2006,
7  * Univ. of Florida. Author: Timothy A. Davis
8  * The CHOLMOD/Core Module is licensed under Version 2.1 of the GNU
9  * Lesser General Public License. See lesser.txt for a text of the license.
10  * CHOLMOD is also available under other licenses; contact authors for details.
11  * http://www.cise.ufl.edu/research/sparse
12  * -------------------------------------------------------------------------- */
13 
14 /* C = tril (triu (A,k1), k2)
15  *
16  * C is a matrix consisting of the diagonals of A from k1 to k2.
17  *
18  * k=0 is the main diagonal of A, k=1 is the superdiagonal, k=-1 is the
19  * subdiagonal, and so on. If A is m-by-n, then:
20  *
21  * k1=-m C = tril (A,k2)
22  * k2=n C = triu (A,k1)
23  * k1=0 and k2=0 C = diag(A), except C is a matrix, not a vector
24  *
25  * Values of k1 and k2 less than -m are treated as -m, and values greater
26  * than n are treated as n.
27  *
28  * A can be of any symmetry (upper, lower, or unsymmetric); C is returned in
29  * the same form, and packed. If A->stype > 0, entries in the lower
30  * triangular part of A are ignored, and the opposite is true if
31  * A->stype < 0. If A has sorted columns, then so does C.
32  * C has the same size as A.
33  *
34  * If inplace is TRUE, then the matrix A is modified in place.
35  * Only packed matrices can be converted in place.
36  *
37  * C can be returned as a numerical valued matrix (if A has numerical values
38  * and mode > 0), as a pattern-only (mode == 0), or as a pattern-only but with
39  * the diagonal entries removed (mode < 0).
40  *
41  * workspace: none
42  *
43  * A can have an xtype of pattern or real. Complex and zomplex cases supported
44  * only if mode <= 0 (in which case the numerical values are ignored).
45  */
46 
47 /* This file should make the long int version of CHOLMOD */
48 #define DLONG 1
49 
51 #include "amesos_cholmod_core.h"
52 
53 static cholmod_sparse *band /* returns C, or NULL if failure */
54 (
55  /* ---- input or in/out if inplace is TRUE --- */
57  /* ---- input ---- */
58  UF_long k1, /* ignore entries below the k1-st diagonal */
59  UF_long k2, /* ignore entries above the k2-nd diagonal */
60  int mode, /* >0: numerical, 0: pattern, <0: pattern (no diagonal) */
61  int inplace, /* if TRUE, then convert A in place */
62  /* --------------- */
63  cholmod_common *Common
64 )
65 {
66  double *Ax, *Cx ;
67  Int packed, nz, j, p, pend, i, ncol, nrow, jlo, jhi, ilo, ihi, sorted,
68  values, diag ;
69  Int *Ap, *Anz, *Ai, *Cp, *Ci ;
70  cholmod_sparse *C ;
71 
72  /* ---------------------------------------------------------------------- */
73  /* check inputs */
74  /* ---------------------------------------------------------------------- */
75 
77  RETURN_IF_NULL (A, NULL) ;
78  values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ;
80  values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ;
81  packed = A->packed ;
82  diag = (mode >= 0) ;
83  if (inplace && !packed)
84  {
85  /* cannot operate on an unpacked matrix in place */
86  ERROR (CHOLMOD_INVALID, "cannot operate on unpacked matrix in-place") ;
87  return (NULL) ;
88  }
89  Common->status = CHOLMOD_OK ;
90 
91  /* ---------------------------------------------------------------------- */
92  /* get inputs */
93  /* ---------------------------------------------------------------------- */
94 
95 
96  PRINT1 (("k1 %ld k2 %ld\n", k1, k2)) ;
97  Ap = A->p ;
98  Anz = A->nz ;
99  Ai = A->i ;
100  Ax = A->x ;
101  sorted = A->sorted ;
102 
103 
104  if (A->stype > 0)
105  {
106  /* ignore any entries in strictly lower triangular part of A */
107  k1 = MAX (k1, 0) ;
108  }
109  if (A->stype < 0)
110  {
111  /* ignore any entries in strictly upper triangular part of A */
112  k2 = MIN (k2, 0) ;
113  }
114  ncol = A->ncol ;
115  nrow = A->nrow ;
116 
117  /* ensure k1 and k2 are in the range -nrow to +ncol to
118  * avoid possible integer overflow if k1 and k2 are huge */
119  k1 = MAX (-nrow, k1) ;
120  k1 = MIN (k1, ncol) ;
121  k2 = MAX (-nrow, k2) ;
122  k2 = MIN (k2, ncol) ;
123 
124  /* consider columns jlo to jhi. columns outside this range are empty */
125  jlo = MAX (k1, 0) ;
126  jhi = MIN (k2+nrow, ncol) ;
127 
128  if (k1 > k2)
129  {
130  /* nothing to do */
131  jlo = ncol ;
132  jhi = ncol ;
133  }
134 
135  /* ---------------------------------------------------------------------- */
136  /* allocate C, or operate on A in place */
137  /* ---------------------------------------------------------------------- */
138 
139  if (inplace)
140  {
141  /* convert A in place */
142  C = A ;
143  }
144  else
145  {
146  /* count the number of entries in the result C */
147  nz = 0 ;
148  if (sorted)
149  {
150  for (j = jlo ; j < jhi ; j++)
151  {
152  ilo = j-k2 ;
153  ihi = j-k1 ;
154  p = Ap [j] ;
155  pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
156  for ( ; p < pend ; p++)
157  {
158  i = Ai [p] ;
159  if (i > ihi)
160  {
161  break ;
162  }
163  if (i >= ilo && (diag || i != j))
164  {
165  nz++ ;
166  }
167  }
168  }
169  }
170  else
171  {
172  for (j = jlo ; j < jhi ; j++)
173  {
174  ilo = j-k2 ;
175  ihi = j-k1 ;
176  p = Ap [j] ;
177  pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
178  for ( ; p < pend ; p++)
179  {
180  i = Ai [p] ;
181  if (i >= ilo && i <= ihi && (diag || i != j))
182  {
183  nz++ ;
184  }
185  }
186  }
187  }
188  /* allocate C; A will not be modified. C is sorted if A is sorted */
189  C = CHOLMOD(allocate_sparse) (A->nrow, ncol, nz, sorted, TRUE,
190  A->stype, values ? A->xtype : CHOLMOD_PATTERN, Common) ;
191  if (Common->status < CHOLMOD_OK)
192  {
193  return (NULL) ; /* out of memory */
194  }
195  }
196 
197  Cp = C->p ;
198  Ci = C->i ;
199  Cx = C->x ;
200 
201  /* ---------------------------------------------------------------------- */
202  /* construct C */
203  /* ---------------------------------------------------------------------- */
204 
205  /* columns 0 to jlo-1 are empty */
206  for (j = 0 ; j < jlo ; j++)
207  {
208  Cp [j] = 0 ;
209  }
210 
211  nz = 0 ;
212  if (sorted)
213  {
214  if (values)
215  {
216  /* pattern and values */
217  ASSERT (diag) ;
218  for (j = jlo ; j < jhi ; j++)
219  {
220  ilo = j-k2 ;
221  ihi = j-k1 ;
222  p = Ap [j] ;
223  pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
224  Cp [j] = nz ;
225  for ( ; p < pend ; p++)
226  {
227  i = Ai [p] ;
228  if (i > ihi)
229  {
230  break ;
231  }
232  if (i >= ilo)
233  {
234  Ci [nz] = i ;
235  Cx [nz] = Ax [p] ;
236  nz++ ;
237  }
238  }
239  }
240  }
241  else
242  {
243  /* pattern only, perhaps with no diagonal */
244  for (j = jlo ; j < jhi ; j++)
245  {
246  ilo = j-k2 ;
247  ihi = j-k1 ;
248  p = Ap [j] ;
249  pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
250  Cp [j] = nz ;
251  for ( ; p < pend ; p++)
252  {
253  i = Ai [p] ;
254  if (i > ihi)
255  {
256  break ;
257  }
258  if (i >= ilo && (diag || i != j))
259  {
260  Ci [nz++] = i ;
261  }
262  }
263  }
264  }
265  }
266  else
267  {
268  if (values)
269  {
270  /* pattern and values */
271  ASSERT (diag) ;
272  for (j = jlo ; j < jhi ; j++)
273  {
274  ilo = j-k2 ;
275  ihi = j-k1 ;
276  p = Ap [j] ;
277  pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
278  Cp [j] = nz ;
279  for ( ; p < pend ; p++)
280  {
281  i = Ai [p] ;
282  if (i >= ilo && i <= ihi)
283  {
284  Ci [nz] = i ;
285  Cx [nz] = Ax [p] ;
286  nz++ ;
287  }
288  }
289  }
290  }
291  else
292  {
293  /* pattern only, perhaps with no diagonal */
294  for (j = jlo ; j < jhi ; j++)
295  {
296  ilo = j-k2 ;
297  ihi = j-k1 ;
298  p = Ap [j] ;
299  pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
300  Cp [j] = nz ;
301  for ( ; p < pend ; p++)
302  {
303  i = Ai [p] ;
304  if (i >= ilo && i <= ihi && (diag || i != j))
305  {
306  Ci [nz++] = i ;
307  }
308  }
309  }
310  }
311  }
312 
313  /* columns jhi to ncol-1 are empty */
314  for (j = jhi ; j <= ncol ; j++)
315  {
316  Cp [j] = nz ;
317  }
318 
319  /* ---------------------------------------------------------------------- */
320  /* reduce A in size if done in place */
321  /* ---------------------------------------------------------------------- */
322 
323  if (inplace)
324  {
325  /* free the unused parts of A, and reduce A->i and A->x in size */
326  ASSERT (MAX (1,nz) <= A->nzmax) ;
327  CHOLMOD(reallocate_sparse) (nz, A, Common) ;
328  ASSERT (Common->status >= CHOLMOD_OK) ;
329  }
330 
331  /* ---------------------------------------------------------------------- */
332  /* return the result C */
333  /* ---------------------------------------------------------------------- */
334 
335  DEBUG (i = CHOLMOD(dump_sparse) (C, "band", Common)) ;
336  ASSERT (IMPLIES (mode < 0, i == 0)) ;
337  return (C) ;
338 }
339 
340 
341 /* ========================================================================== */
342 /* === cholmod_band ========================================================= */
343 /* ========================================================================== */
344 
346 (
347  /* ---- input ---- */
348  cholmod_sparse *A, /* matrix to extract band matrix from */
349  UF_long k1, /* ignore entries below the k1-st diagonal */
350  UF_long k2, /* ignore entries above the k2-nd diagonal */
351  int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */
352  /* --------------- */
353  cholmod_common *Common
354 )
355 {
356  return (band (A, k1, k2, mode, FALSE, Common)) ;
357 }
358 
359 
360 /* ========================================================================== */
361 /* === cholmod_band_inplace ================================================= */
362 /* ========================================================================== */
363 
365 (
366  /* ---- input ---- */
367  UF_long k1, /* ignore entries below the k1-st diagonal */
368  UF_long k2, /* ignore entries above the k2-nd diagonal */
369  int mode, /* >0: numerical, 0: pattern, <0: pattern (no diag) */
370  /* ---- in/out --- */
371  cholmod_sparse *A, /* matrix from which entries not in band are removed */
372  /* --------------- */
373  cholmod_common *Common
374 )
375 {
376  return (band (A, k1, k2, mode, TRUE, Common) != NULL) ;
377 }
static cholmod_sparse * band(cholmod_sparse *A, UF_long k1, UF_long k2, int mode, int inplace, cholmod_common *Common)
#define Int
#define FALSE
#define PRINT1(params)
int CHOLMOD() band_inplace(UF_long k1, UF_long k2, int mode, cholmod_sparse *A, cholmod_common *Common)
int CHOLMOD() reallocate_sparse(size_t nznew, cholmod_sparse *A, cholmod_common *Common)
#define RETURN_IF_NULL_COMMON(result)
#define CHOLMOD_PATTERN
#define CHOLMOD(name)
#define MAX(a, b)
#define CHOLMOD_REAL
#define NULL
#define ASSERT(expression)
#define CHOLMOD_INVALID
#define CHOLMOD_OK
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)
#define RETURN_IF_NULL(A, result)
#define DEBUG(statement)
#define MIN(a, b)
#define UF_long
#define IMPLIES(p, q)
#define ERROR(status, msg)
#define TRUE
#define RETURN_IF_XTYPE_INVALID(A, xtype1, xtype2, result)
#define CHOLMOD_ZOMPLEX