Subject: Re: [boost] [histogram] should some_axis::size() return unsigned or int?
From: Hans Dembinski (hans.dembinski_at_[hidden])
Date: 2018-11-30 14:53:20
> On 30. Nov 2018, at 14:44, Alexander Grund via Boost <boost_at_[hidden]> wrote:
> Am 30.11.18 um 13:27 schrieb Hans Dembinski:
>> I can see that you did not read the rationale carefully yet.
> I just did not understand everything ;)
Fair enough, but then let me know what you don't understand and I will try to explain it better.
>> `i` is the index for the histogram here (!) not for the axis itself. The histogram is also not a container, but it acts more like one. It also has a size() method and the value really includes all bins.
> Ah ok. So the essence of your question was: What should the types be for histogram::size() and histogram::operator?
No, the question is about axis::size(), whether it should return `int` or `unsigned`. There is no problem with histogram::size() or histogram::operator.
> BTW: Where is an interface description of that histogram class? In the reference I only find a forward declaration and "unspecified type", so I don't know what members it has.
There is a technical problem in the reference generation that I haven't been able to fix yet. Help from experts would be very much appreciated. In the code, the histogram interface is documented and the documentation is supposed to be part of the reference.
> In this case I go with the "same-as-stdlib" approach:
> - Types should be the same
> - for(auto i = SizeType(0); i<h.size(); i++) h.at(i).doIt() should be possible and iterate over all bins
>> No, not a good idea. If we do that, then toggling *-flow bins on/off changes your whole program as it is written up to now, it will do something completely different.
>> A user should be able to code the analysis and then decide: "Ah crap, these extra bins cost too much memory and in my special case they are always empty anyway, because my values never go out of the range that I specified. So let's just turn them off". Doing that optimization should not change logic of the program you wrote so far.
> True, ok thanks for the clarification. Then axis.size is what the user says and h.size()==axis.size||axis.size+2. Putting the *flow bins at the end allows iterating over axis.size OR h.size with the same code. You can even go from for(int i=0; i<axis.size(); i++) to iterating till h.size if you chose to include the extra bins in your iteration.
This implies strange behaviour for the axis. Note that you can and sometimes want to use the axis manually to maps values to indices. Then you get this, if I follow your suggestion:
auto a = axis::regular<>(2, 1, 2); // axis with two bins [1, 1.5), [1.5, 2.0)
assert(a(0.99) == 3); // ??
assert(a(1) == 0); // ok
assert(a(1.5) == 1); // ok
assert(a(2.0) == 2); // ok
assert(a(10.0) == 2); // ok
The ordering of the indices is not the same as the ordering of the values.
I find that unacceptable.