Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_cholmod_l_sparse.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Core/cholmod_sparse ================================================== */
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 /* Core utility routines for the cholmod_sparse object:
15  *
16  * A sparse matrix is held in compressed column form. In the basic type
17  * ("packed", which corresponds to a MATLAB sparse matrix), an n-by-n matrix
18  * with nz entries is held in three arrays: p of size n+1, i of size nz, and x
19  * of size nz. Row indices of column j are held in i [p [j] ... p [j+1]-1] and
20  * in the same locations in x. There may be no duplicate entries in a column.
21  * Row indices in each column may be sorted or unsorted (CHOLMOD keeps track).
22  *
23  * Primary routines:
24  * -----------------
25  * cholmod_allocate_sparse allocate a sparse matrix
26  * cholmod_free_sparse free a sparse matrix
27  *
28  * Secondary routines:
29  * -------------------
30  * cholmod_reallocate_sparse change the size (# entries) of sparse matrix
31  * cholmod_nnz number of nonzeros in a sparse matrix
32  * cholmod_speye sparse identity matrix
33  * cholmod_spzeros sparse zero matrix
34  * cholmod_copy_sparse create a copy of a sparse matrix
35  *
36  * All xtypes are supported (pattern, real, complex, and zomplex)
37  */
38 
39 /* This file should make the long int version of CHOLMOD */
40 #define DLONG 1
41 
43 #include "amesos_cholmod_core.h"
44 
45 
46 /* ========================================================================== */
47 /* === cholmod_allocate_sparse ============================================== */
48 /* ========================================================================== */
49 
50 /* Allocate space for a matrix. A->i and A->x are not initialized. A->p
51  * (and A->nz if A is not packed) are set to zero, so a matrix containing no
52  * entries (all zero) is returned. See also cholmod_spzeros.
53  *
54  * workspace: none
55  */
56 
58 (
59  /* ---- input ---- */
60  size_t nrow, /* # of rows of A */
61  size_t ncol, /* # of columns of A */
62  size_t nzmax, /* max # of nonzeros of A */
63  int sorted, /* TRUE if columns of A sorted, FALSE otherwise */
64  int packed, /* TRUE if A will be packed, FALSE otherwise */
65  int stype, /* stype of A */
66  int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */
67  /* --------------- */
68  cholmod_common *Common
69 )
70 {
71  cholmod_sparse *A ;
72  Int *Ap, *Anz ;
73  size_t nzmax0 ;
74  Int j ;
75  int ok = TRUE ;
76 
77  /* ---------------------------------------------------------------------- */
78  /* get inputs */
79  /* ---------------------------------------------------------------------- */
80 
82  if (stype != 0 && nrow != ncol)
83  {
84  ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ;
85  return (NULL) ;
86  }
87  if (xtype < CHOLMOD_PATTERN || xtype > CHOLMOD_ZOMPLEX)
88  {
89  ERROR (CHOLMOD_INVALID, "xtype invalid") ;
90  return (NULL) ;
91  }
92  /* ensure the dimensions do not cause integer overflow */
93  (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ;
94  if (!ok || nrow > Int_max || ncol > Int_max || nzmax > Int_max)
95  {
96  ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
97  return (NULL) ;
98  }
99  Common->status = CHOLMOD_OK ;
100 
101  /* ---------------------------------------------------------------------- */
102  /* allocate header */
103  /* ---------------------------------------------------------------------- */
104 
105  A = CHOLMOD(malloc) (sizeof (cholmod_sparse), 1, Common) ;
106  if (Common->status < CHOLMOD_OK)
107  {
108  return (NULL) ; /* out of memory */
109  }
110  PRINT1 (("cholmod_allocate_sparse %d-by-%d nzmax %d sorted %d packed %d"
111  " xtype %d\n", nrow, ncol, nzmax, sorted, packed, xtype)) ;
112 
113  nzmax = MAX (1, nzmax) ;
114 
115  A->nrow = nrow ;
116  A->ncol = ncol ;
117  A->nzmax = nzmax ;
118  A->packed = packed ; /* default is packed (A->nz not present) */
119  A->stype = stype ;
120  A->itype = ITYPE ;
121  A->xtype = xtype ;
122  A->dtype = DTYPE ;
123 
124  A->nz = NULL ;
125  A->p = NULL ;
126  A->i = NULL ;
127  A->x = NULL ;
128  A->z = NULL ;
129 
130  /* A 1-by-m matrix always has sorted columns */
131  A->sorted = (nrow <= 1) ? TRUE : sorted ;
132 
133  /* ---------------------------------------------------------------------- */
134  /* allocate the matrix itself */
135  /* ---------------------------------------------------------------------- */
136 
137  /* allocate O(ncol) space */
138  A->p = CHOLMOD(malloc) (((size_t) ncol)+1, sizeof (Int), Common) ;
139  if (!packed)
140  {
141  A->nz = CHOLMOD(malloc) (ncol, sizeof (Int), Common) ;
142  }
143 
144  /* allocate O(nz) space */
145  nzmax0 = 0 ;
146  CHOLMOD(realloc_multiple) (nzmax, 1, xtype, &(A->i), NULL, &(A->x), &(A->z),
147  &nzmax0, Common) ;
148 
149  if (Common->status < CHOLMOD_OK)
150  {
151  CHOLMOD(free_sparse) (&A, Common) ;
152  return (NULL) ; /* out of memory */
153  }
154 
155  /* ---------------------------------------------------------------------- */
156  /* initialize A->p and A->nz so that A is an empty matrix */
157  /* ---------------------------------------------------------------------- */
158 
159  Ap = A->p ;
160  for (j = 0 ; j <= (Int) ncol ; j++)
161  {
162  Ap [j] = 0 ;
163  }
164  if (!packed)
165  {
166  Anz = A->nz ;
167  for (j = 0 ; j < (Int) ncol ; j++)
168  {
169  Anz [j] = 0 ;
170  }
171  }
172  return (A) ;
173 }
174 
175 
176 /* ========================================================================== */
177 /* === cholmod_free_sparse ================================================== */
178 /* ========================================================================== */
179 
180 /* free a sparse matrix
181  *
182  * workspace: none
183  */
184 
185 int CHOLMOD(free_sparse)
186 (
187  /* ---- in/out --- */
188  cholmod_sparse **AHandle, /* matrix to deallocate, NULL on output */
189  /* --------------- */
190  cholmod_common *Common
191 )
192 {
193  Int n, nz ;
194  cholmod_sparse *A ;
195 
197 
198  if (AHandle == NULL)
199  {
200  /* nothing to do */
201  return (TRUE) ;
202  }
203  A = *AHandle ;
204  if (A == NULL)
205  {
206  /* nothing to do */
207  return (TRUE) ;
208  }
209  n = A->ncol ;
210  nz = A->nzmax ;
211  A->p = CHOLMOD(free) (n+1, sizeof (Int), A->p, Common) ;
212  A->i = CHOLMOD(free) (nz, sizeof (Int), A->i, Common) ;
213  A->nz = CHOLMOD(free) (n, sizeof (Int), A->nz, Common) ;
214 
215  switch (A->xtype)
216  {
217  case CHOLMOD_REAL:
218  A->x = CHOLMOD(free) (nz, sizeof (double), A->x, Common) ;
219  break ;
220 
221  case CHOLMOD_COMPLEX:
222  A->x = CHOLMOD(free) (nz, 2*sizeof (double), A->x, Common) ;
223  break ;
224 
225  case CHOLMOD_ZOMPLEX:
226  A->x = CHOLMOD(free) (nz, sizeof (double), A->x, Common) ;
227  A->z = CHOLMOD(free) (nz, sizeof (double), A->z, Common) ;
228  break ;
229  }
230 
231  *AHandle = CHOLMOD(free) (1, sizeof (cholmod_sparse), (*AHandle), Common) ;
232  return (TRUE) ;
233 }
234 
235 
236 /* ========================================================================== */
237 /* === cholmod_reallocate_sparse ============================================ */
238 /* ========================================================================== */
239 
240 /* Change the size of A->i, A->x, and A->z, or allocate them if their current
241  * size is zero. A->x and A->z are not modified if A->xtype is CHOLMOD_PATTERN.
242  * A->z is not modified unless A->xtype is CHOLMOD_ZOMPLEX.
243  *
244  * workspace: none
245  */
246 
248 (
249  /* ---- input ---- */
250  size_t nznew, /* new # of entries in A */
251  /* ---- in/out --- */
252  cholmod_sparse *A, /* matrix to reallocate */
253  /* --------------- */
254  cholmod_common *Common
255 )
256 {
257 
258  /* ---------------------------------------------------------------------- */
259  /* get inputs */
260  /* ---------------------------------------------------------------------- */
261 
263  RETURN_IF_NULL (A, FALSE) ;
265  Common->status = CHOLMOD_OK ;
266  PRINT1 (("realloc matrix %d to %d, xtype: %d\n",
267  A->nzmax, nznew, A->xtype)) ;
268 
269  /* ---------------------------------------------------------------------- */
270  /* resize the matrix */
271  /* ---------------------------------------------------------------------- */
272 
273  CHOLMOD(realloc_multiple) (MAX (1,nznew), 1, A->xtype, &(A->i), NULL,
274  &(A->x), &(A->z), &(A->nzmax), Common) ;
275 
276  return (Common->status == CHOLMOD_OK) ;
277 }
278 
279 
280 /* ========================================================================== */
281 /* === cholmod_speye ======================================================== */
282 /* ========================================================================== */
283 
284 /* Return a sparse identity matrix. */
285 
287 (
288  /* ---- input ---- */
289  size_t nrow, /* # of rows of A */
290  size_t ncol, /* # of columns of A */
291  int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */
292  /* --------------- */
293  cholmod_common *Common
294 )
295 {
296  double *Ax, *Az ;
297  cholmod_sparse *A ;
298  Int *Ap, *Ai ;
299  Int j, n ;
300 
301  /* ---------------------------------------------------------------------- */
302  /* get inputs */
303  /* ---------------------------------------------------------------------- */
304 
306  Common->status = CHOLMOD_OK ;
307 
308  /* ---------------------------------------------------------------------- */
309  /* allocate the matrix */
310  /* ---------------------------------------------------------------------- */
311 
312  n = MIN (nrow, ncol) ;
313  A = CHOLMOD(allocate_sparse) (nrow, ncol, n, TRUE, TRUE, 0, xtype,
314  Common) ;
315 
316  if (Common->status < CHOLMOD_OK)
317  {
318  return (NULL) ; /* out of memory or inputs invalid */
319  }
320 
321  /* ---------------------------------------------------------------------- */
322  /* create the identity matrix */
323  /* ---------------------------------------------------------------------- */
324 
325  Ap = A->p ;
326  Ai = A->i ;
327  Ax = A->x ;
328  Az = A->z ;
329 
330  for (j = 0 ; j < n ; j++)
331  {
332  Ap [j] = j ;
333  }
334  for (j = n ; j <= ((Int) ncol) ; j++)
335  {
336  Ap [j] = n ;
337  }
338  for (j = 0 ; j < n ; j++)
339  {
340  Ai [j] = j ;
341  }
342 
343  switch (xtype)
344  {
345  case CHOLMOD_REAL:
346  for (j = 0 ; j < n ; j++)
347  {
348  Ax [j] = 1 ;
349  }
350  break ;
351 
352  case CHOLMOD_COMPLEX:
353  for (j = 0 ; j < n ; j++)
354  {
355  Ax [2*j ] = 1 ;
356  Ax [2*j+1] = 0 ;
357  }
358  break ;
359 
360  case CHOLMOD_ZOMPLEX:
361  for (j = 0 ; j < n ; j++)
362  {
363  Ax [j] = 1 ;
364  }
365  for (j = 0 ; j < n ; j++)
366  {
367  Az [j] = 0 ;
368  }
369  break ;
370  }
371 
372  return (A) ;
373 }
374 
375 
376 /* ========================================================================== */
377 /* === cholmod_spzeros ====================================================== */
378 /* ========================================================================== */
379 
380 /* Return a sparse zero matrix. */
381 
383 (
384  /* ---- input ---- */
385  size_t nrow, /* # of rows of A */
386  size_t ncol, /* # of columns of A */
387  size_t nzmax, /* max # of nonzeros of A */
388  int xtype, /* CHOLMOD_PATTERN, _REAL, _COMPLEX, or _ZOMPLEX */
389  /* --------------- */
390  cholmod_common *Common
391 )
392 {
393 
394  /* ---------------------------------------------------------------------- */
395  /* get inputs */
396  /* ---------------------------------------------------------------------- */
397 
399  Common->status = CHOLMOD_OK ;
400 
401  /* ---------------------------------------------------------------------- */
402  /* allocate the matrix */
403  /* ---------------------------------------------------------------------- */
404 
405  return (CHOLMOD(allocate_sparse) (nrow, ncol, nzmax, TRUE, TRUE, 0, xtype,
406  Common)) ;
407 }
408 
409 
410 /* ========================================================================== */
411 /* === cholmod_nnz ========================================================== */
412 /* ========================================================================== */
413 
414 /* Return the number of entries in a sparse matrix.
415  *
416  * workspace: none
417  * integer overflow cannot occur, since the matrix is already allocated.
418  */
419 
421 (
422  /* ---- input ---- */
423  cholmod_sparse *A,
424  /* --------------- */
425  cholmod_common *Common
426 )
427 {
428  Int *Ap, *Anz ;
429  size_t nz ;
430  Int j, ncol ;
431 
432  /* ---------------------------------------------------------------------- */
433  /* get inputs */
434  /* ---------------------------------------------------------------------- */
435 
437  RETURN_IF_NULL (A, EMPTY) ;
439  Common->status = CHOLMOD_OK ;
440 
441  /* ---------------------------------------------------------------------- */
442  /* return nnz (A) */
443  /* ---------------------------------------------------------------------- */
444 
445  ncol = A->ncol ;
446  if (A->packed)
447  {
448  Ap = A->p ;
449  RETURN_IF_NULL (Ap, EMPTY) ;
450  nz = Ap [ncol] ;
451  }
452  else
453  {
454  Anz = A->nz ;
455  RETURN_IF_NULL (Anz, EMPTY) ;
456  nz = 0 ;
457  for (j = 0 ; j < ncol ; j++)
458  {
459  nz += MAX (0, Anz [j]) ;
460  }
461  }
462  return (nz) ;
463 }
464 
465 
466 /* ========================================================================== */
467 /* === cholmod_copy_sparse ================================================== */
468 /* ========================================================================== */
469 
470 /* C = A. Create an exact copy of a sparse matrix, with one exception.
471  * Entries in unused space are not copied (they might not be initialized,
472  * and copying them would cause program checkers such as purify and
473  * valgrind to complain). The xtype of the resulting matrix C is the same as
474  * the xtype of the input matrix A.
475  *
476  * See also Core/cholmod_copy, which copies a matrix with possible changes
477  * in stype, presence of diagonal entries, pattern vs. numerical values,
478  * real and/or imaginary parts, and so on.
479  */
480 
482 (
483  /* ---- input ---- */
484  cholmod_sparse *A, /* matrix to copy */
485  /* --------------- */
486  cholmod_common *Common
487 )
488 {
489  double *Ax, *Cx, *Az, *Cz ;
490  Int *Ap, *Ai, *Anz, *Cp, *Ci, *Cnz ;
491  cholmod_sparse *C ;
492  Int p, pend, j, ncol, packed, nzmax, nz, xtype ;
493 
494  /* ---------------------------------------------------------------------- */
495  /* check inputs */
496  /* ---------------------------------------------------------------------- */
497 
499  RETURN_IF_NULL (A, NULL) ;
501  if (A->stype != 0 && A->nrow != A->ncol)
502  {
503  ERROR (CHOLMOD_INVALID, "rectangular matrix with stype != 0 invalid") ;
504  return (NULL) ;
505  }
506  Common->status = CHOLMOD_OK ;
507  ASSERT (CHOLMOD(dump_sparse) (A, "A original", Common) >= 0) ;
508 
509  /* ---------------------------------------------------------------------- */
510  /* get inputs */
511  /* ---------------------------------------------------------------------- */
512 
513  ncol = A->ncol ;
514  nzmax = A->nzmax ;
515  packed = A->packed ;
516  Ap = A->p ;
517  Ai = A->i ;
518  Ax = A->x ;
519  Az = A->z ;
520  Anz = A->nz ;
521  xtype = A->xtype ;
522 
523  /* ---------------------------------------------------------------------- */
524  /* allocate the copy */
525  /* ---------------------------------------------------------------------- */
526 
527  C = CHOLMOD(allocate_sparse) (A->nrow, A->ncol, A->nzmax, A->sorted,
528  A->packed, A->stype, A->xtype, Common) ;
529 
530  if (Common->status < CHOLMOD_OK)
531  {
532  return (NULL) ; /* out of memory */
533  }
534 
535  Cp = C->p ;
536  Ci = C->i ;
537  Cx = C->x ;
538  Cz = C->z ;
539  Cnz = C->nz ;
540 
541  /* ---------------------------------------------------------------------- */
542  /* copy the matrix */
543  /* ---------------------------------------------------------------------- */
544 
545  for (j = 0 ; j <= ncol ; j++)
546  {
547  Cp [j] = Ap [j] ;
548  }
549 
550  if (packed)
551  {
552  nz = Ap [ncol] ;
553  for (p = 0 ; p < nz ; p++)
554  {
555  Ci [p] = Ai [p] ;
556  }
557 
558  switch (xtype)
559  {
560  case CHOLMOD_REAL:
561  for (p = 0 ; p < nz ; p++)
562  {
563  Cx [p] = Ax [p] ;
564  }
565  break ;
566 
567  case CHOLMOD_COMPLEX:
568  for (p = 0 ; p < 2*nz ; p++)
569  {
570  Cx [p] = Ax [p] ;
571  }
572  break ;
573 
574  case CHOLMOD_ZOMPLEX:
575  for (p = 0 ; p < nz ; p++)
576  {
577  Cx [p] = Ax [p] ;
578  Cz [p] = Az [p] ;
579  }
580  break ;
581  }
582 
583  }
584  else
585  {
586 
587  for (j = 0 ; j < ncol ; j++)
588  {
589  Cnz [j] = Anz [j] ;
590  }
591 
592  switch (xtype)
593  {
594  case CHOLMOD_PATTERN:
595  for (j = 0 ; j < ncol ; j++)
596  {
597  p = Ap [j] ;
598  pend = p + Anz [j] ;
599  for ( ; p < pend ; p++)
600  {
601  Ci [p] = Ai [p] ;
602  }
603  }
604  break ;
605 
606  case CHOLMOD_REAL:
607  for (j = 0 ; j < ncol ; j++)
608  {
609  p = Ap [j] ;
610  pend = p + Anz [j] ;
611  for ( ; p < pend ; p++)
612  {
613  Ci [p] = Ai [p] ;
614  Cx [p] = Ax [p] ;
615  }
616  }
617  break ;
618 
619  case CHOLMOD_COMPLEX:
620  for (j = 0 ; j < ncol ; j++)
621  {
622  p = Ap [j] ;
623  pend = p + Anz [j] ;
624  for ( ; p < pend ; p++)
625  {
626  Ci [p] = Ai [p] ;
627  Cx [2*p ] = Ax [2*p ] ;
628  Cx [2*p+1] = Ax [2*p+1] ;
629  }
630  }
631  break ;
632 
633  case CHOLMOD_ZOMPLEX:
634  for (j = 0 ; j < ncol ; j++)
635  {
636  p = Ap [j] ;
637  pend = p + Anz [j] ;
638  for ( ; p < pend ; p++)
639  {
640  Ci [p] = Ai [p] ;
641  Cx [p] = Ax [p] ;
642  Cz [p] = Az [p] ;
643  }
644  }
645  break ;
646  }
647  }
648 
649  /* ---------------------------------------------------------------------- */
650  /* return the result */
651  /* ---------------------------------------------------------------------- */
652 
653  ASSERT (CHOLMOD(dump_sparse) (C, "C copy", Common) >= 0) ;
654  return (C) ;
655 }
#define CHOLMOD_TOO_LARGE
#define EMPTY
UF_long CHOLMOD() nnz(cholmod_sparse *A, cholmod_common *Common)
int CHOLMOD() realloc_multiple(size_t nnew, int nint, int xtype, void **I, void **J, void **X, void **Z, size_t *nold_p, cholmod_common *Common)
#define Int
size_t CHOLMOD() add_size_t(size_t a, size_t b, int *ok)
#define CHOLMOD_COMPLEX
#define FALSE
#define PRINT1(params)
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)
int CHOLMOD() free_sparse(cholmod_sparse **AHandle, cholmod_common *Common)
#define CHOLMOD_REAL
#define NULL
#define Int_max
#define ASSERT(expression)
cholmod_sparse *CHOLMOD() spzeros(size_t nrow, size_t ncol, size_t nzmax, int xtype, cholmod_common *Common)
cholmod_sparse *CHOLMOD() copy_sparse(cholmod_sparse *A, cholmod_common *Common)
#define DTYPE
#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)
struct cholmod_sparse_struct cholmod_sparse
#define RETURN_IF_NULL(A, result)
#define MIN(a, b)
cholmod_sparse *CHOLMOD() speye(size_t nrow, size_t ncol, int xtype, cholmod_common *Common)
#define UF_long
int n
#define ERROR(status, msg)
#define TRUE
#define RETURN_IF_XTYPE_INVALID(A, xtype1, xtype2, result)
#define CHOLMOD_ZOMPLEX
#define ITYPE