@@ -104,11 +104,134 @@ struct BidiagonalIndex <: MatrixIndex
104
104
end
105
105
106
106
struct TridiagonalIndex <: MatrixIndex
107
- count:: Int
107
+ count:: Int # count==nsize+nsize-1+nsize-1
108
108
nsize:: Int
109
109
isrow:: Bool
110
110
end
111
111
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
+
112
235
Base. firstindex (ind:: MatrixIndex )= 1
113
236
Base. lastindex (ind:: MatrixIndex )= ind. count
114
237
Base. length (ind:: MatrixIndex )= ind. count
@@ -135,6 +258,49 @@ function Base.getindex(ind::TridiagonalIndex,i::Int)
135
258
end
136
259
end
137
260
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
+
138
304
function findstructralnz (x:: Bidiagonal )
139
305
n= size (x,1 )
140
306
isup= x. uplo== ' U' ? true : false
@@ -225,28 +391,58 @@ function __init__()
225
391
end
226
392
227
393
@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
228
403
is_structured (:: Type{<:BandedMatrices.BandedMatrix} ) = true
229
404
fast_matrix_colors (:: Type{<:BandedMatrices.BandedMatrix} ) = true
230
405
231
406
function matrix_colors (A:: BandedMatrices.BandedMatrix )
232
- u,l = bandwidths (A)
407
+ l,u = BandedMatrices . bandwidths (A)
233
408
width= u+ l+ 1
234
409
_cycle (1 : width,size (A,2 ))
235
410
end
236
411
237
412
end
238
413
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
242
438
fast_matrix_colors (:: Type{<:BlockBandedMatrices.BlockBandedMatrix} ) = true
243
439
fast_matrix_colors (:: Type{<:BlockBandedMatrices.BandedBlockBandedMatrix} ) = true
244
440
245
441
function matrix_colors (A:: BlockBandedMatrices.BlockBandedMatrix )
246
- l,u= blockbandwidths (A)
442
+ l,u= BlockBandedMatrices . blockbandwidths (A)
247
443
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]
250
446
blockcolors= _cycle (1 : blockwidth,nblock)
251
447
# the reserved number of colors of a block is the maximum length of columns of blocks with the same block color
252
448
ncolors= [maximum (cols[i: blockwidth: nblock]) for i in 1 : blockwidth]
@@ -257,12 +453,12 @@ function __init__()
257
453
end
258
454
259
455
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)
262
458
blockwidth= l+ u+ 1
263
459
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]
266
462
blockcolors= _cycle (1 : blockwidth,nblock)
267
463
# 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
268
464
ncolors= [min (subblockwidth,maximum (cols[i: blockwidth: nblock])) for i in 1 : min (blockwidth,nblock)]
0 commit comments