Skip to content

Commit a00c446

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents a3bca35 + 103e9d4 commit a00c446

21 files changed

+251
-109
lines changed

src/MArray.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,6 @@ end
7373

7474
@inline MArray(a::StaticArray) = MArray{size_tuple(Size(a))}(Tuple(a))
7575

76-
# Simplified show for the type
77-
#show(io::IO, ::Type{MArray{S, T, N}}) where {S, T, N} = print(io, "MArray{$S,$T,$N}")
78-
79-
# Some more advanced constructor-like functions
80-
@inline one(::Type{MArray{S}}) where {S} = one(MArray{S,Float64,tuple_length(S)})
81-
@inline one(::Type{MArray{S,T}}) where {S,T} = one(MArray{S,T,tuple_length(S)})
82-
83-
# MArray(I::UniformScaling) methods to replace eye
84-
(::Type{MA})(I::UniformScaling) where {MA<:MArray} = _eye(Size(MA), MA, I)
85-
8676
####################
8777
## MArray methods ##
8878
####################

src/MVector.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ macro MVector(ex)
9595
error("@MVector expected a 1-dimensional array expression")
9696
end
9797
else
98-
error("@MVector only supports the zeros(), ones(), rand(), randn(), randexp(), and eye() functions.")
98+
error("@MVector only supports the zeros(), ones(), rand(), randn(), and randexp() functions.")
9999
end
100100
else
101101
error("Use @MVector [a,b,c] or @MVector([a,b,c])")

src/SArray.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,6 @@ end
5252

5353
@inline SArray(a::StaticArray) = SArray{size_tuple(Size(a))}(Tuple(a))
5454

55-
# Simplified show for the type
56-
# show(io::IO, ::Type{SArray{S, T, N}}) where {S, T, N} = print(io, "SArray{$S,$T,$N}") # TODO reinstate
57-
58-
# Some more advanced constructor-like functions
59-
@inline one(::Type{SArray{S}}) where {S} = one(SArray{S, Float64, tuple_length(S)})
60-
@inline one(::Type{SArray{S, T}}) where {S, T} = one(SArray{S, T, tuple_length(S)})
61-
62-
# SArray(I::UniformScaling) methods to replace eye
63-
(::Type{SA})(I::UniformScaling) where {SA<:SArray} = _eye(Size(SA), SA, I)
64-
6555
####################
6656
## SArray methods ##
6757
####################

src/SDiagonal.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ size(::Type{<:SDiagonal{N}}, d::Int) where {N} = d > 2 ? 1 : N
3333
# override to avoid copying
3434
diag(D::SDiagonal) = D.diag
3535

36-
# SDiagonal(I::UniformScaling) methods to replace eye
36+
# SDiagonal(I::UniformScaling) methods
3737
(::Type{SDiagonal{N}})(I::UniformScaling) where {N} = SDiagonal{N}(ntuple(x->I.λ, Val(N)))
3838
(::Type{SDiagonal{N,T}})(I::UniformScaling) where {N,T} = SDiagonal{N,T}(ntuple(x->I.λ, Val(N)))
3939

src/SHermitianCompact.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ end
230230
end
231231
end
232232

233-
@inline _eye(s::Size{S}, t::Type{SSC}) where {S, SSC <: SHermitianCompact} = _one(s, t)
233+
@inline _scalar_matrix(s::Size{S}, t::Type{SSC}) where {S, SSC <: SHermitianCompact} = _one(s, t)
234234

235235
# _fill covers fill, zeros, and ones:
236236
@generated function _fill(val, ::Size{s}, ::Type{SSC}) where {s, SSC <: SHermitianCompact}

src/SVector.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ macro SVector(ex)
108108
error("@SVector expected a 1-dimensional array expression")
109109
end
110110
else
111-
error("@SVector only supports the zeros(), ones(), rand(), randn(), randexp(), and eye() functions.")
111+
error("@SVector only supports the zeros(), ones(), rand(), randn() and randexp() functions.")
112112
end
113-
else # TODO Expr(:call, :zeros), Expr(:call, :ones), Expr(:call, :eye) ?
113+
else
114114
error("Use @SVector [a,b,c], @SVector Type[a,b,c] or a comprehension like [f(i) for i = i_min:i_max]")
115115
end
116116
end

