Skip to content

Commit 4443df0

Browse files
fix: exponential method ambiguity resolutions (#253)
* restrict types diagonal * DefaultAlgorithm intercepts for Diagonal * update to `default_algorithm` * Algorithm selection * Update src/implementations/exponential.jl Co-authored-by: Lukas Devos <ldevos98@gmail.com> * remove ambiguity * Remove ambiguity * alter ambiguity fix to be in line with decompositions --------- Co-authored-by: Lukas Devos <ldevos98@gmail.com>
1 parent 11096c1 commit 4443df0

2 files changed

Lines changed: 24 additions & 13 deletions

File tree

src/implementations/exponential.jl

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ copy_input(::typeof(exponential), A::Diagonal) = copy(A)
88
copy_input(::typeof(exponential), (τ, A)::Tuple{Number, AbstractMatrix}) = (τ, copy!(similar(A, float(eltype(A))), A))
99
copy_input(::typeof(exponential), (τ, A)::Tuple{Number, Diagonal}) = τ, copy(A)
1010

11-
function check_input(::typeof(exponential!), A::AbstractMatrix, expA::AbstractMatrix, alg::AbstractAlgorithm)
11+
function check_input(::typeof(exponential!), A::AbstractMatrix, expA, alg::AbstractAlgorithm)
1212
m = LinearAlgebra.checksquare(A)
1313
@check_size(expA, (m, m))
1414
@check_scalar(expA, A)
1515
return nothing
1616
end
1717

18-
function check_input(::typeof(exponential!), A::AbstractMatrix, expA::AbstractMatrix, ::DiagonalAlgorithm)
18+
function check_input(::typeof(exponential!), A::AbstractMatrix, expA, ::DiagonalAlgorithm)
1919
m = LinearAlgebra.checksquare(A)
2020
@assert isdiag(A)
2121
@assert expA isa Diagonal
@@ -24,14 +24,14 @@ function check_input(::typeof(exponential!), A::AbstractMatrix, expA::AbstractMa
2424
return nothing
2525
end
2626

27-
function check_input(::typeof(exponential!), (τ, A)::Tuple{Number, AbstractMatrix}, expA::AbstractMatrix, alg::AbstractAlgorithm)
27+
function check_input(::typeof(exponential!), (τ, A)::Tuple{Number, AbstractMatrix}, expA, alg::AbstractAlgorithm)
2828
m = LinearAlgebra.checksquare(A)
2929
@check_size(expA, (m, m))
3030
@check_scalar(expA, A, (τ isa Real) ? identity : complex)
3131
return nothing
3232
end
3333

34-
function check_input(::typeof(exponential!), (τ, A)::Tuple{Number, AbstractMatrix}, expA::AbstractMatrix, ::DiagonalAlgorithm)
34+
function check_input(::typeof(exponential!), (τ, A)::Tuple{Number, AbstractMatrix}, expA, ::DiagonalAlgorithm)
3535
m = LinearAlgebra.checksquare(A)
3636
@assert isdiag(A)
3737
@assert expA isa Diagonal
@@ -40,6 +40,13 @@ function check_input(::typeof(exponential!), (τ, A)::Tuple{Number, AbstractMatr
4040
return nothing
4141
end
4242

43+
# Algorithm selection
44+
# ---------------------------
45+
exponential!(A::AbstractMatrix, alg::DefaultAlgorithm) = exponential!(A, select_algorithm(exponential!, A, nothing; alg.kwargs...))
46+
exponential!(A::AbstractMatrix, out, alg::DefaultAlgorithm) = exponential!(A, out, select_algorithm(exponential!, A, nothing; alg.kwargs...))
47+
exponential!(τA::Tuple{Number, AbstractMatrix}, alg::DefaultAlgorithm) = exponential!(τA, select_algorithm(exponential!, τA, nothing; alg.kwargs...))
48+
exponential!(τA::Tuple{Number, AbstractMatrix}, out, alg::DefaultAlgorithm) = exponential!(τA, out, select_algorithm(exponential!, τA, nothing; alg.kwargs...))
49+
4350
# Outputs
4451
# -------
4552
initialize_output(::typeof(exponential!), A::AbstractMatrix, ::AbstractAlgorithm) = A
@@ -48,22 +55,22 @@ initialize_output(::typeof(exponential!), (τ, A)::Tuple{Number, AbstractMatrix}
4855

4956
# Implementation
5057
# --------------
51-
function exponential!(A::AbstractMatrix, expA::AbstractMatrix, alg::MatrixFunctionViaLA)
58+
function exponential!(A::AbstractMatrix, expA, alg::MatrixFunctionViaLA)
5259
check_input(exponential!, A, expA, alg)
5360
A = LinearAlgebra.exp!(A)
5461
A === expA || copy!(expA, A)
5562
return expA
5663
end
5764

58-
exponential!(A::AbstractMatrix, expA::AbstractMatrix, alg::MatrixFunctionViaEigh) = exponential!((one(eltype(A)), A), expA, alg)
59-
exponential!(A::AbstractMatrix, expA::AbstractMatrix, alg::MatrixFunctionViaEig) = exponential!((one(eltype(A)), A), expA, alg)
65+
exponential!(A::AbstractMatrix, expA, alg::MatrixFunctionViaEigh) = exponential!((one(eltype(A)), A), expA, alg)
66+
exponential!(A::AbstractMatrix, expA, alg::MatrixFunctionViaEig) = exponential!((one(eltype(A)), A), expA, alg)
6067

61-
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA::AbstractMatrix, alg::AbstractAlgorithm)
68+
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA, alg::AbstractAlgorithm)
6269
expA .= A .* τ
6370
return exponential!(expA, expA, alg)
6471
end
6572

66-
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA::AbstractMatrix, alg::MatrixFunctionViaEigh)
73+
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA, alg::MatrixFunctionViaEigh)
6774
check_input(exponential!, (τ, A), expA, alg)
6875
D, V = eigh_full!(A, alg.eigh_alg)
6976
if eltype(A) <: Real
@@ -83,7 +90,7 @@ function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA::AbstractMatr
8390
end
8491
end
8592

86-
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA::AbstractMatrix, alg::MatrixFunctionViaEig)
93+
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA, alg::MatrixFunctionViaEig)
8794
check_input(exponential!, (τ, A), expA, alg)
8895
D, V = eig_full!(A, alg.eig_alg)
8996
if eltype(A) <: Real && eltype(τ) <: Real
@@ -98,12 +105,12 @@ end
98105

