Skip to content

Commit 3c04dd8

Browse files
committed
2 parents 1eea9a9 + d1704dd commit 3c04dd8

File tree

8 files changed

+66
-15
lines changed

8 files changed

+66
-15
lines changed

src/InfiniteLinearAlgebra.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import LinearAlgebra: lmul!, ldiv!, matprod, qr, AbstractTriangular, AbstractQ,
1313
import LazyArrays: CachedArray, CachedMatrix, CachedVector, DenseColumnMajor, FillLayout, ApplyMatrix, check_mul_axes, ApplyStyle, LazyArrayApplyStyle, LazyArrayStyle,
1414
CachedMatrix, CachedArray, resizedata!, MemoryLayout, mulapplystyle, LmulStyle, RmulStyle,
1515
colsupport, rowsupport, triangularlayout, factorize, subarraylayout, sub_materialize,
16-
@lazymul
16+
@lazymul, ApplyLayout, TriangularLayout, PaddedLayout, materialize!, MatLdivVec, triangulardata
1717
import MatrixFactorizations: ql, ql!, QLPackedQ, getL, getR, reflector!, reflectorApply!, QL, QR, QRPackedQ
1818

1919
import BlockArrays: BlockSizes, cumulsizes, _find_block, AbstractBlockVecOrMat, sizes_from_blocks

src/banded/infbanded.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const TriToeplitz{T} = Tridiagonal{T,Fill{T,1,Tuple{OneToInf{Int}}}}
22
const ConstRowMatrix{T} = ApplyMatrix{T,typeof(*),<:Tuple{<:AbstractVector,<:AbstractFill{<:Any,2,Tuple{OneTo{Int},OneToInf{Int}}}}}
3-
const PertConstRowMatrix{T} = Hcat{T,<:Tuple{Matrix{T},<:ConstRowMatrix{T}}}
3+
const PertConstRowMatrix{T} = Hcat{T,<:Tuple{Array{T},<:ConstRowMatrix{T}}}
44
const InfToeplitz{T} = BandedMatrix{T,<:ConstRowMatrix{T},OneToInf{Int}}
55
const PertToeplitz{T} = BandedMatrix{T,<:PertConstRowMatrix{T},OneToInf{Int}}
66

@@ -290,8 +290,13 @@ MemoryLayout(::Type{<:ConstRowMatrix}) = ConstRows()
290290
MemoryLayout(::Type{<:PertConstRowMatrix}) = PertConstRows()
291291
bandedcolumns(::ConstRows) = BandedToeplitzLayout()
292292
bandedcolumns(::PertConstRows) = PertToeplitzLayout()
293-
subarraylayout(::ConstRows, ::Type{<:Tuple{Any,AbstractInfUnitRange{Int}}}) = ConstRows() # no way to lose const rows
294-
subarraylayout(::PertConstRows, ::Type{<:Tuple{Any,AbstractInfUnitRange{Int}}}) = PertConstRows() # no way to lose const rows
293+
subarraylayout(::ConstRows, inds...) = subarraylayout(ApplyLayout{typeof(*)}(), inds...)
294+
subarraylayout(::PertConstRows, inds...) = subarraylayout(ApplyLayout{typeof(hcat)}(), inds...)
295+
for Typ in (:ConstRows, :PertConstRows)
296+
@eval begin
297+
subarraylayout(::$Typ, ::Type{<:Tuple{Any,AbstractInfUnitRange{Int}}}) = $Typ() # no way to lose const rows
298+
end
299+
end
295300

296301
const BandedToeplitzLayout = BandedColumns{ConstRows}
297302
const PertToeplitzLayout = BandedColumns{PertConstRows}

src/banded/infqltoeplitz.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ end
103103

