Bugzilla – Bug 1193
extend lpNorm with 0 and -infinity
Last modified: 2016-07-25 13:34:14 UTC
Currently, v.lpNorm<Infinity>() is implemented as v.cwiseAbs().maxCoeff(), which fails for the corner case of an empty vector. In many occasions, a result of 0 would be more convenient (and also consistent with other p-norms). Also, both Matlab's and Octave's norm(, inf) return 0 (although via interpreting  as a matrix instead of a vector and applying the matrix inf-norm definition).
Of course, one could always check for v.size() > 0 before invoking v.lpNorm<Infinity>(), but this looks inconvenient, especially in templated code where the norm type is a parameter.
Moving the check to src/Core/Dot.h, lpNorm_selector<..., Infinity> (line 233 in current dev branch) seems more appropriate.
Btw. Are there any plans of adding more specializations to lpNorm, e.g.
- v.lpNorm<0> ==> v.array().count()
- v.lpNorm<NegativeInfinity> ==> v.cwiseAbs().minCoeff()
(with a new constant Eigen::NegativeInfinity)
Regarding L_0, v.array().count() does not define a proper norm, and L_0 refers to another definition for mathematicians, i.e.: (v.abs()/(1+v.abs())).sum()/2^n
Regarding minus infinity, are there any use cases?
Using \ell_0 as "counting norm" is not completely uncommon:
But, I guess using v.array().count() would definitely be less confusing here.
The same goes for v.cwiseAbs().minCoeff() instead of lpNorm<NegativeInfinity>();
We could also consider providing a v.lpNorm(const RealScalar& p) function (allowing non-integer p), which for for p<1 returns the corresponding pseudo norm (however, for p-->0 the natural limit for anything with more than one non-zero would be infinity instead of .array().count() -- and for floating point values checking != 0.0 actually is often meaningless ...)
yes, I perfectly agree that using L_0 as v.array().count() is extremely common! I just wanted to point out that there do exist a risk of ambiguity.
Ok for v.lpNorm(const RealScalar& p).
Thanks for the fix!
Regarding the 0-case: After checking the Wikipedia article, I also agree that v.array().count() is less ambiguous and should be preferred.
The variant with a runtime norm type is a good idea, though. For performance reasons, I would also propose an integer overload that behaves exactly as the templated version for the special argument values 1, 2 and Eigen::Infinity.
Regarding minus infinity: I had no particular use case in mind. It was just a consideration for bringing the API on par with Matlab/Octave.