Skip to content

Commit 57eab2f

Browse files
mateuszbaranc42f
authored andcommitted
Generalized eigenvalues of two static matrices (#693)
Support generalized `eigvals` of two `StaticMatrixLike` arguments.
1 parent d0f24c7 commit 57eab2f

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

src/eigen.jl

Lines changed: 13 additions & 0 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

test/eigen.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,20 @@ using StaticArrays, Test, LinearAlgebra
8282
E = eigen(Symmetric(A, uplo))
8383
@test eigvecs(E) * SDiagonal(eigvals(E)) * eigvecs(E)' A
8484
end
85+
86+
m1_a = randn(2,2)
87+
m1_a = m1_a*m1_a'
88+
m1 = SMatrix{2,2}(m1_a)
89+
m2_a = randn(2,2)
90+
m2_a = m2_a*m2_a'
91+
m2 = SMatrix{2,2}(m2_a)
92+
@test (@inferred_maybe_allow SVector{2,ComplexF64} eigvals(m1, m2)) eigvals(m1_a, m2_a)
93+
@test (@inferred_maybe_allow SVector{2,ComplexF64} eigvals(Symmetric(m1), Symmetric(m2))) eigvals(Symmetric(m1_a), Symmetric(m2_a))
8594
end
8695

96+
@test_throws DimensionMismatch eigvals(SA[1 2 3; 4 5 6], SA[1 2 3; 4 5 5])
97+
@test_throws DimensionMismatch eigvals(SA[1 2; 4 5], SA[1 2 3; 4 5 5; 3 4 5])
98+
8799
@testset "3×3" for i = 1:100
88100
m_a = randn(3,3)
89101
m_a = m_a*m_a'
@@ -112,6 +124,14 @@ using StaticArrays, Test, LinearAlgebra
112124
@test vals::SVector sort(m_d)
113125
@test eigvals(m) sort(m_d)
114126
@test eigvals(Hermitian(m)) sort(m_d)
127+
128+
m1_a = randn(3,3)
129+
m1_a = m1_a*m1_a'
130+
m1 = SMatrix{3,3}(m1_a)
131+
m2_a = randn(3,3)
132+
m2_a = m2_a*m2_a'
133+
m2 = SMatrix{3,3}(m2_a)
134+
@test (@inferred_maybe_allow SVector{3,ComplexF64} eigvals(m1, m2)) eigvals(m1_a, m2_a)
115135
end
116136

117137
@testset "3x3 degenerate cases" begin

test/testutil.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,17 @@ should_not_be_inlined(x) = _should_not_be_inlined(x)
9595
@test ts.errorcount == 0 && ts.failcount == 2 && ts.passcount == 0
9696
end
9797

98+
99+
"""
100+
@inferred_maybe_allow allow ex
101+
102+
Expands to `@inferred allow ex` on Julia 1.2 and newer and
103+
`ex` on Julia 1.0 and 1.1.
104+
"""
105+
macro inferred_maybe_allow(allow, ex)
106+
if VERSION < v"1.2"
107+
return esc(:($ex))
108+
else
109+
return esc(:(@inferred $allow $ex))
110+
end
111+
end

0 commit comments

Comments
 (0)