99106
# Diagonal logic
100107
# --------------
101-
function exponential!(A, expA, alg::DiagonalAlgorithm)
108+
function exponential!(A::AbstractMatrix, expA, alg::DiagonalAlgorithm)
102109
check_input(exponential!, A, expA, alg)
103110
return map_diagonal!(exp, expA, A)
104111
end
105112

106-
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA::AbstractMatrix, alg::DiagonalAlgorithm)
113+
function exponential!((τ, A)::Tuple{Number, AbstractMatrix}, expA, alg::DiagonalAlgorithm)
107114
check_input(exponential!, (τ, A), expA, alg)
108115
return map_diagonal!(x -> exp(x * τ), expA, A)
109116
end

src/interface/exponential.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,9 @@ function default_algorithm(::typeof(exponential!), ::Type{A}; kwargs...) where {
3535
end
3636

3737
function default_algorithm(::typeof(exponential!), ::Tuple{A, B}; kwargs...) where {A, B}
38-
return default_exponential_algorithm(B; kwargs...)
38+
return default_algorithm(exponential!, B; kwargs...)
39+
end
40+
41+
function default_algorithm(::typeof(exponential!), ::Type{Tuple{A, B}}; kwargs...) where {A, B}
42+
return default_algorithm(exponential!, B; kwargs...)
3943
end

0 commit comments

Comments
 (0)