//------------------------------------------------------------------------------ // UMFPACK/Source/umfpack_triplet_to_col: convert triplets to CSC sparse matrix //------------------------------------------------------------------------------ // UMFPACK, Copyright (c) 2005-2023, Timothy A. Davis, All Rights Reserved. // SPDX-License-Identifier: GPL-2.0+ //------------------------------------------------------------------------------ /* 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.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 /* ========================================================================== */ 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 ; int 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 \n")) ; 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:\n")) ; Map2 = (Int *) UMF_malloc (nz+1, sizeof (Int)) ; if (!Map2) { DEBUGm4 (("out of memory: triplet map\n")) ; (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)\n")) ; (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) ; }