Skip to content

Commit 380977b

Browse files
committed
add findstructral support for BandedBlockBandedMatrix
1 parent a7981c8 commit 380977b

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

src/ArrayInterface.jl

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ end
146146
function BlockBandedMatrixIndex(nrowblock,ncolblock,rowsizes,colsizes,l,u)
147147
blockrowind=BandedMatrixIndex(nrowblock,ncolblock,l,u,true)
148148
blockcolind=BandedMatrixIndex(nrowblock,ncolblock,l,u,false)
149-
sortedinds=sort([(blockrowind[i],blockcolind[i]) for i in 1:length(blockrowind)],by=x->x[2])
150-
sort!(sortedinds,by=x->x[1],alg=InsertionSort)#stable sort keeps the second index in order
149+
sortedinds=sort([(blockrowind[i],blockcolind[i]) for i in 1:length(blockrowind)],by=x->x[1])
150+
sort!(sortedinds,by=x->x[2],alg=InsertionSort)#stable sort keeps the second index in order
151151
refinds=Array{Int,1}()
152152
refrowcoords=Array{Int,1}()
153153
refcolcoords=Array{Int,1}()
@@ -192,6 +192,46 @@ function BlockBandedMatrixIndex(nrowblock,ncolblock,rowsizes,colsizes,l,u)
192192
rowindobj,colindobj
193193
end
194194

195+
struct BandedBlockBandedMatrixIndex <: MatrixIndex
196+
count::Int
197+
refinds::Array{Int,1}
198+
refcoords::Array{Int,1}#storing col or row inds at ref points
199+
reflocalinds::Array{BandedMatrixIndex,1}
200+
isrow::Bool
201+
end
202+
203+
function BandedBlockBandedMatrixIndex(nrowblock,ncolblock,rowsizes,colsizes,l,u,lambda,mu)
204+
blockrowind=BandedMatrixIndex(nrowblock,ncolblock,l,u,true)
205+
blockcolind=BandedMatrixIndex(nrowblock,ncolblock,l,u,false)
206+
sortedinds=sort([(blockrowind[i],blockcolind[i]) for i in 1:length(blockrowind)],by=x->x[1])
207+
sort!(sortedinds,by=x->x[2],alg=InsertionSort)#stable sort keeps the second index in order
208+
rowheights=cumsum(pushfirst!(copy(rowsizes),1))
209+
colwidths=cumsum(pushfirst!(copy(colsizes),1))
210+
currenti=1
211+
refinds=Array{Int,1}()
212+
refrowcoords=Array{Int,1}()
213+
refcolcoords=Array{Int,1}()
214+
reflocalrowinds=Array{BandedMatrixIndex,1}()
215+
reflocalcolinds=Array{BandedMatrixIndex,1}()
216+
for ind in sortedinds
217+
rowind,colind=ind
218+
localrowind=BandedMatrixIndex(rowsizes[rowind],colsizes[colind],lambda,mu,true)
219+
localcolind=BandedMatrixIndex(rowsizes[rowind],colsizes[colind],lambda,mu,false)
220+
push!(refinds,currenti)
221+
push!(refrowcoords,rowheights[rowind])
222+
push!(refcolcoords,colwidths[colind])
223+
push!(reflocalrowinds,localrowind)
224+
push!(reflocalcolinds,localcolind)
225+
currenti+=localrowind.count
226+
end
227+
push!(refinds,currenti)
228+
push!(refrowcoords,-1)
229+
push!(refcolcoords,-1)
230+
rowindobj=BandedBlockBandedMatrixIndex(currenti-1,refinds,refrowcoords,reflocalrowinds,true)
231+
colindobj=BandedBlockBandedMatrixIndex(currenti-1,refinds,refcolcoords,reflocalcolinds,false)
232+
rowindobj,colindobj
233+
end
234+
195235
Base.firstindex(ind::MatrixIndex)=1
196236
Base.lastindex(ind::MatrixIndex)=ind.count
197237
Base.length(ind::MatrixIndex)=ind.count
@@ -250,6 +290,17 @@ function Base.getindex(ind::BlockBandedMatrixIndex,i::Int)
250290
end
251291
end
252292

293+
function Base.getindex(ind::BandedBlockBandedMatrixIndex,i::Int)
294+
1 <= i <= ind.count || throw(BoundsError(ind, i))
295+
p=1
296+
while i-ind.refinds[p]>=0
297+
p+=1
298+
end
299+
p-=1
300+
_i=i-ind.refinds[p]+1
301+
ind.reflocalinds[p][_i]+ind.refcoords[p]-1
302+
end
303+
253304
function findstructralnz(x::Bidiagonal)
254305
n=size(x,1)
255306
isup= x.uplo=='U' ? true : false
@@ -370,7 +421,18 @@ function __init__()
370421
BlockBandedMatrixIndex(nrowblock,ncolblock,rowsizes,colsizes,l,u)
371422
end
372423

424+
function findstructralnz(x::BlockBandedMatrices.BandedBlockBandedMatrix)
425+
l,u=BlockBandedMatrices.blockbandwidths(x)
426+
lambda,mu=BlockBandedMatrices.subblockbandwidths(x)
427+
nrowblock=BlockBandedMatrices.nblocks(x,1)
428+
ncolblock=BlockBandedMatrices.nblocks(x,2)
429+
rowsizes=[BlockBandedMatrices.blocksize(x,(i,1))[1] for i in 1:nrowblock]
430+
colsizes=[BlockBandedMatrices.blocksize(x,(1,i))[2] for i in 1:ncolblock]
431+
BandedBlockBandedMatrixIndex(nrowblock,ncolblock,rowsizes,colsizes,l,u,lambda,mu)
432+
end
433+
373434
has_sparsestruct(::Type{<:BlockBandedMatrices.BlockBandedMatrix}) = true
435+
has_sparsestruct(::Type{<:BlockBandedMatrices.BandedBlockBandedMatrix}) = true
374436
is_structured(::Type{<:BlockBandedMatrices.BlockBandedMatrix}) = true
375437
is_structured(::Type{<:BlockBandedMatrices.BandedBlockBandedMatrix}) = true
376438
fast_matrix_colors(::Type{<:BlockBandedMatrices.BlockBandedMatrix}) = true

test/runtests.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,14 @@ rowind,colind=findstructralnz(BB)
6161
[1,5,9,2,6,10,3,7,11,4,8,12,
6262
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
6363
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
64-
1,1,1,1,1]
64+
1,1,1,1,1]
65+
66+
dense=collect(Ones(8,8))
67+
for i in 1:8
68+
dense[:,i].=[1,2,3,4,5,6,7,8]
69+
end
70+
BBB=BandedBlockBandedMatrix(dense, ([4, 4] ,[4, 4]), (1, 1), (1, 1))
71+
rowind,colind=findstructralnz(BBB)
72+
@test [BBB[rowind[i],colind[i]] for i in 1:length(rowind)]==
73+
[1,2,3,1,2,3,4,2,3,4,5,6,7,5,6,7,8,6,7,8,
74+
1,2,3,1,2,3,4,2,3,4,5,6,7,5,6,7,8,6,7,8]

0 commit comments

Comments
 (0)