-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix vecnorm for Vector{Vector{T}} #22945
Conversation
@andreasnoack, we assume that |
@@ -431,16 +431,15 @@ julia> vecnorm([1 2 3 4 5 6 7 8 9]) | |||
``` | |||
""" | |||
function vecnorm(itr, p::Real=2) | |||
isempty(itr) && return float(real(zero(eltype(itr)))) | |||
isempty(itr) && return float(norm(zero(eltype(itr)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like it would be clearer to to use a return-type declaration? Then we could just return 0
in the empty case and return count(...)
in the p == 0
case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notice that the two type computations for the empty case and the p=0
case are slightly different. The empty case uses zero(Type)
whereas the p=0
case avoids zero(Type)
which allows us to compute
julia> norm(Float64[])
0.0
as well as
julia> norm([[1,2], [3,4]], 0)
2.0
I think we'd have to give up on one of them if we want to use return type annotation instead.
Maybe I'm missing the right example but I'm not completely convinced that it would be unreasonable if the inner norm was the same as the outer norm. In our use case we have small vectors at each location in a grid and can store that as, say |
@andreasnoack, what about the case (1) of For the cases (2) like |
My gut feeling is that an error would be fine in that case but, as mentioned, I'm probably missing the right example. What kind of |
For example, Honestly, I don't see why the current behavior is a problem. It's a perfectly reasonable definition of a p-norm of an array of vectors. |
I've actually already changed the 0-norm to bypass the call to
I'm not saying it is wrong but I was surprised that we didn't use the same norm all the way down. As you probably noticed, I was not the only one with that expectation. |
I've changed julia> "Julia" != 0
true
julia> !iszero("Julia")
ERROR: MethodError: no method matching zero(::String)
Closest candidates are:
zero(::Type{Base.LibGit2.GitHash}) at libgit2/oid.jl:106
zero(::Type{Base.Pkg.Resolve.VersionWeights.VWPreBuildItem}) at pkg/resolve/versionweight.jl:82
zero(::Type{Base.Pkg.Resolve.VersionWeights.VWPreBuild}) at pkg/resolve/versionweight.jl:124
...
Stacktrace:
[1] iszero(::String) at ./number.jl:22 The main problem seems to be the consequences of the decision in #19561 to allow I think we have two options. Either we loosen the requirement that |
I don't understand why we would want |
I should probably have been more clear here. I'm not trying to make julia> x = [zeros(2) for i in 1:2]
2-element Array{Array{Float64,1},1}:
[0.0, 0.0]
[0.0, 0.0]
julia> countnz(x)
2
julia> count(!iszero, x)
0 because |
From slack/#linalg discussion, crossref. #17623 (comment). (A more permissive fallback for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as Sacha says above, iszero
should error less often if we're going to call it in more places we haven't been before
base/reduce.jl
Outdated
@@ -721,4 +721,4 @@ julia> countnz(A) | |||
6 | |||
``` | |||
""" | |||
countnz(a) = count(x -> x != 0, a) | |||
countnz(a) = count(!iszero, a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe
countnz(a) = count(x -> x != 0, a)
countnz(a::AbstractArray{<:AbstractArray}) = count(!iszero, a)
would be an inelegant way of meeting both needs for now
that should do, 0-vecnorm of a heterogenous array with non-numeric elements would be an odd thing to do
As a consequence of the discussion in #23005, I've changed this PR to explicitly use a predicate in |
Use iszero in countnz
Use iszero in countnz (cherry picked from commit 72be7cb)
Use iszero in countnz (cherry picked from commit 72be7cb)
Realized this issue today when working on a problem where we were using
Vector{SVector{2,Float64}}
. The return types of the empty case and zero norm were computed incorrectly which caused type instability ofnorm
.@stevengj A separate issue but why is the inner norm the two norm regardless of the outer norm? I would have expected
norm([[1,1], [1,1]], Inf)
to be one.