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

deprecate expm in favor of exp #23233

Merged
merged 2 commits into from
Aug 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ Deprecated or removed
full path if you need access to executables or libraries in the `JULIA_HOME` directory, e.g.
`joinpath(JULIA_HOME, "7z.exe")` for `7z.exe` ([#21540]).

* `expm` has been deprecated in favor of `exp` ([#23233]).

* Calling `union` with no arguments is deprecated; construct an empty set with an appropriate
element type using `Set{T}()` instead ([#23144]).

Expand Down Expand Up @@ -1196,4 +1198,5 @@ Command-line option changes
[#23157]: https://github.com/JuliaLang/julia/issues/23157
[#23187]: https://github.com/JuliaLang/julia/issues/23187
[#23207]: https://github.com/JuliaLang/julia/issues/23207
[#23233]: https://github.com/JuliaLang/julia/issues/23233
[#23342]: https://github.com/JuliaLang/julia/issues/23342
8 changes: 6 additions & 2 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ for f in (:sin, :sinh, :sind, :asin, :asinh, :asind,
:tan, :tanh, :tand, :atan, :atanh, :atand,
:sinpi, :cosc, :ceil, :floor, :trunc, :round,
:log1p, :expm1, :abs, :abs2,
:log, :log2, :log10, :exp, :exp2, :exp10, :sinc, :cospi,
:log, :log2, :log10, :exp2, :exp10, :sinc, :cospi,
:cos, :cosh, :cosd, :acos, :acosd,
:cot, :coth, :cotd, :acot, :acotd,
:sec, :sech, :secd, :asech,
Expand Down Expand Up @@ -251,7 +251,7 @@ for f in (
# base/special/gamma.jl
:gamma, :lfact,
# base/math.jl
:cbrt, :sinh, :cosh, :tanh, :atan, :asinh, :exp, :exp2,
:cbrt, :sinh, :cosh, :tanh, :atan, :asinh, :exp2,
:expm1, :exp10, :sin, :cos, :tan, :asin, :acos, :acosh, :atanh,
#=:log,=# :log2, :log10, :lgamma, #=:log1p,=# :sqrt,
# base/floatfuncs.jl
Expand Down Expand Up @@ -1660,6 +1660,10 @@ function Tridiagonal(dl::AbstractVector{Tl}, d::AbstractVector{Td}, du::Abstract
Tridiagonal(map(v->convert(Vector{promote_type(Tl,Td,Tu)}, v), (dl, d, du))...)
end

# deprecate expm in favor of exp
@deprecate expm! exp!
@deprecate expm exp

# PR #23092
@eval LibGit2 begin
function prompt(msg::AbstractString; default::AbstractString="", password::Bool=false)
Expand Down
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,6 @@ export
eigvals,
eigvals!,
eigvecs,
expm,
eye,
factorize,
givens,
Expand Down
15 changes: 7 additions & 8 deletions base/linalg/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,12 @@ function (^)(A::AbstractMatrix{T}, p::Real) where T
# Otherwise, use Schur decomposition
return schurpow(A, p)
end
(^)(A::AbstractMatrix, p::Number) = expm(p*logm(A))
(^)(A::AbstractMatrix, p::Number) = exp(p*logm(A))

# Matrix exponential

"""
expm(A)
exp(A::AbstractMatrix)

Compute the matrix exponential of `A`, defined by

Expand All @@ -445,22 +445,21 @@ julia> A = eye(2, 2)
1.0 0.0
0.0 1.0

julia> expm(A)
julia> exp(A)
2×2 Array{Float64,2}:
2.71828 0.0
0.0 2.71828
```
"""
expm(A::StridedMatrix{<:BlasFloat}) = expm!(copy(A))
expm(A::StridedMatrix{<:Integer}) = expm!(float(A))
expm(x::Number) = exp(x)
exp(A::StridedMatrix{<:BlasFloat}) = exp!(copy(A))
exp(A::StridedMatrix{<:Integer}) = exp!(float(A))

## Destructive matrix exponential using algorithm from Higham, 2008,
## "Functions of Matrices: Theory and Computation", SIAM
function expm!(A::StridedMatrix{T}) where T<:BlasFloat
function exp!(A::StridedMatrix{T}) where T<:BlasFloat
n = checksquare(A)
if ishermitian(A)
return full(expm(Hermitian(A)))
return full(exp(Hermitian(A)))
end
ilo, ihi, scale = LAPACK.gebal!('B', A) # modifies A
nA = norm(A, 1)
Expand Down
3 changes: 1 addition & 2 deletions base/linalg/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,7 @@ end
eye(::Type{Diagonal{T}}, n::Int) where {T} = Diagonal(ones(T,n))

# Matrix functions
expm(D::Diagonal) = Diagonal(exp.(D.diag))
expm(D::Diagonal{<:AbstractMatrix}) = Diagonal(expm.(D.diag))
exp(D::Diagonal) = Diagonal(exp.(D.diag))
logm(D::Diagonal) = Diagonal(log.(D.diag))
logm(D::Diagonal{<:AbstractMatrix}) = Diagonal(logm.(D.diag))
sqrtm(D::Diagonal) = Diagonal(sqrt.(D.diag))
Expand Down
3 changes: 1 addition & 2 deletions base/linalg/linalg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Base: \, /, *, ^, +, -, ==
import Base: A_mul_Bt, At_ldiv_Bt, A_rdiv_Bc, At_ldiv_B, Ac_mul_Bc, A_mul_Bc, Ac_mul_B,
Ac_ldiv_B, Ac_ldiv_Bc, At_mul_Bt, A_rdiv_Bt, At_mul_B
import Base: USE_BLAS64, abs, big, broadcast, ceil, conj, convert, copy, copy!,
adjoint, eltype, eye, findmax, findmin, fill!, floor, full, getindex,
adjoint, eltype, exp, eye, findmax, findmin, fill!, floor, full, getindex,
hcat, imag, indices, inv, isapprox, isone, IndexStyle, kron, length, map,
ndims, oneunit, parent, power_by_squaring, print_matrix, promote_rule, real, round,
setindex!, show, similar, size, transpose, trunc, typed_hcat
Expand Down Expand Up @@ -81,7 +81,6 @@ export
eigvals,
eigvals!,
eigvecs,
expm,
eye,
factorize,
givens,
Expand Down
4 changes: 2 additions & 2 deletions base/linalg/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -589,11 +589,11 @@ function ^(A::Hermitian{T}, p::Real) where T
end
end

function expm(A::Symmetric)
function exp(A::Symmetric)
F = eigfact(A)
return Symmetric((F.vectors * Diagonal(exp.(F.values))) * F.vectors')
end
function expm(A::Hermitian{T}) where T
function exp(A::Hermitian{T}) where T
n = checksquare(A)
F = eigfact(A)
retmat = (F.vectors * Diagonal(exp.(F.values))) * F.vectors'
Expand Down
4 changes: 2 additions & 2 deletions doc/src/manual/linear-algebra.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ as well as whether hooks to various optimized methods for them in LAPACK are ava

| Matrix type | `+` | `-` | `*` | `\` | Other functions with optimized methods |
|:------------------------- |:--- |:--- |:--- |:--- |:------------------------------------------------------------------- |
| [`Symmetric`](@ref) | | | | MV | [`inv()`](@ref), [`sqrtm()`](@ref), [`expm()`](@ref) |
| [`Hermitian`](@ref) | | | | MV | [`inv()`](@ref), [`sqrtm()`](@ref), [`expm()`](@ref) |
| [`Symmetric`](@ref) | | | | MV | [`inv()`](@ref), [`sqrtm()`](@ref), [`exp()`](@ref) |
| [`Hermitian`](@ref) | | | | MV | [`inv()`](@ref), [`sqrtm()`](@ref), [`exp()`](@ref) |
| [`UpperTriangular`](@ref) | | | MV | MV | [`inv()`](@ref), [`det()`](@ref) |
| [`LowerTriangular`](@ref) | | | MV | MV | [`inv()`](@ref), [`det()`](@ref) |
| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax()`](@ref), [`eigmin()`](@ref) |
Expand Down
1 change: 0 additions & 1 deletion doc/src/stdlib/linalg.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ Base.repmat
Base.kron
Base.SparseArrays.blkdiag
Base.LinAlg.linreg
Base.LinAlg.expm
Copy link
Member

@fredrikekre fredrikekre Sep 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this should just have been changed to Base.LinAlg.exp(::StridedMatrix) rather than deleted?

Base.LinAlg.logm
Base.LinAlg.sqrtm
Base.LinAlg.lyap
Expand Down
33 changes: 16 additions & 17 deletions test/linalg/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ bimg = randn(n,2)/2
A = zeros(eltya,1,1)
A[1,1] = α
@test diagm(α) == A # Test behavior of `diagm` when passed a scalar
@test expm(α) == exp(α) # `expm` should behave like `exp` with scalar argument
end

@testset "Factorize" begin
Expand Down Expand Up @@ -416,7 +415,7 @@ end
eA1 = convert(Matrix{elty}, [147.866622446369 127.781085523181 127.781085523182;
183.765138646367 183.765138646366 163.679601723179;
71.797032399996 91.8825693231832 111.968106246371]')
@test expm(A1) ≈ eA1
@test exp(A1) ≈ eA1

A2 = convert(Matrix{elty},
[29.87942128909879 0.7815750847907159 -2.289519314033932;
Expand All @@ -426,21 +425,21 @@ end
[ 5496313853692458.0 -18231880972009236.0 -30475770808580460.0;
-18231880972009252.0 60605228702221920.0 101291842930249760.0;
-30475770808580480.0 101291842930249728.0 169294411240851968.0])
@test expm(A2) ≈ eA2
@test exp(A2) ≈ eA2

A3 = convert(Matrix{elty}, [-131 19 18;-390 56 54;-387 57 52])
eA3 = convert(Matrix{elty}, [-1.50964415879218 -5.6325707998812 -4.934938326092;
0.367879439109187 1.47151775849686 1.10363831732856;
0.135335281175235 0.406005843524598 0.541341126763207]')
@test expm(A3) ≈ eA3
@test exp(A3) ≈ eA3

A4 = convert(Matrix{elty}, [0.25 0.25; 0 0])
eA4 = convert(Matrix{elty}, [1.2840254166877416 0.2840254166877415; 0 1])
@test expm(A4) ≈ eA4
@test exp(A4) ≈ eA4

A5 = convert(Matrix{elty}, [0 0.02; 0 0])
eA5 = convert(Matrix{elty}, [1 0.02; 0 1])
@test expm(A5) ≈ eA5
@test exp(A5) ≈ eA5

# Hessenberg
@test hessfact(A1)[:H] ≈ convert(Matrix{elty},
Expand All @@ -454,20 +453,20 @@ end
1/3 1/4 1/5 1/6;
1/4 1/5 1/6 1/7;
1/5 1/6 1/7 1/8])
@test expm(logm(A4)) ≈ A4
@test exp(logm(A4)) ≈ A4

A5 = convert(Matrix{elty}, [1 1 0 1; 0 1 1 0; 0 0 1 1; 1 0 0 1])
@test expm(logm(A5)) ≈ A5
@test exp(logm(A5)) ≈ A5

A6 = convert(Matrix{elty}, [-5 2 0 0 ; 1/2 -7 3 0; 0 1/3 -9 4; 0 0 1/4 -11])
@test expm(logm(A6)) ≈ A6
@test exp(logm(A6)) ≈ A6

A7 = convert(Matrix{elty}, [1 0 0 1e-8; 0 1 0 0; 0 0 1 0; 0 0 0 1])
@test expm(logm(A7)) ≈ A7
@test exp(logm(A7)) ≈ A7
end

A8 = 100 * [-1+1im 0 0 1e-8; 0 1 0 0; 0 0 1 0; 0 0 0 1]
@test expm(logm(A8)) ≈ A8
@test exp(logm(A8)) ≈ A8
end

@testset "issue 5116" begin
Expand All @@ -476,19 +475,19 @@ end
0.006540706968939 -0.999786072879326 0.0 0.0
0.0 0.0 1.0 0.0
0.013081413937878 -3.999572145758650 0.0 1.0]
@test expm(A9) ≈ eA9
@test exp(A9) ≈ eA9

A10 = [ 0. 0. 0. 0. ; 0. 0. -im 0.; 0. im 0. 0.; 0. 0. 0. 0.]
eA10 = [ 1.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
0.0+0.0im 1.543080634815244+0.0im 0.0-1.175201193643801im 0.0+0.0im
0.0+0.0im 0.0+1.175201193643801im 1.543080634815243+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0+0.0im 1.0+0.0im]
@test expm(A10) ≈ eA10
@test exp(A10) ≈ eA10
end

@testset "Additional matrix logarithm tests" for elty in (Float64, Complex{Float64})
A11 = convert(Matrix{elty}, [3 2; -5 -3])
@test expm(logm(A11)) ≈ A11
@test exp(logm(A11)) ≈ A11

A12 = convert(Matrix{elty}, [1 -1; 1 -1])
@test typeof(logm(A12)) == Array{Complex{Float64}, 2}
Expand All @@ -498,7 +497,7 @@ end
0.2310490602 1.295566591 0.2651438179;
0.2310490602 0.1969543025 1.363756107])
@test logm(A1) ≈ logmA1
@test expm(logm(A1)) ≈ A1
@test exp(logm(A1)) ≈ A1

A4 = convert(Matrix{elty}, [1/2 1/3 1/4 1/5+eps();
1/3 1/4 1/5 1/6;
Expand All @@ -509,7 +508,7 @@ end
0.4462766564 2.994142974 -7.351095988 3.318413247;
0.2414170219 0.5865285289 3.318413247 -5.444632124])
@test logm(A4) ≈ logmA4
@test expm(logm(A4)) ≈ A4
@test exp(logm(A4)) ≈ A4
end

@testset "issue #7181" begin
Expand Down Expand Up @@ -652,7 +651,7 @@ end

@testset "test ops on Numbers for $elty" for elty in [Float32,Float64,Complex64,Complex128]
a = rand(elty)
@test expm(a) == exp(a)
@test exp(a) == exp(a)
@test isposdef(one(elty))
@test sqrtm(a) == sqrt(a)
@test logm(a) ≈ log(a)
Expand Down
4 changes: 2 additions & 2 deletions test/linalg/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ srand(1)
@test func(D) ≈ func(DM) atol=n^2*eps(relty)*(1+(elty<:Complex))
end
if relty <: BlasFloat
for func in (expm,)
for func in (exp,)
@test func(D) ≈ func(DM) atol=n^3*eps(relty)
end
@test logm(Diagonal(abs.(D.diag))) ≈ logm(abs.(DM)) atol=n^3*eps(relty)
Expand Down Expand Up @@ -381,7 +381,7 @@ end
@test ishermitian(Dherm) == true
@test ishermitian(Dsym) == false

@test expm(D) == Diagonal([expm([1 2; 3 4]), expm([1 2; 3 4])])
@test exp(D) == Diagonal([exp([1 2; 3 4]), exp([1 2; 3 4])])
@test logm(D) == Diagonal([logm([1 2; 3 4]), logm([1 2; 3 4])])
@test sqrtm(D) == Diagonal([sqrtm([1 2; 3 4]), sqrtm([1 2; 3 4])])
end
Expand Down
2 changes: 1 addition & 1 deletion test/linalg/lapack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ end

# Issue 13976
let A = [NaN 0.0 NaN; 0 0 0; NaN 0 NaN]
@test_throws ArgumentError expm(A)
@test_throws ArgumentError exp(A)
end

# Issue 14065 (and 14220)
Expand Down
6 changes: 3 additions & 3 deletions test/linalg/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ end
@testset "Hermitian matrix exponential/log" begin
A1 = randn(4,4) + im*randn(4,4)
A2 = A1 + A1'
@test expm(A2) ≈ expm(Hermitian(A2))
@test exp(A2) ≈ exp(Hermitian(A2))
@test logm(A2) ≈ logm(Hermitian(A2))
A3 = A1 * A1' # posdef
@test expm(A3) ≈ expm(Hermitian(A3))
@test exp(A3) ≈ exp(Hermitian(A3))
@test logm(A3) ≈ logm(Hermitian(A3))

A1 = randn(4,4)
A3 = A1 * A1'
A4 = A1 + A1.'
@test expm(A4) ≈ expm(Symmetric(A4))
@test exp(A4) ≈ exp(Symmetric(A4))
@test logm(A3) ≈ logm(Symmetric(A3))
@test logm(A3) ≈ logm(Hermitian(A3))
end
Expand Down
4 changes: 2 additions & 2 deletions test/linalg/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ for elty1 in (Float32, Float64, BigFloat, Complex64, Complex128, Complex{BigFloa
@test B == viewA1.'
end

#expm/logm
#exp/logm
if (elty1 == Float64 || elty1 == Complex128) && (t1 == UpperTriangular || t1 == LowerTriangular)
@test expm(full(logm(A1))) ≈ full(A1)
@test exp(full(logm(A1))) ≈ full(A1)
end

# scale
Expand Down