Skip to content

Commit 15c4673

Browse files
andreasnoackStefanKarpinski
authored andcommitted
Deprecate getindex(::Factorization, ::Symbol) in favor of dot overloading (#25184)
1 parent 5fafb36 commit 15c4673

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+651
-647
lines changed

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,10 @@ Deprecated or removed
879879

880880
* `sub2ind` and `ind2sub` are deprecated in favor of using `CartesianIndices` and `LinearIndices` ([#24715]).
881881

882+
* `getindex(F::Factorizion, s::Symbol)` (usually seen as e.g. `F[:Q]`) is deprecated
883+
in favor of dot overloading (`getproperty`) so factors should now be accessed as e.g.
884+
`F.Q` instead of `F[:Q]` ([#25184]).
885+
882886
Command-line option changes
883887
---------------------------
884888

base/deprecated.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3466,6 +3466,15 @@ workspace() = error("workspace() is discontinued, check out Revise.jl for an alt
34663466
@deprecate Ref(x::Ptr) Ref(x, 1)
34673467
@deprecate Ref(x::Ref) x # or perhaps, `convert(Ref, x)`
34683468

3469+
# PR #25184. Use getproperty instead of getindex for Factorizations
3470+
function getindex(F::Factorization, s::Symbol)
3471+
depwarn("`F[:$s]` is deprecated, use `F.$s` instead.", :getindex)
3472+
return getproperty(F, s)
3473+
end
3474+
@eval Base.LinAlg begin
3475+
@deprecate getq(F::Factorization) F.Q
3476+
end
3477+
34693478
# END 0.7 deprecations
34703479

34713480
# BEGIN 1.0 deprecations

base/linalg/bunchkaufman.jl

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ convert(::Type{BunchKaufman{T}}, B::BunchKaufman) where {T} =
8686
convert(::Type{Factorization{T}}, B::BunchKaufman{T}) where {T} = B
8787
convert(::Type{Factorization{T}}, B::BunchKaufman) where {T} = convert(BunchKaufman{T}, B)
8888

89-
size(B::BunchKaufman) = size(B.LD)
90-
size(B::BunchKaufman, d::Integer) = size(B.LD, d)
89+
size(B::BunchKaufman) = size(getfield(B, :LD))
90+
size(B::BunchKaufman, d::Integer) = size(getfield(B, :LD), d)
9191
issymmetric(B::BunchKaufman) = B.symmetric
9292
ishermitian(B::BunchKaufman) = !B.symmetric
9393

@@ -115,7 +115,7 @@ function _ipiv2perm_bk(v::AbstractVector{T}, maxi::Integer, uplo::Char) where T
115115
end
116116

117117
"""
118-
getindex(B::BunchKaufman, d::Symbol)
118+
getproperty(B::BunchKaufman, d::Symbol)
119119
120120
Extract the factors of the Bunch-Kaufman factorization `B`. The factorization can take the
121121
two forms `L*D*L'` or `U*D*U'` (or `L*D*Transpose(L)` in the complex symmetric case) where `L` is a
@@ -153,43 +153,43 @@ permutation:
153153
3
154154
2
155155
156-
julia> F[:L]*F[:D]*F[:L]' - A[F[:p], F[:p]]
156+
julia> F.L*F.D*F.L' - A[F.p, F.p]
157157
3×3 Array{Float64,2}:
158158
0.0 0.0 0.0
159159
0.0 0.0 0.0
160160
0.0 0.0 0.0
161161
162162
julia> F = bkfact(Symmetric(A));
163163
164-
julia> F[:U]*F[:D]*F[:U]' - F[:P]*A*F[:P]'
164+
julia> F.U*F.D*F.U' - F.P*A*F.P'
165165
3×3 Array{Float64,2}:
166166
0.0 0.0 0.0
167167
0.0 0.0 0.0
168168
0.0 0.0 0.0
169169
```
170170
"""
171-
function getindex(B::BunchKaufman{T}, d::Symbol) where {T<:BlasFloat}
171+
function getproperty(B::BunchKaufman{T}, d::Symbol) where {T<:BlasFloat}
172172
n = size(B, 1)
173173
if d == :p
174-
return _ipiv2perm_bk(B.ipiv, n, B.uplo)
174+
return _ipiv2perm_bk(getfield(B, :ipiv), n, getfield(B, :uplo))
175175
elseif d == :P
176-
return Matrix{T}(I, n, n)[:,invperm(B[:p])]
176+
return Matrix{T}(I, n, n)[:,invperm(B.p)]
177177
elseif d == :L || d == :U || d == :D
178-
if B.rook
179-
LUD, od = LAPACK.syconvf_rook!(B.uplo, 'C', copy(B.LD), B.ipiv)
178+
if getfield(B, :rook)
179+
LUD, od = LAPACK.syconvf_rook!(getfield(B, :uplo), 'C', copy(getfield(B, :LD)), getfield(B, :ipiv))
180180
else
181-
LUD, od = LAPACK.syconv!(B.uplo, copy(B.LD), B.ipiv)
181+
LUD, od = LAPACK.syconv!(getfield(B, :uplo), copy(getfield(B, :LD)), getfield(B, :ipiv))
182182
end
183183
if d == :D
184-
if B.uplo == 'L'
184+
if getfield(B, :uplo) == 'L'
185185
odl = od[1:n - 1]
186-
return Tridiagonal(odl, diag(LUD), B.symmetric ? odl : conj.(odl))
186+
return Tridiagonal(odl, diag(LUD), getfield(B, :symmetric) ? odl : conj.(odl))
187187
else # 'U'
188188
odu = od[2:n]
189-
return Tridiagonal(B.symmetric ? odu : conj.(odu), diag(LUD), odu)
189+
return Tridiagonal(getfield(B, :symmetric) ? odu : conj.(odu), diag(LUD), odu)
190190
end
191191
elseif d == :L
192-
if B.uplo == 'L'
192+
if getfield(B, :uplo) == 'L'
193193
return UnitLowerTriangular(LUD)
194194
else
195195
throw(ArgumentError("factorization is U*D*Transpose(U) but you requested L"))
@@ -202,7 +202,7 @@ function getindex(B::BunchKaufman{T}, d::Symbol) where {T<:BlasFloat}
202202
end
203203
end
204204
else
205-
throw(KeyError(d))
205+
getfield(B, d)
206206
end
207207
end
208208

@@ -212,11 +212,11 @@ function Base.show(io::IO, mime::MIME{Symbol("text/plain")}, B::BunchKaufman)
212212
if issuccess(B)
213213
println(io, summary(B))
214214
println(io, "D factor:")
215-
show(io, mime, B[:D])
215+
show(io, mime, B.D)
216216
println(io, "\n$(B.uplo) factor:")
217-
show(io, mime, B[Symbol(B.uplo)])
217+
show(io, mime, B.uplo == 'L' ? B.L : B.U)
218218
println(io, "\npermutation:")
219-
show(io, mime, B[:p])
219+
show(io, mime, B.p)
220220
else
221221
print(io, "Failed factorization of type $(typeof(B))")
222222
end

base/linalg/cholesky.jl

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ end
285285
Compute the Cholesky factorization of a dense symmetric positive definite matrix `A`
286286
and return a `Cholesky` factorization. The matrix `A` can either be a [`Symmetric`](@ref) or [`Hermitian`](@ref)
287287
`StridedMatrix` or a *perfectly* symmetric or Hermitian `StridedMatrix`.
288-
The triangular Cholesky factor can be obtained from the factorization `F` with: `F[:L]` and `F[:U]`.
288+
The triangular Cholesky factor can be obtained from the factorization `F` with: `F.L` and `F.U`.
289289
The following functions are available for `Cholesky` objects: [`size`](@ref), [`\\`](@ref),
290290
[`inv`](@ref), [`det`](@ref), [`logdet`](@ref) and [`isposdef`](@ref).
291291
@@ -305,19 +305,19 @@ U factor:
305305
⋅ 1.0 5.0
306306
⋅ ⋅ 3.0
307307
308-
julia> C[:U]
308+
julia> C.U
309309
3×3 UpperTriangular{Float64,Array{Float64,2}}:
310310
2.0 6.0 -8.0
311311
⋅ 1.0 5.0
312312
⋅ ⋅ 3.0
313313
314-
julia> C[:L]
314+
julia> C.L
315315
3×3 LowerTriangular{Float64,Array{Float64,2}}:
316316
2.0 ⋅ ⋅
317317
6.0 1.0 ⋅
318318
-8.0 5.0 3.0
319319
320-
julia> C[:L] * C[:U] == A
320+
julia> C.L * C.U == A
321321
true
322322
```
323323
"""
@@ -332,7 +332,7 @@ cholfact(A::Union{StridedMatrix,RealHermSymComplexHerm{<:Real,<:StridedMatrix}},
332332
Compute the pivoted Cholesky factorization of a dense symmetric positive semi-definite matrix `A`
333333
and return a `CholeskyPivoted` factorization. The matrix `A` can either be a [`Symmetric`](@ref)
334334
or [`Hermitian`](@ref) `StridedMatrix` or a *perfectly* symmetric or Hermitian `StridedMatrix`.
335-
The triangular Cholesky factor can be obtained from the factorization `F` with: `F[:L]` and `F[:U]`.
335+
The triangular Cholesky factor can be obtained from the factorization `F` with: `F.L` and `F.U`.
336336
The following functions are available for `PivotedCholesky` objects:
337337
[`size`](@ref), [`\\`](@ref), [`inv`](@ref), [`det`](@ref), and [`rank`](@ref).
338338
The argument `tol` determines the tolerance for determining the rank.
@@ -361,14 +361,14 @@ CholeskyPivoted{T}(C::CholeskyPivoted) where {T} =
361361
Factorization{T}(C::CholeskyPivoted{T}) where {T} = C
362362
Factorization{T}(C::CholeskyPivoted) where {T} = CholeskyPivoted{T}(C)
363363

364-
AbstractMatrix(C::Cholesky) = C.uplo == 'U' ? C[:U]'C[:U] : C[:L]*C[:L]'
364+
AbstractMatrix(C::Cholesky) = C.uplo == 'U' ? C.U'C.U : C.L*C.L'
365365
AbstractArray(C::Cholesky) = AbstractMatrix(C)
366366
Matrix(C::Cholesky) = Array(AbstractArray(C))
367367
Array(C::Cholesky) = Matrix(C)
368368

369369
function AbstractMatrix(F::CholeskyPivoted)
370-
ip = invperm(F[:p])
371-
(F[:L] * F[:U])[ip,ip]
370+
ip = invperm(F.p)
371+
(F.L * F.U)[ip,ip]
372372
end
373373
AbstractArray(F::CholeskyPivoted) = AbstractMatrix(F)
374374
Matrix(F::CholeskyPivoted) = Array(AbstractArray(F))
@@ -380,43 +380,56 @@ copy(C::CholeskyPivoted) = CholeskyPivoted(copy(C.factors), C.uplo, C.piv, C.ran
380380
size(C::Union{Cholesky, CholeskyPivoted}) = size(C.factors)
381381
size(C::Union{Cholesky, CholeskyPivoted}, d::Integer) = size(C.factors, d)
382382

383-
function getindex(C::Cholesky, d::Symbol)
384-
d == :U && return UpperTriangular(Symbol(C.uplo) == d ? C.factors : adjoint(C.factors))
385-
d == :L && return LowerTriangular(Symbol(C.uplo) == d ? C.factors : adjoint(C.factors))
386-
d == :UL && return Symbol(C.uplo) == :U ? UpperTriangular(C.factors) : LowerTriangular(C.factors)
387-
throw(KeyError(d))
388-
end
389-
function getindex(C::CholeskyPivoted{T}, d::Symbol) where T<:BlasFloat
390-
d == :U && return UpperTriangular(Symbol(C.uplo) == d ? C.factors : adjoint(C.factors))
391-
d == :L && return LowerTriangular(Symbol(C.uplo) == d ? C.factors : adjoint(C.factors))
392-
d == :p && return C.piv
393-
if d == :P
383+
function getproperty(C::Cholesky, d::Symbol)
384+
Cfactors = getfield(C, :factors)
385+
Cuplo = getfield(C, :uplo)
386+
if d == :U
387+
return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors))
388+
elseif d == :L
389+
return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors))
390+
elseif d == :UL
391+
return Symbol(Cuplo) == :U ? UpperTriangular(Cfactors) : LowerTriangular(Cfactors)
392+
else
393+
return getfield(C, d)
394+
end
395+
end
396+
function getproperty(C::CholeskyPivoted{T}, d::Symbol) where T<:BlasFloat
397+
Cfactors = getfield(C, :factors)
398+
Cuplo = getfield(C, :uplo)
399+
if d == :U
400+
return UpperTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors))
401+
elseif d == :L
402+
return LowerTriangular(Symbol(Cuplo) == d ? Cfactors : adjoint(Cfactors))
403+
elseif d == :p
404+
return getfield(C, :piv)
405+
elseif d == :P
394406
n = size(C, 1)
395407
P = zeros(T, n, n)
396408
for i = 1:n
397-
P[C.piv[i],i] = one(T)
409+
P[getfield(C, :piv)[i], i] = one(T)
398410
end
399411
return P
412+
else
413+
return getfield(C, d)
400414
end
401-
throw(KeyError(d))
402415
end
403416

404417
issuccess(C::Cholesky) = C.info == 0
405418

406419
function show(io::IO, mime::MIME{Symbol("text/plain")}, C::Cholesky{<:Any,<:AbstractMatrix})
407420
if issuccess(C)
408421
println(io, summary(C), "\n$(C.uplo) factor:")
409-
show(io, mime, C[:UL])
422+
show(io, mime, C.UL)
410423
else
411424
print(io, "Failed factorization of type $(typeof(C))")
412425
end
413426
end
414427

415428
function show(io::IO, mime::MIME{Symbol("text/plain")}, C::CholeskyPivoted{<:Any,<:AbstractMatrix})
416429
println(io, summary(C), "\n$(C.uplo) factor with rank $(rank(C)):")
417-
show(io, mime, C.uplo == 'U' ? C[:U] : C[:L])
430+
show(io, mime, C.uplo == 'U' ? C.U : C.L)
418431
println(io, "\npermutation:")
419-
show(io, mime, C[:p])
432+
show(io, mime, C.p)
420433
end
421434

422435
ldiv!(C::Cholesky{T,<:AbstractMatrix}, B::StridedVecOrMat{T}) where {T<:BlasFloat} =
@@ -534,8 +547,8 @@ rank(C::CholeskyPivoted) = C.rank
534547
"""
535548
lowrankupdate!(C::Cholesky, v::StridedVector) -> CC::Cholesky
536549
537-
Update a Cholesky factorization `C` with the vector `v`. If `A = C[:U]'C[:U]` then
538-
`CC = cholfact(C[:U]'C[:U] + v*v')` but the computation of `CC` only uses `O(n^2)`
550+
Update a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U` then
551+
`CC = cholfact(C.U'C.U + v*v')` but the computation of `CC` only uses `O(n^2)`
539552
operations. The input factorization `C` is updated in place such that on exit `C == CC`.
540553
The vector `v` is destroyed during the computation.
541554
"""
@@ -580,8 +593,8 @@ end
580593
"""
581594
lowrankdowndate!(C::Cholesky, v::StridedVector) -> CC::Cholesky
582595
583-
Downdate a Cholesky factorization `C` with the vector `v`. If `A = C[:U]'C[:U]` then
584-
`CC = cholfact(C[:U]'C[:U] - v*v')` but the computation of `CC` only uses `O(n^2)`
596+
Downdate a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U` then
597+
`CC = cholfact(C.U'C.U - v*v')` but the computation of `CC` only uses `O(n^2)`
585598
operations. The input factorization `C` is updated in place such that on exit `C == CC`.
586599
The vector `v` is destroyed during the computation.
587600
"""
@@ -633,17 +646,17 @@ end
633646
"""
634647
lowrankupdate(C::Cholesky, v::StridedVector) -> CC::Cholesky
635648
636-
Update a Cholesky factorization `C` with the vector `v`. If `A = C[:U]'C[:U]`
637-
then `CC = cholfact(C[:U]'C[:U] + v*v')` but the computation of `CC` only uses
649+
Update a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U`
650+
then `CC = cholfact(C.U'C.U + v*v')` but the computation of `CC` only uses
638651
`O(n^2)` operations.
639652
"""
640653
lowrankupdate(C::Cholesky, v::StridedVector) = lowrankupdate!(copy(C), copy(v))
641654

642655
"""
643656
lowrankdowndate(C::Cholesky, v::StridedVector) -> CC::Cholesky
644657
645-
Downdate a Cholesky factorization `C` with the vector `v`. If `A = C[:U]'C[:U]`
646-
then `CC = cholfact(C[:U]'C[:U] - v*v')` but the computation of `CC` only uses
658+
Downdate a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U`
659+
then `CC = cholfact(C.U'C.U - v*v')` but the computation of `CC` only uses
647660
`O(n^2)` operations.
648661
"""
649662
lowrankdowndate(C::Cholesky, v::StridedVector) = lowrankdowndate!(copy(C), copy(v))

base/linalg/dense.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,8 @@ function sqrt(A::StridedMatrix{<:Real})
709709
return triu!(parent(sqrt(UpperTriangular(A))))
710710
else
711711
SchurF = schurfact(complex(A))
712-
R = triu!(parent(sqrt(UpperTriangular(SchurF[:T])))) # unwrapping unnecessary?
713-
return SchurF[:vectors] * R * SchurF[:vectors]'
712+
R = triu!(parent(sqrt(UpperTriangular(SchurF.T)))) # unwrapping unnecessary?
713+
return SchurF.vectors * R * SchurF.vectors'
714714
end
715715
end
716716
function sqrt(A::StridedMatrix{<:Complex})
@@ -723,8 +723,8 @@ function sqrt(A::StridedMatrix{<:Complex})
723723
return triu!(parent(sqrt(UpperTriangular(A))))
724724
else
725725
SchurF = schurfact(A)
726-
R = triu!(parent(sqrt(UpperTriangular(SchurF[:T])))) # unwrapping unnecessary?
727-
return SchurF[:vectors] * R * SchurF[:vectors]'
726+
R = triu!(parent(sqrt(UpperTriangular(SchurF.T)))) # unwrapping unnecessary?
727+
return SchurF.vectors * R * SchurF.vectors'
728728
end
729729
end
730730

0 commit comments

Comments
 (0)