Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2109,7 +2109,7 @@ NaN
function normalize(a::AbstractArray, p::Real = 2)
nrm = norm(a, p)
if !isempty(a)
aa = copymutable_oftype(a, typeof(first(a)/nrm))
aa = copymutable_oftype(a, float(Base.promote_eltype(a, nrm)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work for arrays of arrays:

julia> a = [[1,2], [3,4]]; nrm = norm(a)
5.477225575051661

julia> Base.promote_eltype(a, nrm)
Any

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead of calling __normalize!, which requires us to compute the type of the array, we should just call map, which does the type computation for us. Something like:

function normalize(a::AbstractArray, p::Real = 2)
    nrm = norm(a, p)
    # duplicate logic from __normalize!, but applied to map:
    δ = inv(prevfloat(typemax(nrm)))
    if nrm  δ # Safe to multiply with inverse
        return map(Base.Fix2(*, inv(nrm)), a)
    else # scale elements to avoid overflow
        εδ = eps(one(nrm))/δ
        result = map(Base.Fix2(*, εδ), a)
        return rmul!(result, inv(nrm*εδ))
    end
end

This duplicates the logic in __normalize!, but that seems easier than duplicating the logic in map?

return __normalize!(aa, nrm)
else
T = typeof(zero(eltype(a))/nrm)
Expand Down