@@ -642,82 +642,50 @@ end
642642
643643# Tridiagonal
644644
645- function _opnorm1 (A:: Tridiagonal{T} ) where T
646- n = size (A, 1 )
647- Tnorm = typeof (float (real (zero (T))))
648- Tsum = promote_type (Float64, Tnorm)
649-
650- # first col
651- nrm:: Tsum = norm (A. d[1 ]) + norm (A. dl[1 ])
652- @inbounds begin
653- for i = 2 : n- 1
654- nrmj:: Tsum = norm (A. d[i]) + norm (A. dl[i]) + norm (A. du[i- 1 ])
655- nrm = max (nrm,nrmj)
656- end
657- end
658-
659- # last col
660- @inbounds nrm = max (nrm, norm (A. d[n])+ norm (A. du[n- 1 ]))
661- return convert (Tnorm, nrm)
662- end
663-
664- function _opnormInf (A:: Tridiagonal{T} ) where T
665- n = size (A, 1 )
666- Tnorm = typeof (float (real (zero (T))))
667- Tsum = promote_type (Float64, Tnorm)
668-
669- # first row
670- nrm:: Tsum = norm (A. d[1 ]) + norm (A. du[1 ])
671- @inbounds begin
672- for i = 2 : n- 1
673- nrmj:: Tsum = norm (A. d[i]) + norm (A. du[i]) + norm (A. dl[i- 1 ])
674- nrm = max (nrm,nrmj)
675- end
676- end
677-
678- # last row
679- @inbounds nrm = max (nrm, norm (A. d[n])+ norm (A. dl[n- 1 ]))
680- return convert (Tnorm, nrm)
645+ function _opnorm1Inf (A:: Tridiagonal , p)
646+ size (A, 1 ) == 1 && return norm (first (A. d))
647+ case = p == Inf
648+ lowerrange, upperrange = case ? (1 : length (A. dl)- 1 , 2 : length (A. dl)) : (2 : length (A. dl), 1 : length (A. dl)- 1 )
649+ normfirst, normend = case ? (norm (first (A. d))+ norm (first (A. du)), norm (last (A. dl))+ norm (last (A. d))) : (norm (first (A. d))+ norm (first (A. dl)), norm (last (A. du))+ norm (last (A. d)))
650+
651+ return max (
652+ mapreduce (t -> sum (norm, t),
653+ max,
654+ zip (view (A. d, (2 : length (A. d)- 1 )), view (A. dl, lowerrange), view (A. du, upperrange))
655+ ),
656+ normfirst, normend)
681657end
682658
683659function opnorm (A:: Tridiagonal , p:: Real = 2 )
684660 if p == 2
685661 return opnorm2 (A)
686- elseif p == 1
687- return _opnorm1 (A)
688- elseif p == Inf
689- return _opnormInf (A)
662+ elseif p == 1 || p == Inf
663+ _opnorm1Inf (A, p)
690664 else
691665 throw (ArgumentError (" invalid p-norm p=$p . Valid: 1, 2, Inf" ))
692666 end
693667end
694668
695669# SymTridiagonal
696670
697- function _opnormInf1 (A:: SymTridiagonal{T} ) where T
698- n = size (A, 1 )
699- Tnorm = typeof (float (real (zero (T))))
700- Tsum = promote_type (Float64, Tnorm)
701-
702- # first col/row
703- nrm:: Tsum = norm (A. dv[1 ]) + norm (A. ev[1 ])
704- @inbounds begin
705- for i = 2 : n- 1
706- nrmj:: Tsum = norm (A. dv[i]) + norm (A. ev[i- 1 ]) + norm (A. ev[i])
707- nrm = max (nrm,nrmj)
708- end
709- end
671+ function _opnorm1Inf (A:: SymTridiagonal )
672+ size (A, 1 ) == 1 && return norm (first (A. dv))
673+ lowerrange, upperrange = 1 : length (A. ev)- 1 , 2 : length (A. ev)
674+ normfirst, normend = norm (first (A. dv))+ norm (first (A. ev)), norm (last (A. ev))+ norm (last (A. dv))
710675
711- # last col/row
712- @inbounds nrm = max (nrm, norm (A. dv[n])+ norm (A. ev[n- 1 ]))
713- return convert (Tnorm, nrm)
676+ return max (
677+ mapreduce (t -> sum (norm, t),
678+ max,
679+ zip (view (A. dv, (2 : length (A. dv)- 1 )), view (A. ev, lowerrange), view (A. ev, upperrange))
680+ ),
681+ normfirst, normend)
714682end
715683
716684function opnorm (A:: SymTridiagonal , p:: Real = 2 )
717685 if p == 2
718686 return opnorm2 (A)
719687 elseif p == 1 || p == Inf # these are the same for symmetric matrices
720- return _opnormInf1 (A)
688+ return _opnorm1Inf (A)
721689 else
722690 throw (ArgumentError (" invalid p-norm p=$p . Valid: 1, 2, Inf" ))
723691 end
0 commit comments