Blame view
fvn_sparse/UMFPACK/Source/umfpack_triplet_to_col.c
6.41 KB
422234dc3 git-svn-id: https... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
/* ========================================================================== */ /* === UMFPACK_triplet_to_col =============================================== */ /* ========================================================================== */ /* -------------------------------------------------------------------------- */ /* UMFPACK Copyright (c) Timothy A. Davis, CISE, */ /* Univ. of Florida. All Rights Reserved. See ../Doc/License for License. */ /* web: http://www.cise.ufl.edu/research/sparse/umfpack */ /* -------------------------------------------------------------------------- */ /* User callable. Converts triplet input to column-oriented form. Duplicate entries may exist (they are summed in the output). The columns of the column-oriented form are in sorted order. The input is not modified. Returns 1 if OK, 0 if an error occurred. See umfpack_triplet_to_col.h for details. If Map is present (a non-NULL pointer to an Int array of size nz), then on output it holds the position of the triplets in the column-form matrix. That is, suppose p = Map [k], and the k-th triplet is i=Ti[k], j=Tj[k], and aij=Tx[k]. Then i=Ai[p], and aij will have been summed into Ax[p]. Also, Ap[j] <= p < Ap[j+1]. The Map array is not computed if it is (Int *) NULL. Dynamic memory usage: If numerical values are present, then one (two for complex version) workspace of size (nz+1)*sizeof(double) is allocated via UMF_malloc. Next, 4 calls to UMF_malloc are made to obtain workspace of size ((nz+1) + (n_row+1) + n_row + MAX (n_row,n_col)) * sizeof(Int). All of this workspace (4 to 6 objects) are free'd via UMF_free on return. For the complex version, additional space is allocated. An extra array of size nz*sizeof(Int) is allocated if Map is present. */ #include "umf_internal.h" #include "umf_malloc.h" #include "umf_free.h" #include "umf_triplet.h" #ifndef NDEBUG PRIVATE Int init_count ; #endif /* ========================================================================== */ GLOBAL Int UMFPACK_triplet_to_col ( Int n_row, Int n_col, Int nz, const Int Ti [ ], /* size nz */ const Int Tj [ ], /* size nz */ const double Tx [ ], /* size nz */ #ifdef COMPLEX const double Tz [ ], /* size nz */ #endif Int Ap [ ], /* size n_col + 1 */ Int Ai [ ], /* size nz */ double Ax [ ] /* size nz */ #ifdef COMPLEX , double Az [ ] /* size nz */ #endif , Int Map [ ] /* size nz */ ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ Int *RowCount, *Rp, *Rj, *W, nn, do_values, do_map, *Map2, status ; double *Rx ; #ifdef COMPLEX double *Rz ; Int split ; #endif #ifndef NDEBUG UMF_dump_start ( ) ; init_count = UMF_malloc_count ; #endif /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ if (!Ai || !Ap || !Ti || !Tj) { return (UMFPACK_ERROR_argument_missing) ; } if (n_row <= 0 || n_col <= 0) /* must be > 0 */ { return (UMFPACK_ERROR_n_nonpositive) ; } if (nz < 0) /* nz must be >= 0 (singular matrices are OK) */ { return (UMFPACK_ERROR_invalid_matrix) ; } nn = MAX (n_row, n_col) ; /* ---------------------------------------------------------------------- */ /* allocate workspace */ /* ---------------------------------------------------------------------- */ Rx = (double *) NULL ; do_values = Ax && Tx ; if (do_values) { #ifdef COMPLEX Rx = (double *) UMF_malloc (2*nz+2, sizeof (double)) ; split = SPLIT (Tz) && SPLIT (Az) ; if (split) { Rz = Rx + nz ; } else { Rz = (double *) NULL ; } #else Rx = (double *) UMF_malloc (nz+1, sizeof (double)) ; #endif if (!Rx) { DEBUGm4 (("out of memory: triplet work ")) ; ASSERT (UMF_malloc_count == init_count) ; return (UMFPACK_ERROR_out_of_memory) ; } } do_map = (Map != (Int *) NULL) ; Map2 = (Int *) NULL ; if (do_map) { DEBUG0 (("Do map: ")) ; Map2 = (Int *) UMF_malloc (nz+1, sizeof (Int)) ; if (!Map2) { DEBUGm4 (("out of memory: triplet map ")) ; (void) UMF_free ((void *) Rx) ; ASSERT (UMF_malloc_count == init_count) ; return (UMFPACK_ERROR_out_of_memory) ; } } Rj = (Int *) UMF_malloc (nz+1, sizeof (Int)) ; Rp = (Int *) UMF_malloc (n_row+1, sizeof (Int)) ; RowCount = (Int *) UMF_malloc (n_row, sizeof (Int)) ; W = (Int *) UMF_malloc (nn, sizeof (Int)) ; if (!Rj || !Rp || !RowCount || !W) { DEBUGm4 (("out of memory: triplet work (int) ")) ; (void) UMF_free ((void *) Rx) ; (void) UMF_free ((void *) Map2) ; (void) UMF_free ((void *) Rp) ; (void) UMF_free ((void *) Rj) ; (void) UMF_free ((void *) RowCount) ; (void) UMF_free ((void *) W) ; ASSERT (UMF_malloc_count == init_count) ; return (UMFPACK_ERROR_out_of_memory) ; } ASSERT (UMF_malloc_count == init_count + 4 + (Rx != (double *) NULL) + do_map) ; /* ---------------------------------------------------------------------- */ /* convert from triplet to column form */ /* ---------------------------------------------------------------------- */ if (do_map) { if (do_values) { status = UMF_triplet_map_x (n_row, n_col, nz, Ti, Tj, Ap, Ai, Rp, Rj, W, RowCount, Tx, Ax, Rx #ifdef COMPLEX , Tz, Az, Rz #endif , Map, Map2) ; } else { status = UMF_triplet_map_nox (n_row, n_col, nz, Ti, Tj, Ap, Ai, Rp, Rj, W, RowCount, Map, Map2) ; } } else { if (do_values) { status = UMF_triplet_nomap_x (n_row, n_col, nz, Ti, Tj, Ap, Ai, Rp, Rj, W, RowCount , Tx, Ax, Rx #ifdef COMPLEX , Tz, Az, Rz #endif ) ; } else { status = UMF_triplet_nomap_nox (n_row, n_col, nz, Ti, Tj, Ap, Ai, Rp, Rj, W, RowCount) ; } } /* ---------------------------------------------------------------------- */ /* free the workspace */ /* ---------------------------------------------------------------------- */ (void) UMF_free ((void *) Rx) ; (void) UMF_free ((void *) Map2) ; (void) UMF_free ((void *) Rp) ; (void) UMF_free ((void *) Rj) ; (void) UMF_free ((void *) RowCount) ; (void) UMF_free ((void *) W) ; ASSERT (UMF_malloc_count == init_count) ; return (status) ; } |