# Norm, normalize

I just realized, that `normalize` only has methods for `AbstractVectors`.

``````julia> methods(normalize)
# 2 methods for generic function "normalize":
normalize(v::AbstractArray{T,1} where T) in Base.LinAlg at linalg/generic.jl:1294
normalize(v::AbstractArray{T,1} where T, p::Real) in Base.LinAlg at linalg/generic.jl:1294
``````

And `norm` is only defined for vectors and matrices. Mathematically the `p` norm is reasonable for
arrays of any dimension, so to me it seems both of these should be defined for `AbstractArray`.

Is there a good reason for limiting these definitions?

2 Likes

It is usually not ambiguous how people would like to normalize a vector whereas I think that would be the case for matrices. We could choose a default but Iâ€™m not sure that there is as much a demand for that compared to how frequently people normalize vectors.

The `norm` function for matrices is the operator norm where the operator is applied with `*` on a `Vector`. We donâ€™t define an operator for arrays of higher dimension so I think it is fine not to define a `norm` in that case. Notice that the elementwise norm function is called `vecnorm` and works for arrays of all dimensions and even iterators.

1 Like

It seems to me that the most consistent thing would be to define `normalize!(x::T, p::Real)` for all `T` accepted by `norm(x::T, p::Real)`, and define `vecnormalize!` for the normalization by the Frobenius norm.

3 Likes

Would the proposed functionality produce the projection to the Lp unit ball? Or just divide each element by the norm? My impression is that these two concepts are equivalent for the L2 norm, but arenâ€™t generally equivalent.

You are right, they differ. I prefer division. I often want to normalize the largest entry of an array to be one. This corresponds to division by `Inf` norm. Projection on the other hand is a quite useless operation in case of the `Inf` norm:
`clamp.(arr, -1, 1)`

Notice that you can simply do

``````scale!(A, inv(vecnorm(A, Inf)))
``````

to achieve that which might be sufficient and not much longer than `vecnormalize!(A, Inf)`. The `normalize!` function has the convenience of returning the norm and then it handles some corner cases.

Elementwise division by the norm seems the most predicable behavior to me, but maybe thatâ€™s just my backgroundâ€¦

If itâ€™s worth anything, it seems that Mathematica defines `Normalize[expr, f]` to do elementwise division by the norm calculated via `f` when `expr` is a matrix (the matrix example is under â€śGeneralizations and Extensionsâ€ť):

2 Likes