Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_cholmod_dense.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === Core/cholmod_dense =================================================== */
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_dense object:
15  *
16  * The solve routines and some of the MatrixOps and Modify routines use dense
17  * matrices as inputs. These are held in column-major order. With a leading
18  * dimension of d, the entry in row i and column j is held in x [i+j*d].
19  *
20  * Primary routines:
21  * -----------------
22  * cholmod_allocate_dense allocate a dense matrix
23  * cholmod_free_dense free a dense matrix
24  *
25  * Secondary routines:
26  * -------------------
27  * cholmod_zeros allocate a dense matrix of all zeros
28  * cholmod_ones allocate a dense matrix of all ones
29  * cholmod_eye allocate a dense identity matrix
30  * cholmod_sparse_to_dense create a dense matrix copy of a sparse matrix
31  * cholmod_dense_to_sparse create a sparse matrix copy of a dense matrix
32  * cholmod_copy_dense create a copy of a dense matrix
33  * cholmod_copy_dense2 copy a dense matrix (pre-allocated)
34  *
35  * All routines in this file can handle the real, complex, and zomplex cases.
36  * Pattern-only dense matrices are not supported. cholmod_sparse_to_dense can
37  * take a pattern-only input sparse matrix, however, and cholmod_dense_to_sparse
38  * can generate a pattern-only output sparse matrix.
39  */
40 
42 #include "amesos_cholmod_core.h"
43 
44 /* ========================================================================== */
45 /* === TEMPLATE ============================================================= */
46 /* ========================================================================== */
47 
48 #define PATTERN
49 #include "amesos_t_cholmod_dense.c"
50 #define REAL
51 #include "amesos_t_cholmod_dense.c"
52 #define COMPLEX
53 #include "amesos_t_cholmod_dense.c"
54 #define ZOMPLEX
55 #include "amesos_t_cholmod_dense.c"
56 
57 
58 /* ========================================================================== */
59 /* === cholmod_allocate_dense =============================================== */
60 /* ========================================================================== */
61 
62 /* Allocate a dense matrix with leading dimension d. The space is not
63  * initialized.
64  */
65 
67 (
68  /* ---- input ---- */
69  size_t nrow, /* # of rows of matrix */
70  size_t ncol, /* # of columns of matrix */
71  size_t d, /* leading dimension */
72  int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
73  /* --------------- */
74  cholmod_common *Common
75 )
76 {
77  cholmod_dense *X ;
78  size_t nzmax, nzmax0 ;
79  int ok = TRUE ;
80 
81  /* ---------------------------------------------------------------------- */
82  /* get inputs */
83  /* ---------------------------------------------------------------------- */
84 
86  if (d < nrow)
87  {
88  ERROR (CHOLMOD_INVALID, "leading dimension invalid") ;
89  return (NULL) ;
90  }
91  if (xtype < CHOLMOD_REAL || xtype > CHOLMOD_ZOMPLEX)
92  {
93  ERROR (CHOLMOD_INVALID, "xtype invalid") ;
94  return (NULL) ;
95  }
96 
97  /* ensure the dimensions do not cause integer overflow */
98  (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ;
99 
100  /* nzmax = MAX (1, d*ncol) ; */
101  nzmax = CHOLMOD(mult_size_t) (d, ncol, &ok) ;
102  nzmax = MAX (1, nzmax) ;
103 
104  if (!ok || nrow > Int_max || ncol > Int_max || nzmax > Int_max)
105  {
106  ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
107  return (NULL) ;
108  }
109  Common->status = CHOLMOD_OK ;
110 
111  /* ---------------------------------------------------------------------- */
112  /* allocate header */
113  /* ---------------------------------------------------------------------- */
114 
115  X = CHOLMOD(malloc) (sizeof (cholmod_dense), 1, Common) ;
116  if (Common->status < CHOLMOD_OK)
117  {
118  return (NULL) ; /* out of memory */
119  }
120 
121  PRINT1 (("cholmod_allocate_dense %d-by-%d nzmax %d xtype %d\n",
122  nrow, ncol, nzmax, xtype)) ;
123 
124  X->nrow = nrow ;
125  X->ncol = ncol ;
126  X->nzmax = nzmax ;
127  X->xtype = xtype ;
128  X->dtype = DTYPE ;
129  X->x = NULL ;
130  X->z = NULL ;
131  X->d = d ;
132 
133  /* ---------------------------------------------------------------------- */
134  /* allocate the matrix itself */
135  /* ---------------------------------------------------------------------- */
136 
137  nzmax0 = 0 ;
138  CHOLMOD(realloc_multiple) (nzmax, 0, xtype, NULL, NULL, &(X->x), &(X->z),
139  &nzmax0, Common) ;
140 
141  if (Common->status < CHOLMOD_OK)
142  {
143  CHOLMOD(free_dense) (&X, Common) ;
144  return (NULL) ; /* out of memory */
145  }
146 
147  return (X) ;
148 }
149 
150 
151 /* ========================================================================== */
152 /* === cholmod_zeros ======================================================== */
153 /* ========================================================================== */
154 
155 /* Allocate a dense matrix and set it to zero */
156 
158 (
159  /* ---- input ---- */
160  size_t nrow, /* # of rows of matrix */
161  size_t ncol, /* # of columns of matrix */
162  int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
163  /* --------------- */
164  cholmod_common *Common
165 )
166 {
167  cholmod_dense *X ;
168  double *Xx, *Xz ;
169  Int i, nz ;
170 
171  /* ---------------------------------------------------------------------- */
172  /* allocate a dense matrix and set it to zero */
173  /* ---------------------------------------------------------------------- */
174 
176  X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ;
177  if (Common->status < CHOLMOD_OK)
178  {
179  return (NULL) ; /* NULL Common, out of memory, or inputs invalid */
180  }
181 
182  Xx = X->x ;
183  Xz = X->z ;
184  nz = MAX (1, X->nzmax) ;
185 
186  switch (xtype)
187  {
188  case CHOLMOD_REAL:
189  for (i = 0 ; i < nz ; i++)
190  {
191  Xx [i] = 0 ;
192  }
193  break ;
194 
195  case CHOLMOD_COMPLEX:
196  for (i = 0 ; i < 2*nz ; i++)
197  {
198  Xx [i] = 0 ;
199  }
200  break ;
201 
202  case CHOLMOD_ZOMPLEX:
203  for (i = 0 ; i < nz ; i++)
204  {
205  Xx [i] = 0 ;
206  }
207  for (i = 0 ; i < nz ; i++)
208  {
209  Xz [i] = 0 ;
210  }
211  break ;
212  }
213 
214  return (X) ;
215 }
216 
217 
218 /* ========================================================================== */
219 /* === cholmod_ones ========================================================= */
220 /* ========================================================================== */
221 
222 /* Allocate a dense matrix and set it to zero */
223 
225 (
226  /* ---- input ---- */
227  size_t nrow, /* # of rows of matrix */
228  size_t ncol, /* # of columns of matrix */
229  int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
230  /* --------------- */
231  cholmod_common *Common
232 )
233 {
234  cholmod_dense *X ;
235  double *Xx, *Xz ;
236  Int i, nz ;
237 
238  /* ---------------------------------------------------------------------- */
239  /* allocate a dense matrix and set it to all ones */
240  /* ---------------------------------------------------------------------- */
241 
243  X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ;
244  if (Common->status < CHOLMOD_OK)
245  {
246  return (NULL) ; /* NULL Common, out of memory, or inputs invalid */
247  }
248 
249  Xx = X->x ;
250  Xz = X->z ;
251  nz = MAX (1, X->nzmax) ;
252 
253  switch (xtype)
254  {
255  case CHOLMOD_REAL:
256  for (i = 0 ; i < nz ; i++)
257  {
258  Xx [i] = 1 ;
259  }
260  break ;
261 
262  case CHOLMOD_COMPLEX:
263  for (i = 0 ; i < nz ; i++)
264  {
265  Xx [2*i ] = 1 ;
266  Xx [2*i+1] = 0 ;
267  }
268  break ;
269 
270  case CHOLMOD_ZOMPLEX:
271  for (i = 0 ; i < nz ; i++)
272  {
273  Xx [i] = 1 ;
274  }
275  for (i = 0 ; i < nz ; i++)
276  {
277  Xz [i] = 0 ;
278  }
279  break ;
280  }
281 
282  return (X) ;
283 }
284 
285 
286 /* ========================================================================== */
287 /* === cholmod_eye ========================================================== */
288 /* ========================================================================== */
289 
290 /* Allocate a dense matrix and set it to the identity matrix */
291 
293 (
294  /* ---- input ---- */
295  size_t nrow, /* # of rows of matrix */
296  size_t ncol, /* # of columns of matrix */
297  int xtype, /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
298  /* --------------- */
299  cholmod_common *Common
300 )
301 {
302  cholmod_dense *X ;
303  double *Xx, *Xz ;
304  Int i, n, nz ;
305 
306  /* ---------------------------------------------------------------------- */
307  /* allocate a dense matrix and set it to the identity matrix */
308  /* ---------------------------------------------------------------------- */
309 
311  X = CHOLMOD(zeros) (nrow, ncol, xtype, Common) ;
312  if (Common->status < CHOLMOD_OK)
313  {
314  return (NULL) ; /* NULL Common, out of memory, or inputs invalid */
315  }
316 
317  nz = MAX (1, nrow*ncol) ;
318  Xx = X->x ;
319  Xz = X->z ;
320 
321  n = MIN (nrow, ncol) ;
322 
323  switch (xtype)
324  {
325  case CHOLMOD_REAL:
326  case CHOLMOD_ZOMPLEX:
327  for (i = 0 ; i < n ; i++)
328  {
329  Xx [i + i*nrow] = 1 ;
330  }
331  break ;
332 
333  case CHOLMOD_COMPLEX:
334  for (i = 0 ; i < n ; i++)
335  {
336  Xx [2 * (i + i*nrow)] = 1 ;
337  }
338  break ;
339  }
340 
341  return (X) ;
342 }
343 
344 /* ========================================================================== */
345 /* === cholmod_free_dense =================================================== */
346 /* ========================================================================== */
347 
348 /* free a dense matrix
349  *
350  * workspace: none
351  */
352 
353 int CHOLMOD(free_dense)
354 (
355  /* ---- in/out --- */
356  cholmod_dense **XHandle, /* dense matrix to deallocate, NULL on output */
357  /* --------------- */
358  cholmod_common *Common
359 )
360 {
361  cholmod_dense *X ;
362 
364 
365  if (XHandle == NULL)
366  {
367  /* nothing to do */
368  return (TRUE) ;
369  }
370  X = *XHandle ;
371  if (X == NULL)
372  {
373  /* nothing to do */
374  return (TRUE) ;
375  }
376 
377  switch (X->xtype)
378  {
379  case CHOLMOD_REAL:
380  X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ;
381  break ;
382 
383  case CHOLMOD_COMPLEX:
384  X->x = CHOLMOD(free) (X->nzmax, 2*sizeof (double), X->x, Common) ;
385  break ;
386 
387  case CHOLMOD_ZOMPLEX:
388  X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ;
389  X->z = CHOLMOD(free) (X->nzmax, sizeof (double), X->z, Common) ;
390  break ;
391  }
392 
393  *XHandle = CHOLMOD(free) (1, sizeof (cholmod_dense), (*XHandle), Common) ;
394  return (TRUE) ;
395 }
396 
397 
398 /* ========================================================================== */
399 /* === cholmod_sparse_to_dense ============================================== */
400 /* ========================================================================== */
401 
402 /* Convert a sparse matrix to a dense matrix.
403  * The output dense matrix has the same xtype as the input sparse matrix,
404  * except that a pattern-only sparse matrix A is converted into a real dense
405  * matrix X, with 1's and 0's. All xtypes are supported.
406  */
407 
409 (
410  /* ---- input ---- */
411  cholmod_sparse *A, /* matrix to copy */
412  /* --------------- */
413  cholmod_common *Common
414 )
415 {
416  cholmod_dense *X = NULL ;
417 
418  /* ---------------------------------------------------------------------- */
419  /* check inputs */
420  /* ---------------------------------------------------------------------- */
421 
423  RETURN_IF_NULL (A, NULL) ;
425  if (A->stype && A->nrow != A->ncol)
426  {
427  ERROR (CHOLMOD_INVALID, "matrix invalid") ;
428  return (NULL) ;
429  }
430  Common->status = CHOLMOD_OK ;
431  ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ;
432 
433  /* ---------------------------------------------------------------------- */
434  /* convert the matrix, using template routine */
435  /* ---------------------------------------------------------------------- */
436 
437  switch (A->xtype)
438  {
439  case CHOLMOD_PATTERN:
440  X = amesos_p_cholmod_sparse_to_dense (A, Common) ;
441  break ;
442 
443  case CHOLMOD_REAL:
444  X = amesos_r_cholmod_sparse_to_dense (A, Common) ;
445  break ;
446 
447  case CHOLMOD_COMPLEX:
448  X = amesos_c_cholmod_sparse_to_dense (A, Common) ;
449  break ;
450 
451  case CHOLMOD_ZOMPLEX:
452  X = amesos_z_cholmod_sparse_to_dense (A, Common) ;
453  break ;
454  }
455  return (X) ;
456 }
457 
458 
459 /* ========================================================================== */
460 /* === cholmod_dense_to_sparse ============================================== */
461 /* ========================================================================== */
462 
463 /* Convert a dense matrix to a sparse matrix, similar to the MATLAB statements:
464  *
465  * C = sparse (X) values = TRUE
466  * C = spones (sparse (X)) values = FALSE
467  *
468  * except that X must be double (it can be of many different types in MATLAB)
469  *
470  * The resulting sparse matrix C has the same numeric xtype as the input dense
471  * matrix X, unless "values" is FALSE (in which case C is real, where C(i,j)=1
472  * if (i,j) is an entry in X.
473  */
474 
476 (
477  /* ---- input ---- */
478  cholmod_dense *X, /* matrix to copy */
479  int values, /* TRUE if values to be copied, FALSE otherwise */
480  /* --------------- */
481  cholmod_common *Common
482 )
483 {
484  cholmod_sparse *C = NULL ;
485 
486  DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ;
487 
488  /* ---------------------------------------------------------------------- */
489  /* check inputs */
490  /* ---------------------------------------------------------------------- */
491 
493  RETURN_IF_NULL (X, NULL) ;
495  if (X->d < X->nrow)
496  {
497  ERROR (CHOLMOD_INVALID, "matrix invalid") ;
498  return (NULL) ;
499  }
500  Common->status = CHOLMOD_OK ;
501 
502  /* ---------------------------------------------------------------------- */
503  /* convert the matrix, using template routine */
504  /* ---------------------------------------------------------------------- */
505 
506  switch (X->xtype)
507  {
508  case CHOLMOD_REAL:
509  C = amesos_r_cholmod_dense_to_sparse (X, values, Common) ;
510  break ;
511 
512  case CHOLMOD_COMPLEX:
513  C = amesos_c_cholmod_dense_to_sparse (X, values, Common) ;
514  break ;
515 
516  case CHOLMOD_ZOMPLEX:
517  C = amesos_z_cholmod_dense_to_sparse (X, values, Common) ;
518  break ;
519  }
520  return (C) ;
521 }
522 
523 
524 /* ========================================================================== */
525 /* === cholmod_copy_dense2 ================================================== */
526 /* ========================================================================== */
527 
528 /* Y = X, where X and Y are both already allocated. The leading dimensions of
529  * X and Y may differ, but both must be >= the # of rows in X and Y.
530  * Entries in rows nrow to d-1 are not copied from X, since the space might not
531  * be initialized. Y->nzmax is unchanged. X->nzmax is typically
532  * (X->d)*(X->ncol), but a user might modify that condition outside of any
533  * CHOLMOD routine.
534  *
535  * The two dense matrices X and Y must have the same numeric xtype.
536  */
537 
538 int CHOLMOD(copy_dense2)
539 (
540  /* ---- input ---- */
541  cholmod_dense *X, /* matrix to copy */
542  /* ---- output --- */
543  cholmod_dense *Y, /* copy of matrix X */
544  /* --------------- */
545  cholmod_common *Common
546 )
547 {
548  /* ---------------------------------------------------------------------- */
549  /* check inputs */
550  /* ---------------------------------------------------------------------- */
551 
553  RETURN_IF_NULL (X, FALSE) ;
554  RETURN_IF_NULL (Y, FALSE) ;
557  if (X->nrow != Y->nrow || X->ncol != Y->ncol || X->xtype != Y->xtype)
558  {
559  ERROR (CHOLMOD_INVALID, "X and Y must have same dimensions and xtype") ;
560  return (FALSE) ;
561  }
562  if (X->d < X->nrow || Y->d < Y->nrow
563  || (X->d * X->ncol) > X->nzmax || (Y->d * Y->ncol) > Y->nzmax)
564  {
565  ERROR (CHOLMOD_INVALID, "X and/or Y invalid") ;
566  return (FALSE) ;
567  }
568  Common->status = CHOLMOD_OK ;
569 
570  /* ---------------------------------------------------------------------- */
571  /* copy the matrix, using template routine */
572  /* ---------------------------------------------------------------------- */
573 
574  switch (X->xtype)
575  {
576  case CHOLMOD_REAL:
577  amesos_r_cholmod_copy_dense2 (X, Y) ;
578  break ;
579 
580  case CHOLMOD_COMPLEX:
581  amesos_c_cholmod_copy_dense2 (X, Y) ;
582  break ;
583 
584  case CHOLMOD_ZOMPLEX:
585  amesos_z_cholmod_copy_dense2 (X, Y) ;
586  break ;
587  }
588  return (TRUE) ;
589 }
590 
591 
592 /* ========================================================================== */
593 /* === cholmod_copy_dense =================================================== */
594 /* ========================================================================== */
595 
596 /* Y = X, copy a dense matrix */
597 
599 (
600  /* ---- input ---- */
601  cholmod_dense *X, /* matrix to copy */
602  /* --------------- */
603  cholmod_common *Common
604 )
605 {
606  cholmod_dense *Y ;
607 
608  /* ---------------------------------------------------------------------- */
609  /* check inputs */
610  /* ---------------------------------------------------------------------- */
611 
613  RETURN_IF_NULL (X, NULL) ;
615  Common->status = CHOLMOD_OK ;
616 
617  /* ---------------------------------------------------------------------- */
618  /* allocate result */
619  /* ---------------------------------------------------------------------- */
620 
621  Y = CHOLMOD(allocate_dense) (X->nrow, X->ncol, X->d, X->xtype, Common) ;
622  if (Common->status < CHOLMOD_OK)
623  {
624  return (NULL) ; /* out of memory or X invalid */
625  }
626 
627  /* ---------------------------------------------------------------------- */
628  /* Y = X */
629  /* ---------------------------------------------------------------------- */
630 
631  /* This cannot fail (X and Y are allocated, and have the same nrow, ncol
632  * d, and xtype) */
633  CHOLMOD(copy_dense2) (X, Y, Common) ;
634 
635  /* ---------------------------------------------------------------------- */
636  /* return result */
637  /* ---------------------------------------------------------------------- */
638 
639  return (Y) ;
640 }
#define CHOLMOD_TOO_LARGE
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
cholmod_dense *CHOLMOD() copy_dense(cholmod_dense *X, cholmod_common *Common)
#define FALSE
#define PRINT1(params)
struct cholmod_dense_struct cholmod_dense
#define RETURN_IF_NULL_COMMON(result)
size_t CHOLMOD() mult_size_t(size_t a, size_t k, int *ok)
int CHOLMOD() copy_dense2(cholmod_dense *X, cholmod_dense *Y, cholmod_common *Common)
#define CHOLMOD_PATTERN
#define CHOLMOD(name)
#define MAX(a, b)
#define CHOLMOD_REAL
#define NULL
cholmod_dense *CHOLMOD() zeros(size_t nrow, size_t ncol, int xtype, cholmod_common *Common)
#define Int_max
int CHOLMOD() dump_dense(cholmod_dense *X, char *name, cholmod_common *Common)
#define ASSERT(expression)
cholmod_dense *CHOLMOD() ones(size_t nrow, size_t ncol, int xtype, cholmod_common *Common)
cholmod_dense *CHOLMOD() eye(size_t nrow, size_t ncol, int xtype, cholmod_common *Common)
cholmod_dense *CHOLMOD() sparse_to_dense(cholmod_sparse *A, cholmod_common *Common)
#define DTYPE
cholmod_sparse *CHOLMOD() dense_to_sparse(cholmod_dense *X, int values, cholmod_common *Common)
int CHOLMOD() free_dense(cholmod_dense **XHandle, cholmod_common *Common)
#define CHOLMOD_INVALID
#define CHOLMOD_OK
#define RETURN_IF_NULL(A, result)
#define DEBUG(statement)
cholmod_dense *CHOLMOD() allocate_dense(size_t nrow, size_t ncol, size_t d, int xtype, cholmod_common *Common)
#define MIN(a, b)
int n
#define ERROR(status, msg)
#define TRUE
#define RETURN_IF_XTYPE_INVALID(A, xtype1, xtype2, result)
#define CHOLMOD_ZOMPLEX