Skip to content

Commit 0abc263

Browse files
authored
Merge pull request #25461 from Sacha0/consify
make Adjoint/Transpose behave like typical constructors
2 parents 3d64d39 + 3c28b79 commit 0abc263

13 files changed

+153
-161
lines changed

base/deprecated.jl

+8-8
Original file line numberDiff line numberDiff line change
@@ -2226,10 +2226,10 @@ end
22262226
@deprecate A_mul_Bt(A::AbstractMatrix, B::AbstractTriangular) (*)(A, transpose(B))
22272227
end
22282228
for (f, op, transform) in (
2229-
(:A_mul_Bc, :*, :Adjoint),
2230-
(:A_mul_Bt, :*, :Transpose),
2231-
(:A_rdiv_Bc, :/, :Adjoint),
2232-
(:A_rdiv_Bt, :/, :Transpose))
2229+
(:A_mul_Bc, :*, :adjoint),
2230+
(:A_mul_Bt, :*, :transpose),
2231+
(:A_rdiv_Bc, :/, :adjoint),
2232+
(:A_rdiv_Bt, :/, :transpose))
22332233
@eval Base.LinAlg begin
22342234
@deprecate $f(A::LowerTriangular, B::UpperTriangular) ($op)(A, ($transform)(B))
22352235
@deprecate $f(A::LowerTriangular, B::UnitUpperTriangular) ($op)(A, ($transform)(B))
@@ -2238,10 +2238,10 @@ for (f, op, transform) in (
22382238
end
22392239
end
22402240
for (f, op, transform) in (
2241-
(:Ac_mul_B, :*, :Adjoint),
2242-
(:At_mul_B, :*, :Transpose),
2243-
(:Ac_ldiv_B, :\, :Adjoint),
2244-
(:At_ldiv_B, :\, :Transpose))
2241+
(:Ac_mul_B, :*, :adjoint),
2242+
(:At_mul_B, :*, :transpose),
2243+
(:Ac_ldiv_B, :\, :adjoint),
2244+
(:At_ldiv_B, :\, :transpose))
22452245
@eval Base.LinAlg begin
22462246
@deprecate ($f)(A::UpperTriangular, B::LowerTriangular) ($op)(($transform)(A), B)
22472247
@deprecate ($f)(A::UnitUpperTriangular, B::LowerTriangular) ($op)(($transform)(A), B)

base/linalg/adjtrans.jl

+47-55
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,38 @@ import Base: length, size, axes, IndexStyle, getindex, setindex!, parent, vec, c
1111
struct Adjoint{T,S} <: AbstractMatrix{T}
1212
parent::S
1313
function Adjoint{T,S}(A::S) where {T,S}
14-
checkeltype(Adjoint, T, eltype(A))
14+
checkeltype_adjoint(T, eltype(A))
1515
new(A)
1616
end
1717
end
1818
struct Transpose{T,S} <: AbstractMatrix{T}
1919
parent::S
2020
function Transpose{T,S}(A::S) where {T,S}
21-
checkeltype(Transpose, T, eltype(A))
21+
checkeltype_transpose(T, eltype(A))
2222
new(A)
2323
end
2424
end
2525

