Skip to content

Fix#25242 #25268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions base/linalg/adjtrans.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

using Base: @pure, @propagate_inbounds, _return_type, _default_type, _isleaftype, @_inline_meta
using Base: @propagate_inbounds, _return_type, _default_type, _isleaftype, @_inline_meta
import Base: length, size, axes, IndexStyle, getindex, setindex!, parent, vec, convert, similar

### basic definitions (types, aliases, constructors, abstractarray interface, sundry similar)
Expand All @@ -10,20 +10,20 @@ import Base: length, size, axes, IndexStyle, getindex, setindex!, parent, vec, c
# user-defined such objects. so do not restrict the wrapped type.
struct Adjoint{T,S} <: AbstractMatrix{T}
parent::S
function Adjoint{T,S}(A::S) where {T,S}
checkeltype(Adjoint, T, eltype(A))
function Adjoint{T,S}(A::S, check::Bool=true) where {T,S}
check && checkeltype(Adjoint, T, eltype(A))
new(A)
end
end
struct Transpose{T,S} <: AbstractMatrix{T}
parent::S
function Transpose{T,S}(A::S) where {T,S}
checkeltype(Transpose, T, eltype(A))
function Transpose{T,S}(A::S, check::Bool=true) where {T,S}
check && checkeltype(Transpose, T, eltype(A))
new(A)
end
end

@pure function checkeltype(::Type{Transform}, ::Type{ResultEltype}, ::Type{ParentEltype}) where {Transform, ResultEltype, ParentEltype}
function checkeltype(::Type{Transform}, ::Type{ResultEltype}, ::Type{ParentEltype}) where {Transform, ResultEltype, ParentEltype}
if ResultEltype !== transformtype(Transform, ParentEltype)
error(string("Element type mismatch. Tried to create an `$Transform{$ResultEltype}` ",
"from an object with eltype `$ParentEltype`, but the element type of the ",
Expand All @@ -32,6 +32,7 @@ end
end
return nothing
end

function transformtype(::Type{O}, ::Type{S}) where {O,S}
# similar to promote_op(::Any, ::Type)
@_inline_meta
Expand All @@ -41,13 +42,16 @@ function transformtype(::Type{O}, ::Type{S}) where {O,S}
end

# basic outer constructors
Adjoint(A) = Adjoint{transformtype(Adjoint,eltype(A)),typeof(A)}(A)
Transpose(A) = Transpose{transformtype(Transpose,eltype(A)),typeof(A)}(A)
Adjoint(A) = Adjoint{transformtype(Adjoint,eltype(A)),typeof(A)}(A, false)
Transpose(A) = Transpose{transformtype(Transpose,eltype(A)),typeof(A)}(A, false)

# numbers are the end of the line
Adjoint(x::Number) = adjoint(x)
Transpose(x::Number) = transpose(x)

Adjoint(x::Union{Char,AbstractString,Symbol}) = x
Transpose(x::Union{Char,AbstractString,Symbol}) = x

# unwrapping constructors
Adjoint(A::Adjoint) = A.parent
Transpose(A::Transpose) = A.parent
Expand Down
9 changes: 9 additions & 0 deletions test/linalg/adjtrans.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ end
@test Transpose(1.0im) == 1.0im
end

@testset "Adjoint and Transpose of Char, String, Symbol" begin
@test Adjoint('A') === 'A'
@test Adjoint("hello") === "hello"
@test Adjoint(:testsym) === :testsym
@test Transpose('A') === 'A'
@test Transpose("hello") === "hello"
@test Transpose(:testsym) === :testsym
end

@testset "Adjoint and Transpose unwrapping" begin
intvec, intmat = [1, 2], [1 2; 3 4]
@test Adjoint(Adjoint(intvec)) === intvec
Expand Down