This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
Bug 1193 - extend lpNorm with 0 and -infinity
Summary: extend lpNorm with 0 and -infinity
Status: DECISIONNEEDED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: unspecified
Hardware: All All
: Normal Feature Request
Assignee: Nobody
URL:
Whiteboard:
Keywords: JuniorJob
Depends on:
Blocks:
 
Reported: 2016-04-08 08:50 UTC by MartinS
Modified: 2019-12-04 15:37 UTC (History)
4 users (show)



Attachments

Description MartinS 2016-04-08 08:50:13 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)
Comment 1 Gael Guennebaud 2016-06-02 13:34:58 UTC
Fixed: https://bitbucket.org/eigen/eigen/commits/677c9f157781/

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?
Comment 2 Christoph Hertzberg 2016-06-06 13:45:22 UTC
Using \ell_0 as "counting norm" is not completely uncommon:
https://en.wikipedia.org/wiki/Lp_space#When_p_.3D_0

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 ...)
Comment 3 Gael Guennebaud 2016-06-06 15:03:45 UTC
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).
Comment 4 MartinS 2016-06-07 10:16:57 UTC
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.
Comment 5 Nobody 2019-12-04 15:37:35 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1193.

Note You need to log in before you can comment on or make changes to this bug.