Skip to content

Commit 46c61c2

Browse files
committed
Fix method ambiguity for qr (JuliaArrays#931) and lingering ambiguities for lu (JuliaArrays#932)
* fix `qr` method ambiguities (JuliaArrays#931) and lingering `lu` ambiguities (JuliaArrays#920) * fix inferrence issues due to using `@invoke` for `lu` keyword arguments * bump version
1 parent d2c58fa commit 46c61c2

File tree

5 files changed

+51
-31
lines changed

5 files changed

+51
-31
lines changed

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "StaticArrays"
22
uuid = "90137ffa-7385-5640-81b9-e52037218182"
3-
version = "1.2.4"
3+
version = "1.2.5"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

src/lu.jl

+12-16
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,21 @@ function Base.show(io::IO, mime::MIME{Symbol("text/plain")}, F::LU)
3030
end
3131

3232
# LU decomposition
33-
function lu(A::StaticMatrix, pivot::Union{Val{false},Val{true}}=Val(true); check = true)
34-
L, U, p = _lu(A, pivot, check)
35-
LU(L, U, p)
36-
end
37-
38-
# For the square version, return explicit lower and upper triangular matrices.
39-
# We would do this for the rectangular case too, but Base doesn't support that.
40-
function lu(A::StaticMatrix{N,N}, pivot::Union{Val{false},Val{true}}=Val(true);
41-
check = true) where {N}
42-
L, U, p = _lu(A, pivot, check)
43-
LU(LowerTriangular(L), UpperTriangular(U), p)
44-
end
33+
for pv in (:true, :false)
34+
# ... define each `pivot::Val{true/false}` method individually to avoid ambiguties
35+
@eval function lu(A::StaticMatrix, pivot::Val{$pv}; check = true)
36+
L, U, p = _lu(A, pivot, check)
37+
LU(L, U, p)
38+
end
4539

46-
@static if VERSION >= v"1.7-DEV"
47-
# disambiguation
48-
function lu(A::StaticMatrix{N,N}, pivot::Val{true}) where {N}
49-
Base.@invoke lu(A::StaticMatrix{N,N} where N, pivot::Union{Val{false},Val{true}})
40+
# For the square version, return explicit lower and upper triangular matrices.
41+
# We would do this for the rectangular case too, but Base doesn't support that.
42+
@eval function lu(A::StaticMatrix{N,N}, pivot::Val{$pv}; check = true) where {N}
43+
L, U, p = _lu(A, pivot, check)
44+
LU(LowerTriangular(L), UpperTriangular(U), p)
5045
end
5146
end
47+
lu(A::StaticMatrix; check = true) = lu(A, Val(true); check=check)
5248

5349
# location of the first zero on the diagonal, 0 when not found
5450
function _first_zero_on_diagonal(A::StaticMatrix{M,N,T}) where {M,N,T}

src/qr.jl

+19-14
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,26 @@ Base.iterate(S::QR, ::Val{:R}) = (S.R, Val(:p))
1111
Base.iterate(S::QR, ::Val{:p}) = (S.p, Val(:done))
1212
Base.iterate(S::QR, ::Val{:done}) = nothing
1313

14+
for pv in (:true, :false)
15+
@eval begin
16+
@inline function qr(A::StaticMatrix, pivot::Val{$pv})
17+
QRp = _qr(Size(A), A, pivot)
18+
if length(QRp) === 2
19+
# create an identity permutation since that is cheap,
20+
# and much safer since, in the case of isbits types, we can't
21+
# safely leave the field undefined.
22+
p = identity_perm(QRp[2])
23+
return QR(QRp[1], QRp[2], p)
24+
else # length(QRp) === 3
25+
return QR(QRp[1], QRp[2], QRp[3])
26+
end
27+
end
28+
end
29+
end
1430
"""
15-
qr(A::StaticMatrix, pivot=Val(false))
31+
qr(A::StaticMatrix, pivot::Union{Val{true}, Val{false}} = Val(false))
1632
17-
Compute the QR factorization of `A`. The factors can be obtain by iteration:
33+
Compute the QR factorization of `A`. The factors can be obtained by iteration:
1834
1935
```julia
2036
julia> A = @SMatrix rand(3,4);
@@ -34,18 +50,7 @@ julia> F.Q * F.R ≈ A
3450
true
3551
```
3652
"""
37-
@inline function qr(A::StaticMatrix, pivot::Union{Val{false}, Val{true}} = Val(false))
38-
QRp = _qr(Size(A), A, pivot)
39-
if length(QRp) === 2
40-
# create an identity permutation since that is cheap,
41-
# and much safer since, in the case of isbits types, we can't
42-
# safely leave the field undefined.
43-
p = identity_perm(QRp[2])
44-
return QR(QRp[1], QRp[2], p)
45-
else # length(QRp) === 3
46-
return QR(QRp[1], QRp[2], QRp[3])
47-
end
48-
end
53+
qr(A::StaticMatrix) = qr(A, Val(false))
4954

5055
function identity_perm(R::StaticMatrix{N,M,T}) where {N,M,T}
5156
return similar_type(R, Int, Size((M,)))(ntuple(x -> x, Val{M}()))

test/lu.jl

+11
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,14 @@ end
6565
@test_throws SingularException lu(A)
6666
@test !issuccess(lu(A; check = false))
6767
end
68+
69+
@testset "LU method ambiguity" begin
70+
# Issue #920; just test that methods do not throw an ambiguity error when called
71+
for A in ((@SMatrix [1.0 2.0; 3.0 4.0]), (@SMatrix [1.0 2.0 3.0; 4.0 5.0 6.0]))
72+
@test isa(lu(A), StaticArrays.LU)
73+
@test isa(lu(A, Val(true)), StaticArrays.LU)
74+
@test isa(lu(A, Val(false)), StaticArrays.LU)
75+
@test isa(lu(A; check=false), StaticArrays.LU)
76+
@test isa(lu(A; check=true), StaticArrays.LU)
77+
end
78+
end

test/qr.jl

+8
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,11 @@ Random.seed!(42)
6060
test_qr(arr)
6161
end
6262
end
63+
64+
@testset "QR method ambiguity" begin
65+
# Issue #931; just test that methods do not throw an ambiguity error when called
66+
A = @SMatrix [1.0 2.0 3.0; 4.0 5.0 6.0]
67+
@test isa(qr(A), StaticArrays.QR)
68+
@test isa(qr(A, Val(true)), StaticArrays.QR)
69+
@test isa(qr(A, Val(false)), StaticArrays.QR)
70+
end

0 commit comments

Comments
 (0)