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