104104
getindex(Q::ProductQ{<:Any,<:Tuple{Vararg{LowerHessenbergQ}}}, i::Integer, j::Integer) = (Q')[j,i]'
105105

106+
107+
function (*)(A::ProductQ{T}, x::AbstractVector{S}) where {T,S}
108+
TS = promote_op(matprod, T, S)
109+
lmul!(A, Base.copymutable(convert(AbstractVector{TS},x)))
110+
end
111+
112+
106113
# LQ where Q is a product of orthogonal operations
107114
struct QLProduct{T,QQ<:Tuple,LL} <: Factorization{T}
108115
Qs::QQ

src/infql.jl

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ getL(Q::QLHessenberg, ::Tuple{OneToInf{Int},OneToInf{Int}}) where T = LowerTrian
106106
nzzeros(A::AbstractArray, k) = size(A,k)
107107
nzzeros(::Zeros, k) = 0
108108
nzzeros(B::Vcat, k) = sum(size.(B.args[1:end-1],k))
109-
nzzeros(B::CachedArray, k) = max(size(B.data,k), nzzeros(B.array,k))
109+
nzzeros(B::CachedArray, k) = max(B.datasize[k], nzzeros(B.array,k))
110110
function nzzeros(B::AbstractMatrix, k)
111111
l,u = bandwidths(B)
112112
k == 1 ? size(B,2) + l : size(B,1) + u
@@ -276,4 +276,28 @@ end
276276
function (*)(A::Adjoint{T,<:QLPackedQ{T,<:InfBlockBandedMatrix}}, x::AbstractVector{S}) where {T,S}
277277
TS = promote_op(matprod, T, S)
278278
lmul!(A, cache(convert(AbstractVector{TS},x)))
279-
end
279+
end
280+
281+
ldiv!(F::QLProduct, b::AbstractVector) = ldiv!(F.L, lmul!(F.Q',b))
282+
283+
function materialize!(M::MatLdivVec{<:TriangularLayout{'L','N',BandedColumns{PertConstRows}},<:PaddedLayout})
284+
A,b = M.A,M.B
285+
require_one_based_indexing(A, b)
286+
n = size(A, 2)
287+
if !(n == length(b))
288+
throw(DimensionMismatch("second dimension of left hand side A, $n, and length of right hand side b, $(length(b)), must be equal"))
289+
end
290+
data = triangulardata(A)
291+
nz = nzzeros(b,1)
292+
@inbounds for j in 1:n
293+
iszero(data[j,j]) && throw(SingularException(j))
294+
bj = b[j] = data[j,j] \ b[j]
295+
allzero = j > nz && iszero(bj)
296+
for i in (j+1:n) colsupport(data,j)
297+
b[i] -= data[i,j] * bj
298+
allzero = allzero && iszero(b[i])
299+
end
300+
allzero && break
301+
end
302+
b
303+
end

src/infqr.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ end
9191
function lmul!(A::QRPackedQ{<:Any,<:AdaptiveQRFactors}, B::CachedVector{T,Vector{T},<:Zeros{T,1}}) where T
9292
require_one_based_indexing(B)
9393
mA, nA = size(A.factors)
94-
sB = length(B.data)
94+
sB = B.datasize[1]
9595
mB = length(B)
9696
if mA != mB
9797
throw(DimensionMismatch("matrix A has dimensions ($mA,$nA) but B has dimensions ($mB, $nB)"))
@@ -124,7 +124,7 @@ end
124124

125125
function lmul!(adjA::Adjoint{<:Any,<:QRPackedQ{<:Any,<:AdaptiveQRFactors}}, B::CachedVector{T,Vector{T},<:Zeros{T,1}}) where T
126126
COLGROWTH = 1000 # rate to grow columns
127-
tol = floatmin(T)
127+
tol = floatmin(real(T))
128128

129129
require_one_based_indexing(B)
130130
A = adjA.parent
@@ -164,7 +164,12 @@ function (*)(A::Adjoint{T,<:QRPackedQ{T,<:AdaptiveQRFactors}}, x::AbstractVector
164164
lmul!(A, Base.copymutable(convert(AbstractVector{TS},x)))
165165
end
166166

167-
ldiv!(R::UpperTriangular{<:Any,<:AdaptiveQRFactors}, B::AbstractVector) = materialize!(Ldiv(R, B))
167+
function ldiv!(R::UpperTriangular{<:Any,<:AdaptiveQRFactors}, B::CachedVector{<:Any,<:Any,<:Zeros{<:Any,1}})
168+
n = B.datasize[1]
169+
partialqr!(parent(R).data, n)
170+
materialize!(Ldiv(UpperTriangular(view(parent(R).data.data.data,OneTo(n),OneTo(n))), view(B.data,OneTo(n))))
171+
B
172+
end
168173

169174

170175

test/runtests.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import BlockArrays: _BlockArray
77
import BlockBandedMatrices: isblockbanded, _BlockBandedMatrix
88
import MatrixFactorizations: QLPackedQ
99
import BandedMatrices: bandeddata, _BandedMatrix
10-
import LazyArrays: colsupport, ApplyStyle, MemoryLayout
10+
import LazyArrays: colsupport, ApplyStyle, MemoryLayout, ApplyLayout
1111

1212
@testset "∞-Toeplitz and Pert-Toeplitz" begin
1313
A = BandedMatrix(1 => Fill(2im,∞), 2 => Fill(-1,∞), 3 => Fill(2,∞), -2 => Fill(-4,∞), -3 => Fill(-2im,∞))
@@ -47,6 +47,7 @@ end
4747
@test At[1:10,1:10] transpose(A)[1:10,1:10] transpose(A[1:10,1:10])
4848

4949
A = BandedMatrix(-1 => Vcat(Float64[], Fill(1/4,∞)), 0 => Vcat([1.0+im],Fill(0,∞)), 1 => Vcat(Float64[], Fill(1,∞)))
50+
@test MemoryLayout(typeof(view(A.data,:,1:10))) == ApplyLayout{typeof(hcat)}()
5051
Ac = BandedMatrix(A')
5152
At = BandedMatrix(transpose(A))
5253
@test Ac[1:10,1:10] (A')[1:10,1:10] A[1:10,1:10]'

test/test_infql.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import BandedMatrices: _BandedMatrix
1313
L = _BandedMatrix(Hcat([e; X[2,2]; X[2,1]], X[2,end:-1:1] * Ones{Float64}(1,∞)), ∞, 2, 0)
1414
Qn,Ln = ql(A[1:1000,1:1000])
1515
@test Q[1:10,1:10] Qn[1:10,1:10]
16+
@test Array((Q'A)[1:10,1:10]) [(Q'A)[k,j] for k=1:10,j=1:10]
1617
@test (Q'A)[1:10,1:10] Ln[1:10,1:10] L[1:10,1:10]
1718

1819
A = BandedMatrix(-1 => Fill(2,∞), 0 => Fill(5+im,∞), 1 => Fill(0.5,∞))
@@ -37,7 +38,7 @@ import BandedMatrices: _BandedMatrix
3738
@test Q[1:10,1:11]*L[1:11,1:10] T[1:10,1:10]
3839
end
3940

40-
for (Z,A,B) in ((2,5.0im,0.5),
41+
for (Z,A,B) in ((2,5.0im,0.5),
4142
(2,2.1+0.1im,0.5),
4243
(2,2.1-0.1im,0.5),
4344
(2,1.5+0.1im,0.5),
@@ -158,4 +159,9 @@ import BandedMatrices: _BandedMatrix
158159
@test Qn[1:10,1:10] * diagm(0 => [Ones(5); -(-1).^(1:5)]) Q[1:10,1:10]
159160
@test diagm(0 => [Ones(5); -(-1).^(1:5)]) * Ln[1:10,1:10] L[1:10,1:10]
160161
end
162+
163+
@testset "solve with QL" begin
164+
A = BandedMatrix(-1 => Fill(2,∞), 0 => Fill(5,∞), 1 => Fill(0.5,∞))
165+
@test (qr(A)\Vcat(1.0,Zeros(∞)))[1:1000] (ql(A)\Vcat(1.0,Zeros(∞)))[1:1000]
166+
end
161167
end

test/test_infqr.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveLayout
6262
A = _BandedMatrix(Vcat(Ones(1,∞), (1:∞)', Ones(1,∞)), ∞, 1, 1)
6363
Q,R = qr(A);
6464
b = Vcat([1.,2,3],Zeros(∞))
65-
@test lmul!(Q, Base.copymutable(b)).data qr(A[1:4,1:3]).Q*[1,2,3]
65+
@test lmul!(Q, Base.copymutable(b)).datasize[1] == 4
66+
@test lmul!(Q, Base.copymutable(b)).data[1:4] qr(A[1:4,1:3]).Q*[1,2,3]
6667

6768
@test Q[1,1] -1/sqrt(2)
6869
@test Q[200_000,200_000] -1.0
@@ -111,10 +112,12 @@ import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveLayout
111112
C = cache(AB);
112113
resizedata!(C,103,100); resizedata!(C,203,200);
113114
@test C[103,104] 1.0
115+
C = qr(AB).factors.data.data;
116+
resizedata!(C,102,104); resizedata!(C,202,204);
117+
@test C[202,204] == AB[202,204]
114118
F = qr(AB);
115-
partialqr!(F.factors.data, 100);
116-
partialqr!(F.factors.data, 200);
117-
@test norm(F.factors.data.data.data)  4000
119+
partialqr!(F.factors.data, 100); partialqr!(F.factors.data, 200);
120+
@test norm(F.factors.data.data.data[Base.OneTo.(F.factors.data.data.datasize)...])  4000
118121
b = Vcat([3,4,5],Zeros(∞))
119122
@time x = qr(AB) \ b;
120123
@test x[1:300] AB[1:300,1:300] \ b[1:300]

0 commit comments

Comments
 (0)