Least-squares minimization is ubiquitous and a typical implementation involves minimizing a cost function of the form cost(x) = norm(model(x) - data)^2
However, norm(x)^2 is not auto-differentiable at zero because of the sqrt in the implementation of norm.
See: https://juliadiff.org/ForwardDiff.jl/stable/user/limitations/
It would be convenient for LinearAlgebra to provide the square of the 2-norm
as a built-in exported function to encourage use of the auto-differentiable version, e.g.:
norm_sqr(x) = sum(abs2, x)
Importantly, this version is also more efficient because it avoids the redundant sqrt and squaring operations.
The predictable pushback here is that it is a simple one-line function that anyone can implement themselves. My counter is that Julia base provides abs2(x::Real) = x*x (and something related for complex values), presumably both for efficiency and for differentiability compared to the "obvious" way abs(x)^2.
A main question would be the name. A natural parallel to abs2 would be norm2 but that name is already used internally in the package and could be confused with the 2-norm itself.
The package already has norm_sqr hidden inside it:
but it is not exported, there is no docstring, and sadly it uses the inefficient and non-differentiable version!
Proposal:
- fix the definition to be
norm_sqr(x) = sum(abs2, x) or norm_sqr(x) = sum(abs2 ∘ float , x)
- add docstring
- export it.
I'd make a PR if there is openness to this.
I am unsure whether the ∘ float part should be included. I saw that version in #1650
Least-squares minimization is ubiquitous and a typical implementation involves minimizing a cost function of the form
cost(x) = norm(model(x) - data)^2However,
norm(x)^2is not auto-differentiable at zero because of thesqrtin the implementation ofnorm.See: https://juliadiff.org/ForwardDiff.jl/stable/user/limitations/
It would be convenient for LinearAlgebra to provide the square of the 2-norm
as a built-in exported function to encourage use of the auto-differentiable version, e.g.:
norm_sqr(x) = sum(abs2, x)Importantly, this version is also more efficient because it avoids the redundant
sqrtand squaring operations.The predictable pushback here is that it is a simple one-line function that anyone can implement themselves. My counter is that Julia base provides
abs2(x::Real) = x*x(and something related for complex values), presumably both for efficiency and for differentiability compared to the "obvious" wayabs(x)^2.A main question would be the name. A natural parallel to
abs2would benorm2but that name is already used internally in the package and could be confused with the 2-norm itself.The package already has
norm_sqrhidden inside it:LinearAlgebra.jl/src/generic.jl
Line 571 in 46a7550
but it is not exported, there is no docstring, and sadly it uses the inefficient and non-differentiable version!
Proposal:
norm_sqr(x) = sum(abs2, x)ornorm_sqr(x) = sum(abs2 ∘ float , x)I'd make a PR if there is openness to this.
I am unsure whether the
∘ floatpart should be included. I saw that version in #1650