src/StaticArrays.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ import LinearAlgebra: transpose, adjoint, dot, eigvals, eigen, lyap, tr,
1919
kron, diag, norm, dot, diagm, lu, svd, svdvals,
2020
factorize, ishermitian, issymmetric, isposdef, normalize,
2121
normalize!, Eigen, det, logdet, cross, diff, qr, \
22-
23-
# import eye for deprecation warnings
24-
@static if isdefined(LinearAlgebra, :eye)
25-
import LinearAlgebra: eye
26-
end
22+
using LinearAlgebra: checksquare
2723

2824
export SOneTo
2925
export StaticScalar, StaticArray, StaticVector, StaticMatrix
@@ -88,9 +84,15 @@ const StaticMatrixLike{T} = Union{
8884
StaticMatrix{<:Any, <:Any, T},
8985
Transpose{T, <:StaticVecOrMat{T}},
9086
Adjoint{T, <:StaticVecOrMat{T}},
91-
Symmetric{T, <:StaticMatrix{T}},
92-
Hermitian{T, <:StaticMatrix{T}},
93-
Diagonal{T, <:StaticVector{<:Any, T}}
87+
Symmetric{T, <:StaticMatrix{<:Any, <:Any, T}},
88+
Hermitian{T, <:StaticMatrix{<:Any, <:Any, T}},
89+
Diagonal{T, <:StaticVector{<:Any, T}},
90+
# We specifically list *Triangular here rather than using
91+
# AbstractTriangular to avoid ambiguities in size() etc.
92+
UpperTriangular{T, <:StaticMatrix{<:Any, <:Any, T}},
93+
LowerTriangular{T, <:StaticMatrix{<:Any, <:Any, T}},
94+
UnitUpperTriangular{T, <:StaticMatrix{<:Any, <:Any, T}},
95+
UnitLowerTriangular{T, <:StaticMatrix{<:Any, <:Any, T}}
9496
}
9597
const StaticVecOrMatLike{T} = Union{StaticVector{<:Any, T}, StaticMatrixLike{T}}
9698
const StaticArrayLike{T} = Union{StaticVecOrMatLike{T}, StaticArray{<:Tuple, T}}

src/abstractarray.jl

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
length(a::SA) where {SA <: StaticArrayLike} = length(SA)
1+
length(a::StaticArrayLike) = prod(Size(a))
22
length(a::Type{SA}) where {SA <: StaticArrayLike} = prod(Size(SA))
33

4-
@pure size(::Type{SA}) where {SA <: StaticArrayLike} = get(Size(SA))
4+
@pure size(::Type{SA}) where {SA <: StaticArrayLike} = Tuple(Size(SA))
55
@inline function size(t::Type{<:StaticArrayLike}, d::Int)
66
S = size(t)
77
d > length(S) ? 1 : S[d]
88
end
9-
@inline size(a::StaticArrayLike) = size(typeof(a))
10-
@inline size(a::StaticArrayLike, d::Int) = size(typeof(a), d)
9+
@inline size(a::StaticArrayLike) = Tuple(Size(a))
1110

1211
Base.axes(s::StaticArray) = _axes(Size(s))
1312
@pure function _axes(::Size{sizes}) where {sizes}
@@ -93,6 +92,27 @@ mutable_similar_type(::Type{T}, s::Size{S}, ::Type{Val{D}}) where {T,S,D} = MArr
9392

9493
sizedarray_similar_type(::Type{T},s::Size{S},::Type{Val{D}}) where {T,S,D} = SizedArray{Tuple{S...},T,D,length(s)}
9594

95+
# Utility for computing the eltype of an array instance, type, or type
96+
# constructor. For type constructors without a definite eltype, the default
97+
# value is returned.
98+
Base.@pure _eltype_or(a::AbstractArray, default) = eltype(a)
99+
Base.@pure _eltype_or(::Type{<:AbstractArray{T}}, default) where {T} = T
100+
Base.@pure _eltype_or(::Type{<:AbstractArray}, default) = default # eltype not available
101+
102+
"""
103+
_construct_similar(a, ::Size, elements::NTuple)
104+
105+
Construct a static array of similar type to `a` with the given `elements`.
106+
107+
When `a` is an instance or a concrete type the element type `eltype(a)` is
108+
used. However, when `a` is a `UnionAll` type such as `SMatrix{2,2}`, the
109+
promoted type of `elements` is used instead.
110+
"""
111+
@inline function _construct_similar(a, s::Size, elements::NTuple{L,ET}) where {L,ET}
112+
similar_type(a, _eltype_or(a, ET), s)(elements)
113+
end
114+
115+
96116
# Field vectors are user controlled, and currently default to SVector, etc
97117

