@@ -1364,6 +1364,77 @@ function sparse_sortedlinearindices!(I::Vector{Ti}, V::Vector, m::Int, n::Int) w
13641364 return SparseMatrixCSC (m, n, colptr, I, V)
13651365end
13661366
1367+ # findfirst/next/prev/last
1368+ function _idxfirstnz (A:: SparseMatrixCSC , ij:: CartesianIndex{2} )
1369+ nzr = nzrange (A, ij[2 ])
1370+ searchk = searchsortedfirst (A. rowval, ij[1 ], first (nzr), last (nzr), Forward)
1371+ return _idxnextnz (A, searchk)
1372+ end
1373+
1374+ function _idxlastnz (A:: SparseMatrixCSC , ij:: CartesianIndex{2} )
1375+ nzr = nzrange (A, ij[2 ])
1376+ searchk = searchsortedlast (A. rowval, ij[1 ], first (nzr), last (nzr), Forward)
1377+ return _idxprevnz (A, searchk)
1378+ end
1379+
1380+ function _idxnextnz (A:: SparseMatrixCSC , idx:: Integer )
1381+ nnza = nnz (A)
1382+ nzval = nonzeros (A)
1383+ z = zero (eltype (A))
1384+ while idx <= nnza
1385+ nzv = nzval[idx]
1386+ ! isequal (nzv, z) && return idx, nzv
1387+ idx += 1
1388+ end
1389+ return zero (idx), z
1390+ end
1391+
1392+ function _idxprevnz (A:: SparseMatrixCSC , idx:: Integer )
1393+ nzval = nonzeros (A)
1394+ z = zero (eltype (A))
1395+ while idx > 0
1396+ nzv = nzval[idx]
1397+ ! isequal (nzv, z) && return idx, nzv
1398+ idx -= 1
1399+ end
1400+ return zero (idx), z
1401+ end
1402+
1403+ function _idx_to_cartesian (A:: SparseMatrixCSC , idx:: Integer )
1404+ rowval = rowvals (A)
1405+ i = rowval[idx]
1406+ j = searchsortedlast (A. colptr, idx, 1 , size (A, 2 ), Base. Order. Forward)
1407+ return CartesianIndex (i, j)
1408+ end
1409+
1410+ function Base. findnext (pred:: Function , A:: SparseMatrixCSC , ij:: CartesianIndex{2} )
1411+ if nnz (A) == length (A) || pred (zero (eltype (A)))
1412+ return invoke (findnext, Tuple{Function,Any,Any}, pred, A, ij)
1413+ end
1414+ idx, nzv = _idxfirstnz (A, ij)
1415+ while idx > 0
1416+ if pred (nzv)
1417+ return _idx_to_cartesian (A, idx)
1418+ end
1419+ idx, nzv = _idxnextnz (A, idx + 1 )
1420+ end
1421+ return nothing
1422+ end
1423+
1424+ function Base. findprev (pred:: Function , A:: SparseMatrixCSC , ij:: CartesianIndex{2} )
1425+ if nnz (A) == length (A) || pred (zero (eltype (A)))
1426+ return invoke (findprev, Tuple{Function,Any,Any}, pred, A, ij)
1427+ end
1428+ idx, nzv = _idxlastnz (A, ij)
1429+ while idx > 0
1430+ if pred (nzv)
1431+ return _idx_to_cartesian (A, idx)
1432+ end
1433+ idx, nzv = _idxprevnz (A, idx - 1 )
1434+ end
1435+ return nothing
1436+ end
1437+
13671438"""
13681439 sprand([rng],[type],m,[n],p::AbstractFloat,[rfn])
13691440
0 commit comments