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