diff --git a/src/generic.jl b/src/generic.jl index de37f081..4625aac8 100644 --- a/src/generic.jl +++ b/src/generic.jl @@ -1493,6 +1493,24 @@ function _isbanded_impl(A, kl, ku) beyond ku, where the elements should all be zero. The reason we separate this from the third group is that we may loop over all the rows using A[:, col] instead of A[rowrange, col], which is usually faster. + + E.g., in the following 6x10 matrix with (kl,ku) = (-1,1): + 1 1 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 0 0 0 + 0 2 3 3 0 0 0 0 0 0 + 0 0 3 4 4 0 0 0 0 0 + 0 0 0 4 5 5 0 0 0 0 + 0 0 0 0 5 6 6 0 0 0 + + last_col_nonzeroblocks: 7, as every column beyond this is entirely zero + last_col_emptytoprows: 2, as there are zeros above the stored bands beyond this column + last_col_nonemptybottomrows: 4, as there are no zeros below the stored bands beyond this column + colrange_onlybottomrows: 1:2, as these columns only have zeros below the stored bands + colrange_topbottomrows: 3:4, as these columns have zeros both above and below the stored bands + colrange_onlytoprows_nonzero: 5:7, as these columns only have zeros above the stored bands + colrange_zero_block: 8:10, as every column in this range is filled with zeros + + These are used to determine which rows to check for zeros in each column. =# last_col_nonzeroblocks = size(A,1) + ku # fully zero rectangular block beyond this column @@ -1500,7 +1518,9 @@ function _isbanded_impl(A, kl, ku) last_col_nonemptybottomrows = size(A,1) + kl - 1 # empty bottom rows after this column colrange_onlybottomrows = firstindex(A,2):min(last_col_nonemptybottomrows, last_col_emptytoprows) - colrange_topbottomrows = max(last_col_emptytoprows, last(colrange_onlybottomrows))+1:last_col_nonzeroblocks + col_topbotrows_start = max(last_col_emptytoprows, last(colrange_onlybottomrows))+1 + col_topbotrows_end = min(last_col_nonemptybottomrows, last_col_nonzeroblocks) + colrange_topbottomrows = col_topbotrows_start:col_topbotrows_end colrange_onlytoprows_nonzero = last(colrange_topbottomrows)+1:last_col_nonzeroblocks colrange_zero_block = last_col_nonzeroblocks+1:lastindex(A,2) diff --git a/test/generic.jl b/test/generic.jl index 36dc5c94..758f4744 100644 --- a/test/generic.jl +++ b/test/generic.jl @@ -534,17 +534,17 @@ end @testset "generic functions for checking whether matrices have banded structure" begin pentadiag = [1 2 3; 4 5 6; 7 8 9] - tridiag = [1 2 0; 4 5 6; 0 8 9] - tridiagG = GenericArray([1 2 0; 4 5 6; 0 8 9]) + tridiag = diagm(-1=>1:6, 1=>1:6) + tridiagG = GenericArray(tridiag) Tridiag = Tridiagonal(tridiag) ubidiag = [1 2 0; 0 5 6; 0 0 9] - ubidiagG = GenericArray([1 2 0; 0 5 6; 0 0 9]) + ubidiagG = GenericArray(ubidiag) uBidiag = Bidiagonal(ubidiag, :U) lbidiag = [1 0 0; 4 5 0; 0 8 9] - lbidiagG = GenericArray([1 0 0; 4 5 0; 0 8 9]) + lbidiagG = GenericArray(lbidiag) lBidiag = Bidiagonal(lbidiag, :L) adiag = [1 0 0; 0 5 0; 0 0 9] - adiagG = GenericArray([1 0 0; 0 5 0; 0 0 9]) + adiagG = GenericArray(adiag) aDiag = Diagonal(adiag) @testset "istriu" begin @test !istriu(pentadiag) @@ -638,6 +638,17 @@ end end end end + + tridiag = diagm(-1=>1:6, 1=>1:6) + A = [tridiag zeros(size(tridiag,1), 2)] + G = GenericArray(A) + @testset for (kl,ku) in Iterators.product(-10:10, -10:10) + @test isbanded(A, kl, ku) == isbanded(G, kl, ku) + end + @testset for k in -10:10 + @test istriu(A,k) == istriu(G,k) + @test istril(A,k) == istril(G,k) + end end @testset "missing values" begin