@@ -104,11 +104,134 @@ struct BidiagonalIndex <: MatrixIndex
104104end
105105
106106struct TridiagonalIndex <: MatrixIndex
107- count:: Int
107+ count:: Int # count==nsize+nsize-1+nsize-1
108108 nsize:: Int
109109 isrow:: Bool
110110end
111111
112+ struct BandedMatrixIndex <: MatrixIndex
113+ count:: Int
114+ rowsize:: Int
115+ colsize:: Int
116+ bandinds:: Array{Int,1}
117+ bandsizes:: Array{Int,1}
118+ isrow:: Bool
119+ end
120+
121+ function _bandsize (bandind,rowsize,colsize)
122+ - (rowsize- 1 ) <= bandind <= colsize- 1 || throw (ErrorException (" Invalid Bandind" ))
123+ if (bandind* (colsize- rowsize)> 0 ) & (abs (bandind)<= abs (colsize- rowsize))
124+ return min (rowsize,colsize)
125+ elseif bandind* (colsize- rowsize)<= 0
126+ return min (rowsize,colsize)- abs (bandind)
127+ else
128+ return min (rowsize,colsize)- abs (bandind)+ abs (colsize- rowsize)
129+ end
130+ end
131+
132+ function BandedMatrixIndex (rowsize,colsize,lowerbandwidth,upperbandwidth,isrow)
133+ upperbandwidth> - lowerbandwidth || throw (ErrorException (" Invalid Bandwidths" ))
134+ bandinds= upperbandwidth: - 1 : - lowerbandwidth
135+ bandsizes= [_bandsize (band,rowsize,colsize) for band in bandinds]
136+ BandedMatrixIndex (sum (bandsizes),rowsize,colsize,bandinds,bandsizes,isrow)
137+ end
138+
139+ struct BlockBandedMatrixIndex <: MatrixIndex
140+ count:: Int
141+ refinds:: Array{Int,1}
142+ refcoords:: Array{Int,1} # storing col or row inds at ref points
143+ isrow:: Bool
144+ end
145+
146+ function BlockBandedMatrixIndex (nrowblock,ncolblock,rowsizes,colsizes,l,u)
147+ blockrowind= BandedMatrixIndex (nrowblock,ncolblock,l,u,true )
148+ blockcolind= BandedMatrixIndex (nrowblock,ncolblock,l,u,false )
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
151+ refinds= Array {Int,1} ()
152+ refrowcoords= Array {Int,1} ()
153+ refcolcoords= Array {Int,1} ()
154+ rowheights= cumsum (pushfirst! (copy (rowsizes),1 ))
155+ blockheight= 0
156+ blockrow= 1
157+ blockcol= 1
158+ currenti= 1
159+ lastrowind= sortedinds[1 ][1 ]- 1
160+ lastcolind= sortedinds[1 ][2 ]
161+ for ind in sortedinds
162+ rowind,colind= ind
163+ if colind== lastcolind
164+ if rowind> lastrowind
165+ blockheight+= rowsizes[rowind]
166+ end
167+ else
168+ for j in blockcol: blockcol+ colsizes[lastcolind]- 1
169+ push! (refinds,currenti)
170+ push! (refrowcoords,blockrow)
171+ push! (refcolcoords,j)
172+ currenti+= blockheight
173+ end
174+ blockcol+= colsizes[lastcolind]
175+ blockrow= rowheights[rowind]
176+ blockheight= rowsizes[rowind]
177+ end
178+ lastcolind= colind
179+ lastrowind= rowind
180+ end
181+ for j in blockcol: blockcol+ colsizes[lastcolind]- 1
182+ push! (refinds,currenti)
183+ push! (refrowcoords,blockrow)
184+ push! (refcolcoords,j)
185+ currenti+= blockheight
186+ end
187+ push! (refinds,currenti)# guard
188+ push! (refrowcoords,- 1 )
189+ push! (refcolcoords,- 1 )
190+ rowindobj= BlockBandedMatrixIndex (currenti- 1 ,refinds,refrowcoords,true )
191+ colindobj= BlockBandedMatrixIndex (currenti- 1 ,refinds,refcolcoords,false )
192+ rowindobj,colindobj
193+ end
194+
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+
112235Base. firstindex (ind:: MatrixIndex )= 1
113236Base. lastindex (ind:: MatrixIndex )= ind. count
114237Base. length (ind:: MatrixIndex )= ind. count
@@ -135,6 +258,49 @@ function Base.getindex(ind::TridiagonalIndex,i::Int)
135258 end
136259end
137260
261+ function Base. getindex (ind:: BandedMatrixIndex ,i:: Int )
262+ 1 <= i <= ind. count || throw (BoundsError (ind, i))
263+ _i= i
264+ p= 1
265+ while _i- ind. bandsizes[p]> 0
266+ _i-= ind. bandsizes[p]
267+ p+= 1
268+ end
269+ bandind= ind. bandinds[p]
270+ startfromone= ! xor (ind. isrow,(bandind> 0 ))
271+ if startfromone
272+ return _i
273+ else
274+ return _i+ abs (bandind)
275+ end
276+ end
277+
278+ function Base. getindex (ind:: BlockBandedMatrixIndex ,i:: Int )
279+ 1 <= i <= ind. count || throw (BoundsError (ind, i))
280+ p= 1
281+ while i- ind. refinds[p]>= 0
282+ p+= 1
283+ end
284+ p-= 1
285+ _i= i- ind. refinds[p]
286+ if ind. isrow
287+ return ind. refcoords[p]+ _i
288+ else
289+ return ind. refcoords[p]
290+ end
291+ end
292+
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+
138304function findstructralnz (x:: Bidiagonal )
139305 n= size (x,1 )
140306 isup= x. uplo== ' U' ? true : false
@@ -225,28 +391,58 @@ function __init__()
225391 end
226392
227393 @require BandedMatrices= " aae01518-5342-5314-be14-df237901396f" begin
394+ function findstructralnz (x:: BandedMatrices.BandedMatrix )
395+ l,u= BandedMatrices. bandwidths (x)
396+ rowsize,colsize= size (x)
397+ rowind= BandedMatrixIndex (rowsize,colsize,l,u,true )
398+ colind= BandedMatrixIndex (rowsize,colsize,l,u,false )
399+ (rowind,colind)
400+ end
401+
402+ has_sparsestruct (:: Type{<:BandedMatrices.BandedMatrix} ) = true
228403 is_structured (:: Type{<:BandedMatrices.BandedMatrix} ) = true
229404 fast_matrix_colors (:: Type{<:BandedMatrices.BandedMatrix} ) = true
230405
231406 function matrix_colors (A:: BandedMatrices.BandedMatrix )
232- u,l = bandwidths (A)
407+ l,u = BandedMatrices . bandwidths (A)
233408 width= u+ l+ 1
234409 _cycle (1 : width,size (A,2 ))
235410 end
236411
237412 end
238413
239- @require BlockBandedMatrices= " aae01518-5342-5314-be14-df237901396f" begin
240- is_structured (:: Type{<:BandedMatrices.BlockBandedMatrix} ) = true
241- is_structured (:: Type{<:BandedMatrices.BandedBlockBandedMatrix} ) = true
414+ @require BlockBandedMatrices= " ffab5731-97b5-5995-9138-79e8c1846df0" begin
415+ function findstructralnz (x:: BlockBandedMatrices.BlockBandedMatrix )
416+ l,u= BlockBandedMatrices. blockbandwidths (x)
417+ nrowblock= BlockBandedMatrices. nblocks (x,1 )
418+ ncolblock= BlockBandedMatrices. nblocks (x,2 )
419+ rowsizes= [BlockBandedMatrices. blocksize (x,(i,1 ))[1 ] for i in 1 : nrowblock]
420+ colsizes= [BlockBandedMatrices. blocksize (x,(1 ,i))[2 ] for i in 1 : ncolblock]
421+ BlockBandedMatrixIndex (nrowblock,ncolblock,rowsizes,colsizes,l,u)
422+ end
423+
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+
434+ has_sparsestruct (:: Type{<:BlockBandedMatrices.BlockBandedMatrix} ) = true
435+ has_sparsestruct (:: Type{<:BlockBandedMatrices.BandedBlockBandedMatrix} ) = true
436+ is_structured (:: Type{<:BlockBandedMatrices.BlockBandedMatrix} ) = true
437+ is_structured (:: Type{<:BlockBandedMatrices.BandedBlockBandedMatrix} ) = true
242438 fast_matrix_colors (:: Type{<:BlockBandedMatrices.BlockBandedMatrix} ) = true
243439 fast_matrix_colors (:: Type{<:BlockBandedMatrices.BandedBlockBandedMatrix} ) = true
244440
245441 function matrix_colors (A:: BlockBandedMatrices.BlockBandedMatrix )
246- l,u= blockbandwidths (A)
442+ l,u= BlockBandedMatrices . blockbandwidths (A)
247443 blockwidth= l+ u+ 1
248- nblock= nblocks (A,2 )
249- cols= [blocksize (A,(1 ,i))[2 ] for i in 1 : nblock]
444+ nblock= BlockBandedMatrices . nblocks (A,2 )
445+ cols= [BlockBandedMatrices . blocksize (A,(1 ,i))[2 ] for i in 1 : nblock]
250446 blockcolors= _cycle (1 : blockwidth,nblock)
251447 # the reserved number of colors of a block is the maximum length of columns of blocks with the same block color
252448 ncolors= [maximum (cols[i: blockwidth: nblock]) for i in 1 : blockwidth]
@@ -257,12 +453,12 @@ function __init__()
257453 end
258454
259455 function matrix_colors (A:: BlockBandedMatrices.BandedBlockBandedMatrix )
260- l,u= blockbandwidths (A)
261- lambda,mu= subblockbandwidths (A)
456+ l,u= BlockBandedMatrices . blockbandwidths (A)
457+ lambda,mu= BlockBandedMatrices . subblockbandwidths (A)
262458 blockwidth= l+ u+ 1
263459 subblockwidth= lambda+ mu+ 1
264- nblock= nblocks (A,2 )
265- cols= [blocksize (A,(1 ,i))[2 ] for i in 1 : nblock]
460+ nblock= BlockBandedMatrices . nblocks (A,2 )
461+ cols= [BlockBandedMatrices . blocksize (A,(1 ,i))[2 ] for i in 1 : nblock]
266462 blockcolors= _cycle (1 : blockwidth,nblock)
267463 # the reserved number of colors of a block is the min of subblockwidth and the largest length of columns of blocks with the same block color
268464 ncolors= [min (subblockwidth,maximum (cols[i: blockwidth: nblock])) for i in 1 : min (blockwidth,nblock)]
0 commit comments