From 68ff2bcaa3d3a75b0e3b3061167e2ff59ca8885c Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Fri, 21 Dec 2018 18:45:04 +0530 Subject: [PATCH 1/8] Fixed norm --- stdlib/LinearAlgebra/src/generic.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index a730e213017a3..05066c88b8e38 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -447,17 +447,17 @@ true function norm(itr, p::Real=2) isempty(itr) && return float(norm(zero(eltype(itr)))) if p == 2 - return norm2(itr) + return norm2(float(itr)) elseif p == 1 - return norm1(itr) + return norm1(float(itr)) elseif p == Inf - return normInf(itr) + return normInf(float(itr)) elseif p == 0 return typeof(float(norm(first(itr))))(count(!iszero, itr)) elseif p == -Inf - return normMinusInf(itr) + return normMinusInf(float(itr)) else - normp(itr, p) + normp(float(itr), p) end end From 88296268733928d520788f8f3a3cb132da8f6de9 Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Sun, 23 Dec 2018 00:27:19 +0530 Subject: [PATCH 2/8] Modified and added tests for norm --- stdlib/LinearAlgebra/src/generic.jl | 34 ++++++++++++++-------------- stdlib/LinearAlgebra/test/generic.jl | 6 +++++ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index 05066c88b8e38..6bdbc95622fac 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -273,12 +273,12 @@ diag(A::AbstractVector) = throw(ArgumentError("use diagm instead of diag to cons # special cases of norm; note that they don't need to handle isempty(x) function generic_normMinusInf(x) (v, s) = iterate(x)::Tuple - minabs = norm(v) + minabs = norm(float(v)) while true y = iterate(x, s) y === nothing && break (v, s) = y - vnorm = norm(v) + vnorm = norm(float(v)) minabs = ifelse(isnan(minabs) | (minabs < vnorm), minabs, vnorm) end return float(minabs) @@ -286,12 +286,12 @@ end function generic_normInf(x) (v, s) = iterate(x)::Tuple - maxabs = norm(v) + maxabs = norm(float(v)) while true y = iterate(x, s) y === nothing && break (v, s) = y - vnorm = norm(v) + vnorm = norm(float(v)) maxabs = ifelse(isnan(maxabs) | (maxabs > vnorm), maxabs, vnorm) end return float(maxabs) @@ -299,14 +299,14 @@ end function generic_norm1(x) (v, s) = iterate(x)::Tuple - av = float(norm(v)) + av = float(norm(float(v))) T = typeof(av) sum::promote_type(Float64, T) = av while true y = iterate(x, s) y === nothing && break (v, s) = y - sum += norm(v) + sum += norm(float(v)) end return convert(T, sum) end @@ -331,12 +331,12 @@ function generic_norm2(x) end return convert(T, sqrt(sum)) else - sum = abs2(norm(v)/maxabs) + sum = abs2(norm(float(v))/maxabs) while true y = iterate(x, s) y === nothing && break (v, s) = y - sum += (norm(v)/maxabs)^2 + sum += (norm(float(v))/maxabs)^2 end return convert(T, maxabs*sqrt(sum)) end @@ -355,21 +355,21 @@ function generic_normp(x, p) end spp::promote_type(Float64, T) = p if -1 <= p <= 1 || (isfinite(length(x)*maxabs^spp) && maxabs^spp != 0) # scaling not necessary - sum::promote_type(Float64, T) = norm(v)^spp + sum::promote_type(Float64, T) = norm(float(v))^spp while true y = iterate(x, s) y === nothing && break (v, s) = y - sum += norm(v)^spp + sum += norm(float(v))^spp end return convert(T, sum^inv(spp)) else # rescaling - sum = (norm(v)/maxabs)^spp + sum = (norm(float(v))/maxabs)^spp while true y = iterate(x, s) y == nothing && break (v, s) = y - sum += (norm(v)/maxabs)^spp + sum += (norm(float(v))/maxabs)^spp end return convert(T, maxabs*sum^inv(spp)) end @@ -447,17 +447,17 @@ true function norm(itr, p::Real=2) isempty(itr) && return float(norm(zero(eltype(itr)))) if p == 2 - return norm2(float(itr)) + return norm2(itr) elseif p == 1 - return norm1(float(itr)) + return norm1(itr) elseif p == Inf - return normInf(float(itr)) + return normInf(itr) elseif p == 0 return typeof(float(norm(first(itr))))(count(!iszero, itr)) elseif p == -Inf - return normMinusInf(float(itr)) + return normMinusInf(itr) else - normp(float(itr), p) + normp(itr, p) end end diff --git a/stdlib/LinearAlgebra/test/generic.jl b/stdlib/LinearAlgebra/test/generic.jl index cff5aefff6a8f..4c1578ffff72d 100644 --- a/stdlib/LinearAlgebra/test/generic.jl +++ b/stdlib/LinearAlgebra/test/generic.jl @@ -225,6 +225,12 @@ end end end +@testset "Issue #30466" begin + @test norm([typemin(Int), typemin(Int)], Inf) == 9.223372036854776e18 + @test norm([typemin(Int), typemin(Int)], -Inf) == 9.223372036854776e18 + @test norm([typemin(Int), typemin(Int)], 1) == 1.8446744073709552e19 +end + @testset "potential overflow in normalize!" begin δ = inv(prevfloat(typemax(Float64))) v = [δ, -δ] From d63a87de23959c05782ea676d327dfeccae16145 Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Sat, 29 Dec 2018 19:31:22 +0530 Subject: [PATCH 3/8] Added AbstractFloat for Quaternion Type --- stdlib/LinearAlgebra/src/generic.jl | 26 +++++++++++++------------- test/testhelpers/Quaternions.jl | 1 + 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index 6bdbc95622fac..24fc467e9cba3 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -273,12 +273,12 @@ diag(A::AbstractVector) = throw(ArgumentError("use diagm instead of diag to cons # special cases of norm; note that they don't need to handle isempty(x) function generic_normMinusInf(x) (v, s) = iterate(x)::Tuple - minabs = norm(float(v)) + minabs = norm(v) while true y = iterate(x, s) y === nothing && break (v, s) = y - vnorm = norm(float(v)) + vnorm = norm(v) minabs = ifelse(isnan(minabs) | (minabs < vnorm), minabs, vnorm) end return float(minabs) @@ -286,12 +286,12 @@ end function generic_normInf(x) (v, s) = iterate(x)::Tuple - maxabs = norm(float(v)) + maxabs = norm(v) while true y = iterate(x, s) y === nothing && break (v, s) = y - vnorm = norm(float(v)) + vnorm = norm(v) maxabs = ifelse(isnan(maxabs) | (maxabs > vnorm), maxabs, vnorm) end return float(maxabs) @@ -299,14 +299,14 @@ end function generic_norm1(x) (v, s) = iterate(x)::Tuple - av = float(norm(float(v))) + av = float(norm(v)) T = typeof(av) sum::promote_type(Float64, T) = av while true y = iterate(x, s) y === nothing && break (v, s) = y - sum += norm(float(v)) + sum += norm(v) end return convert(T, sum) end @@ -331,12 +331,12 @@ function generic_norm2(x) end return convert(T, sqrt(sum)) else - sum = abs2(norm(float(v))/maxabs) + sum = abs2(norm(v)/maxabs) while true y = iterate(x, s) y === nothing && break (v, s) = y - sum += (norm(float(v))/maxabs)^2 + sum += (norm(v)/maxabs)^2 end return convert(T, maxabs*sqrt(sum)) end @@ -355,21 +355,21 @@ function generic_normp(x, p) end spp::promote_type(Float64, T) = p if -1 <= p <= 1 || (isfinite(length(x)*maxabs^spp) && maxabs^spp != 0) # scaling not necessary - sum::promote_type(Float64, T) = norm(float(v))^spp + sum::promote_type(Float64, T) = norm(v)^spp while true y = iterate(x, s) y === nothing && break (v, s) = y - sum += norm(float(v))^spp + sum += norm(v)^spp end return convert(T, sum^inv(spp)) else # rescaling - sum = (norm(float(v))/maxabs)^spp + sum = (norm(v)/maxabs)^spp while true y = iterate(x, s) y == nothing && break (v, s) = y - sum += (norm(float(v))/maxabs)^spp + sum += (norm(v)/maxabs)^spp end return convert(T, maxabs*sum^inv(spp)) end @@ -487,7 +487,7 @@ julia> norm(-2, Inf) 2 ``` """ -@inline norm(x::Number, p::Real=2) = p == 0 ? (x==0 ? zero(abs(x)) : oneunit(abs(x))) : abs(x) +@inline norm(x::Number, p::Real=2) = p == 0 ? (x==0 ? zero(abs(float(x))) : oneunit(abs(float(x)))) : abs(float(x)) norm(::Missing, p::Real=2) = missing # special cases of opnorm diff --git a/test/testhelpers/Quaternions.jl b/test/testhelpers/Quaternions.jl index 0920b9dea00c6..7b779f793de2e 100644 --- a/test/testhelpers/Quaternions.jl +++ b/test/testhelpers/Quaternions.jl @@ -12,6 +12,7 @@ struct Quaternion{T<:Real} <: Number end Quaternion(s::Real, v1::Real, v2::Real, v3::Real) = Quaternion(promote(s, v1, v2, v3)...) Base.abs2(q::Quaternion) = q.s*q.s + q.v1*q.v1 + q.v2*q.v2 + q.v3*q.v3 +Base.AbstractFloat(q::Quaternion) = Quaternion(float(q.s), float(q.v1), float(q.v2), float(q.v3)) Base.abs(q::Quaternion) = sqrt(abs2(q)) Base.real(::Type{Quaternion{T}}) where {T} = T Base.conj(q::Quaternion) = Quaternion(q.s, -q.v1, -q.v2, -q.v3) From c6caf3bfa20be0c230b3df52b78b70283c9ed1d8 Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Mon, 31 Dec 2018 15:25:57 +0530 Subject: [PATCH 4/8] Updated norm --- stdlib/LinearAlgebra/src/generic.jl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index 24fc467e9cba3..7502e120c8168 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -273,11 +273,13 @@ diag(A::AbstractVector) = throw(ArgumentError("use diagm instead of diag to cons # special cases of norm; note that they don't need to handle isempty(x) function generic_normMinusInf(x) (v, s) = iterate(x)::Tuple + v = isa(v, Number) ? float(v) : v minabs = norm(v) while true y = iterate(x, s) y === nothing && break (v, s) = y + v = isa(v, Number) ? float(v) : v vnorm = norm(v) minabs = ifelse(isnan(minabs) | (minabs < vnorm), minabs, vnorm) end @@ -286,11 +288,13 @@ end function generic_normInf(x) (v, s) = iterate(x)::Tuple + v = isa(v, Number) ? float(v) : v maxabs = norm(v) while true y = iterate(x, s) y === nothing && break (v, s) = y + v = isa(v, Number) ? float(v) : v vnorm = norm(v) maxabs = ifelse(isnan(maxabs) | (maxabs > vnorm), maxabs, vnorm) end @@ -299,6 +303,7 @@ end function generic_norm1(x) (v, s) = iterate(x)::Tuple + v = isa(v, Number) ? float(v) : v av = float(norm(v)) T = typeof(av) sum::promote_type(Float64, T) = av @@ -306,6 +311,7 @@ function generic_norm1(x) y = iterate(x, s) y === nothing && break (v, s) = y + v = isa(v, Number) ? float(v) : v sum += norm(v) end return convert(T, sum) @@ -331,11 +337,13 @@ function generic_norm2(x) end return convert(T, sqrt(sum)) else + v = isa(v, Number) ? float(v) : v sum = abs2(norm(v)/maxabs) while true y = iterate(x, s) y === nothing && break (v, s) = y + v = isa(v, Number) ? float(v) : v sum += (norm(v)/maxabs)^2 end return convert(T, maxabs*sqrt(sum)) @@ -355,20 +363,24 @@ function generic_normp(x, p) end spp::promote_type(Float64, T) = p if -1 <= p <= 1 || (isfinite(length(x)*maxabs^spp) && maxabs^spp != 0) # scaling not necessary + v = isa(v, Number) ? float(v) : v sum::promote_type(Float64, T) = norm(v)^spp while true y = iterate(x, s) y === nothing && break (v, s) = y + v = isa(v, Number) ? float(v) : v sum += norm(v)^spp end return convert(T, sum^inv(spp)) else # rescaling + v = isa(v, Number) ? float(v) : v sum = (norm(v)/maxabs)^spp while true y = iterate(x, s) y == nothing && break (v, s) = y + v = isa(v, Number) ? float(v) : v sum += (norm(v)/maxabs)^spp end return convert(T, maxabs*sum^inv(spp)) @@ -487,7 +499,7 @@ julia> norm(-2, Inf) 2 ``` """ -@inline norm(x::Number, p::Real=2) = p == 0 ? (x==0 ? zero(abs(float(x))) : oneunit(abs(float(x)))) : abs(float(x)) +@inline norm(x::Number, p::Real=2) = p == 0 ? (x==0 ? zero(abs(x)) : oneunit(abs(x))) : abs(x) norm(::Missing, p::Real=2) = missing # special cases of opnorm From d3e32356eb9ecc487b3e46b494f8e2e19d7076f3 Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Thu, 3 Jan 2019 16:50:15 +0530 Subject: [PATCH 5/8] Modified norm(::Number) to return float --- stdlib/LinearAlgebra/src/generic.jl | 26 +++++++------------------- test/testhelpers/Quaternions.jl | 2 +- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/stdlib/LinearAlgebra/src/generic.jl b/stdlib/LinearAlgebra/src/generic.jl index 7502e120c8168..4f0b404bafe89 100644 --- a/stdlib/LinearAlgebra/src/generic.jl +++ b/stdlib/LinearAlgebra/src/generic.jl @@ -273,13 +273,11 @@ diag(A::AbstractVector) = throw(ArgumentError("use diagm instead of diag to cons # special cases of norm; note that they don't need to handle isempty(x) function generic_normMinusInf(x) (v, s) = iterate(x)::Tuple - v = isa(v, Number) ? float(v) : v minabs = norm(v) while true y = iterate(x, s) y === nothing && break (v, s) = y - v = isa(v, Number) ? float(v) : v vnorm = norm(v) minabs = ifelse(isnan(minabs) | (minabs < vnorm), minabs, vnorm) end @@ -288,13 +286,11 @@ end function generic_normInf(x) (v, s) = iterate(x)::Tuple - v = isa(v, Number) ? float(v) : v maxabs = norm(v) while true y = iterate(x, s) y === nothing && break (v, s) = y - v = isa(v, Number) ? float(v) : v vnorm = norm(v) maxabs = ifelse(isnan(maxabs) | (maxabs > vnorm), maxabs, vnorm) end @@ -303,7 +299,6 @@ end function generic_norm1(x) (v, s) = iterate(x)::Tuple - v = isa(v, Number) ? float(v) : v av = float(norm(v)) T = typeof(av) sum::promote_type(Float64, T) = av @@ -311,7 +306,6 @@ function generic_norm1(x) y = iterate(x, s) y === nothing && break (v, s) = y - v = isa(v, Number) ? float(v) : v sum += norm(v) end return convert(T, sum) @@ -337,13 +331,11 @@ function generic_norm2(x) end return convert(T, sqrt(sum)) else - v = isa(v, Number) ? float(v) : v sum = abs2(norm(v)/maxabs) while true y = iterate(x, s) y === nothing && break (v, s) = y - v = isa(v, Number) ? float(v) : v sum += (norm(v)/maxabs)^2 end return convert(T, maxabs*sqrt(sum)) @@ -363,24 +355,20 @@ function generic_normp(x, p) end spp::promote_type(Float64, T) = p if -1 <= p <= 1 || (isfinite(length(x)*maxabs^spp) && maxabs^spp != 0) # scaling not necessary - v = isa(v, Number) ? float(v) : v sum::promote_type(Float64, T) = norm(v)^spp while true y = iterate(x, s) y === nothing && break (v, s) = y - v = isa(v, Number) ? float(v) : v sum += norm(v)^spp end return convert(T, sum^inv(spp)) else # rescaling - v = isa(v, Number) ? float(v) : v sum = (norm(v)/maxabs)^spp while true y = iterate(x, s) y == nothing && break (v, s) = y - v = isa(v, Number) ? float(v) : v sum += (norm(v)/maxabs)^spp end return convert(T, maxabs*sum^inv(spp)) @@ -481,25 +469,25 @@ For numbers, return ``\\left( |x|^p \\right)^{1/p}``. # Examples ```jldoctest julia> norm(2, 1) -2 +2.0 julia> norm(-2, 1) -2 +2.0 julia> norm(2, 2) -2 +2.0 julia> norm(-2, 2) -2 +2.0 julia> norm(2, Inf) -2 +2.0 julia> norm(-2, Inf) -2 +2.0 ``` """ -@inline norm(x::Number, p::Real=2) = p == 0 ? (x==0 ? zero(abs(x)) : oneunit(abs(x))) : abs(x) +@inline norm(x::Number, p::Real=2) = p == 0 ? (x==0 ? zero(abs(float(x))) : oneunit(abs(float(x)))) : abs(float(x)) norm(::Missing, p::Real=2) = missing # special cases of opnorm diff --git a/test/testhelpers/Quaternions.jl b/test/testhelpers/Quaternions.jl index 7b779f793de2e..280965f3a70e1 100644 --- a/test/testhelpers/Quaternions.jl +++ b/test/testhelpers/Quaternions.jl @@ -12,7 +12,7 @@ struct Quaternion{T<:Real} <: Number end Quaternion(s::Real, v1::Real, v2::Real, v3::Real) = Quaternion(promote(s, v1, v2, v3)...) Base.abs2(q::Quaternion) = q.s*q.s + q.v1*q.v1 + q.v2*q.v2 + q.v3*q.v3 -Base.AbstractFloat(q::Quaternion) = Quaternion(float(q.s), float(q.v1), float(q.v2), float(q.v3)) +Base.float(z::Quaternion{T}) where T = Quaternion(float(z.s), float(z.v1), float(z.v2), float(z.v3)) Base.abs(q::Quaternion) = sqrt(abs2(q)) Base.real(::Type{Quaternion{T}}) where {T} = T Base.conj(q::Quaternion) = Quaternion(q.s, -q.v1, -q.v2, -q.v3) From 445a52cd937b3c4ccc6c176fb787aeecd0670834 Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Thu, 3 Jan 2019 17:09:05 +0530 Subject: [PATCH 6/8] Removed -p test for norm --- stdlib/LinearAlgebra/test/generic.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/LinearAlgebra/test/generic.jl b/stdlib/LinearAlgebra/test/generic.jl index 4c1578ffff72d..9151dbad98878 100644 --- a/stdlib/LinearAlgebra/test/generic.jl +++ b/stdlib/LinearAlgebra/test/generic.jl @@ -227,7 +227,6 @@ end @testset "Issue #30466" begin @test norm([typemin(Int), typemin(Int)], Inf) == 9.223372036854776e18 - @test norm([typemin(Int), typemin(Int)], -Inf) == 9.223372036854776e18 @test norm([typemin(Int), typemin(Int)], 1) == 1.8446744073709552e19 end From 81ce23751c2ea8e943485d240640c971b73b6113 Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Fri, 4 Jan 2019 21:17:40 +0530 Subject: [PATCH 7/8] Updated tests --- stdlib/LinearAlgebra/test/generic.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/LinearAlgebra/test/generic.jl b/stdlib/LinearAlgebra/test/generic.jl index 9151dbad98878..8c17818a46c13 100644 --- a/stdlib/LinearAlgebra/test/generic.jl +++ b/stdlib/LinearAlgebra/test/generic.jl @@ -226,8 +226,8 @@ end end @testset "Issue #30466" begin - @test norm([typemin(Int), typemin(Int)], Inf) == 9.223372036854776e18 - @test norm([typemin(Int), typemin(Int)], 1) == 1.8446744073709552e19 + @test norm([typemin(Int), typemin(Int)], Inf) == float(typemax(Int)) + @test norm([typemin(Int), typemin(Int)], 1) == 2float(typemax(Int)) end @testset "potential overflow in normalize!" begin From eb23b9cb3abfe6ed27eec3e08d6e205d06d30a55 Mon Sep 17 00:00:00 2001 From: raghav9-97 Date: Fri, 4 Jan 2019 23:04:49 +0530 Subject: [PATCH 8/8] Minor change in tests --- stdlib/LinearAlgebra/test/generic.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/LinearAlgebra/test/generic.jl b/stdlib/LinearAlgebra/test/generic.jl index 8c17818a46c13..2146fb5112f5e 100644 --- a/stdlib/LinearAlgebra/test/generic.jl +++ b/stdlib/LinearAlgebra/test/generic.jl @@ -226,8 +226,8 @@ end end @testset "Issue #30466" begin - @test norm([typemin(Int), typemin(Int)], Inf) == float(typemax(Int)) - @test norm([typemin(Int), typemin(Int)], 1) == 2float(typemax(Int)) + @test norm([typemin(Int), typemin(Int)], Inf) == -float(typemin(Int)) + @test norm([typemin(Int), typemin(Int)], 1) == -2float(typemin(Int)) end @testset "potential overflow in normalize!" begin