Skip to content

Commit 07caacf

Browse files
committed
Make the algorithm for real powers of a matrix robust
1 parent 617b2a6 commit 07caacf

File tree

2 files changed

+65
-19
lines changed

2 files changed

+65
-19
lines changed

base/linalg/diagonal.jl

+8
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ expm(D::Diagonal) = Diagonal(exp.(D.diag))
251251
logm(D::Diagonal) = Diagonal(log.(D.diag))
252252
sqrtm(D::Diagonal) = Diagonal(sqrt.(D.diag))
253253

254+
# Matrix functions
255+
^(D::Diagonal, p::Real) = Diagonal((D.diag).^p)
256+
for (funm, func) in ([:expm,:exp], [:sqrtm,:sqrt], [:logm,:log])
257+
@eval begin
258+
($funm)(D::Diagonal) = Diagonal(($func)(D.diag))
259+
end
260+
end
261+
254262
#Linear solver
255263
function A_ldiv_B!(D::Diagonal, B::StridedVecOrMat)
256264
m, n = size(B, 1), size(B, 2)

base/linalg/triangular.jl

+57-19
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,7 @@ powm(A::LowerTriangular, p::Real) = powm(A.', p::Real).'
16721672
# Based on the code available at http://eprints.ma.man.ac.uk/1851/02/logm.zip,
16731673
# Copyright (c) 2011, Awad H. Al-Mohy and Nicholas J. Higham
16741674
# Julia version relicensed with permission from original authors
1675-
function logm{T<:Union{Float32,Float64,Complex{Float32},Complex{Float64}}}(A0::UpperTriangular{T})
1675+
function logm{T<:Union{Float64,Complex{Float64}}}(A0::UpperTriangular{T})
16761676
theta = [1.586970738772063e-005,
16771677
2.313807884242979e-003,
16781678
1.938179313533253e-002,
@@ -1718,7 +1718,11 @@ function logm{T<:Union{Float32,Float64,Complex{Float32},Complex{Float64}}}(A0::U
17181718
scale!(2^s,Y.data)
17191719

17201720
# Compute accurate diagonal and superdiagonal of log(A)
1721+
<<<<<<< 617b2a62223cd7cd0883a248a124b313bcf9d8b4
17211722
for k = 1:n-1
1723+
=======
1724+
@inbounds for k = 1:n-1
1725+
>>>>>>> Make the algorithm for real powers of a matrix robust
17221726
Ak = complex(A0[k,k])
17231727
Akp1 = complex(A0[k+1,k+1])
17241728
logAk = log(Ak)
@@ -1749,7 +1753,11 @@ logm(A::LowerTriangular) = logm(A.').'
17491753
# Numer. Algorithms, 59, (2012), 393–402.
17501754
function sqrt_diag!(A0::UpperTriangular, A::UpperTriangular, s)
17511755
n = checksquare(A0)
1756+
<<<<<<< 617b2a62223cd7cd0883a248a124b313bcf9d8b4
17521757
for i = 1:n
1758+
=======
1759+
@inbounds for i = 1:n
1760+
>>>>>>> Make the algorithm for real powers of a matrix robust
17531761
a = complex(A0[i,i])
17541762
if s == 0
17551763
A[i,i] = a - 1
@@ -1806,25 +1814,31 @@ function invsquaring(A0::UpperTriangular, theta)
18061814
d2 = sqrt(norm(AmI^2, 1))
18071815
d3 = cbrt(norm(AmI^3, 1))
18081816
alpha2 = max(d2, d3)
1809-
foundm = false
18101817
if alpha2 <= theta[2]
18111818
m = alpha2<=theta[1]?1:2
1812-
foundm = true
1813-
end
1814-
1815-
while ~foundm
1816-
more = false
1817-
if s > s0
1818-
d3 = cbrt(norm(AmI^3, 1))
1819-
end
1820-
d4 = norm(AmI^4, 1)^(1/4)
1821-
alpha3 = max(d3, d4)
1822-
if alpha3 <= theta[tmax]
1823-
for j = 3:tmax
1824-
if alpha3 <= theta[j]
1819+
else
1820+
while true
1821+
more = false
1822+
if s > s0
1823+
d3 = cbrt(norm(AmI^3, 1))
1824+
end
1825+
d4 = norm(AmI^4, 1)^(1/4)
1826+
alpha3 = max(d3, d4)
1827+
if alpha3 <= theta[tmax]
1828+
for j = 3:tmax
1829+
if alpha3 <= theta[j]
1830+
break
1831+
end
1832+
end
1833+
if j <= 6
1834+
m = j
18251835
break
1836+
elseif alpha3 / 2 <= theta[5] && p < 2
1837+
more = true
1838+
p = p + 1
18261839
end
18271840
end
1841+
<<<<<<< 617b2a62223cd7cd0883a248a124b313bcf9d8b4
18281842
if j <= 6
18291843
m = j
18301844
foundm = true
@@ -1845,21 +1859,45 @@ function invsquaring(A0::UpperTriangular, theta)
18451859
if eta <= theta[j]
18461860
m = j
18471861
break
1862+
=======
1863+
1864+
if ~more
1865+
d5 = norm(AmI^5, 1)^(1/5)
1866+
alpha4 = max(d4, d5)
1867+
eta = min(alpha3, alpha4)
1868+
if eta <= theta[tmax]
1869+
j = 0
1870+
for j = 6:tmax
1871+
if eta <= theta[j]
1872+
m = j
1873+
break
1874+
end
1875+
>>>>>>> Make the algorithm for real powers of a matrix robust
18481876
end
1877+
break
18491878
end
1879+
<<<<<<< 617b2a62223cd7cd0883a248a124b313bcf9d8b4
18501880
foundm = true
18511881
break
1882+
=======
1883+
>>>>>>> Make the algorithm for real powers of a matrix robust
18521884
end
1853-
end
18541885

1886+
<<<<<<< 617b2a62223cd7cd0883a248a124b313bcf9d8b4
18551887
if s == maxsqrt
18561888
m = tmax
18571889
foundm = true
18581890
break
1891+
=======
1892+
if s == maxsqrt
1893+
m = tmax
1894+
break
1895+
end
1896+
A = sqrtm(A)
1897+
AmI = A - I
1898+
s = s + 1
1899+
>>>>>>> Make the algorithm for real powers of a matrix robust
18591900
end
1860-
A = sqrtm(A)
1861-
AmI = A - I
1862-
s = s + 1
18631901
end
18641902

18651903
# Compute accurate superdiagonal of T

0 commit comments

Comments
 (0)