Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(H+­μI) \ x solvers for Hessenberg factorizations #31853

Merged
merged 40 commits into from
May 17, 2019
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e1539f9
first draft of new Hessenberg operations
stevengj Apr 26, 2019
6ca092d
fixes
stevengj Apr 27, 2019
c914120
more fixes and tests
stevengj Apr 27, 2019
02c4c02
fixes and tests
stevengj Apr 27, 2019
7e1e452
fix ambiguity
stevengj Apr 27, 2019
600abb4
fix complex shift, pretty-print
stevengj Apr 27, 2019
c029fd9
ambiguity fix
stevengj Apr 27, 2019
98abf8f
rdiv support
stevengj Apr 27, 2019
61ed19f
NEWS
stevengj Apr 27, 2019
6efdafe
adjoint support
stevengj Apr 27, 2019
b9b1786
add fast determinant for Hessenberg
stevengj Apr 28, 2019
984263c
slight simplification
stevengj Apr 28, 2019
69bcc9b
clarify citation
stevengj Apr 28, 2019
af0d995
tweaks
stevengj Apr 28, 2019
915c8cf
fast logdet
stevengj Apr 28, 2019
d462234
fix propertynames
stevengj Apr 28, 2019
63e7b5d
use RQ rather than QR for logabsdet to make memory access more consec…
stevengj Apr 28, 2019
f02bc4a
comment fix
stevengj Apr 28, 2019
014b9da
fix ambiguities
stevengj Apr 28, 2019
47786bc
comment typo
stevengj Apr 28, 2019
c4aef93
add another test
stevengj Apr 29, 2019
eecbc57
tweak
stevengj Apr 29, 2019
1b978e6
add UpperHessenberg type
stevengj May 1, 2019
53d870e
hessenberg docs
stevengj May 1, 2019
7ba75c4
tweak
stevengj May 1, 2019
4b6c12b
fix doc reference for non-exported HessenbergQ
stevengj May 1, 2019
330ca95
make τ type more generic
stevengj May 1, 2019
3d37fb2
update NEWS
stevengj May 1, 2019
8e2dbea
put shifts into Hessenberg object, store factors separately in prepar…
stevengj May 3, 2019
8d612b8
correct comment
stevengj May 3, 2019
9056d42
hessenberg for Hermitian matrices -> real-symmetric tridiagonal
stevengj May 10, 2019
9f5c32d
shifted solvers for symtridiag
stevengj May 10, 2019
1ecd267
rm redundant methods
stevengj May 11, 2019
ce05928
test workaround
stevengj May 11, 2019
01df020
news for tridiagonal Hessenberg
stevengj May 11, 2019
e4afbc4
grammar
stevengj May 13, 2019
2a91795
make sure Matrix(H.Q) is tested
stevengj May 15, 2019
ef3644f
rm workaround now that 32001 is merged
stevengj May 15, 2019
41ea262
clarifications
stevengj May 15, 2019
b3d33ed
fix typo
stevengj May 17, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Standard library changes
* The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838]).
* `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654]).

* `Hessenberg` factorizations `H` now support efficient shifted solves `(H+µI) \ b` and determinants, and use a specialized tridiagonal factorization for Hermitian matrices. There is also a new `UpperHessenberg` matrix type ([#31853]).

#### SparseArrays


Expand Down
11 changes: 10 additions & 1 deletion stdlib/LinearAlgebra/docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,9 @@ as well as whether hooks to various optimized methods for them in LAPACK are ava
| [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) |
| [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) |
| [`UnitUpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal |
| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) |
| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | |
| [`UnitLowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal |
| [`UpperHessenberg`](@ref) | Upper [Hessenberg matrix](https://en.wikipedia.org/wiki/Hessenberg_matrix)
| [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) |
| [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix |
| [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) |
Expand All @@ -186,6 +187,7 @@ as well as whether hooks to various optimized methods for them in LAPACK are ava
| [`UnitUpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) |
| [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) |
| [`UnitLowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) |
| [`UpperHessenberg`](@ref) | | | | MM | [`inv`](@ref), [`det`](@ref) |
| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) |
| [`Tridiagonal`](@ref) | M | M | MS | MV | |
| [`Bidiagonal`](@ref) | M | M | MS | MV | |
Expand Down Expand Up @@ -269,6 +271,12 @@ Stacktrace:
[...]
```

If you need to solve many systems of the form `(A+μI)x = b`, it might be beneficial
stevengj marked this conversation as resolved.
Show resolved Hide resolved
to first compute the Hessenberg factorization `F` of `A` via the [`hessenberg`](@ref) function.
Given `F`, Julia employs an efficient algorithm for `(F+μ*I) \ b` and related
operations.


## [Matrix factorizations](@id man-linalg-factorizations)

[Matrix factorizations (a.k.a. matrix decompositions)](https://en.wikipedia.org/wiki/Matrix_decomposition)
Expand Down Expand Up @@ -319,6 +327,7 @@ LinearAlgebra.LowerTriangular
LinearAlgebra.UpperTriangular
LinearAlgebra.UnitLowerTriangular
LinearAlgebra.UnitUpperTriangular
LinearAlgebra.UpperHessenberg
LinearAlgebra.UniformScaling
LinearAlgebra.lu
LinearAlgebra.lu!
Expand Down
3 changes: 2 additions & 1 deletion stdlib/LinearAlgebra/src/LinearAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export
UpperTriangular,
UnitLowerTriangular,
UnitUpperTriangular,
UpperHessenberg,
Diagonal,
UniformScaling,

Expand Down Expand Up @@ -356,7 +357,6 @@ include("triangular.jl")

include("factorization.jl")
include("qr.jl")
include("hessenberg.jl")
include("lq.jl")
include("eigen.jl")
include("svd.jl")
Expand All @@ -367,6 +367,7 @@ include("bunchkaufman.jl")
include("diagonal.jl")
include("bidiag.jl")
include("uniformscaling.jl")
include("hessenberg.jl")
include("givens.jl")
include("special.jl")
include("bitarray.jl")
Expand Down
2 changes: 1 addition & 1 deletion stdlib/LinearAlgebra/src/adjtrans.jl
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ pinv(v::TransposeAbsVec, tol::Real = 0) = pinv(conj(v.parent)).parent
\(u::AdjOrTransAbsVec, v::AdjOrTransAbsVec) = pinv(u) * v


## right-division \
## right-division /
/(u::AdjointAbsVec, A::AbstractMatrix) = adjoint(adjoint(A) \ u.parent)
/(u::TransposeAbsVec, A::AbstractMatrix) = transpose(transpose(A) \ u.parent)
/(u::AdjointAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = adjoint(conj(A.parent) \ u.parent) # technically should be adjoint(copy(adjoint(copy(A))) \ u.parent)
Expand Down
32 changes: 31 additions & 1 deletion stdlib/LinearAlgebra/src/factorization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,18 @@ function Base.show(io::IO, ::MIME"text/plain", x::Transpose{<:Any,<:Factorizatio
end

# With a real lhs and complex rhs with the same precision, we can reinterpret
# the complex rhs as a real rhs with twice the number of columns
# the complex rhs as a real rhs with twice the number of columns or rows
function (\)(F::Factorization{T}, B::VecOrMat{Complex{T}}) where T<:BlasReal
require_one_based_indexing(B)
c2r = reshape(copy(transpose(reinterpret(T, reshape(B, (1, length(B)))))), size(B, 1), 2*size(B, 2))
x = ldiv!(F, c2r)
return reshape(copy(reinterpret(Complex{T}, copy(transpose(reshape(x, div(length(x), 2), 2))))), _ret_size(F, B))
end
function (/)(B::VecOrMat{Complex{T}}, F::Factorization{T}) where T<:BlasReal
require_one_based_indexing(B)
x = rdiv!(copy(reinterpret(T, B)), F)
return copy(reinterpret(Complex{T}, x))
end

function \(F::Factorization, B::AbstractVecOrMat)
require_one_based_indexing(B)
Expand All @@ -95,6 +100,24 @@ function \(adjF::Adjoint{<:Any,<:Factorization}, B::AbstractVecOrMat)
ldiv!(adjoint(F), BB)
end

function /(B::AbstractMatrix, F::Factorization)
require_one_based_indexing(B)
TFB = typeof(oneunit(eltype(B)) / oneunit(eltype(F)))
BB = similar(B, TFB, size(B))
copyto!(BB, B)
rdiv!(BB, F)
end
function /(B::AbstractMatrix, adjF::Adjoint{<:Any,<:Factorization})
require_one_based_indexing(B)
F = adjF.parent
TFB = typeof(oneunit(eltype(B)) / oneunit(eltype(F)))
BB = similar(B, TFB, size(B))
copyto!(BB, B)
rdiv!(BB, adjoint(F))
end
/(adjB::AdjointAbsVec, adjF::Adjoint{<:Any,<:Factorization}) = adjoint(adjF.parent \ adjB.parent)
/(B::TransposeAbsVec, adjF::Adjoint{<:Any,<:Factorization}) = adjoint(adjF.parent \ adjoint(B))

# support the same 3-arg idiom as in our other in-place A_*_B functions:
function ldiv!(Y::AbstractVecOrMat, A::Factorization, B::AbstractVecOrMat)
require_one_based_indexing(Y, B)
Expand All @@ -120,3 +143,10 @@ end
# fallback methods for transposed solves
\(F::Transpose{<:Any,<:Factorization{<:Real}}, B::AbstractVecOrMat) = adjoint(F.parent) \ B
\(F::Transpose{<:Any,<:Factorization}, B::AbstractVecOrMat) = conj.(adjoint(F.parent) \ conj.(B))

/(B::AbstractMatrix, F::Transpose{<:Any,<:Factorization{<:Real}}) = B / adjoint(F.parent)
/(B::AbstractMatrix, F::Transpose{<:Any,<:Factorization}) = conj.(conj.(B) / adjoint(F.parent))
/(B::AdjointAbsVec, F::Transpose{<:Any,<:Factorization{<:Real}}) = B / adjoint(F.parent)
/(B::TransposeAbsVec, F::Transpose{<:Any,<:Factorization{<:Real}}) = B / adjoint(F.parent)
/(B::AdjointAbsVec, F::Transpose{<:Any,<:Factorization}) = conj.(conj.(B) / adjoint(F.parent))
/(B::TransposeAbsVec, F::Transpose{<:Any,<:Factorization}) = conj.(conj.(B) / adjoint(F.parent))
2 changes: 2 additions & 0 deletions stdlib/LinearAlgebra/src/givens.jl
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ function givensAlgorithm(f::Complex{T}, g::Complex{T}) where T<:AbstractFloat
return cs, sn, r
end

givensAlgorithm(f, g) = givensAlgorithm(promote(float(f), float(g))...)

"""

givens(f::T, g::T, i1::Integer, i2::Integer) where {T} -> (G::Givens, r::T)
Expand Down
Loading