//------------------------------------------------------------------------------ // GxB_rowIterator_*: iterate over the rows of a matrix //------------------------------------------------------------------------------ // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2023, All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 //------------------------------------------------------------------------------ #include "GB.h" #undef GxB_rowIterator_attach #undef GxB_rowIterator_kount #undef GxB_rowIterator_seekRow #undef GxB_rowIterator_kseek #undef GxB_rowIterator_nextRow #undef GxB_rowIterator_nextCol #undef GxB_rowIterator_getRowIndex #undef GxB_rowIterator_getColIndex //------------------------------------------------------------------------------ // GxB_rowIterator_attach: attach a row iterator to a matrix //------------------------------------------------------------------------------ // On input, the iterator must already exist, having been created by // GxB_Iterator_new. // GxB_rowIterator_attach attaches a row iterator to a matrix. If the iterator // is already attached to a matrix, it is detached and then attached to the // given matrix A. // The following error conditions are returned: // GrB_NULL_POINTER: if the iterator or A are NULL. // GrB_INVALID_OBJECT: if the matrix A is invalid. // GrB_NOT_IMPLEMENTED: if the matrix A cannot be iterated by row. // GrB_OUT_OF_MEMORY: if the method runs out of memory. // If successful, the row iterator is attached to the matrix, but not to any // specific row. Use GxB_rowIterator_*seek* to move the iterator to a row. GrB_Info GxB_rowIterator_attach ( GxB_Iterator iterator, GrB_Matrix A, GrB_Descriptor desc ) { return (GB_Iterator_attach (iterator, A, GxB_BY_ROW, desc)) ; } //------------------------------------------------------------------------------ // GxB_rowIterator_kount: upper bound on the # of nonempty rows of a matrix //------------------------------------------------------------------------------ // On input, the row iterator must be attached to a matrix, but need not be at // any specific row; results are undefined if this condition is not met. // GxB_rowIterator_kount returns an upper bound on the # of non-empty rows of a // matrix. A GraphBLAS library may always return this as simply nrows(A), but // in some libraries, it may be a value between the # of rows with at least one // entry, and nrows(A), inclusive. Any value in this range is a valid return // value from this function. // For SuiteSparse:GraphBLAS: If A is m-by-n, and sparse, bitmap, or full, then // kount == m. If A is hypersparse, kount is the # of vectors held in the data // structure for the matrix, some of which may be empty, and kount <= m. GrB_Index GxB_rowIterator_kount (GxB_Iterator iterator) { return (iterator->anvec) ; } //------------------------------------------------------------------------------ // GxB_rowIterator_seekRow: move a row iterator to a different row of a matrix //------------------------------------------------------------------------------ // On input, the row iterator must be attached to a matrix, but need not be at // any specific row; results are undefined if this condition is not met. // GxB_rowIterator_seekRow moves a row iterator to the first entry of A(row,:). // If A(row,:) has no entries, the iterator may move to the first entry of next // nonempty row i for some i > row. The row index can be determined by // GxB_rowIterator_getRowIndex. // For SuiteSparse:GraphBLAS: If the matrix is hypersparse, and the row // does not appear in the hyperlist, then the iterator is moved to the first // row after the given row that does appear in the hyperlist. // The method is always successful; the following are conditions are returned: // GxB_EXHAUSTED: if the row index is >= nrows(A); the row iterator is // exhausted, but is still attached to the matrix. // GrB_NO_VALUE: if the row index is valid but A(row,:) has no entries; the // row iterator is positioned at A(row,:). // GrB_SUCCESS: if the row index is valid and A(row,:) has at least one // entry. The row iterator is positioned at A(row,:). // GxB_rowIterator_get* can be used to return the indices of // the first entry in A(row,:), and GxB_Iterator_get* can // return its value. GrB_Info GxB_rowIterator_seekRow (GxB_Iterator iterator, GrB_Index row) { return (GB_Iterator_rc_seek (iterator, row, false)) ; } //------------------------------------------------------------------------------ // GxB_rowIterator_kseek: move a row iterator to a different row of a matrix //------------------------------------------------------------------------------ // On input, the row iterator must be attached to a matrix, but need not be at // any specific row; results are undefined if this condition is not met. // GxB_rowIterator_kseek is identical to GxB_rowIterator_seekRow, except for // how the row index is specified. The row is the kth non-empty row of A. // More precisely, k is in the range 0 to kount-1, where kount is the value // returned by GxB_rowIterator_kount. GrB_Info GxB_rowIterator_kseek (GxB_Iterator iterator, GrB_Index k) { return (GB_Iterator_rc_seek (iterator, k, true)) ; } //------------------------------------------------------------------------------ // GxB_rowIterator_nextRow: move a row iterator to the next row of a matrix //------------------------------------------------------------------------------ // On input, the row iterator must already be attached to a matrix via a prior // call to GxB_rowIterator_attach, and the iterator must be at a specific row, // via a prior call to GxB_rowIterator_*seek* or GxB_rowIterator_nextRow; // results are undefined if this condition is not met. // If the the row iterator is currently at A(row,:), it is moved to A(row+1,:), // or to the first non-empty row after A(row,:), at the discretion of this // method. That is, empty rows may be skipped. // The method is always successful, and the return conditions are identical to // the return conditions of GxB_rowIterator_seekRow. GrB_Info GxB_rowIterator_nextRow (GxB_Iterator iterator) { return (GB_Iterator_rc_knext (iterator)) ; } //------------------------------------------------------------------------------ // GxB_rowIterator_nextCol: move a row iterator to the next entry in A(row,:) //------------------------------------------------------------------------------ // On input, the row iterator must already be attached to a matrix via a prior // call to GxB_rowIterator_attach, and the iterator must be at a specific row, // via a prior call to GxB_rowIterator_*seek* or GxB_rowIterator_nextRow; // results are undefined if this condition is not met. // The method is always successful, and returns the following conditions: // GrB_NO_VALUE: If the iterator is already exhausted, or if there is no // entry in the current A(row,;), // GrB_SUCCESS: If the row iterator has been moved to the next entry in // A(row,:). GrB_Info GxB_rowIterator_nextCol (GxB_Iterator iterator) { return (GB_Iterator_rc_inext (iterator)) ; } //------------------------------------------------------------------------------ // GxB_rowIterator_getRowIndex: get current row index of a row iterator //------------------------------------------------------------------------------ // On input, the iterator must be already successfully attached to matrix as a // row iterator; results are undefined if this condition is not met. // The method returns nrows(A) if the iterator is exhausted, or the current // row index otherwise. There need not be any entry in the current row. // Zero is returned if the iterator is attached to the matrix but // GxB_rowIterator_*seek* has not been called, but this does not mean the // iterator is positioned at row zero. GrB_Index GxB_rowIterator_getRowIndex (GxB_Iterator iterator) { return (GB_Iterator_rc_getj (iterator)) ; } //------------------------------------------------------------------------------ // GxB_rowIterator_getColIndex: get current column index of a row iterator //------------------------------------------------------------------------------ // On input, the iterator must be already successfully attached to matrix as a // row iterator, and in addition, the row iterator must be positioned at a // valid entry present in the matrix. That is, the last call to // GxB_rowIterator_*seek* or GxB_rowIterator_*next*, must have returned // GrB_SUCCESS. Results are undefined if this condition is not met. GrB_Index GxB_rowIterator_getColIndex (GxB_Iterator iterator) { return (GB_Iterator_rc_geti (iterator)) ; }