26-
function checkeltype(::Type{Transform}, ::Type{ResultEltype}, ::Type{ParentEltype}) where {Transform, ResultEltype, ParentEltype}
27-
if ResultEltype !== transformtype(Transform, ParentEltype)
28-
error(string("Element type mismatch. Tried to create an `$Transform{$ResultEltype}` ",
29-
"from an object with eltype `$ParentEltype`, but the element type of the ",
30-
"`$Transform` of an object with eltype `$ParentEltype` must be ",
31-
"`$(transformtype(Transform, ParentEltype))`"))
32-
end
26+
function checkeltype_adjoint(::Type{ResultEltype}, ::Type{ParentEltype}) where {ResultEltype,ParentEltype}
27+
ResultEltype === Base.promote_op(adjoint, ParentEltype) || error(string(
28+
"Element type mismatch. Tried to create an `Adjoint{$ResultEltype}` ",
29+
"from an object with eltype `$ParentEltype`, but the element type of ",
30+
"the adjoint of an object with eltype `$ParentEltype` must be ",
31+
"`$(Base.promote_op(adjoint, ParentEltype))`."))
3332
return nothing
3433
end
35-
function transformtype(::Type{O}, ::Type{S}) where {O,S}
36-
# similar to promote_op(::Any, ::Type)
37-
@_inline_meta
38-
T = _return_type(O, Tuple{_default_type(S)})
39-
_isleaftype(S) && return _isleaftype(T) ? T : Any
40-
return typejoin(S, T)
34+
function checkeltype_transpose(::Type{ResultEltype}, ::Type{ParentEltype}) where {ResultEltype,ParentEltype}
35+
ResultEltype === Base.promote_op(transpose, ParentEltype) || error(string(
36+
"Element type mismatch. Tried to create a `Transpose{$ResultEltype}` ",
37+
"from an object with eltype `$ParentEltype`, but the element type of ",
38+
"the transpose of an object with eltype `$ParentEltype` must be ",
39+
"`$(Base.promote_op(transpose, ParentEltype))`."))
40+
return nothing
4141
end
4242

4343
# basic outer constructors
44-
Adjoint(A) = Adjoint{transformtype(Adjoint,eltype(A)),typeof(A)}(A)
45-
Transpose(A) = Transpose{transformtype(Transpose,eltype(A)),typeof(A)}(A)
46-
47-
# numbers are the end of the line
48-
Adjoint(x::Number) = adjoint(x)
49-
Transpose(x::Number) = transpose(x)
50-
51-
# unwrapping constructors
52-
Adjoint(A::Adjoint) = A.parent
53-
Transpose(A::Transpose) = A.parent
44+
Adjoint(A) = Adjoint{Base.promote_op(adjoint,eltype(A)),typeof(A)}(A)
45+
Transpose(A) = Transpose{Base.promote_op(transpose,eltype(A)),typeof(A)}(A)
5446

5547
# wrapping lowercase quasi-constructors
5648
adjoint(A::AbstractVecOrMat) = Adjoint(A)
@@ -80,6 +72,7 @@ julia> transpose(A)
8072
```
8173
"""
8274
transpose(A::AbstractVecOrMat) = Transpose(A)
75+
8376
# unwrapping lowercase quasi-constructors
8477
adjoint(A::Adjoint) = A.parent
8578
transpose(A::Transpose) = A.parent
@@ -95,10 +88,8 @@ const AdjOrTransAbsVec{T} = AdjOrTrans{T,<:AbstractVector}
9588
const AdjOrTransAbsMat{T} = AdjOrTrans{T,<:AbstractMatrix}
9689

9790
# for internal use below
98-
wrappertype(A::Adjoint) = Adjoint
99-
wrappertype(A::Transpose) = Transpose
100-
wrappertype(::Type{<:Adjoint}) = Adjoint
101-
wrappertype(::Type{<:Transpose}) = Transpose
91+
wrapperop(A::Adjoint) = adjoint
92+
wrapperop(A::Transpose) = transpose
10293

10394
# AbstractArray interface, basic definitions
10495
length(A::AdjOrTrans) = length(A.parent)
@@ -108,22 +99,22 @@ axes(v::AdjOrTransAbsVec) = (Base.OneTo(1), axes(v.parent)...)
10899
axes(A::AdjOrTransAbsMat) = reverse(axes(A.parent))
109100
IndexStyle(::Type{<:AdjOrTransAbsVec}) = IndexLinear()
110101
IndexStyle(::Type{<:AdjOrTransAbsMat}) = IndexCartesian()
111-
@propagate_inbounds getindex(v::AdjOrTransAbsVec, i::Int) = wrappertype(v)(v.parent[i])
112-
@propagate_inbounds getindex(A::AdjOrTransAbsMat, i::Int, j::Int) = wrappertype(A)(A.parent[j, i])
113-
@propagate_inbounds setindex!(v::AdjOrTransAbsVec, x, i::Int) = (setindex!(v.parent, wrappertype(v)(x), i); v)
114-
@propagate_inbounds setindex!(A::AdjOrTransAbsMat, x, i::Int, j::Int) = (setindex!(A.parent, wrappertype(A)(x), j, i); A)
102+
@propagate_inbounds getindex(v::AdjOrTransAbsVec, i::Int) = wrapperop(v)(v.parent[i])
103+
@propagate_inbounds getindex(A::AdjOrTransAbsMat, i::Int, j::Int) = wrapperop(A)(A.parent[j, i])
104+
@propagate_inbounds setindex!(v::AdjOrTransAbsVec, x, i::Int) = (setindex!(v.parent, wrapperop(v)(x), i); v)
105+
@propagate_inbounds setindex!(A::AdjOrTransAbsMat, x, i::Int, j::Int) = (setindex!(A.parent, wrapperop(A)(x), j, i); A)
115106
# AbstractArray interface, additional definitions to retain wrapper over vectors where appropriate
116-
@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, is::AbstractArray{Int}) = wrappertype(v)(v.parent[is])
117-
@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, ::Colon) = wrappertype(v)(v.parent[:])
107+
@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, is::AbstractArray{Int}) = wrapperop(v)(v.parent[is])
108+
@propagate_inbounds getindex(v::AdjOrTransAbsVec, ::Colon, ::Colon) = wrapperop(v)(v.parent[:])
118109

119110
# conversion of underlying storage
120111
convert(::Type{Adjoint{T,S}}, A::Adjoint) where {T,S} = Adjoint{T,S}(convert(S, A.parent))
121112
convert(::Type{Transpose{T,S}}, A::Transpose) where {T,S} = Transpose{T,S}(convert(S, A.parent))
122113

123114
# for vectors, the semantics of the wrapped and unwrapped types differ
124115
# so attempt to maintain both the parent and wrapper type insofar as possible
125-
similar(A::AdjOrTransAbsVec) = wrappertype(A)(similar(A.parent))
126-
similar(A::AdjOrTransAbsVec, ::Type{T}) where {T} = wrappertype(A)(similar(A.parent, transformtype(wrappertype(A), T)))
116+
similar(A::AdjOrTransAbsVec) = wrapperop(A)(similar(A.parent))
117+
similar(A::AdjOrTransAbsVec, ::Type{T}) where {T} = wrapperop(A)(similar(A.parent, Base.promote_op(wrapperop(A), T)))
127118
# for matrices, the semantics of the wrapped and unwrapped types are generally the same
128119
# and as you are allocating with similar anyway, you might as well get something unwrapped
129120
similar(A::AdjOrTrans) = similar(A.parent, eltype(A), size(A))
@@ -142,30 +133,31 @@ isless(A::AdjOrTransAbsVec, B::AdjOrTransAbsVec) = isless(parent(A), parent(B))
142133
# to retain the associated semantics post-concatenation
143134
hcat(avs::Union{Number,AdjointAbsVec}...) = _adjoint_hcat(avs...)
144135
hcat(tvs::Union{Number,TransposeAbsVec}...) = _transpose_hcat(tvs...)
145-
_adjoint_hcat(avs::Union{Number,AdjointAbsVec}...) = Adjoint(vcat(map(Adjoint, avs)...))
146-
_transpose_hcat(tvs::Union{Number,TransposeAbsVec}...) = Transpose(vcat(map(Transpose, tvs)...))
147-
typed_hcat(::Type{T}, avs::Union{Number,AdjointAbsVec}...) where {T} = Adjoint(typed_vcat(T, map(Adjoint, avs)...))
148-
typed_hcat(::Type{T}, tvs::Union{Number,TransposeAbsVec}...) where {T} = Transpose(typed_vcat(T, map(Transpose, tvs)...))
136+
_adjoint_hcat(avs::Union{Number,AdjointAbsVec}...) = adjoint(vcat(map(adjoint, avs)...))
137+
_transpose_hcat(tvs::Union{Number,TransposeAbsVec}...) = transpose(vcat(map(transpose, tvs)...))
138+
typed_hcat(::Type{T}, avs::Union{Number,AdjointAbsVec}...) where {T} = adjoint(typed_vcat(T, map(adjoint, avs)...))
139+
typed_hcat(::Type{T}, tvs::Union{Number,TransposeAbsVec}...) where {T} = transpose(typed_vcat(T, map(transpose, tvs)...))
149140
# otherwise-redundant definitions necessary to prevent hitting the concat methods in sparse/sparsevector.jl
150141
hcat(avs::Adjoint{<:Any,<:Vector}...) = _adjoint_hcat(avs...)
151142
hcat(tvs::Transpose{<:Any,<:Vector}...) = _transpose_hcat(tvs...)
152143
hcat(avs::Adjoint{T,Vector{T}}...) where {T} = _adjoint_hcat(avs...)
153144
hcat(tvs::Transpose{T,Vector{T}}...) where {T} = _transpose_hcat(tvs...)
145+
# TODO unify and allow mixed combinations
154146

155147

156148
### higher order functions
157149
# preserve Adjoint/Transpose wrapper around vectors
158150
# to retain the associated semantics post-map/broadcast
159151
#
160152
# note that the caller's operation f operates in the domain of the wrapped vectors' entries.
161-
# hence the Adjoint->f->Adjoint shenanigans applied to the parent vectors' entries.
162-
map(f, avs::AdjointAbsVec...) = Adjoint(map((xs...) -> Adjoint(f(Adjoint.(xs)...)), parent.(avs)...))
163-
map(f, tvs::TransposeAbsVec...) = Transpose(map((xs...) -> Transpose(f(Transpose.(xs)...)), parent.(tvs)...))
153+
# hence the adjoint->f->adjoint shenanigans applied to the parent vectors' entries.
154+
map(f, avs::AdjointAbsVec...) = adjoint(map((xs...) -> adjoint(f(adjoint.(xs)...)), parent.(avs)...))
155+
map(f, tvs::TransposeAbsVec...) = transpose(map((xs...) -> transpose(f(transpose.(xs)...)), parent.(tvs)...))
164156
quasiparentt(x) = parent(x); quasiparentt(x::Number) = x # to handle numbers in the defs below
165157
quasiparenta(x) = parent(x); quasiparenta(x::Number) = conj(x) # to handle numbers in the defs below
166-
broadcast(f, avs::Union{Number,AdjointAbsVec}...) = Adjoint(broadcast((xs...) -> Adjoint(f(Adjoint.(xs)...)), quasiparenta.(avs)...))
167-
broadcast(f, tvs::Union{Number,TransposeAbsVec}...) = Transpose(broadcast((xs...) -> Transpose(f(Transpose.(xs)...)), quasiparentt.(tvs)...))
168-
158+
broadcast(f, avs::Union{Number,AdjointAbsVec}...) = adjoint(broadcast((xs...) -> adjoint(f(adjoint.(xs)...)), quasiparenta.(avs)...))
159+
broadcast(f, tvs::Union{Number,TransposeAbsVec}...) = transpose(broadcast((xs...) -> transpose(f(transpose.(xs)...)), quasiparentt.(tvs)...))
160+
# TODO unify and allow mixed combinations
169161

170162
### linear algebra
171163

@@ -186,11 +178,11 @@ end
186178
*(u::TransposeAbsVec, v::TransposeAbsVec) = throw(MethodError(*, (u, v)))
187179

188180
# Adjoint/Transpose-vector * matrix
189-
*(u::AdjointAbsVec, A::AbstractMatrix) = Adjoint(Adjoint(A) * u.parent)
190-
*(u::TransposeAbsVec, A::AbstractMatrix) = Transpose(Transpose(A) * u.parent)
181+
*(u::AdjointAbsVec, A::AbstractMatrix) = adjoint(adjoint(A) * u.parent)
182+
*(u::TransposeAbsVec, A::AbstractMatrix) = transpose(transpose(A) * u.parent)
191183
# Adjoint/Transpose-vector * Adjoint/Transpose-matrix
192-
*(u::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractMatrix}) = Adjoint(A.parent * u.parent)
193-
*(u::TransposeAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = Transpose(A.parent * u.parent)
184+
*(u::AdjointAbsVec, A::Adjoint{<:Any,<:AbstractMatrix}) = adjoint(A.parent * u.parent)
185+
*(u::TransposeAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = transpose(A.parent * u.parent)
194186

195187

196188
## pseudoinversion
@@ -203,10 +195,10 @@ pinv(v::TransposeAbsVec, tol::Real = 0) = pinv(conj(v.parent)).parent
203195

204196

205197
## right-division \
206-
/(u::AdjointAbsVec, A::AbstractMatrix) = Adjoint(Adjoint(A) \ u.parent)
207-
/(u::TransposeAbsVec, A::AbstractMatrix) = Transpose(Transpose(A) \ u.parent)
208-
/(u::AdjointAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = Adjoint(conj(A.parent) \ u.parent) # technically should be Adjoint(copy(Adjoint(copy(A))) \ u.parent)
209-
/(u::TransposeAbsVec, A::Adjoint{<:Any,<:AbstractMatrix}) = Transpose(conj(A.parent) \ u.parent) # technically should be Transpose(copy(Transpose(copy(A))) \ u.parent)
198+
/(u::AdjointAbsVec, A::AbstractMatrix) = adjoint(adjoint(A) \ u.parent)
199+
/(u::TransposeAbsVec, A::AbstractMatrix) = transpose(transpose(A) \ u.parent)
200+
/(u::AdjointAbsVec, A::Transpose{<:Any,<:AbstractMatrix}) = adjoint(conj(A.parent) \ u.parent) # technically should be adjoint(copy(adjoint(copy(A))) \ u.parent)
201+
/(u::TransposeAbsVec, A::Adjoint{<:Any,<:AbstractMatrix}) = transpose(conj(A.parent) \ u.parent) # technically should be transpose(copy(transpose(copy(A))) \ u.parent)
210202

211203
# dismabiguation methods
212204
*(A::AdjointAbsVec, B::Transpose{<:Any,<:AbstractMatrix}) = A * copy(B)

base/linalg/bidiag.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,9 @@ transpose(B::Bidiagonal) = Transpose(B)
252252
adjoint(B::Bidiagonal{<:Real}) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? :L : :U)
253253
transpose(B::Bidiagonal{<:Number}) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? :L : :U)
254254
Base.copy(aB::Adjoint{<:Any,<:Bidiagonal}) =
255-
(B = aB.parent; Bidiagonal(map(x -> copy.(Adjoint.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U))
255+
(B = aB.parent; Bidiagonal(map(x -> copy.(adjoint.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U))
256256
Base.copy(tB::Transpose{<:Any,<:Bidiagonal}) =
257-
(B = tB.parent; Bidiagonal(map(x -> copy.(Transpose.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U))
257+
(B = tB.parent; Bidiagonal(map(x -> copy.(transpose.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U))
258258

259259
istriu(M::Bidiagonal) = M.uplo == 'U' || iszero(M.ev)
260260
istril(M::Bidiagonal) = M.uplo == 'L' || iszero(M.ev)

base/linalg/diagonal.jl

+12-12
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ function mul!(D::Diagonal, B::UnitUpperTriangular)
188188
UpperTriangular(B.data)
189189
end
190190

191-
*(D::Adjoint{<:Any,<:Diagonal}, B::Diagonal) = Diagonal(Adjoint.(D.parent.diag) .* B.diag)
191+
*(D::Adjoint{<:Any,<:Diagonal}, B::Diagonal) = Diagonal(adjoint.(D.parent.diag) .* B.diag)
192192
*(A::Adjoint{<:Any,<:AbstractTriangular}, D::Diagonal) = mul!(copy(A), D)
193193
function *(adjA::Adjoint{<:Any,<:AbstractMatrix}, D::Diagonal)
194194
A = adjA.parent
@@ -197,7 +197,7 @@ function *(adjA::Adjoint{<:Any,<:AbstractMatrix}, D::Diagonal)
197197
mul!(Ac, D)
198198
end
199199

200-
*(D::Transpose{<:Any,<:Diagonal}, B::Diagonal) = Diagonal(Transpose.(D.parent.diag) .* B.diag)
200+
*(D::Transpose{<:Any,<:Diagonal}, B::Diagonal) = Diagonal(transpose.(D.parent.diag) .* B.diag)
201201
*(A::Transpose{<:Any,<:AbstractTriangular}, D::Diagonal) = mul!(copy(A), D)
202202
function *(transA::Transpose{<:Any,<:AbstractMatrix}, D::Diagonal)
203203
A = transA.parent
@@ -206,7 +206,7 @@ function *(transA::Transpose{<:Any,<:AbstractMatrix}, D::Diagonal)
206206
mul!(At, D)
207207
end
208208

209-
*(D::Diagonal, B::Adjoint{<:Any,<:Diagonal}) = Diagonal(D.diag .* Adjoint.(B.parent.diag))
209+
*(D::Diagonal, B::Adjoint{<:Any,<:Diagonal}) = Diagonal(D.diag .* adjoint.(B.parent.diag))
210210
*(D::Diagonal, B::Adjoint{<:Any,<:AbstractTriangular}) = mul!(D, collect(B))
211211
*(D::Diagonal, adjQ::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = (Q = adjQ.parent; mul!(Array(D), adjoint(Q)))
212212
function *(D::Diagonal, adjA::Adjoint{<:Any,<:AbstractMatrix})
@@ -216,7 +216,7 @@ function *(D::Diagonal, adjA::Adjoint{<:Any,<:AbstractMatrix})
216216
mul!(D, Ac)
217217
end
218218

219-
*(D::Diagonal, B::Transpose{<:Any,<:Diagonal}) = Diagonal(D.diag .* Transpose.(B.parent.diag))
219+
*(D::Diagonal, B::Transpose{<:Any,<:Diagonal}) = Diagonal(D.diag .* transpose.(B.parent.diag))
220220
*(D::Diagonal, B::Transpose{<:Any,<:AbstractTriangular}) = mul!(D, copy(B))
221221
function *(D::Diagonal, transA::Transpose{<:Any,<:AbstractMatrix})
222222
A = transA.parent
@@ -226,9 +226,9 @@ function *(D::Diagonal, transA::Transpose{<:Any,<:AbstractMatrix})
226226
end
227227

228228
*(D::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:Diagonal}) =
229-
Diagonal(Adjoint.(D.parent.diag) .* Adjoint.(B.parent.diag))
229+
Diagonal(adjoint.(D.parent.diag) .* adjoint.(B.parent.diag))
230230
*(D::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Diagonal}) =
231-
Diagonal(Transpose.(D.parent.diag) .* Transpose.(B.parent.diag))
231+
Diagonal(transpose.(D.parent.diag) .* transpose.(B.parent.diag))
232232

233233
mul!(A::Diagonal, B::Diagonal) = throw(MethodError(mul!, (A, B)))
234234
mul!(A::QRPackedQ, D::Diagonal) = throw(MethodError(mul!, (A, D)))
@@ -254,12 +254,12 @@ mul!(A::AbstractMatrix, transB::Transpose{<:Any,<:Diagonal}) = (B = transB.paren
254254

255255
# Get ambiguous method if try to unify AbstractVector/AbstractMatrix here using AbstractVecOrMat
256256
mul!(out::AbstractVector, A::Diagonal, in::AbstractVector) = out .= A.diag .* in
257-
mul!(out::AbstractVector, A::Adjoint{<:Any,<:Diagonal}, in::AbstractVector) = out .= Adjoint.(A.parent.diag) .* in
258-
mul!(out::AbstractVector, A::Transpose{<:Any,<:Diagonal}, in::AbstractVector) = out .= Transpose.(A.parent.diag) .* in
257+
mul!(out::AbstractVector, A::Adjoint{<:Any,<:Diagonal}, in::AbstractVector) = out .= adjoint.(A.parent.diag) .* in
258+
mul!(out::AbstractVector, A::Transpose{<:Any,<:Diagonal}, in::AbstractVector) = out .= transpose.(A.parent.diag) .* in
259259

260260
mul!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = out .= A.diag .* in
261-
mul!(out::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= Adjoint.(A.parent.diag) .* in
262-
mul!(out::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= Transpose.(A.parent.diag) .* in
261+
mul!(out::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= adjoint.(A.parent.diag) .* in
262+
mul!(out::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= transpose.(A.parent.diag) .* in
263263

264264
mul!(C::AbstractMatrix, A::Diagonal, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B))
265265
mul!(C::AbstractMatrix, A::Diagonal, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B))
@@ -281,8 +281,8 @@ mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Abs
281281
*(adjD::Adjoint{<:Any,<:Diagonal}, adjA::Adjoint{<:Any,<:RealHermSymComplexHerm}) = adjD * adjA.parent
282282
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexHerm}) = mul!(C, A, B.parent)
283283
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexSym}) = mul!(C, A, B.parent)
284-
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexSym}) = C .= Adjoint.(A.parent.diag) .* B
285-
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexHerm}) = C .= Transpose.(A.parent.diag) .* B
284+
mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexSym}) = C .= adjoint.(A.parent.diag) .* B
285+
mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexHerm}) = C .= transpose.(A.parent.diag) .* B
286286

287287

288288
(/)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag ./ Db.diag)

base/linalg/generic.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -823,9 +823,9 @@ function inv(A::AbstractMatrix{T}) where T
823823
ldiv!(factorize(convert(AbstractMatrix{S}, A)), dest)
824824
end
825825

826-
pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Real} = _vectorpinv(Transpose, v, tol)
827-
pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Complex} = _vectorpinv(Adjoint, v, tol)
828-
pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T} = _vectorpinv(Adjoint, v, tol)
826+
pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Real} = _vectorpinv(transpose, v, tol)
827+
pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T<:Complex} = _vectorpinv(adjoint, v, tol)
828+
pinv(v::AbstractVector{T}, tol::Real = real(zero(T))) where {T} = _vectorpinv(adjoint, v, tol)
829829
function _vectorpinv(dualfn::Tf, v::AbstractVector{Tv}, tol) where {Tv,Tf}
830830
res = dualfn(similar(v, typeof(zero(Tv) / (abs2(one(Tv)) + abs2(one(Tv))))))
831831
den = sum(abs2, v)

base/linalg/lu.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ function ldiv!(adjA::Adjoint{<:Any,LU{T,Tridiagonal{T,V}}}, B::AbstractVecOrMat)
584584
return B
585585
end
586586

587-
/(B::AbstractMatrix, A::LU) = copy(Transpose(transpose(A) \ transpose(B)))
587+
/(B::AbstractMatrix, A::LU) = copy(transpose(transpose(A) \ transpose(B)))
588588

589589
# Conversions
590590
AbstractMatrix(F::LU) = (F.L * F.U)[invperm(F.p),:]

0 commit comments

Comments
 (0)