alpar@1: /* ========================================================================= */ alpar@1: /* === AMD_valid =========================================================== */ alpar@1: /* ========================================================================= */ alpar@1: alpar@1: /* ------------------------------------------------------------------------- */ alpar@1: /* AMD, Copyright (c) Timothy A. Davis, */ alpar@1: /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ alpar@1: /* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ alpar@1: /* web: http://www.cise.ufl.edu/research/sparse/amd */ alpar@1: /* ------------------------------------------------------------------------- */ alpar@1: alpar@1: /* Check if a column-form matrix is valid or not. The matrix A is alpar@1: * n_row-by-n_col. The row indices of entries in column j are in alpar@1: * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are: alpar@1: * alpar@1: * n_row >= 0 alpar@1: * n_col >= 0 alpar@1: * nz = Ap [n_col] >= 0 number of entries in the matrix alpar@1: * Ap [0] == 0 alpar@1: * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col. alpar@1: * Ai [0 ... nz-1] must be in the range 0 to n_row-1. alpar@1: * alpar@1: * If any of the above conditions hold, AMD_INVALID is returned. If the alpar@1: * following condition holds, AMD_OK_BUT_JUMBLED is returned (a warning, alpar@1: * not an error): alpar@1: * alpar@1: * row indices in Ai [Ap [j] ... Ap [j+1]-1] are not sorted in ascending alpar@1: * order, and/or duplicate entries exist. alpar@1: * alpar@1: * Otherwise, AMD_OK is returned. alpar@1: * alpar@1: * In v1.2 and earlier, this function returned TRUE if the matrix was valid alpar@1: * (now returns AMD_OK), or FALSE otherwise (now returns AMD_INVALID or alpar@1: * AMD_OK_BUT_JUMBLED). alpar@1: */ alpar@1: alpar@1: #include "amd_internal.h" alpar@1: alpar@1: GLOBAL Int AMD_valid alpar@1: ( alpar@1: /* inputs, not modified on output: */ alpar@1: Int n_row, /* A is n_row-by-n_col */ alpar@1: Int n_col, alpar@1: const Int Ap [ ], /* column pointers of A, of size n_col+1 */ alpar@1: const Int Ai [ ] /* row indices of A, of size nz = Ap [n_col] */ alpar@1: ) alpar@1: { alpar@1: Int nz, j, p1, p2, ilast, i, p, result = AMD_OK ; alpar@1: alpar@1: if (n_row < 0 || n_col < 0 || Ap == NULL || Ai == NULL) alpar@1: { alpar@1: return (AMD_INVALID) ; alpar@1: } alpar@1: nz = Ap [n_col] ; alpar@1: if (Ap [0] != 0 || nz < 0) alpar@1: { alpar@1: /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */ alpar@1: AMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ; alpar@1: return (AMD_INVALID) ; alpar@1: } alpar@1: for (j = 0 ; j < n_col ; j++) alpar@1: { alpar@1: p1 = Ap [j] ; alpar@1: p2 = Ap [j+1] ; alpar@1: AMD_DEBUG2 (("\nColumn: "ID" p1: "ID" p2: "ID"\n", j, p1, p2)) ; alpar@1: if (p1 > p2) alpar@1: { alpar@1: /* column pointers must be ascending */ alpar@1: AMD_DEBUG0 (("column "ID" pointer bad\n", j)) ; alpar@1: return (AMD_INVALID) ; alpar@1: } alpar@1: ilast = EMPTY ; alpar@1: for (p = p1 ; p < p2 ; p++) alpar@1: { alpar@1: i = Ai [p] ; alpar@1: AMD_DEBUG3 (("row: "ID"\n", i)) ; alpar@1: if (i < 0 || i >= n_row) alpar@1: { alpar@1: /* row index out of range */ alpar@1: AMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i)); alpar@1: return (AMD_INVALID) ; alpar@1: } alpar@1: if (i <= ilast) alpar@1: { alpar@1: /* row index unsorted, or duplicate entry present */ alpar@1: AMD_DEBUG1 (("index unsorted/dupl col "ID" row "ID"\n", j, i)); alpar@1: result = AMD_OK_BUT_JUMBLED ; alpar@1: } alpar@1: ilast = i ; alpar@1: } alpar@1: } alpar@1: return (result) ; alpar@1: }