Skip to content

Commit 81c70b7

Browse files
authored
Fix indexing for PartialInverseOperator (#188)
* domain promotion for cached operator * Fix PartialInverseOperator indexing
1 parent fc6f19d commit 81c70b7

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

src/Operators/general/PartialInverseOperator.jl

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
export PartialInverseOperator
42

53

@@ -23,18 +21,39 @@ rangespace(P::PartialInverseOperator)=domainspace(P.cache)
2321
domain(P::PartialInverseOperator)=domain(domainspace(P))
2422
bandwidths(P::PartialInverseOperator) = P.bandwidths
2523

24+
# Compute the value at the (k,j)th index of inv(C), assumming that C is upper triangular
25+
function _getindexinv(C, k::Integer, j::Integer, ::Type{UpperTriangular})
26+
j >= k || return zero(inv(one(eltype(C))))
27+
j == k && return inv(C[k,k])
28+
t = inv(C[k,k])
29+
# k-th row of the inverse, starting from the diagonal
30+
# but leaving out the j-th column
31+
ret = zeros(eltype(t), j-k)
32+
ret[1] = t
33+
for m in k+1:j-1 # populate the k-th row of the inverse
34+
t = zero(eltype(ret))
35+
for i in k:j-1
36+
t -= ret[i-k+1] * C[i,m]
37+
end
38+
ret[m - k + 1] = t/C[m,m]
39+
end
40+
t = zero(eltype(ret))
41+
for (rind, i) in enumerate(k:j-1)
42+
t -= ret[rind] * C[i,j]
43+
end
44+
t/C[j,j]
45+
end
46+
2647
function getindex(P::PartialInverseOperator,k::Integer,j::Integer)
27-
b = bandwidth(P.cache, 2)
48+
b = bandwidth(P, 2)
2849
if k == j
29-
return inv(P.cache[k,k])
50+
inv(P.cache[k,k])
51+
elseif j > k + b + 1
52+
zero(eltype(P))
3053
elseif j > k
31-
t = zero(T)
32-
for i = max(k,j-b-1):j-1
33-
t += ret[k,i]*P.cache[i,j]
34-
end
35-
return -t/P.cache[j,j]
54+
_getindexinv(P.cache, k, j, UpperTriangular)
3655
else
37-
return zero(eltype(P))
56+
zero(eltype(P))
3857
end
3958
end
4059

test/SpacesTest.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,27 @@ using LinearAlgebra
409409
end
410410
end
411411

412+
@testset "PartialInverseOperator" begin
413+
@testset "sanity check" begin
414+
A = UpperTriangular(rand(10, 10))
415+
B = inv(A)
416+
for I in CartesianIndices(B)
417+
@test B[I] ApproxFunBase._getindexinv(A, Tuple(I)..., UpperTriangular)
418+
end
419+
end
420+
C = Conversion(Chebyshev(), Ultraspherical(1))
421+
P = PartialInverseOperator(C, (0, 6))
422+
Iapprox = (P * C)[1:10, 1:10]
423+
@test all(isone, diag(Iapprox))
424+
for k in axes(Iapprox,1), j in k + 1:min(k + bandwidths(P,2), size(Iapprox, 2))
425+
@test Iapprox[k,j] 0 atol=eps(eltype(Iapprox))
426+
end
427+
B = AbstractMatrix(P[1:10, 1:10])
428+
@testset for I in CartesianIndices(B)
429+
@test B[I] P[Tuple(I)...] rtol=1e-8 atol=eps(eltype(B))
430+
end
431+
end
432+
412433
@testset "istriu/istril" begin
413434
for D in Any[Derivative(Chebyshev()),
414435
Conversion(Chebyshev(), Legendre()),

0 commit comments

Comments
 (0)