@@ -911,15 +911,18 @@ function pinv(D::Diagonal{T}, tol::Real) where T
911
911
Diagonal (Di)
912
912
end
913
913
914
+ _ortho_eltype (T) = Base. promote_op (/ , T, T)
915
+ _ortho_eltype (T:: Type{<:Number} ) = typeof (one (T)/ one (T))
916
+
914
917
# TODO Docstrings for eigvals, eigvecs, eigen all mention permute, scale, sortby as keyword args
915
918
# but not all of them below provide them. Do we need to fix that?
916
919
# Eigensystem
917
920
eigvals (D:: Diagonal{<:Number} ; permute:: Bool = true , scale:: Bool = true ) = copy (D. diag)
918
921
eigvals (D:: Diagonal ; permute:: Bool = true , scale:: Bool = true ) =
919
922
reduce (vcat, eigvals (x) for x in D. diag) # For block matrices, etc.
920
- function eigvecs (D:: Diagonal{T} ) where T<: AbstractMatrix
923
+ function eigvecs (D:: Diagonal{T} ) where { T<: AbstractMatrix }
921
924
diag_vecs = [ eigvecs (x) for x in D. diag ]
922
- matT = reduce ((a,b) -> promote_type (typeof (a), typeof (b)) , diag_vecs)
925
+ matT = promote_type (map ( typeof, diag_vecs) ... )
923
926
ncols_diag = [ size (x, 2 ) for x in D. diag ]
924
927
nrows = size (D, 1 )
925
928
vecs = Matrix {Vector{eltype(matT)}} (undef, nrows, sum (ncols_diag))
@@ -941,7 +944,7 @@ function eigen(D::Diagonal; permute::Bool=true, scale::Bool=true, sortby::Union{
941
944
if any (! isfinite, D. diag)
942
945
throw (ArgumentError (" matrix contains Infs or NaNs" ))
943
946
end
944
- Td = Base . promote_op ( / , eltype (D), eltype (D))
947
+ Td = _ortho_eltype ( eltype (D))
945
948
λ = eigvals (D)
946
949
if ! isnothing (sortby)
947
950
p = sortperm (λ; alg= QuickSort, by= sortby)
@@ -999,13 +1002,13 @@ function svd(D::Diagonal{T}) where {T<:Number}
999
1002
s = abs .(d)
1000
1003
piv = sortperm (s, rev = true )
1001
1004
S = s[piv]
1002
- Td = typeof ( oneunit (T) / oneunit (T) )
1005
+ Td = _ortho_eltype (T )
1003
1006
U = zeros (Td, size (D))
1004
1007
Vt = copy (U)
1005
1008
for i in 1 : length (d)
1006
1009
j = piv[i]
1007
- U[j,i] = iszero (d[j]) ? oneunit (Td) : d[j] / S[i]
1008
- Vt[i,j] = oneunit (Td)
1010
+ U[j,i] = iszero (d[j]) ? one (Td) : d[j] / S[i]
1011
+ Vt[i,j] = one (Td)
1009
1012
end
1010
1013
return SVD (U, S, Vt)
1011
1014
end
0 commit comments