Skip to content
This repository was archived by the owner on Apr 26, 2021. It is now read-only.

Commit 3b7c2a9

Browse files
RalphASsimonbyrne
authored andcommitted
Update to Julia v0.7 (#9)
* update to Julia v0.7 * update CI to v0.7
1 parent aff5695 commit 3b7c2a9

File tree

10 files changed

+143
-104
lines changed

10 files changed

+143
-104
lines changed

.travis.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 0.5
8-
- 0.6
7+
- 0.7
98
- nightly
109
notifications:
1110
email: false
12-
# uncomment the following lines to override the default test script
13-
#script:
14-
# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
15-
# - julia -e 'Pkg.clone(pwd()); Pkg.build("GenericSVD"); Pkg.test("GenericSVD"; coverage=true)'
11+
12+
script:
13+
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
14+
- julia --color=yes -e 'using InteractiveUtils; versioninfo(); import Pkg; Pkg.clone(pwd()); Pkg.build("GenericSVD")'
15+
- julia --color=yes --check-bounds=yes -e 'import Pkg; Pkg.test("GenericSVD"; coverage=true)'
16+
after_success:
17+
- julia -e 'import Pkg; cd(Pkg.dir("GenericSVD")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder()); Codecov.submit(process_folder())'

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
julia 0.5
1+
julia 0.7-beta

appveyor.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
environment:
22
matrix:
3-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
4-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
5-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
6-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
3+
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe"
4+
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe"
75
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
86
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
97

@@ -20,6 +18,11 @@ notifications:
2018

2119
install:
2220
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
21+
# if there's a newer build queued for the same PR, cancel this one
22+
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
23+
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
24+
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
25+
throw "There are newer queued builds for this pull request, failing early." }
2326
# Download most recent Julia Windows binary
2427
- ps: (new-object net.webclient).DownloadFile(
2528
$env:JULIA_URL,
@@ -30,8 +33,8 @@ install:
3033
build_script:
3134
# Need to convert from shallow to complete for Pkg.clone to work
3235
- IF EXIST .git\shallow (git fetch --unshallow)
33-
- C:\projects\julia\bin\julia -e "versioninfo();
36+
- C:\projects\julia\bin\julia -e "using InteractiveUtils; versioninfo(); import Pkg;
3437
Pkg.clone(pwd(), \"GenericSVD\"); Pkg.build(\"GenericSVD\")"
3538

3639
test_script:
37-
- C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"GenericSVD\")"
40+
- C:\projects\julia\bin\julia --check-bounds=yes -e "import Pkg; Pkg.test(\"GenericSVD\")"

src/GenericSVD.jl

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,35 @@
11
__precompile__(true)
22
module GenericSVD
3-
4-
import Base: SVD
3+
using LinearAlgebra
4+
import LinearAlgebra: SVD, svd!
55

66
include("utils.jl")
77
include("bidiagonalize.jl")
88

9-
Base.svdfact!(X::AbstractMatrix; thin=true) = generic_svdfact!(X; thin=thin)
10-
Base.svdvals!(X::AbstractMatrix) = generic_svdvals!(X)
9+
function svd!(X::AbstractMatrix; full::Bool=false, thin::Union{Bool,Nothing} = nothing)
10+
if thin != nothing
11+
@warn "obsolete keyword thin in generic svd!"
12+
thinx = thin
13+
else
14+
thinx = !full
15+
end
16+
generic_svdfact!(X; thin=thinx)
17+
end
18+
19+
LinearAlgebra.svdvals!(X::AbstractMatrix) = generic_svdvals!(X)
1120

1221
function generic_svdfact!(X::AbstractMatrix; sorted=true, thin=true)
1322
m,n = size(X)
14-
t =false
15-
if m < n
23+
wide = m < n
24+
if wide
1625
m,n = n,m
1726
X = X'
18-
t = true
1927
end
2028
B,P = bidiagonalize_tall!(X)
21-
U,Vt = full(P,thin=thin)
29+
U,Vt = unpack(P,thin=thin)
2230
U,S,Vt = svd!(B,U,Vt)
31+
# as of Julia v0.7 we need to revert a mysterious transpose here
32+
Vt=Vt'
2333
for i = 1:n
2434
if signbit(S[i])
2535
S[i] = -S[i]
@@ -29,12 +39,12 @@ function generic_svdfact!(X::AbstractMatrix; sorted=true, thin=true)
2939
end
3040
end
3141
if sorted
32-
I = sortperm(S,rev=true)
33-
S = S[I]
34-
U = U[:,I]
35-
Vt = Vt[I,:]
42+
Idx = sortperm(S,rev=true)
43+
S = S[Idx]
44+
U = U[:,Idx]
45+
Vt = Vt[Idx,:]
3646
end
37-
t ? SVD(Vt',S,U') : SVD(U,S,Vt)
47+
wide ? SVD(Vt',S,U') : SVD(U,S,Vt)
3848
end
3949

4050
function generic_svdvals!(X::AbstractMatrix; sorted=true)
@@ -43,7 +53,7 @@ function generic_svdvals!(X::AbstractMatrix; sorted=true)
4353
X = X'
4454
end
4555
B,P = bidiagonalize_tall!(X)
46-
S = svd!(B)[2]
56+
S = svd!(B)
4757
for i = eachindex(S)
4858
if signbit(S[i])
4959
S[i] = -S[i]
@@ -95,7 +105,7 @@ This proceeds by iteratively finding the lowest strictly-bidiagonal submatrix, i
95105
```
96106
then applying a Golub-Kahan QR iteration.
97107
"""
98-
function svd!{T<:Real}(B::Bidiagonal{T}, U=nothing, Vt=nothing, ɛ=eps(T))
108+
function svd!(B::Bidiagonal{T}, U=nothing, Vt=nothing, ɛ=eps(T)) where T <: Real
99109
n = size(B, 1)
100110
if n == 1
101111
@goto done
@@ -143,13 +153,22 @@ function svd!{T<:Real}(B::Bidiagonal{T}, U=nothing, Vt=nothing, ɛ=eps(T))
143153
# use singular value closest to sqrt of final element of B'*B
144154
h = hypot(d₂,e)
145155
shift = abs(s₁-h) < abs(s₂-h) ? s₁ : s₂
156+
# avoid infinite loop
157+
if !all(isfinite.(B))
158+
(U == nothing) && return B.dv+NaN
159+
return SVD(U .+ NaN, B.dv .+ NaN, Vt .+ NaN)
160+
end
146161
svd_gk!(B, U, Vt, n₁, n₂, shift)
147162
end
148163
else
149164
throw(ArgumentError("lower bidiagonal version not implemented yet"))
150165
end
151166
@label done
152-
U, B.dv, Vt
167+
if U == nothing
168+
return B.dv
169+
else
170+
return SVD(U, B.dv, Vt)
171+
end
153172
end
154173

155174

@@ -170,7 +189,7 @@ function svd_zerodiag_row!(U,B,n₁,n₂)
170189
dᵢ = B.dv[i]
171190

172191
G,r = givens(dᵢ,e,i,n₁)
173-
A_mul_Bc!(U,G)
192+
rmul!(U,adjoint(G))
174193
B.dv[i] = r # -G.s*e + G.c*dᵢ
175194

176195
if i < n₂
@@ -199,7 +218,7 @@ function svd_zerodiag_col!(B,Vt,n₁,n₂)
199218
dᵢ = B.dv[i]
200219

201220
G,r = givens(dᵢ,e,i,n₂)
202-
A_mul_B!(G,Vt)
221+
lmul!(G,Vt)
203222

204223
B.dv[i] = r # G.c*dᵢ + G.s*e
205224

@@ -214,13 +233,13 @@ end
214233

215234

216235
"""
217-
svd_gk!{T<:Real}(B::Bidiagonal{T},U,Vt,n₁,n₂,shift)
236+
svd_gk!(B::Bidiagonal{T},U,Vt,n₁,n₂,shift) where T <: Real
218237
219238
Applies a Golub-Kahan SVD step (an implicit QR with shift) to the submatrix `B[n₁:n₂,n₁:n₂]`, applying the inverse transformations to `U` and `Vt` (preserving `U*B*Vt`).
220239
221240
A Givens rotation is applied to the top 2x2 matrix, and the resulting "bulge" is "chased" down the diagonal to the bottom of the matrix.
222241
"""
223-
function svd_gk!{T<:Real}(B::Bidiagonal{T},U,Vt,n₁,n₂,shift)
242+
function svd_gk!(B::Bidiagonal{T},U,Vt,n₁,n₂,shift) where T <: Real
224243

225244
if istriu(B)
226245

@@ -229,7 +248,7 @@ function svd_gk!{T<:Real}(B::Bidiagonal{T},U,Vt,n₁,n₂,shift)
229248
d₂′ = B.dv[n₁+1]
230249

231250
G, r = givens(d₁′ - abs2(shift)/d₁′, e₁′, n₁, n₁+1)
232-
A_mul_B!(G, Vt)
251+
lmul!(G,Vt)
233252

234253
# [d₁,e₁] = [d₁′,e₁′] * G'
235254
# [b ,d₂] [0 ,d₂′]
@@ -248,7 +267,7 @@ function svd_gk!{T<:Real}(B::Bidiagonal{T},U,Vt,n₁,n₂,shift)
248267
e₂ = B.ev[i+1]
249268

250269
G, r = givens(d₁, b, i, i+1)
251-
A_mul_Bc!(U, G)
270+
rmul!(U,adjoint(G))
252271

253272
B.dv[i] = r # G.c*d₁ + G.s*b
254273

@@ -265,7 +284,7 @@ function svd_gk!{T<:Real}(B::Bidiagonal{T},U,Vt,n₁,n₂,shift)
265284
d₃′ = B.dv[i+2]
266285

267286
G, r = givens(e₁′, b′, i+1, i+2)
268-
A_mul_B!(G, Vt)
287+
lmul!(G, Vt)
269288

270289
B.ev[i] = r # e₁′*G.c + b′*G.s
271290

@@ -280,7 +299,7 @@ function svd_gk!{T<:Real}(B::Bidiagonal{T},U,Vt,n₁,n₂,shift)
280299
# [0 ,.] [b ,d₂]
281300

282301
G, r = givens(d₁,b,n₂-1,n₂)
283-
A_mul_Bc!(U, G)
302+
rmul!(U, adjoint(G))
284303

285304
B.dv[n₂-1] = r # G.c*d₁ + G.s*b
286305

src/bidiagonalize.jl

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Packed storage of bidiagonalizing QR reflectors `U` and `V'`.
55
66
77
"""
8-
immutable PackedUVt{T} <: Factorization{T}
8+
struct PackedUVt{T} <: Factorization{T}
99
A::Matrix{T}
1010
end
1111

@@ -15,60 +15,64 @@ end
1515
1616
Bidiagonalize a tall matrix `A` into `B`. Both arguments are overwritten.
1717
"""
18-
function bidiagonalize_tall!{T}(A::Matrix{T},B::Bidiagonal)
18+
function bidiagonalize_tall!(A::Matrix{T},B::Bidiagonal) where T
1919
m, n = size(A)
2020
# tall case: assumes m >= n
2121
# upper bidiagonal
22+
istriu(B) || throw(ArgumentError("not implemented for lower BiDiag B"))
2223

2324
for i = 1:n
2425
x = @view A[i:m, i]
25-
τi = LinAlg.reflector!(x)
26+
τi = LinearAlgebra.reflector!(x)
2627
B.dv[i] = real(A[i,i])
27-
LinAlg.reflectorApply!(x, τi, @view(A[i:m, i+1:n]))
28+
LinearAlgebra.reflectorApply!(x, τi, @view(A[i:m, i+1:n]))
2829
A[i,i] = τi # store reflector coefficient in diagonal
2930

3031
# for Real, this only needs to be n-2
3132
# needed for Complex to ensure superdiagonal is Real
3233
if i <= n-1
3334
x = @view A[i, i+1:n]
3435
conj!(x)
35-
τi = LinAlg.reflector!(x)
36+
τi = LinearAlgebra.reflector!(x)
3637
B.ev[i] = real(A[i,i+1])
37-
LinAlg.reflectorApply!(@view(A[i+1:m, i+1:n]), x, τi)
38+
LinearAlgebra.reflectorApply!(@view(A[i+1:m, i+1:n]), x, τi)
3839
A[i,i+1] = τi
3940
end
4041
end
41-
B.isupper = true
4242

4343
B, PackedUVt(A)
4444
end
4545

46-
function bidiagonalize_tall!{T}(A::Matrix{T})
46+
function bidiagonalize_tall!(A::Adjoint{T2,Matrix{T}}) where {T,T2}
47+
bidiagonalize_tall!(Matrix(A))
48+
end
49+
50+
function bidiagonalize_tall!(A::Matrix{T}) where T
4751
m,n = size(A)
4852
R = real(T)
49-
B = Bidiagonal{R}(Vector{R}(n), Vector{R}(n - 1), true)
53+
B = Bidiagonal(Vector{R}(undef, n), Vector{R}(undef, n - 1), :U)
5054
bidiagonalize_tall!(A, B)
5155
end
5256

53-
function Base.full{T}(P::PackedUVt{T};thin=true)
57+
function unpack(P::PackedUVt{T};thin=true) where T
5458
A = P.A
5559
m,n = size(A)
5660

5761
# U = Q_1 ... Q_n I_{m,n}
5862
w = thin ? n : m
59-
U = eye(T,m,w)
63+
U = Matrix(one(T)*I,m,w) # eye(T,m,w)
6064
for i = n:-1:1
6165
τi = A[i,i]
6266
x = @view A[i:m, i]
63-
LinAlg.reflectorApply!(x, τi', @view(U[i:m, i:w]))
67+
LinearAlgebra.reflectorApply!(x, τi', @view(U[i:m, i:w]))
6468
end
6569

6670
# Vt = P_{n_2} ... P_1
67-
Vt = eye(T,n,n)
71+
Vt = Matrix(one(T)*I,n,n) # eye(T,n,n)
6872
for i = n-1:-1:1
6973
τi = A[i,i+1]
7074
x = @view A[i, i+1:n]
71-
LinAlg.reflectorApply!(@view(Vt[i:n, i+1:n]), x, τi')
75+
reflectorApply!(@view(Vt[i:n, i+1:n]), x, τi')
7276
end
7377
U,Vt
7478
end

src/utils.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import Base.LinAlg: reflectorApply!
1+
# Avast, LinearAlgebra, prepare to be boarded!
2+
import LinearAlgebra: reflectorApply!
3+
24
@inline function reflectorApply!(A::StridedMatrix, x::AbstractVector, τ::Number) # apply conjugate transpose reflector from right.
35
m, n = size(A)
46
if length(x) != n
@@ -21,7 +23,7 @@ import Base.LinAlg: reflectorApply!
2123
end
2224

2325

24-
import Base: A_mul_B!, A_mul_Bc!, A_ldiv_B!
26+
import LinearAlgebra: lmul!, rmul!
2527

26-
A_mul_B!(G::LinAlg.Givens, ::Void) = nothing
27-
A_mul_Bc!(::Void, G::LinAlg.Givens) = nothing
28+
lmul!(G::LinearAlgebra.Givens{T}, ::Nothing) where T = nothing
29+
rmul!(::Nothing, Ga::Adjoint{Any,LinearAlgebra.Givens{T}}) where T = nothing

0 commit comments

Comments
 (0)