300
300
(* )(A:: HermOrSym , D:: Diagonal ) =
301
301
mul! (similar (A, promote_op (* , eltype (A), eltype (D. diag)), size (A)), A, D)
302
302
(* )(D:: Diagonal , A:: AbstractMatrix ) =
303
- mul! (similar (A, promote_op (* , eltype (A ), eltype (D . diag ))), D, A)
303
+ mul! (similar (A, promote_op (* , eltype (D . diag ), eltype (A ))), D, A)
304
304
(* )(D:: Diagonal , A:: HermOrSym ) =
305
305
mul! (similar (A, promote_op (* , eltype (A), eltype (D. diag)), size (A)), D, A)
306
306
@@ -768,11 +768,32 @@ function pinv(D::Diagonal{T}, tol::Real) where T
768
768
Diagonal (Di)
769
769
end
770
770
771
+ # TODO Docstrings for eigvals, eigvecs, eigen all mention permute, scale, sortby as keyword args
772
+ # but not all of them below provide them. Do we need to fix that?
771
773
# Eigensystem
772
774
eigvals (D:: Diagonal{<:Number} ; permute:: Bool = true , scale:: Bool = true ) = copy (D. diag)
773
775
eigvals (D:: Diagonal ; permute:: Bool = true , scale:: Bool = true ) =
774
- [eigvals (x) for x in D. diag] # For block matrices, etc.
775
- eigvecs (D:: Diagonal ) = Matrix {eltype(D)} (I, size (D))
776
+ reduce (vcat, eigvals (x) for x in D. diag) # For block matrices, etc.
777
+ function eigvecs (D:: Diagonal{T} ) where T<: AbstractMatrix
778
+ diag_vecs = [ eigvecs (x) for x in D. diag ]
779
+ matT = reduce ((a,b) -> promote_type (typeof (a),typeof (b)), diag_vecs)
780
+ ncols_diag = [ size (x, 2 ) for x in D. diag ]
781
+ nrows = size (D, 1 )
782
+ vecs = Matrix {Vector{eltype(matT)}} (undef, nrows, sum (ncols_diag))
783
+ for j in axes (D, 2 ), i in axes (D, 1 )
784
+ jj = sum (view (ncols_diag,1 : j- 1 ))
785
+ if i == j
786
+ for k in 1 : ncols_diag[j]
787
+ vecs[i,jj+ k] = diag_vecs[i][:,k]
788
+ end
789
+ else
790
+ for k in 1 : ncols_diag[j]
791
+ vecs[i,jj+ k] = zeros (eltype (T), ncols_diag[i])
792
+ end
793
+ end
794
+ end
795
+ return vecs
796
+ end
776
797
function eigen (D:: Diagonal ; permute:: Bool = true , scale:: Bool = true , sortby:: Union{Function,Nothing} = nothing )
777
798
if any (! isfinite, D. diag)
778
799
throw (ArgumentError (" matrix contains Infs or NaNs" ))
@@ -791,6 +812,19 @@ function eigen(D::Diagonal; permute::Bool=true, scale::Bool=true, sortby::Union{
791
812
end
792
813
Eigen (λ, evecs)
793
814
end
815
+ function eigen (D:: Diagonal{<:AbstractMatrix} ; permute:: Bool = true , scale:: Bool = true , sortby:: Union{Function,Nothing} = nothing )
816
+ if any (any (! isfinite, x) for x in D. diag)
817
+ throw (ArgumentError (" matrix contains Infs or NaNs" ))
818
+ end
819
+ λ = eigvals (D)
820
+ evecs = eigvecs (D)
821
+ if ! isnothing (sortby)
822
+ p = sortperm (λ; alg= QuickSort, by= sortby)
823
+ λ = λ[p]
824
+ evecs = evecs[:,p]
825
+ end
826
+ Eigen (λ, evecs)
827
+ end
794
828
function eigen (Da:: Diagonal , Db:: Diagonal ; sortby:: Union{Function,Nothing} = nothing )
795
829
if any (! isfinite, Da. diag) || any (! isfinite, Db. diag)
796
830
throw (ArgumentError (" matrices contain Infs or NaNs" ))
0 commit comments