Skip to content

Commit

Permalink
Make norm handle missings (#40790)
Browse files Browse the repository at this point in the history
  • Loading branch information
dkarrasch authored Nov 2, 2022
1 parent 22fe28b commit df06375
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
9 changes: 7 additions & 2 deletions stdlib/LinearAlgebra/src/generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ norm_sqr(x::Union{T,Complex{T},Rational{T}}) where {T<:Integer} = abs2(float(x))

function generic_norm2(x)
maxabs = normInf(x)
(iszero(maxabs) || isinf(maxabs)) && return maxabs
(ismissing(maxabs) || iszero(maxabs) || isinf(maxabs)) && return maxabs
(v, s) = iterate(x)::Tuple
T = typeof(maxabs)
if isfinite(length(x)*maxabs*maxabs) && !iszero(maxabs*maxabs) # Scaling not necessary
Expand All @@ -472,6 +472,7 @@ function generic_norm2(x)
(v, s) = y
sum += norm_sqr(v)
end
ismissing(sum) && return missing
return convert(T, sqrt(sum))
else
sum = abs2(norm(v)/maxabs)
Expand All @@ -481,6 +482,7 @@ function generic_norm2(x)
(v, s) = y
sum += (norm(v)/maxabs)^2
end
ismissing(sum) && return missing
return convert(T, maxabs*sqrt(sum))
end
end
Expand All @@ -491,7 +493,7 @@ function generic_normp(x, p)
(v, s) = iterate(x)::Tuple
if p > 1 || p < -1 # might need to rescale to avoid overflow
maxabs = p > 1 ? normInf(x) : normMinusInf(x)
(iszero(maxabs) || isinf(maxabs)) && return maxabs
(ismissing(maxabs) || iszero(maxabs) || isinf(maxabs)) && return maxabs
T = typeof(maxabs)
else
T = typeof(float(norm(v)))
Expand All @@ -503,15 +505,18 @@ function generic_normp(x, p)
y = iterate(x, s)
y === nothing && break
(v, s) = y
ismissing(v) && return missing
sum += norm(v)^spp
end
return convert(T, sum^inv(spp))
else # rescaling
sum = (norm(v)/maxabs)^spp
ismissing(sum) && return missing
while true
y = iterate(x, s)
y === nothing && break
(v, s) = y
ismissing(v) && return missing
sum += (norm(v)/maxabs)^spp
end
return convert(T, maxabs*sum^inv(spp))
Expand Down
7 changes: 7 additions & 0 deletions stdlib/LinearAlgebra/test/generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,13 @@ end

@testset "missing values" begin
@test ismissing(norm(missing))
x = [5, 6, missing]
y = [missing, 5, 6]
for p in (-Inf, -1, 1, 2, 3, Inf)
@test ismissing(norm(x, p))
@test ismissing(norm(y, p))
end
@test_broken ismissing(norm(x, 0))
end

@testset "peakflops" begin
Expand Down

0 comments on commit df06375

Please sign in to comment.