Skip to content

Commit 1c67da4

Browse files
authored
Optimized TimesOperator AbstractRange indexing (#293)
1 parent 55cdd2f commit 1c67da4

File tree

2 files changed

+75
-55
lines changed

2 files changed

+75
-55
lines changed

src/Operators/general/algebra.jl

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,16 @@ end
105105
for TYP in (:RaggedMatrix,:Matrix,:BandedMatrix,
106106
:BlockBandedMatrix,:BandedBlockBandedMatrix)
107107
@eval begin
108-
$TYP(P::SubOperator{T,PP,NTuple{2,BlockRange1}}) where {T,PP<:PlusOperator} =
108+
$TYP(P::SubOperator{<:Any,<:PlusOperator,NTuple{2,BlockRange1}}) =
109109
convert_axpy!($TYP,P) # use axpy! to copy
110-
$TYP(P::SubOperator{T,PP}) where {T,PP<:PlusOperator} =
110+
$TYP(P::SubOperator{<:Any,<:PlusOperator}) =
111111
convert_axpy!($TYP,P) # use axpy! to copy
112-
$TYP(P::SubOperator{T,PP,NTuple{2,UnitRange{Int}}}) where {T,PP<:PlusOperator} =
112+
$TYP(P::SubOperator{<:Any,<:PlusOperator,NTuple{2,UnitRange{Int}}}) =
113113
convert_axpy!($TYP,P) # use axpy! to copy
114114
end
115115
end
116116

117-
function BLAS.axpy!(α,P::SubOperator{T,PP},A::AbstractMatrix) where {T,PP<:PlusOperator}
117+
function BLAS.axpy!(α,P::SubOperator{<:Any,<:PlusOperator},A::AbstractMatrix)
118118
for op in parent(P).ops
119119
BLAS.axpy!(α, view(op,P.indexes[1],P.indexes[2]), A)
120120
end
@@ -393,73 +393,84 @@ end
393393
_rettype(::Type{BandedMatrix{T}}) where {T} = BandedMatrix{T,Matrix{T},Base.OneTo{Int}}
394394
_rettype(T) = T
395395
for TYP in (:Matrix, :BandedMatrix, :RaggedMatrix)
396-
@eval function $TYP(V::SubOperator{T,<:TimesOperator,NTuple{2,UnitRange{Int}}}) where {T}
397-
P = parent(V)
398-
399-
if isbanded(P)
400-
if $TYP BandedMatrix
401-
return $TYP(BandedMatrix(V))
396+
@eval begin
397+
function $TYP(V::SubOperator{T,<:TimesOperator,NTuple{2,UnitRange{Int}}}) where {T}
398+
P = parent(V)
399+
400+
if isbanded(P)
401+
if $TYP BandedMatrix
402+
return $TYP(BandedMatrix(V))
403+
end
404+
elseif isbandedblockbanded(P)
405+
N = block(rangespace(P), last(parentindices(V)[1]))
406+
M = block(domainspace(P), last(parentindices(V)[2]))
407+
B = P[Block(1):N, Block(1):M]
408+
return $TYP(view(B, parentindices(V)...), _colstops(V))
402409
end
403-
elseif isbandedblockbanded(P)
404-
N = block(rangespace(P), last(parentindices(V)[1]))
405-
M = block(domainspace(P), last(parentindices(V)[2]))
406-
B = P[Block(1):N, Block(1):M]
407-
return $TYP(view(B, parentindices(V)...), _colstops(V))
408-
end
409410

410-
kr,jr = parentindices(V)
411+
kr,jr = parentindices(V)
411412

412-
(isempty(kr) || isempty(jr)) && return $TYP(Zeros, V)
413+
(isempty(kr) || isempty(jr)) && return $TYP(Zeros, V)
413414

414-
if maximum(kr) > size(P,1) || maximum(jr) > size(P,2) ||
415-
minimum(kr) < 1 || minimum(jr) < 1
416-
throw(BoundsError(P, (kr,jr)))
417-
end
415+
if maximum(kr) > size(P,1) || maximum(jr) > size(P,2) ||
416+
minimum(kr) < 1 || minimum(jr) < 1
417+
throw(BoundsError(P, (kr,jr)))
418+
end
418419

419-
@assert length(P.ops) 2
420-
if size(V,1)==0
421-
return $TYP(Zeros, V)
422-
end
420+
@assert length(P.ops) 2
421+
if size(V,1)==0
422+
return $TYP(Zeros, V)
423+
end
423424

424425

425-
# find optimal truncations for each operator
426-
# by finding the non-zero entries
427-
krlin = Matrix{Union{Int,InfiniteCardinal{0}}}(undef,length(P.ops),2)
426+
# find optimal truncations for each operator
427+
# by finding the non-zero entries
428+
krlin = Matrix{Union{Int,InfiniteCardinal{0}}}(undef,length(P.ops),2)
428429

429-
krlin[1,1],krlin[1,2]=kr[1],kr[end]
430-
for m=1:length(P.ops)-1
431-
krlin[m+1,1]=rowstart(P.ops[m],krlin[m,1])
432-
krlin[m+1,2]=rowstop(P.ops[m],krlin[m,2])
433-
end
434-
krlin[end,1]=max(krlin[end,1],colstart(P.ops[end],jr[1]))
435-
krlin[end,2]=min(krlin[end,2],colstop(P.ops[end],jr[end]))
436-
for m=length(P.ops)-1:-1:2
437-
krlin[m,1]=max(krlin[m,1],colstart(P.ops[m],krlin[m+1,1]))
438-
krlin[m,2]=min(krlin[m,2],colstop(P.ops[m],krlin[m+1,2]))
439-
end
430+
krlin[1,1],krlin[1,2]=kr[1],kr[end]
431+
for m=1:length(P.ops)-1
432+
krlin[m+1,1]=rowstart(P.ops[m],krlin[m,1])
433+
krlin[m+1,2]=rowstop(P.ops[m],krlin[m,2])
434+
end
435+
krlin[end,1]=max(krlin[end,1],colstart(P.ops[end],jr[1]))
436+
krlin[end,2]=min(krlin[end,2],colstop(P.ops[end],jr[end]))
437+
for m=length(P.ops)-1:-1:2
438+
krlin[m,1]=max(krlin[m,1],colstart(P.ops[m],krlin[m+1,1]))
439+
krlin[m,2]=min(krlin[m,2],colstop(P.ops[m],krlin[m+1,2]))
440+
end
440441

441442

442-
krl = Matrix{Int}(krlin)
443+
krl = Matrix{Int}(krlin)
443444

444-
# Check if any range is invalid, in which case return zero
445-
for m=1:length(P.ops)
446-
if krl[m,1]>krl[m,2]
447-
return $TYP(Zeros, V)
445+
# Check if any range is invalid, in which case return zero
446+
for m=1:length(P.ops)
447+
if krl[m,1]>krl[m,2]
448+
return $TYP(Zeros, V)
449+
end
448450
end
449-
end
450451

451452

452453

453-
# The following returns a banded Matrix with all rows
454-
# for large k its upper triangular
455-
RT = $TYP{T}
456-
RT2 = _rettype(RT)
457-
BA::RT2 = strictconvert(RT, P.ops[end][krl[end,1]:krl[end,2],jr])
458-
for m = (length(P.ops)-1):-1:1
459-
BA = strictconvert(RT, P.ops[m][krl[m,1]:krl[m,2],krl[m+1,1]:krl[m+1,2]]) * BA
460-
end
454+
# The following returns a banded Matrix with all rows
455+
# for large k its upper triangular
456+
RT = $TYP{T}
457+
RT2 = _rettype(RT)
458+
BA::RT2 = strictconvert(RT, P.ops[end][krl[end,1]:krl[end,2],jr])
459+
for m = (length(P.ops)-1):-1:1
460+
BA = strictconvert(RT, P.ops[m][krl[m,1]:krl[m,2],krl[m+1,1]:krl[m+1,2]]) * BA
461+
end
461462

462-
RT(BA)
463+
RT(BA)
464+
end
465+
function $TYP(V::SubOperator{<:Any,<:TimesOperator,<:NTuple{2,AbstractRange{Int}}})
466+
pinds = parentindices(V)
467+
P = parent(V)
468+
pinds_ur = map(x->first(x):last(x), pinds)
469+
W = view(P, pinds_ur...)
470+
A = $TYP(W)
471+
B = A[map(x -> range(1, step=step(x), length=length(x)), pinds)...]
472+
strictconvert($TYP, B)
473+
end
463474
end
464475
end
465476

test/runtests.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,15 @@ end
286286
C = B * B
287287
@test_throws BoundsError @view C[1:2, 0:2]
288288
@test_throws BoundsError @view C[1:10, 1:2]
289+
290+
f = Fun(PointSpace(1:10))
291+
M = Multiplication(f, space(f))
292+
T = TimesOperator([M,M])
293+
S = view(T, 1:2:7, 1:2:7)
294+
B = BandedMatrix(S)
295+
for I in CartesianIndices(B)
296+
@test B[I] S[Tuple(I)...]
297+
end
289298
end
290299
end
291300
@testset "conversion to a matrix" begin

0 commit comments

Comments
 (0)