Amesos Package Browser (Single Doxygen Collection) Development
amesos_cholmod_dense.c
Go to the documentation of this file.
00001 /* ========================================================================== */
00002 /* === Core/cholmod_dense =================================================== */
00003 /* ========================================================================== */
00004 
00005 /* -----------------------------------------------------------------------------
00006  * CHOLMOD/Core Module.  Copyright (C) 2005-2006,
00007  * Univ. of Florida.  Author: Timothy A. Davis
00008  * The CHOLMOD/Core Module is licensed under Version 2.1 of the GNU
00009  * Lesser General Public License.  See lesser.txt for a text of the license.
00010  * CHOLMOD is also available under other licenses; contact authors for details.
00011  * http://www.cise.ufl.edu/research/sparse
00012  * -------------------------------------------------------------------------- */
00013 
00014 /* Core utility routines for the cholmod_dense object:
00015  *
00016  * The solve routines and some of the MatrixOps and Modify routines use dense
00017  * matrices as inputs.  These are held in column-major order.  With a leading
00018  * dimension of d, the entry in row i and column j is held in x [i+j*d].
00019  *
00020  * Primary routines:
00021  * -----------------
00022  * cholmod_allocate_dense allocate a dense matrix
00023  * cholmod_free_dense   free a dense matrix
00024  *
00025  * Secondary routines:
00026  * -------------------
00027  * cholmod_zeros    allocate a dense matrix of all zeros
00028  * cholmod_ones     allocate a dense matrix of all ones
00029  * cholmod_eye      allocate a dense identity matrix 
00030  * cholmod_sparse_to_dense  create a dense matrix copy of a sparse matrix
00031  * cholmod_dense_to_sparse  create a sparse matrix copy of a dense matrix
00032  * cholmod_copy_dense   create a copy of a dense matrix
00033  * cholmod_copy_dense2    copy a dense matrix (pre-allocated)
00034  *
00035  * All routines in this file can handle the real, complex, and zomplex cases.
00036  * Pattern-only dense matrices are not supported.  cholmod_sparse_to_dense can
00037  * take a pattern-only input sparse matrix, however, and cholmod_dense_to_sparse
00038  * can generate a pattern-only output sparse matrix.
00039  */
00040 
00041 #include "amesos_cholmod_internal.h"
00042 #include "amesos_cholmod_core.h"
00043 
00044 /* ========================================================================== */
00045 /* === TEMPLATE ============================================================= */
00046 /* ========================================================================== */
00047 
00048 #define PATTERN
00049 #include "amesos_t_cholmod_dense.c"
00050 #define REAL
00051 #include "amesos_t_cholmod_dense.c"
00052 #define COMPLEX
00053 #include "amesos_t_cholmod_dense.c"
00054 #define ZOMPLEX
00055 #include "amesos_t_cholmod_dense.c"
00056 
00057 
00058 /* ========================================================================== */
00059 /* === cholmod_allocate_dense =============================================== */
00060 /* ========================================================================== */
00061 
00062 /* Allocate a dense matrix with leading dimension d.  The space is not
00063  * initialized.
00064  */
00065 
00066 cholmod_dense *CHOLMOD(allocate_dense)
00067 (
00068     /* ---- input ---- */
00069     size_t nrow,  /* # of rows of matrix */
00070     size_t ncol,  /* # of columns of matrix */
00071     size_t d,   /* leading dimension */
00072     int xtype,    /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
00073     /* --------------- */
00074     cholmod_common *Common
00075 )
00076 {
00077     cholmod_dense *X ;
00078     size_t nzmax, nzmax0 ;
00079     int ok = TRUE ;
00080 
00081     /* ---------------------------------------------------------------------- */
00082     /* get inputs */
00083     /* ---------------------------------------------------------------------- */
00084 
00085     RETURN_IF_NULL_COMMON (NULL) ;
00086     if (d < nrow)
00087     {
00088   ERROR (CHOLMOD_INVALID, "leading dimension invalid") ;
00089   return (NULL) ;
00090     }
00091     if (xtype < CHOLMOD_REAL || xtype > CHOLMOD_ZOMPLEX)
00092     {
00093   ERROR (CHOLMOD_INVALID, "xtype invalid") ;
00094   return (NULL) ;
00095     }
00096 
00097     /* ensure the dimensions do not cause integer overflow */
00098     (void) CHOLMOD(add_size_t) (ncol, 2, &ok) ;
00099 
00100     /* nzmax = MAX (1, d*ncol) ; */
00101     nzmax = CHOLMOD(mult_size_t) (d, ncol, &ok) ;
00102     nzmax = MAX (1, nzmax) ;
00103 
00104     if (!ok || nrow > Int_max || ncol > Int_max || nzmax > Int_max)
00105     {
00106   ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
00107   return (NULL) ;
00108     }
00109     Common->status = CHOLMOD_OK ;
00110 
00111     /* ---------------------------------------------------------------------- */
00112     /* allocate header */
00113     /* ---------------------------------------------------------------------- */
00114 
00115     X = CHOLMOD(malloc) (sizeof (cholmod_dense), 1, Common) ;
00116     if (Common->status < CHOLMOD_OK)
00117     {
00118   return (NULL) ;     /* out of memory */
00119     }
00120 
00121     PRINT1 (("cholmod_allocate_dense %d-by-%d nzmax %d xtype %d\n",
00122     nrow, ncol, nzmax, xtype)) ;
00123 
00124     X->nrow = nrow ;
00125     X->ncol = ncol ;
00126     X->nzmax = nzmax ;
00127     X->xtype = xtype ;
00128     X->dtype = DTYPE ;
00129     X->x = NULL ;
00130     X->z = NULL ;
00131     X->d = d ;
00132 
00133     /* ---------------------------------------------------------------------- */
00134     /* allocate the matrix itself */
00135     /* ---------------------------------------------------------------------- */
00136 
00137     nzmax0 = 0 ;
00138     CHOLMOD(realloc_multiple) (nzmax, 0, xtype, NULL, NULL, &(X->x), &(X->z),
00139       &nzmax0, Common) ;
00140 
00141     if (Common->status < CHOLMOD_OK)
00142     {
00143   CHOLMOD(free_dense) (&X, Common) ;
00144   return (NULL) ;     /* out of memory */
00145     }
00146 
00147     return (X) ;
00148 }
00149 
00150 
00151 /* ========================================================================== */
00152 /* === cholmod_zeros ======================================================== */
00153 /* ========================================================================== */
00154 
00155 /* Allocate a dense matrix and set it to zero */
00156 
00157 cholmod_dense *CHOLMOD(zeros)
00158 (
00159     /* ---- input ---- */
00160     size_t nrow,  /* # of rows of matrix */
00161     size_t ncol,  /* # of columns of matrix */
00162     int xtype,    /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
00163     /* --------------- */
00164     cholmod_common *Common
00165 )
00166 {
00167     cholmod_dense *X ;
00168     double *Xx, *Xz ;
00169     Int i, nz ;
00170 
00171     /* ---------------------------------------------------------------------- */
00172     /* allocate a dense matrix and set it to zero */
00173     /* ---------------------------------------------------------------------- */
00174 
00175     RETURN_IF_NULL_COMMON (NULL) ;
00176     X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ;
00177     if (Common->status < CHOLMOD_OK)
00178     {
00179   return (NULL) ;     /* NULL Common, out of memory, or inputs invalid */
00180     }
00181 
00182     Xx = X->x ;
00183     Xz = X->z ;
00184     nz = MAX (1, X->nzmax) ;
00185 
00186     switch (xtype)
00187     {
00188   case CHOLMOD_REAL:
00189       for (i = 0 ; i < nz ; i++)
00190       {
00191     Xx [i] = 0 ;
00192       }
00193       break ;
00194 
00195   case CHOLMOD_COMPLEX:
00196       for (i = 0 ; i < 2*nz ; i++)
00197       {
00198     Xx [i] = 0 ;
00199       }
00200       break ;
00201 
00202   case CHOLMOD_ZOMPLEX:
00203       for (i = 0 ; i < nz ; i++)
00204       {
00205     Xx [i] = 0 ;
00206       }
00207       for (i = 0 ; i < nz ; i++)
00208       {
00209     Xz [i] = 0 ;
00210       }
00211       break ;
00212     }
00213 
00214     return (X) ;
00215 }
00216 
00217 
00218 /* ========================================================================== */
00219 /* === cholmod_ones ========================================================= */
00220 /* ========================================================================== */
00221 
00222 /* Allocate a dense matrix and set it to zero */
00223 
00224 cholmod_dense *CHOLMOD(ones)
00225 (
00226     /* ---- input ---- */
00227     size_t nrow,  /* # of rows of matrix */
00228     size_t ncol,  /* # of columns of matrix */
00229     int xtype,    /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
00230     /* --------------- */
00231     cholmod_common *Common
00232 )
00233 {
00234     cholmod_dense *X ;
00235     double *Xx, *Xz ;
00236     Int i, nz ;
00237 
00238     /* ---------------------------------------------------------------------- */
00239     /* allocate a dense matrix and set it to all ones */
00240     /* ---------------------------------------------------------------------- */
00241 
00242     RETURN_IF_NULL_COMMON (NULL) ;
00243     X = CHOLMOD(allocate_dense) (nrow, ncol, nrow, xtype, Common) ;
00244     if (Common->status < CHOLMOD_OK)
00245     {
00246   return (NULL) ;     /* NULL Common, out of memory, or inputs invalid */
00247     }
00248 
00249     Xx = X->x ;
00250     Xz = X->z ;
00251     nz = MAX (1, X->nzmax) ;
00252 
00253     switch (xtype)
00254     {
00255   case CHOLMOD_REAL:
00256       for (i = 0 ; i < nz ; i++)
00257       {
00258     Xx [i] = 1 ;
00259       }
00260       break ;
00261 
00262   case CHOLMOD_COMPLEX:
00263       for (i = 0 ; i < nz ; i++)
00264       {
00265     Xx [2*i  ] = 1 ;
00266     Xx [2*i+1] = 0 ;
00267       }
00268       break ;
00269 
00270   case CHOLMOD_ZOMPLEX:
00271       for (i = 0 ; i < nz ; i++)
00272       {
00273     Xx [i] = 1 ;
00274       }
00275       for (i = 0 ; i < nz ; i++)
00276       {
00277     Xz [i] = 0 ;
00278       }
00279       break ;
00280     }
00281 
00282     return (X) ;
00283 }
00284 
00285 
00286 /* ========================================================================== */
00287 /* === cholmod_eye ========================================================== */
00288 /* ========================================================================== */
00289 
00290 /* Allocate a dense matrix and set it to the identity matrix */
00291 
00292 cholmod_dense *CHOLMOD(eye)
00293 (
00294     /* ---- input ---- */
00295     size_t nrow,  /* # of rows of matrix */
00296     size_t ncol,  /* # of columns of matrix */
00297     int xtype,    /* CHOLMOD_REAL, _COMPLEX, or _ZOMPLEX */
00298     /* --------------- */
00299     cholmod_common *Common
00300 )
00301 {
00302     cholmod_dense *X ;
00303     double *Xx, *Xz ;
00304     Int i, n, nz ;
00305 
00306     /* ---------------------------------------------------------------------- */
00307     /* allocate a dense matrix and set it to the identity matrix */
00308     /* ---------------------------------------------------------------------- */
00309 
00310     RETURN_IF_NULL_COMMON (NULL) ;
00311     X = CHOLMOD(zeros) (nrow, ncol, xtype, Common) ;
00312     if (Common->status < CHOLMOD_OK)
00313     {
00314   return (NULL) ;     /* NULL Common, out of memory, or inputs invalid */
00315     }
00316 
00317     nz = MAX (1, nrow*ncol) ;
00318     Xx = X->x ;
00319     Xz = X->z ;
00320 
00321     n = MIN (nrow, ncol) ;
00322 
00323     switch (xtype)
00324     {
00325   case CHOLMOD_REAL:
00326   case CHOLMOD_ZOMPLEX:
00327       for (i = 0 ; i < n ; i++)
00328       {
00329     Xx [i + i*nrow] = 1 ;
00330       }
00331       break ;
00332 
00333   case CHOLMOD_COMPLEX:
00334       for (i = 0 ; i < n ; i++)
00335       {
00336     Xx [2 * (i + i*nrow)] = 1 ;
00337       }
00338       break ;
00339     }
00340 
00341     return (X) ;
00342 }
00343 
00344 /* ========================================================================== */
00345 /* === cholmod_free_dense =================================================== */
00346 /* ========================================================================== */
00347 
00348 /* free a dense matrix
00349  *
00350  * workspace: none
00351  */
00352 
00353 int CHOLMOD(free_dense)
00354 (
00355     /* ---- in/out --- */
00356     cholmod_dense **XHandle,  /* dense matrix to deallocate, NULL on output */
00357     /* --------------- */
00358     cholmod_common *Common
00359 )
00360 {
00361     cholmod_dense *X ;
00362 
00363     RETURN_IF_NULL_COMMON (FALSE) ;
00364 
00365     if (XHandle == NULL)
00366     {
00367   /* nothing to do */
00368   return (TRUE) ;
00369     }
00370     X = *XHandle ;
00371     if (X == NULL)
00372     {
00373   /* nothing to do */
00374   return (TRUE) ;
00375     }
00376 
00377     switch (X->xtype)
00378     {
00379   case CHOLMOD_REAL:
00380       X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ;
00381       break ;
00382 
00383   case CHOLMOD_COMPLEX:
00384       X->x = CHOLMOD(free) (X->nzmax, 2*sizeof (double), X->x, Common) ;
00385       break ;
00386 
00387   case CHOLMOD_ZOMPLEX:
00388       X->x = CHOLMOD(free) (X->nzmax, sizeof (double), X->x, Common) ;
00389       X->z = CHOLMOD(free) (X->nzmax, sizeof (double), X->z, Common) ;
00390       break ;
00391     }
00392 
00393     *XHandle = CHOLMOD(free) (1, sizeof (cholmod_dense), (*XHandle), Common) ;
00394     return (TRUE) ;
00395 }
00396 
00397 
00398 /* ========================================================================== */
00399 /* === cholmod_sparse_to_dense ============================================== */
00400 /* ========================================================================== */
00401 
00402 /* Convert a sparse matrix to a dense matrix.
00403  * The output dense matrix has the same xtype as the input sparse matrix,
00404  * except that a pattern-only sparse matrix A is converted into a real dense
00405  * matrix X, with 1's and 0's.  All xtypes are supported.
00406  */
00407 
00408 cholmod_dense *CHOLMOD(sparse_to_dense)
00409 (
00410     /* ---- input ---- */
00411     cholmod_sparse *A,  /* matrix to copy */
00412     /* --------------- */
00413     cholmod_common *Common
00414 )
00415 {
00416     cholmod_dense *X = NULL ;
00417 
00418     /* ---------------------------------------------------------------------- */
00419     /* check inputs */
00420     /* ---------------------------------------------------------------------- */
00421 
00422     RETURN_IF_NULL_COMMON (NULL) ;
00423     RETURN_IF_NULL (A, NULL) ;
00424     RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, NULL) ;
00425     if (A->stype && A->nrow != A->ncol)
00426     {
00427   ERROR (CHOLMOD_INVALID, "matrix invalid") ;
00428   return (NULL) ;
00429     }
00430     Common->status = CHOLMOD_OK ;
00431     ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ;
00432 
00433     /* ---------------------------------------------------------------------- */
00434     /* convert the matrix, using template routine */
00435     /* ---------------------------------------------------------------------- */
00436 
00437     switch (A->xtype)
00438     {
00439   case CHOLMOD_PATTERN:
00440       X = amesos_p_cholmod_sparse_to_dense (A, Common) ;
00441       break ;
00442 
00443   case CHOLMOD_REAL:
00444       X = amesos_r_cholmod_sparse_to_dense (A, Common) ;
00445       break ;
00446 
00447   case CHOLMOD_COMPLEX:
00448       X = amesos_c_cholmod_sparse_to_dense (A, Common) ;
00449       break ;
00450 
00451   case CHOLMOD_ZOMPLEX:
00452       X = amesos_z_cholmod_sparse_to_dense (A, Common) ;
00453       break ;
00454     }
00455     return (X) ;
00456 }
00457 
00458 
00459 /* ========================================================================== */
00460 /* === cholmod_dense_to_sparse ============================================== */
00461 /* ========================================================================== */
00462 
00463 /* Convert a dense matrix to a sparse matrix, similar to the MATLAB statements:
00464  *
00465  * C = sparse (X)     values = TRUE
00466  * C = spones (sparse (X))    values = FALSE
00467  *
00468  * except that X must be double (it can be of many different types in MATLAB)
00469  *
00470  * The resulting sparse matrix C has the same numeric xtype as the input dense
00471  * matrix X, unless "values" is FALSE (in which case C is real, where C(i,j)=1
00472  * if (i,j) is an entry in X.
00473  */
00474 
00475 cholmod_sparse *CHOLMOD(dense_to_sparse)
00476 (
00477     /* ---- input ---- */
00478     cholmod_dense *X, /* matrix to copy */
00479     int values,   /* TRUE if values to be copied, FALSE otherwise */
00480     /* --------------- */
00481     cholmod_common *Common
00482 )
00483 {
00484     cholmod_sparse *C = NULL ;
00485 
00486     DEBUG (CHOLMOD(dump_dense) (X, "X", Common)) ;
00487 
00488     /* ---------------------------------------------------------------------- */
00489     /* check inputs */
00490     /* ---------------------------------------------------------------------- */
00491 
00492     RETURN_IF_NULL_COMMON (NULL) ;
00493     RETURN_IF_NULL (X, NULL) ;
00494     RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ;
00495     if (X->d < X->nrow)
00496     {
00497   ERROR (CHOLMOD_INVALID, "matrix invalid") ;
00498   return (NULL) ;
00499     }
00500     Common->status = CHOLMOD_OK ;
00501 
00502     /* ---------------------------------------------------------------------- */
00503     /* convert the matrix, using template routine */
00504     /* ---------------------------------------------------------------------- */
00505 
00506     switch (X->xtype)
00507     {
00508   case CHOLMOD_REAL:
00509       C = amesos_r_cholmod_dense_to_sparse (X, values, Common) ;
00510       break ;
00511 
00512   case CHOLMOD_COMPLEX:
00513       C = amesos_c_cholmod_dense_to_sparse (X, values, Common) ;
00514       break ;
00515 
00516   case CHOLMOD_ZOMPLEX:
00517       C = amesos_z_cholmod_dense_to_sparse (X, values, Common) ;
00518       break ;
00519     }
00520     return (C) ;
00521 }
00522 
00523 
00524 /* ========================================================================== */
00525 /* === cholmod_copy_dense2 ================================================== */
00526 /* ========================================================================== */
00527 
00528 /* Y = X, where X and Y are both already allocated.  The leading dimensions of
00529  * X and Y may differ, but both must be >= the # of rows in X and Y.
00530  * Entries in rows nrow to d-1 are not copied from X, since the space might not
00531  * be initialized.  Y->nzmax is unchanged.  X->nzmax is typically
00532  * (X->d)*(X->ncol), but a user might modify that condition outside of any
00533  * CHOLMOD routine.
00534  *
00535  * The two dense matrices X and Y must have the same numeric xtype.
00536  */
00537 
00538 int CHOLMOD(copy_dense2)
00539 (
00540     /* ---- input ---- */
00541     cholmod_dense *X, /* matrix to copy */
00542     /* ---- output --- */
00543     cholmod_dense *Y, /* copy of matrix X */
00544     /* --------------- */
00545     cholmod_common *Common
00546 )
00547 {
00548     /* ---------------------------------------------------------------------- */
00549     /* check inputs */
00550     /* ---------------------------------------------------------------------- */
00551 
00552     RETURN_IF_NULL_COMMON (FALSE) ;
00553     RETURN_IF_NULL (X, FALSE) ;
00554     RETURN_IF_NULL (Y, FALSE) ;
00555     RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ;
00556     RETURN_IF_XTYPE_INVALID (Y, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ;
00557     if (X->nrow != Y->nrow || X->ncol != Y->ncol || X->xtype != Y->xtype)
00558     {
00559   ERROR (CHOLMOD_INVALID, "X and Y must have same dimensions and xtype") ;
00560   return (FALSE) ;
00561     }
00562     if (X->d < X->nrow || Y->d < Y->nrow
00563       || (X->d * X->ncol) > X->nzmax || (Y->d * Y->ncol) > Y->nzmax)
00564     {
00565   ERROR (CHOLMOD_INVALID, "X and/or Y invalid") ;
00566   return (FALSE) ;
00567     }
00568     Common->status = CHOLMOD_OK ;
00569 
00570     /* ---------------------------------------------------------------------- */
00571     /* copy the matrix, using template routine */
00572     /* ---------------------------------------------------------------------- */
00573 
00574     switch (X->xtype)
00575     {
00576   case CHOLMOD_REAL:
00577       amesos_r_cholmod_copy_dense2 (X, Y) ;
00578       break ;
00579 
00580   case CHOLMOD_COMPLEX:
00581       amesos_c_cholmod_copy_dense2 (X, Y) ;
00582       break ;
00583 
00584   case CHOLMOD_ZOMPLEX:
00585       amesos_z_cholmod_copy_dense2 (X, Y) ;
00586       break ;
00587     }
00588     return (TRUE) ;
00589 }
00590 
00591 
00592 /* ========================================================================== */
00593 /* === cholmod_copy_dense =================================================== */
00594 /* ========================================================================== */
00595 
00596 /* Y = X, copy a dense matrix */
00597 
00598 cholmod_dense *CHOLMOD(copy_dense)
00599 (
00600     /* ---- input ---- */
00601     cholmod_dense *X, /* matrix to copy */
00602     /* --------------- */
00603     cholmod_common *Common
00604 )
00605 {
00606     cholmod_dense *Y ;
00607 
00608     /* ---------------------------------------------------------------------- */
00609     /* check inputs */
00610     /* ---------------------------------------------------------------------- */
00611 
00612     RETURN_IF_NULL_COMMON (NULL) ;
00613     RETURN_IF_NULL (X, NULL) ;
00614     RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, NULL) ;
00615     Common->status = CHOLMOD_OK ;
00616 
00617     /* ---------------------------------------------------------------------- */
00618     /* allocate result */
00619     /* ---------------------------------------------------------------------- */
00620 
00621     Y = CHOLMOD(allocate_dense) (X->nrow, X->ncol, X->d, X->xtype, Common) ;
00622     if (Common->status < CHOLMOD_OK)
00623     {
00624   return (NULL) ;     /* out of memory or X invalid */
00625     }
00626 
00627     /* ---------------------------------------------------------------------- */
00628     /* Y = X */
00629     /* ---------------------------------------------------------------------- */
00630 
00631     /* This cannot fail (X and Y are allocated, and have the same nrow, ncol
00632      * d, and xtype) */
00633     CHOLMOD(copy_dense2) (X, Y, Common) ;
00634 
00635     /* ---------------------------------------------------------------------- */
00636     /* return result */
00637     /* ---------------------------------------------------------------------- */
00638 
00639     return (Y) ;
00640 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines