Skip to content

Commit dcc0efe

Browse files
authored
RFC: Rework copy_oftype a bit (#44756)
1 parent 967b974 commit dcc0efe

18 files changed

+66
-63
lines changed

stdlib/LinearAlgebra/src/LinearAlgebra.jl

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -356,44 +356,47 @@ control over the factorization of `B`.
356356
"""
357357
rdiv!(A, B)
358358

359+
"""
360+
copy_oftype(A, T)
359361
362+
Creates a copy of `A` with eltype `T`. No assertions about mutability of the result are
363+
made. When `eltype(A) == T`, then this calls `copy(A)` which may be overloaded for custom
364+
array types. Otherwise, this calls `convert(AbstractArray{T}, A)`.
365+
"""
366+
copy_oftype(A::AbstractArray{T}, ::Type{T}) where {T} = copy(A)
367+
copy_oftype(A::AbstractArray{T,N}, ::Type{S}) where {T,N,S} = convert(AbstractArray{S,N}, A)
360368

361369
"""
362-
copy_oftype(A, T)
370+
copymutable_oftype(A, T)
363371
364372
Copy `A` to a mutable array with eltype `T` based on `similar(A, T)`.
365373
366374
The resulting matrix typically has similar algebraic structure as `A`. For
367375
example, supplying a tridiagonal matrix results in another tridiagonal matrix.
368376
In general, the type of the output corresponds to that of `similar(A, T)`.
369377
370-
There are three often used methods in LinearAlgebra to create a mutable copy
371-
of an array with a given eltype. These copies can be passed to in-place
372-
algorithms (such as `ldiv!`, `rdiv!`, `lu!` and so on). Which one to use in practice
373-
depends on what is known (or assumed) about the structure of the array in that
374-
algorithm.
378+
In LinearAlgebra, mutable copies (of some desired eltype) are created to be passed
379+
to in-place algorithms (such as `ldiv!`, `rdiv!`, `lu!` and so on). If the specific
380+
algorithm is known to preserve the algebraic structure, use `copymutable_oftype`.
381+
If the algorithm is known to return a dense matrix (or some wrapper backed by a dense
382+
matrix), then use `copy_similar`.
375383
376-
See also: `copy_similar`.
384+
See also: `Base.copymutable`, `copy_similar`.
377385
"""
378-
copy_oftype(A::AbstractArray, ::Type{T}) where {T} = copyto!(similar(A, T), A)
386+
copymutable_oftype(A::AbstractArray, ::Type{S}) where {S} = copyto!(similar(A, S), A)
379387

380388
"""
381389
copy_similar(A, T)
382390
383391
Copy `A` to a mutable array with eltype `T` based on `similar(A, T, size(A))`.
384392
385-
Compared to `copy_oftype`, the result can be more flexible. In general, the type
393+
Compared to `copymutable_oftype`, the result can be more flexible. In general, the type
386394
of the output corresponds to that of the three-argument method `similar(A, T, size(A))`.
387395
388-
See also: `copy_oftype`.
396+
See also: `copymutable_oftype`.
389397
"""
390398
copy_similar(A::AbstractArray, ::Type{T}) where {T} = copyto!(similar(A, T, size(A)), A)
391399

392-
# The three copy functions above return mutable arrays with eltype T.
393-
# To only ensure a certain eltype, and if a mutable copy is not needed, it is
394-
# more efficient to use:
395-
# convert(AbstractArray{T}, A)
396-
397400

398401
include("adjtrans.jl")
399402
include("transpose.jl")

stdlib/LinearAlgebra/src/bunchkaufman.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ julia> S.L*S.D*S.L' - A[S.p, S.p]
197197
```
198198
"""
199199
bunchkaufman(A::AbstractMatrix{T}, rook::Bool=false; check::Bool = true) where {T} =
200-
bunchkaufman!(copy_oftype(A, typeof(sqrt(oneunit(T)))), rook; check = check)
200+
bunchkaufman!(copymutable_oftype(A, typeof(sqrt(oneunit(T)))), rook; check = check)
201201

202202
BunchKaufman{T}(B::BunchKaufman) where {T} =
203203
BunchKaufman(convert(Matrix{T}, B.LD), B.ipiv, B.uplo, B.symmetric, B.rook, B.info)

stdlib/LinearAlgebra/src/cholesky.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ Base.iterate(C::CholeskyPivoted, ::Val{:done}) = nothing
179179

180180
# make a copy that allow inplace Cholesky factorization
181181
@inline choltype(A) = promote_type(typeof(sqrt(oneunit(eltype(A)))), Float32)
182-
@inline cholcopy(A::StridedMatrix) = copy_oftype(A, choltype(A))
183-
@inline cholcopy(A::RealHermSymComplexHerm) = copy_oftype(A, choltype(A))
182+
@inline cholcopy(A::StridedMatrix) = copymutable_oftype(A, choltype(A))
183+
@inline cholcopy(A::RealHermSymComplexHerm) = copymutable_oftype(A, choltype(A))
184184
@inline cholcopy(A::AbstractMatrix) = copy_similar(A, choltype(A))
185185

186186
# _chol!. Internal methods for calling unpivoted Cholesky

stdlib/LinearAlgebra/src/dense.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ function (^)(A::AbstractMatrix{T}, p::Real) where T
500500
# Quicker return if A is diagonal
501501
if isdiag(A)
502502
TT = promote_op(^, T, typeof(p))
503-
retmat = copy_oftype(A, TT)
503+
retmat = copymutable_oftype(A, TT)
504504
for i in 1:n
505505
retmat[i, i] = retmat[i, i] ^ p
506506
end

stdlib/LinearAlgebra/src/diagonal.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,8 +792,8 @@ end
792792
@deprecate cholesky!(A::Diagonal, ::Val{false}; check::Bool = true) cholesky!(A::Diagonal, NoPivot(); check) false
793793
@deprecate cholesky(A::Diagonal, ::Val{false}; check::Bool = true) cholesky(A::Diagonal, NoPivot(); check) false
794794

795-
@inline cholcopy(A::Diagonal) = copy_oftype(A, choltype(A))
796-
@inline cholcopy(A::RealHermSymComplexHerm{<:Real,<:Diagonal}) = copy_oftype(A, choltype(A))
795+
@inline cholcopy(A::Diagonal) = copymutable_oftype(A, choltype(A))
796+
@inline cholcopy(A::RealHermSymComplexHerm{<:Real,<:Diagonal}) = copymutable_oftype(A, choltype(A))
797797

798798
function getproperty(C::Cholesky{<:Any,<:Diagonal}, d::Symbol)
799799
Cfactors = getfield(C, :factors)

stdlib/LinearAlgebra/src/eigen.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,12 @@ true
233233
```
234234
"""
235235
function eigen(A::AbstractMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby) where T
236-
AA = copy_oftype(A, eigtype(T))
236+
AA = copymutable_oftype(A, eigtype(T))
237237
isdiag(AA) && return eigen(Diagonal(AA); permute=permute, scale=scale, sortby=sortby)
238238
return eigen!(AA; permute=permute, scale=scale, sortby=sortby)
239239
end
240240
function eigen(A::AbstractMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function,Nothing}=eigsortby) where {T <: Union{Float16,Complex{Float16}}}
241-
AA = copy_oftype(A, eigtype(T))
241+
AA = copymutable_oftype(A, eigtype(T))
242242
isdiag(AA) && return eigen(Diagonal(AA); permute=permute, scale=scale, sortby=sortby)
243243
A = eigen!(AA; permute, scale, sortby)
244244
values = convert(AbstractVector{isreal(A.values) ? Float16 : Complex{Float16}}, A.values)
@@ -333,7 +333,7 @@ julia> eigvals(diag_matrix)
333333
```
334334
"""
335335
eigvals(A::AbstractMatrix{T}; kws...) where T =
336-
eigvals!(copy_oftype(A, eigtype(T)); kws...)
336+
eigvals!(copymutable_oftype(A, eigtype(T)); kws...)
337337

338338
"""
339339
For a scalar input, `eigvals` will return a scalar.
@@ -508,7 +508,7 @@ true
508508
"""
509509
function eigen(A::AbstractMatrix{TA}, B::AbstractMatrix{TB}; kws...) where {TA,TB}
510510
S = promote_type(eigtype(TA),TB)
511-
eigen!(copy_oftype(A, S), copy_oftype(B, S); kws...)
511+
eigen!(copymutable_oftype(A, S), copymutable_oftype(B, S); kws...)
512512
end
513513

514514
eigen(A::Number, B::Number) = eigen(fill(A,1,1), fill(B,1,1))
@@ -587,7 +587,7 @@ julia> eigvals(A,B)
587587
"""
588588
function eigvals(A::AbstractMatrix{TA}, B::AbstractMatrix{TB}; kws...) where {TA,TB}
589589
S = promote_type(eigtype(TA),TB)
590-
return eigvals!(copy_oftype(A, S), copy_oftype(B, S); kws...)
590+
return eigvals!(copymutable_oftype(A, S), copymutable_oftype(B, S); kws...)
591591
end
592592

593593
"""

stdlib/LinearAlgebra/src/generic.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1779,7 +1779,7 @@ julia> normalize(a)
17791779
function normalize(a::AbstractArray, p::Real = 2)
17801780
nrm = norm(a, p)
17811781
if !isempty(a)
1782-
aa = copy_oftype(a, typeof(first(a)/nrm))
1782+
aa = copymutable_oftype(a, typeof(first(a)/nrm))
17831783
return __normalize!(aa, nrm)
17841784
else
17851785
T = typeof(zero(eltype(a))/nrm)

stdlib/LinearAlgebra/src/givens.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ transpose(R::AbstractRotation) = error("transpose not implemented for $(typeof(R
88

99
function (*)(R::AbstractRotation{T}, A::AbstractVecOrMat{S}) where {T,S}
1010
TS = typeof(zero(T)*zero(S) + zero(T)*zero(S))
11-
lmul!(convert(AbstractRotation{TS}, R), copy_oftype(A, TS))
11+
lmul!(convert(AbstractRotation{TS}, R), copy_similar(A, TS))
1212
end
1313
(*)(A::AbstractVector, adjR::Adjoint{<:Any,<:AbstractRotation}) = _absvecormat_mul_adjrot(A, adjR)
1414
(*)(A::AbstractMatrix, adjR::Adjoint{<:Any,<:AbstractRotation}) = _absvecormat_mul_adjrot(A, adjR)

stdlib/LinearAlgebra/src/hessenberg.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ true
502502
```
503503
"""
504504
hessenberg(A::AbstractMatrix{T}) where T =
505-
hessenberg!(copy_oftype(A, eigtype(T)))
505+
hessenberg!(copymutable_oftype(A, eigtype(T)))
506506

507507
function show(io::IO, mime::MIME"text/plain", F::Hessenberg)
508508
summary(io, F)

stdlib/LinearAlgebra/src/ldlt.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ julia> S \\ b
162162
"""
163163
function ldlt(M::SymTridiagonal{T}; shift::Number=false) where T
164164
S = typeof((zero(T)+shift)/one(T))
165-
Mₛ = SymTridiagonal{S}(copy_oftype(M.dv, S), copy_oftype(M.ev, S))
165+
Mₛ = SymTridiagonal{S}(copymutable_oftype(M.dv, S), copymutable_oftype(M.ev, S))
166166
if !iszero(shift)
167167
Mₛ.dv .+= shift
168168
end

stdlib/LinearAlgebra/src/lq.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ julia> l == S.L && q == S.Q
120120
true
121121
```
122122
"""
123-
lq(A::AbstractMatrix{T}) where {T} = lq!(copy_oftype(A, lq_eltype(T)))
123+
lq(A::AbstractMatrix{T}) where {T} = lq!(copymutable_oftype(A, lq_eltype(T)))
124124
lq(x::Number) = lq!(fill(convert(lq_eltype(typeof(x)), x), 1, 1))
125125

126126
lq_eltype(::Type{T}) where {T} = typeof(zero(T) / sqrt(abs2(one(T))))
@@ -197,15 +197,15 @@ function lmul!(A::LQ, B::StridedVecOrMat)
197197
end
198198
function *(A::LQ{TA}, B::StridedVecOrMat{TB}) where {TA,TB}
199199
TAB = promote_type(TA, TB)
200-
_cut_B(lmul!(convert(Factorization{TAB}, A), copy_oftype(B, TAB)), 1:size(A,1))
200+
_cut_B(lmul!(convert(Factorization{TAB}, A), copymutable_oftype(B, TAB)), 1:size(A,1))
201201
end
202202

203203
## Multiplication by Q
204204
### QB
205205
lmul!(A::LQPackedQ{T}, B::StridedVecOrMat{T}) where {T<:BlasFloat} = LAPACK.ormlq!('L','N',A.factors,A.τ,B)
206206
function (*)(A::LQPackedQ, B::StridedVecOrMat)
207207
TAB = promote_type(eltype(A), eltype(B))
208-
lmul!(AbstractMatrix{TAB}(A), copy_oftype(B, TAB))
208+
lmul!(AbstractMatrix{TAB}(A), copymutable_oftype(B, TAB))
209209
end
210210

211211
### QcB
@@ -218,7 +218,7 @@ function *(adjA::Adjoint{<:Any,<:LQPackedQ}, B::StridedVecOrMat)
218218
A = adjA.parent
219219
TAB = promote_type(eltype(A), eltype(B))
220220
if size(B,1) == size(A.factors,2)
221-
lmul!(adjoint(AbstractMatrix{TAB}(A)), copy_oftype(B, TAB))
221+
lmul!(adjoint(AbstractMatrix{TAB}(A)), copymutable_oftype(B, TAB))
222222
elseif size(B,1) == size(A.factors,1)
223223
lmul!(adjoint(AbstractMatrix{TAB}(A)), [B; zeros(TAB, size(A.factors, 2) - size(A.factors, 1), size(B, 2))])
224224
else
@@ -269,7 +269,7 @@ rmul!(A::StridedMatrix{T}, adjB::Adjoint{<:Any,<:LQPackedQ{T}}) where {T<:BlasCo
269269
function *(A::StridedVecOrMat, adjQ::Adjoint{<:Any,<:LQPackedQ})
270270
Q = adjQ.parent
271271
TR = promote_type(eltype(A), eltype(Q))
272-
return rmul!(copy_oftype(A, TR), adjoint(AbstractMatrix{TR}(Q)))
272+
return rmul!(copymutable_oftype(A, TR), adjoint(AbstractMatrix{TR}(Q)))
273273
end
274274
function *(adjA::Adjoint{<:Any,<:StridedMatrix}, adjQ::Adjoint{<:Any,<:LQPackedQ})
275275
A, Q = adjA.parent, adjQ.parent
@@ -293,7 +293,7 @@ end
293293
function *(A::StridedVecOrMat, Q::LQPackedQ)
294294
TR = promote_type(eltype(A), eltype(Q))
295295
if size(A, 2) == size(Q.factors, 2)
296-
C = copy_oftype(A, TR)
296+
C = copymutable_oftype(A, TR)
297297
elseif size(A, 2) == size(Q.factors, 1)
298298
C = zeros(TR, size(A, 1), size(Q.factors, 2))
299299
copyto!(C, 1, A, 1, length(A))

stdlib/LinearAlgebra/src/lu.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,8 @@ end
283283
@deprecate lu(A::AbstractMatrix, ::Val{false}; check::Bool = true) lu(A, NoPivot(); check=check)
284284

285285
_lucopy(A::AbstractMatrix, T) = copy_similar(A, T)
286-
_lucopy(A::HermOrSym, T) = copy_oftype(A, T)
287-
_lucopy(A::Tridiagonal, T) = copy_oftype(A, T)
286+
_lucopy(A::HermOrSym, T) = copymutable_oftype(A, T)
287+
_lucopy(A::Tridiagonal, T) = copymutable_oftype(A, T)
288288

289289
lu(S::LU) = S
290290
function lu(x::Number; check::Bool=true)
@@ -438,18 +438,18 @@ end
438438

439439
function (/)(A::AbstractMatrix, F::Adjoint{<:Any,<:LU})
440440
T = promote_type(eltype(A), eltype(F))
441-
return adjoint(ldiv!(F.parent, copy_oftype(adjoint(A), T)))
441+
return adjoint(ldiv!(F.parent, copymutable_oftype(adjoint(A), T)))
442442
end
443443
# To avoid ambiguities with definitions in adjtrans.jl and factorizations.jl
444444
(/)(adjA::Adjoint{<:Any,<:AbstractVector}, F::Adjoint{<:Any,<:LU}) = adjoint(F.parent \ adjA.parent)
445445
(/)(adjA::Adjoint{<:Any,<:AbstractMatrix}, F::Adjoint{<:Any,<:LU}) = adjoint(F.parent \ adjA.parent)
446446
function (/)(trA::Transpose{<:Any,<:AbstractVector}, F::Adjoint{<:Any,<:LU})
447447
T = promote_type(eltype(trA), eltype(F))
448-
return adjoint(ldiv!(F.parent, conj!(copy_oftype(trA.parent, T))))
448+
return adjoint(ldiv!(F.parent, conj!(copymutable_oftype(trA.parent, T))))
449449
end
450450
function (/)(trA::Transpose{<:Any,<:AbstractMatrix}, F::Adjoint{<:Any,<:LU})
451451
T = promote_type(eltype(trA), eltype(F))
452-
return adjoint(ldiv!(F.parent, conj!(copy_oftype(trA.parent, T))))
452+
return adjoint(ldiv!(F.parent, conj!(copymutable_oftype(trA.parent, T))))
453453
end
454454

455455
function det(F::LU{T}) where T

stdlib/LinearAlgebra/src/matmul.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ end
171171
function (*)(A::AdjOrTransStridedMat{<:BlasComplex}, B::StridedMaybeAdjOrTransMat{<:BlasReal})
172172
TS = promote_type(eltype(A), eltype(B))
173173
mul!(similar(B, TS, (size(A, 1), size(B, 2))),
174-
copy_oftype(A, TS), # remove AdjOrTrans to use reinterpret trick below
174+
copymutable_oftype(A, TS), # remove AdjOrTrans to use reinterpret trick below
175175
wrapperop(B)(convert(AbstractArray{real(TS)}, _parent(B))))
176176
end
177177
# the following case doesn't seem to benefit from the translation A*B = (B' * A')'

stdlib/LinearAlgebra/src/qr.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ function (*)(A::AbstractQ, b::StridedVector)
657657
TAb = promote_type(eltype(A), eltype(b))
658658
Anew = convert(AbstractMatrix{TAb}, A)
659659
if size(A.factors, 1) == length(b)
660-
bnew = copy_oftype(b, TAb)
660+
bnew = copymutable_oftype(b, TAb)
661661
elseif size(A.factors, 2) == length(b)
662662
bnew = [b; zeros(TAb, size(A.factors, 1) - length(b))]
663663
else
@@ -669,7 +669,7 @@ function (*)(A::AbstractQ, B::StridedMatrix)
669669
TAB = promote_type(eltype(A), eltype(B))
670670
Anew = convert(AbstractMatrix{TAB}, A)
671671
if size(A.factors, 1) == size(B, 1)
672-
Bnew = copy_oftype(B, TAB)
672+
Bnew = copymutable_oftype(B, TAB)
673673
elseif size(A.factors, 2) == size(B, 1)
674674
Bnew = [B; zeros(TAB, size(A.factors, 1) - size(B,1), size(B, 2))]
675675
else
@@ -723,7 +723,7 @@ end
723723
function *(adjQ::Adjoint{<:Any,<:AbstractQ}, B::StridedVecOrMat)
724724
Q = adjQ.parent
725725
TQB = promote_type(eltype(Q), eltype(B))
726-
return lmul!(adjoint(convert(AbstractMatrix{TQB}, Q)), copy_oftype(B, TQB))
726+
return lmul!(adjoint(convert(AbstractMatrix{TQB}, Q)), copymutable_oftype(B, TQB))
727727
end
728728

729729
### QBc/QcBc
@@ -775,7 +775,7 @@ end
775775
function (*)(A::StridedMatrix, Q::AbstractQ)
776776
TAQ = promote_type(eltype(A), eltype(Q))
777777

778-
return rmul!(copy_oftype(A, TAQ), convert(AbstractMatrix{TAQ}, Q))
778+
return rmul!(copymutable_oftype(A, TAQ), convert(AbstractMatrix{TAQ}, Q))
779779
end
780780

781781
function (*)(a::Number, B::AbstractQ)

stdlib/LinearAlgebra/src/special.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ Bidiagonal(A::AbstractTriangular) =
5050
isbanded(A, -1, 0) ? Bidiagonal(diag(A, 0), diag(A, -1), :L) : # is lower bidiagonal
5151
throw(ArgumentError("matrix cannot be represented as Bidiagonal"))
5252

53-
_lucopy(A::Bidiagonal, T) = copy_oftype(Tridiagonal(A), T)
54-
_lucopy(A::Diagonal, T) = copy_oftype(Tridiagonal(A), T)
53+
_lucopy(A::Bidiagonal, T) = copymutable_oftype(Tridiagonal(A), T)
54+
_lucopy(A::Diagonal, T) = copymutable_oftype(Tridiagonal(A), T)
5555
function _lucopy(A::SymTridiagonal, T)
5656
du = copy_similar(_evview(A), T)
5757
dl = copy.(transpose.(du))

stdlib/LinearAlgebra/src/svd.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,10 @@ true
176176
```
177177
"""
178178
function svd(A::StridedVecOrMat{T}; full::Bool = false, alg::Algorithm = default_svd_alg(A)) where {T}
179-
svd!(copy_oftype(A, eigtype(T)), full = full, alg = alg)
179+
svd!(copymutable_oftype(A, eigtype(T)), full = full, alg = alg)
180180
end
181181
function svd(A::StridedVecOrMat{T}; full::Bool = false, alg::Algorithm = default_svd_alg(A)) where {T <: Union{Float16,Complex{Float16}}}
182-
A = svd!(copy_oftype(A, eigtype(T)), full = full, alg = alg)
182+
A = svd!(copymutable_oftype(A, eigtype(T)), full = full, alg = alg)
183183
return SVD{T}(A)
184184
end
185185
function svd(x::Number; full::Bool = false, alg::Algorithm = default_svd_alg(x))
@@ -240,7 +240,7 @@ julia> svdvals(A)
240240
0.0
241241
```
242242
"""
243-
svdvals(A::AbstractMatrix{T}) where {T} = svdvals!(copy_oftype(A, eigtype(T)))
243+
svdvals(A::AbstractMatrix{T}) where {T} = svdvals!(copymutable_oftype(A, eigtype(T)))
244244
svdvals(A::AbstractVector{T}) where {T} = [convert(eigtype(T), norm(A))]
245245
svdvals(A::AbstractMatrix{<:BlasFloat}) = svdvals!(copy(A))
246246
svdvals(A::AbstractVector{<:BlasFloat}) = [norm(A)]
@@ -459,7 +459,7 @@ true
459459
"""
460460
function svd(A::StridedMatrix{TA}, B::StridedMatrix{TB}) where {TA,TB}
461461
S = promote_type(eigtype(TA),TB)
462-
return svd!(copy_oftype(A, S), copy_oftype(B, S))
462+
return svd!(copymutable_oftype(A, S), copymutable_oftype(B, S))
463463
end
464464
# This method can be heavily optimized but it is probably not critical
465465
# and might introduce bugs or inconsistencies relative to the 1x1 matrix
@@ -569,7 +569,7 @@ julia> svdvals(A, B)
569569
"""
570570
function svdvals(A::StridedMatrix{TA}, B::StridedMatrix{TB}) where {TA,TB}
571571
S = promote_type(eigtype(TA), TB)
572-
return svdvals!(copy_oftype(A, S), copy_oftype(B, S))
572+
return svdvals!(copymutable_oftype(A, S), copymutable_oftype(B, S))
573573
end
574574
svdvals(x::Number, y::Number) = abs(x/y)
575575

0 commit comments

Comments
 (0)