Skip to content

Commit 60cdcf2

Browse files
committed
make norm handle missings
1 parent 51d6c15 commit 60cdcf2

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

stdlib/LinearAlgebra/src/generic.jl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ function generic_normMinusInf(x)
456456
y === nothing && break
457457
(v, s) = y
458458
vnorm = norm(v)
459+
ismissing(vnorm) && return missing
459460
minabs = ifelse(isnan(minabs) | (minabs < vnorm), minabs, vnorm)
460461
end
461462
return float(minabs)
@@ -464,11 +465,13 @@ end
464465
function generic_normInf(x)
465466
(v, s) = iterate(x)::Tuple
466467
maxabs = norm(v)
468+
ismissing(maxabs) && return missing
467469
while true
468470
y = iterate(x, s)
469471
y === nothing && break
470472
(v, s) = y
471473
vnorm = norm(v)
474+
ismissing(vnorm) && return missing
472475
maxabs = ifelse(isnan(maxabs) | (maxabs > vnorm), maxabs, vnorm)
473476
end
474477
return float(maxabs)
@@ -477,6 +480,7 @@ end
477480
function generic_norm1(x)
478481
(v, s) = iterate(x)::Tuple
479482
av = float(norm(v))
483+
ismissing(av) && return missing
480484
T = typeof(av)
481485
sum::promote_type(Float64, T) = av
482486
while true
@@ -485,6 +489,7 @@ function generic_norm1(x)
485489
(v, s) = y
486490
sum += norm(v)
487491
end
492+
ismissing(sum) && return missing
488493
return convert(T, sum)
489494
end
490495

@@ -495,7 +500,7 @@ norm_sqr(x::Union{T,Complex{T},Rational{T}}) where {T<:Integer} = abs2(float(x))
495500

496501
function generic_norm2(x)
497502
maxabs = normInf(x)
498-
(maxabs == 0 || isinf(maxabs)) && return maxabs
503+
(ismissing(maxabs) || maxabs == 0 || isinf(maxabs)) && return maxabs
499504
(v, s) = iterate(x)::Tuple
500505
T = typeof(maxabs)
501506
if isfinite(length(x)*maxabs*maxabs) && maxabs*maxabs != 0 # Scaling not necessary
@@ -506,6 +511,7 @@ function generic_norm2(x)
506511
(v, s) = y
507512
sum += norm_sqr(v)
508513
end
514+
ismissing(sum) && return missing
509515
return convert(T, sqrt(sum))
510516
else
511517
sum = abs2(norm(v)/maxabs)
@@ -515,6 +521,7 @@ function generic_norm2(x)
515521
(v, s) = y
516522
sum += (norm(v)/maxabs)^2
517523
end
524+
ismissing(sum) && return missing
518525
return convert(T, maxabs*sqrt(sum))
519526
end
520527
end
@@ -525,7 +532,7 @@ function generic_normp(x, p)
525532
(v, s) = iterate(x)::Tuple
526533
if p > 1 || p < -1 # might need to rescale to avoid overflow
527534
maxabs = p > 1 ? normInf(x) : normMinusInf(x)
528-
(maxabs == 0 || isinf(maxabs)) && return maxabs
535+
(ismissing(maxabs) || maxabs == 0 || isinf(maxabs)) && return maxabs
529536
T = typeof(maxabs)
530537
else
531538
T = typeof(float(norm(v)))
@@ -539,15 +546,18 @@ function generic_normp(x, p)
539546
(v, s) = y
540547
sum += norm(v)^spp
541548
end
549+
ismissing(sum) && return missing
542550
return convert(T, sum^inv(spp))
543551
else # rescaling
544552
sum = (norm(v)/maxabs)^spp
553+
ismissing(sum) && return missing
545554
while true
546555
y = iterate(x, s)
547556
y === nothing && break
548557
(v, s) = y
549558
sum += (norm(v)/maxabs)^spp
550559
end
560+
ismissing(sum) && return missing
551561
return convert(T, maxabs*sum^inv(spp))
552562
end
553563
end

stdlib/LinearAlgebra/test/generic.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,15 @@ end
448448

449449
@testset "missing values" begin
450450
@test ismissing(norm(missing))
451+
x = [5, 6, missing]
452+
y = [missing, 5, 6]
453+
@test ismissing(dot(x, x))
454+
@test ismissing(dot(x, y))
455+
@test ismissing(dot(y, x))
456+
for p in (-Inf, -1, 0, 1, 2, 3, Inf)
457+
@test ismissing(norm(x))
458+
@test ismissing(norm(y))
459+
end
451460
end
452461

453462
@testset "peakflops" begin
@@ -512,14 +521,6 @@ end
512521
end
513522
end
514523

515-
@testset "dot with missing" begin
516-
x = [5, 6, missing]
517-
y = [missing, 5, 6]
518-
@test ismissing(dot(x, x))
519-
@test ismissing(dot(x, y))
520-
@test ismissing(dot(y, x))
521-
end
522-
523524
@testset "condskeel #34512" begin
524525
A = rand(3, 3)
525526
@test condskeel(A) condskeel(A, [8,8,8])

0 commit comments

Comments
 (0)