98118
"""

src/det.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ end
4343
end
4444

4545
@generated function _det(::Size{S}, A::StaticMatrix) where S
46-
LinearAlgebra.checksquare(A)
46+
checksquare(A)
4747
if prod(S) 14*14
4848
quote
4949
@_inline_meta
@@ -58,7 +58,7 @@ end
5858
@inline logdet(A::StaticMatrix) = _logdet(Size(A), A)
5959
@inline _logdet(::Union{Size{(1,1)}, Size{(2,2)}, Size{(3,3)}, Size{(4,4)}}, A::StaticMatrix) = log(det(A))
6060
@generated function _logdet(::Size{S}, A::StaticMatrix) where S
61-
LinearAlgebra.checksquare(A)
61+
checksquare(A)
6262
if prod(S) 14*14
6363
quote
6464
@_inline_meta

src/eigen.jl

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ end
1313
end
1414
end
1515

16+
function eigvals(A::StaticMatrixLike, B::StaticMatrixLike; kwargs...)
17+
SA = Size(A)
18+
if SA != Size(B)
19+
throw(DimensionMismatch("Generalized eigenvalues can only be calculated for matrices of equal sizes: dimensions are $SA and $(Size(B))"))
20+
end
21+
checksquare(A)
22+
return _eigvals(SA, A, B; kwargs...)
23+
end
24+
25+
@inline function _eigvals(s::Size, A::StaticMatrixLike, B::StaticMatrixLike; kwargs...)
26+
return SVector{s[1]}(eigvals(Array(A), Array(B); kwargs...))
27+
end
28+
1629
@inline _eigvals(::Size{(1,1)}, a, permute, scale) = @inbounds return SVector(Tuple(a))
1730
@inline _eigvals(::Size{(1, 1)}, a::LinearAlgebra.RealHermSymComplexHerm{T}, permute, scale) where {T <: Real} = @inbounds return SVector(real(parent(a).data[1]))
1831

@@ -110,25 +123,33 @@ end
110123
return SVector{s[1], T}(vals)
111124
end
112125

126+
# Utility to rewrap `Eigen` of normal `Array` into an Eigen containing `SArray`.
127+
@inline function _make_static(s::Size, E::Eigen{T,V}) where {T,V}
128+
Eigen(similar_type(SVector, V, Size(s[1]))(E.values),
129+
similar_type(SMatrix, T, s)(E.vectors))
130+
end
113131

114-
@inline function _eig(s::Size, A::StaticMatrix, permute, scale)
115-
# Only cover the hermitian branch, for now at least
116-
# This also solves some type-stability issues that arise in Base
132+
@inline function _eig(s::Size, A::T, permute, scale) where {T <: StaticMatrix}
117133
if ishermitian(A)
118-
return _eig(s, Hermitian(A), permute, scale)
134+
return _eig(s, Hermitian(A), permute, scale)
119135
else
120-
error("Only hermitian matrices are diagonalizable by *StaticArrays*. Non-Hermitian matrices should be converted to `Array` first.")
136+
# For the non-hermitian branch fall back to LinearAlgebra eigen().
137+
# Eigenvalues could be real or complex so a Union of concrete types is
138+
# inferred. Having _make_static a separate function allows inference to
139+
# preserve the union of concrete types:
140+
# Union{E{A,B},E{C,D}} -> Union{E{SA,SB},E{SC,SD}}
141+
_make_static(s, eigen(Array(A); permute = permute, scale = scale))
121142
end
122143
end
123144

124145
@inline function _eig(s::Size, A::LinearAlgebra.RealHermSymComplexHerm{T}, permute, scale) where {T <: Real}
125146
E = eigen(Hermitian(Array(parent(A))))
126-
return (SVector{s[1], T}(E.values), SMatrix{s[1], s[2], eltype(A)}(E.vectors))
147+
return Eigen(SVector{s[1], T}(E.values), SMatrix{s[1], s[2], eltype(A)}(E.vectors))
127148
end
128149

129150

130151
@inline function _eig(::Size{(1,1)}, A::LinearAlgebra.RealHermSymComplexHerm{T}, permute, scale) where {T <: Real}
131-
@inbounds return (SVector{1,T}((real(A[1]),)), SMatrix{1,1,eltype(A)}(I))
152+
@inbounds return Eigen(SVector{1,T}((real(A[1]),)), SMatrix{1,1,eltype(A)}(I))
132153
end
133154

134155
@inline function _eig(::Size{(2,2)}, A::LinearAlgebra.RealHermSymComplexHerm{T}, permute, scale) where {T <: Real}
@@ -157,7 +178,7 @@ end
157178
vecs = @SMatrix [ v11 v21 ;
158179
v12 v22 ]
159180

160-
return (vals, vecs)
181+
return Eigen(vals, vecs)
161182
end
162183
else # A.uplo == 'L'
163184
if !iszero(a[2]) # A is not diagonal
@@ -181,7 +202,7 @@ end
181202
vecs = @SMatrix [ v11 v21 ;
182203
v12 v22 ]
183204

184-
return (vals,vecs)
205+
return Eigen(vals,vecs)
185206
end
186207
end
187208

@@ -197,7 +218,7 @@ end
197218
vecs = @SMatrix [convert(TA, 0) convert(TA, 1);
198219
convert(TA, 1) convert(TA, 0)]
199220
end
200-
return (vals,vecs)
221+
return Eigen(vals,vecs)
201222
end
202223

203224
# A small part of the code in the following method was inspired by works of David
@@ -230,19 +251,19 @@ end
230251

231252
if a11 < a22
232253
if a22 < a33
233-
return (SVector(a11, a22, a33), hcat(v1,v2,v3))
254+
return Eigen(SVector((a11, a22, a33)), hcat(v1,v2,v3))
234255
elseif a33 < a11
235-
return (SVector(a33, a11, a22), hcat(v3,v1,v2))
256+
return Eigen(SVector((a33, a11, a22)), hcat(v3,v1,v2))
236257
else
237-
return (SVector(a11, a33, a22), hcat(v1,v3,v2))
258+
return Eigen(SVector((a11, a33, a22)), hcat(v1,v3,v2))
238259
end
239260
else #a22 < a11
240261
if a11 < a33
241-
return (SVector(a22, a11, a33), hcat(v2,v1,v3))
262+
return Eigen(SVector((a22, a11, a33)), hcat(v2,v1,v3))
242263
elseif a33 < a22
243-
return (SVector(a33, a22, a11), hcat(v3,v2,v1))
264+
return Eigen(SVector((a33, a22, a11)), hcat(v3,v2,v1))
244265
else
245-
return (SVector(a22, a33, a11), hcat(v2,v3,v1))
266+
return Eigen(SVector((a22, a33, a11)), hcat(v2,v3,v1))
246267
end
247268
end
248269
end
@@ -379,12 +400,11 @@ end
379400
(eigvec1, eigvec3) = (eigvec3, eigvec1)
380401
end
381402

382-
return (SVector(eig1, eig2, eig3), hcat(eigvec1, eigvec2, eigvec3))
403+
return Eigen(SVector(eig1, eig2, eig3), hcat(eigvec1, eigvec2, eigvec3))
383404
end
384405

385406
@inline function eigen(A::StaticMatrix; permute::Bool=true, scale::Bool=true)
386-
vals, vecs = _eig(Size(A), A, permute, scale)
387-
return Eigen(vals, vecs)
407+
_eig(Size(A), A, permute, scale)
388408
end
389409

390410
# to avoid method ambiguity with LinearAlgebra
@@ -394,8 +414,7 @@ end
394414
@inline eigen(A::Symmetric{<:Complex,<:StaticMatrix}; kwargs...) = _eigen(A; kwargs...)
395415

396416
@inline function _eigen(A::LinearAlgebra.HermOrSym; permute::Bool=true, scale::Bool=true)
397-
vals, vecs = _eig(Size(A), A, permute, scale)
398-
return Eigen(vals, vecs)
417+
_eig(Size(A), A, permute, scale)
399418
end
400419

401420
# NOTE: The following Boost Software License applies to parts of the method:

0 commit comments

Comments
 (0)