Skip to content

Commit ae5385b

Browse files
authored
Specialize isreal for banded matrices (#1271)
This makes the check O(n) from O(n^2). It should still be evaluated at compile-time for matrices with `Real` `eltype`s.
1 parent 0a253be commit ae5385b

File tree

7 files changed

+32
-1
lines changed

7 files changed

+32
-1
lines changed

src/LinearAlgebra.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Base: USE_BLAS64, abs, acos, acosh, acot, acoth, acsc, acsch, adjoint, as
1313
copy, copyto!, copymutable, cos, cosh, cot, coth, csc, csch, eltype, exp, fill!, floor,
1414
getindex, hcat, getproperty, imag, inv, invpermuterows!, isapprox, isequal, isone, iszero,
1515
IndexStyle, kron, kron!, length, log, map, ndims, one, oneunit, parent, permutecols!,
16-
permutedims, permuterows!, power_by_squaring, promote_rule, real, sec, sech, setindex!,
16+
permutedims, permuterows!, power_by_squaring, promote_rule, real, isreal, sec, sech, setindex!,
1717
show, similar, sin, sincos, sinh, size, sqrt, strides, stride, tan, tanh, transpose, trunc,
1818
typed_hcat, vec, view, zero
1919
import Base: AbstractArray, AbstractMatrix, Array, Matrix

src/bidiag.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ axes(M::Bidiagonal) = (ax = axes(M.dv, 1); (ax, ax))
286286
for func in (:conj, :copy, :real, :imag)
287287
@eval ($func)(M::Bidiagonal) = Bidiagonal(($func)(M.dv), ($func)(M.ev), M.uplo)
288288
end
289+
isreal(M::Bidiagonal) = isreal(M.dv) && isreal(M.ev)
289290

290291
adjoint(B::Bidiagonal{<:Number}) = Bidiagonal(vec(adjoint(B.dv)), vec(adjoint(B.ev)), B.uplo == 'U' ? :L : :U)
291292
adjoint(B::Bidiagonal{<:Number, <:Base.ReshapedArray{<:Number,1,<:Adjoint}}) =

src/diagonal.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ factorize(D::Diagonal) = D
256256
real(D::Diagonal) = Diagonal(real(D.diag))
257257
imag(D::Diagonal) = Diagonal(imag(D.diag))
258258

259+
isreal(D::Diagonal) = isreal(D.diag)
260+
259261
iszero(D::Diagonal) = all(iszero, D.diag)
260262
isone(D::Diagonal) = all(isone, D.diag)
261263
isdiag(D::Diagonal) = all(isdiag, D.diag)

src/tridiag.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ _copyto_banded!(dest::SymTridiagonal, src::SymTridiagonal) =
173173
for func in (:conj, :copy, :real, :imag)
174174
@eval ($func)(M::SymTridiagonal) = SymTridiagonal(($func)(M.dv), ($func)(M.ev))
175175
end
176+
isreal(S::SymTridiagonal) = isreal(S.dv) && isreal(S.ev)
176177

177178
transpose(S::SymTridiagonal) = S
178179
adjoint(S::SymTridiagonal{<:Number}) = SymTridiagonal(vec(adjoint(S.dv)), vec(adjoint(S.ev)))
@@ -667,6 +668,7 @@ for func in (:conj, :copy, :real, :imag)
667668
Tridiagonal(($func)(M.dl), ($func)(M.d), ($func)(M.du))
668669
end
669670
end
671+
isreal(T::Tridiagonal) = isreal(T.dl) && isreal(T.d) && isreal(T.du)
670672

671673
adjoint(S::Tridiagonal{<:Number}) = Tridiagonal(vec(adjoint(S.du)), vec(adjoint(S.d)), vec(adjoint(S.dl)))
672674
adjoint(S::Tridiagonal{<:Number, <:Base.ReshapedArray{<:Number,1,<:Adjoint}}) =

test/bidiag.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,4 +1172,12 @@ end
11721172
@test_throws InexactError convert(Bidiagonal, M)
11731173
end
11741174

1175+
@testset "isreal" begin
1176+
M = Bidiagonal(ones(2), ones(1), :U)
1177+
@test @inferred((M -> Val(isreal(M)))(M)) == Val(true)
1178+
M = complex.(M)
1179+
@test isreal(M)
1180+
@test !isreal(im*M)
1181+
end
1182+
11751183
end # module TestBidiagonal

test/diagonal.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,4 +1481,12 @@ end
14811481
@test ishermitian(D) == ishermitian(A)
14821482
end
14831483

1484+
@testset "isreal" begin
1485+
D = Diagonal(ones(2))
1486+
@test @inferred((D -> Val(isreal(D)))(D)) == Val(true)
1487+
D = complex.(D)
1488+
@test isreal(D)
1489+
@test !isreal(im*D)
1490+
end
1491+
14841492
end # module TestDiagonal

test/tridiag.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,4 +1162,14 @@ end
11621162
end
11631163
end
11641164

1165+
@testset "isreal" begin
1166+
for M in (SymTridiagonal(ones(2), ones(1)),
1167+
Tridiagonal(ones(2), ones(3), ones(2)))
1168+
@test @inferred((M -> Val(isreal(M)))(M)) == Val(true)
1169+
M = complex.(M)
1170+
@test isreal(M)
1171+
@test !isreal(im*M)
1172+
end
1173+
end
1174+
11651175
end # module TestTridiagonal

0 commit comments

Comments
 (0)