Skip to content

Commit 3ada9e9

Browse files
committed
Specialize norm-related functions for Diagonal
1 parent 8d6ca14 commit 3ada9e9

File tree

2 files changed

+26
-19
lines changed

2 files changed

+26
-19
lines changed

src/diagonal.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,3 +1246,14 @@ function fillband!(D::Diagonal, x, l, u)
12461246
end
12471247
return D
12481248
end
1249+
1250+
# norm
1251+
function generic_normMinusInf(D::Diagonal)
1252+
norm_diag = generic_normMinusInf(D.diag)
1253+
min(norm_diag, zero(norm_diag))
1254+
end
1255+
generic_normInf(D::Diagonal) = generic_normInf(D.diag)
1256+
generic_norm1(D::Diagonal) = generic_norm1(D.diag)
1257+
_generic_norm2(D::Diagonal, maxabs) = _generic_norm2(D.diag, maxabs)
1258+
_generic_normp(D::Diagonal, p, maxabs) = _generic_normp(D.diag, p, maxabs)
1259+
norm_x_minus_y(D1::Diagonal, D2::Diagonal) = norm_x_minus_y(D1.diag, D2.diag)

src/generic.jl

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -575,24 +575,21 @@ norm_sqr(x::Union{T,Complex{T},Rational{T}}) where {T<:Integer} = abs2(float(x))
575575
function generic_norm2(x)
576576
maxabs = normInf(x)
577577
(ismissing(maxabs) || iszero(maxabs) || isinf(maxabs)) && return maxabs
578+
return _generic_norm2(x, maxabs)
579+
end
580+
581+
function _generic_norm2(x, maxabs::T) where {T}
578582
(v, s) = iterate(x)::Tuple
579-
T = typeof(maxabs)
580583
if isfinite(length(x)*maxabs*maxabs) && !iszero(maxabs*maxabs) # Scaling not necessary
581584
sum::promote_type(Float64, T) = norm_sqr(v)
582-
while true
583-
y = iterate(x, s)
584-
y === nothing && break
585-
(v, s) = y
585+
for v in Iterators.rest(x, s)
586586
sum += norm_sqr(v)
587587
end
588588
ismissing(sum) && return missing
589589
return convert(T, sqrt(sum))
590590
else
591591
sum = abs2(norm(v)/maxabs)
592-
while true
593-
y = iterate(x, s)
594-
y === nothing && break
595-
(v, s) = y
592+
for v in Iterators.rest(x, s)
596593
sum += (norm(v)/maxabs)^2
597594
end
598595
ismissing(sum) && return missing
@@ -607,28 +604,27 @@ function generic_normp(x, p)
607604
if p > 1 || p < -1 # might need to rescale to avoid overflow
608605
maxabs = p > 1 ? normInf(x) : normMinusInf(x)
609606
(ismissing(maxabs) || iszero(maxabs) || isinf(maxabs)) && return maxabs
610-
T = typeof(maxabs)
607+
return _generic_normp(x, p, maxabs)
611608
else
612-
T = typeof(float(norm(v)))
609+
# in this case, only the type of the last argument is used
610+
# there is no scaling involved
611+
return _generic_normp(x, p, float(norm(v)))
613612
end
613+
end
614+
615+
function _generic_normp(x, p, maxabs::T) where {T}
614616
spp::promote_type(Float64, T) = p
615617
if -1 <= p <= 1 || (isfinite(length(x)*maxabs^spp) && !iszero(maxabs^spp)) # scaling not necessary
616618
sum::promote_type(Float64, T) = norm(v)^spp
617-
while true
618-
y = iterate(x, s)
619-
y === nothing && break
620-
(v, s) = y
619+
for v in Iterators.rest(x, s)
621620
ismissing(v) && return missing
622621
sum += norm(v)^spp
623622
end
624623
return convert(T, sum^inv(spp))
625624
else # rescaling
626625
sum = (norm(v)/maxabs)^spp
627626
ismissing(sum) && return missing
628-
while true
629-
y = iterate(x, s)
630-
y === nothing && break
631-
(v, s) = y
627+
for v in Iterators.rest(x, s)
632628
ismissing(v) && return missing
633629
sum += (norm(v)/maxabs)^spp
634630
end

0 commit comments

Comments
 (0)