Skip to content

Commit 2b4c088

Browse files
authored
simplify views of adjoint matrices (#39467)
1 parent 07bf9da commit 2b4c088

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

stdlib/LinearAlgebra/src/adjtrans.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,20 @@ parent(A::AdjOrTrans) = A.parent
241241
vec(v::TransposeAbsVec) = parent(v)
242242
vec(v::AdjointAbsVec{<:Real}) = parent(v)
243243

244+
Base.reshape(v::TransposeAbsVec{<:Number}, ::Val{1}) = parent(v)
245+
Base.reshape(v::AdjointAbsVec{<:Real}, ::Val{1}) = parent(v)
246+
247+
# these make eachrow(A') produce simpler views
248+
@inline Base.unsafe_view(A::Transpose{<:Number, <:AbstractMatrix}, i::Integer, j::AbstractArray) =
249+
Base.unsafe_view(parent(A), j, i)
250+
@inline Base.unsafe_view(A::Transpose{<:Number, <:AbstractMatrix}, i::AbstractArray, j::Integer) =
251+
Base.unsafe_view(parent(A), j, i)
252+
253+
@inline Base.unsafe_view(A::Adjoint{<:Real, <:AbstractMatrix}, i::Integer, j::AbstractArray) =
254+
Base.unsafe_view(parent(A), j, i)
255+
@inline Base.unsafe_view(A::Adjoint{<:Real, <:AbstractMatrix}, i::AbstractArray, j::Integer) =
256+
Base.unsafe_view(parent(A), j, i)
257+
244258
### concatenation
245259
# preserve Adjoint/Transpose wrapper around vectors
246260
# to retain the associated semantics post-concatenation

stdlib/LinearAlgebra/test/adjtrans.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,35 @@ end
277277
@test vec(cvec')[1] == cvec[1]'
278278
end
279279

280+
@testset "Adjoint and Transpose view methods" begin
281+
intvec, intmat = [1, 2], [1 2 3; 4 5 6]
282+
# overload of reshape(v, Val(1)) simplifies views of row vectors:
283+
@test view(adjoint(intvec), 1:2) isa SubArray{Int, 1, Vector{Int}}
284+
@test view(transpose(intvec), 1:2) isa SubArray{Int, 1, Vector{Int}}
285+
cvec = [1, 2im, 3, 4im]
286+
@test view(transpose(cvec), 2:3) === view(cvec, 2:3)
287+
@test view(adjoint(cvec), 2:3) == conj(view(cvec, 2:3))
288+
289+
# vector slices of transposed matrices are simplified:
290+
@test view(adjoint(intmat), 1, :) isa SubArray{Int, 1, Matrix{Int}}
291+
@test view(transpose(intmat), 1, :) isa SubArray{Int, 1, Matrix{Int}}
292+
@test view(adjoint(intmat), 1, :) == permutedims(intmat)[1, :]
293+
@test view(transpose(intmat), 1:1, :) == permutedims(intmat)[1:1, :] # not simplified
294+
@test view(adjoint(intmat), :, 2) isa SubArray{Int, 1, Matrix{Int}}
295+
@test view(transpose(intmat), :, 2) isa SubArray{Int, 1, Matrix{Int}}
296+
@test view(adjoint(intmat), :, 2) == permutedims(intmat)[:, 2]
297+
@test view(transpose(intmat), :, 2:2) == permutedims(intmat)[:, 2:2] # not simplified
298+
cmat = [1 2im 3; 4im 5 6im]
299+
@test view(transpose(cmat), 1, :) isa SubArray{Complex{Int}, 1, Matrix{Complex{Int}}}
300+
@test view(transpose(cmat), :, 2) == cmat[2, :]
301+
@test view(adjoint(cmat), :, 2) == conj(cmat[2, :]) # not simplified
302+
303+
# bounds checks happen before this
304+
@test_throws BoundsError view(adjoint(intvec), 0:3)
305+
@test_throws BoundsError view(transpose(cvec), 0:3)
306+
@test_throws BoundsError view(adjoint(intmat), :, 3)
307+
end
308+
280309
@testset "horizontal concatenation of Adjoint/Transpose-wrapped vectors and Numbers" begin
281310
# horizontal concatenation of Adjoint/Transpose-wrapped vectors and Numbers
282311
# should preserve the Adjoint/Transpose-wrapper to preserve semantics downstream

0 commit comments

Comments
 (0)