/* ========================================================================= */ /* === CAMD_valid ========================================================== */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ /* CAMD, Copyright (c) Timothy A. Davis, Yanqing Chen, */ /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ /* email: DrTimothyAldenDavis@gmail.com */ /* ------------------------------------------------------------------------- */ /* Check if a column-form matrix is valid or not. The matrix A is * n_row-by-n_col. The row indices of entries in column j are in * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are: * * n_row >= 0 * n_col >= 0 * nz = Ap [n_col] >= 0 number of entries in the matrix * Ap [0] == 0 * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col. * Ai [0 ... nz-1] must be in the range 0 to n_row-1. * * If any of the above conditions hold, CAMD_INVALID is returned. If the * following condition holds, CAMD_OK_BUT_JUMBLED is returned (a warning, * not an error): * * row indices in Ai [Ap [j] ... Ap [j+1]-1] are not sorted in ascending * order, and/or duplicate entries exist. * * Otherwise, CAMD_OK is returned. */ #include "camd_internal.h" GLOBAL Int CAMD_valid ( /* inputs, not modified on output: */ Int n_row, /* A is n_row-by-n_col */ Int n_col, const Int Ap [ ], /* column pointers of A, of size n_col+1 */ const Int Ai [ ] /* row indices of A, of size nz = Ap [n_col] */ ) { Int nz, j, p1, p2, ilast, i, p, result = CAMD_OK ; if (n_row < 0 || n_col < 0 || Ap == NULL || Ai == NULL) { return (CAMD_INVALID) ; } nz = Ap [n_col] ; if (Ap [0] != 0 || nz < 0) { /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */ CAMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ; return (CAMD_INVALID) ; } for (j = 0 ; j < n_col ; j++) { p1 = Ap [j] ; p2 = Ap [j+1] ; CAMD_DEBUG2 (("\nColumn: "ID" p1: "ID" p2: "ID"\n", j, p1, p2)) ; if (p1 > p2) { /* column pointers must be ascending */ CAMD_DEBUG0 (("column "ID" pointer bad\n", j)) ; return (CAMD_INVALID) ; } ilast = EMPTY ; for (p = p1 ; p < p2 ; p++) { i = Ai [p] ; CAMD_DEBUG3 (("row: "ID"\n", i)) ; if (i < 0 || i >= n_row) { /* row index out of range */ CAMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i)); return (CAMD_INVALID) ; } if (i <= ilast) { /* row index unsorted, or duplicate entry present */ CAMD_DEBUG1 (("index unsorted/dupl col "ID" row "ID"\n", j, i)); result = CAMD_OK_BUT_JUMBLED ; } ilast = i ; } } return (result) ; } GLOBAL Int CAMD_cvalid /* return TRUE if the Constraint set is valid, * FALSE otherwise */ ( /* inputs, not modified on output: */ Int n, /* the length of constraint set */ const Int C [ ] /* constraint set */ ) { Int i ; if (C != NULL) { for (i = 0 ; i < n ; i++) { if (C [i] < 0 || C [i] > n - 1) { CAMD_DEBUG0 (("C["ID"] = "ID" invalid\n", i, C [i])) ; return (FALSE) ; } } } return (TRUE) ; }