diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index ac56cb191488a..d13faf3cdadc7 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -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 @@ -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) @@ -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 @@ -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))) @@ -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)) diff --git a/stdlib/LinearAlgebra/test/generic.jl b/stdlib/LinearAlgebra/test/generic.jl index 25a89977bce54..f1a617d12ead7 100644 --- a/stdlib/LinearAlgebra/test/generic.jl +++ b/stdlib/LinearAlgebra/test/generic.jl @@ -543,6 +543,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