[accumulators] Help understanding implementation of weighted accumulators
Hi folks, I am trying to implement a weighted accumulator, but I'm having trouble understanding a few things about the existing ones. Looking at the implementation of weighted_sum, I see (weighted_sum.hpp:37): template<typename Args> weighted_sum_impl(Args const &args) : weighted_sum_( args[parameter::keyword<Tag>::get() | Sample()] * numeric::one<Weight>::value ) { } My questions are: - It's taking the first sample from the args and multiplying it by a weight of 1. Isn't this wrong - ignoring the real weight of this sample? Shouldn't this produce incorrect results? - I've never understood anyways how there can be an initial argument during construction of the accumulator. I haven't found any explanation in the docs beyond "Maybe there is an initial value in the argument pack". Maybe? How? Probably more questions later. Thanks, -Gabe
On 5/1/2013 1:13 PM, Gabriel Redner wrote:
Hi folks,
I am trying to implement a weighted accumulator, but I'm having trouble understanding a few things about the existing ones.
Looking at the implementation of weighted_sum, I see (weighted_sum.hpp:37):
template<typename Args> weighted_sum_impl(Args const &args) : weighted_sum_( args[parameter::keyword<Tag>::get() | Sample()] * numeric::one<Weight>::value ) { }
My questions are:
- It's taking the first sample from the args and multiplying it by a weight of 1. Isn't this wrong - ignoring the real weight of this sample? Shouldn't this produce incorrect results?
It's not taking the first sample. It's (optionally) taking an element representing zero. In most cases, a default-constructed Sample() is satisfactory for a zero element, but in some cases it's not. Consider what happens if your Sample type is std::vector<int>, and all your samples are going to be 3-element vectors. Then your zero is a std::vector<int> with 3 zeros. Any other starting value would cause all future computation to fail. And we multiply by one to make the type promotion come out right.
- I've never understood anyways how there can be an initial argument during construction of the accumulator. I haven't found any explanation in the docs beyond "Maybe there is an initial value in the argument pack". Maybe? How?
I hope that clears it up. -- Eric Niebler Boost.org http://www.boost.org
Hi Eric,
Thanks very much for your response. That does help, and I have some follow-ups.
First, let me make sure I am understanding correctly. If my Sample is
some FancyType whose default constructor does not do the right thing
(or perhaps does not exist), I should do:
accumulator_set
On 5/1/2013 1:13 PM, Gabriel Redner wrote:
Hi folks,
I am trying to implement a weighted accumulator, but I'm having trouble understanding a few things about the existing ones.
Looking at the implementation of weighted_sum, I see (weighted_sum.hpp:37):
template<typename Args> weighted_sum_impl(Args const &args) : weighted_sum_( args[parameter::keyword<Tag>::get() | Sample()] * numeric::one<Weight>::value ) { }
My questions are:
- It's taking the first sample from the args and multiplying it by a weight of 1. Isn't this wrong - ignoring the real weight of this sample? Shouldn't this produce incorrect results?
It's not taking the first sample. It's (optionally) taking an element representing zero. In most cases, a default-constructed Sample() is satisfactory for a zero element, but in some cases it's not. Consider what happens if your Sample type is std::vector<int>, and all your samples are going to be 3-element vectors. Then your zero is a std::vector<int> with 3 zeros. Any other starting value would cause all future computation to fail.
And we multiply by one to make the type promotion come out right.
- I've never understood anyways how there can be an initial argument during construction of the accumulator. I haven't found any explanation in the docs beyond "Maybe there is an initial value in the argument pack". Maybe? How?
I hope that clears it up.
-- Eric Niebler Boost.org http://www.boost.org
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Sorry to revive an old thread, but I'd still be interested in the
answers to these questions.
-Gabe
On Wed, May 1, 2013 at 11:06 PM, Gabriel Redner
Hi Eric,
Thanks very much for your response. That does help, and I have some follow-ups.
First, let me make sure I am understanding correctly. If my Sample is some FancyType whose default constructor does not do the right thing (or perhaps does not exist), I should do:
accumulator_set
> acc(sample = some_initial_fancytype_value); Is that right? If so, I would say that: - This usage is not mentioned in the docs anywhere, and - It seems strange to overload the meaning of 'sample' in this way. Wouldn't it be clearer and accomplish the same goal to use a different name? "initialValue" perhaps? - Do all accumulators support this feature? I can imagine some that might not (indeed I am implementing one). This is not mentioned in the docs either.
Second, I have a sort-of-question-but-mostly-a-kvetch about defining keywords for accumulators that need initialization parameters (e.g. tail). The library itself uses the macro BOOST_PARAMETER_NESTED_KEYWORD for this, which is not documented. I do not understand what this macro does - why the name, why the alias, etc? My own accumulators need initialization parameters, and I have just been aping what the library itself does - using the macro although it's not documented, and hoping for the best. It seems to be working, but I'd like to understand if this is the right approach, whether I can rely on this undocumented macro, and what it's doing. Can you shed any light?
Thanks, -Gabe
On Wed, May 1, 2013 at 8:23 PM, Eric Niebler
wrote: On 5/1/2013 1:13 PM, Gabriel Redner wrote:
Hi folks,
I am trying to implement a weighted accumulator, but I'm having trouble understanding a few things about the existing ones.
Looking at the implementation of weighted_sum, I see (weighted_sum.hpp:37):
template<typename Args> weighted_sum_impl(Args const &args) : weighted_sum_( args[parameter::keyword<Tag>::get() | Sample()] * numeric::one<Weight>::value ) { }
My questions are:
- It's taking the first sample from the args and multiplying it by a weight of 1. Isn't this wrong - ignoring the real weight of this sample? Shouldn't this produce incorrect results?
It's not taking the first sample. It's (optionally) taking an element representing zero. In most cases, a default-constructed Sample() is satisfactory for a zero element, but in some cases it's not. Consider what happens if your Sample type is std::vector<int>, and all your samples are going to be 3-element vectors. Then your zero is a std::vector<int> with 3 zeros. Any other starting value would cause all future computation to fail.
And we multiply by one to make the type promotion come out right.
- I've never understood anyways how there can be an initial argument during construction of the accumulator. I haven't found any explanation in the docs beyond "Maybe there is an initial value in the argument pack". Maybe? How?
I hope that clears it up.
-- Eric Niebler Boost.org http://www.boost.org
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 10/2/2013 1:48 PM, Gabriel Redner wrote:
Sorry to revive an old thread, but I'd still be interested in the answers to these questions.
Apologies.
On Wed, May 1, 2013 at 11:06 PM, Gabriel Redner
wrote: Hi Eric,
Thanks very much for your response. That does help, and I have some follow-ups.
First, let me make sure I am understanding correctly. If my Sample is some FancyType whose default constructor does not do the right thing (or perhaps does not exist), I should do:
accumulator_set
> acc(sample = some_initial_fancytype_value); Is that right?
Right.
If so, I would say that: - This usage is not mentioned in the docs anywhere, and
Well, it's sort of mentioned here: http://www.boost.org/doc/libs/1_54_0/doc/html/accumulators/user_s_guide.html... Look at the comment to the right of the "sum_accumulator" constructor. But I agree this needs to be dealt with more explicitly in the docs.
- It seems strange to overload the meaning of 'sample' in this way. Wouldn't it be clearer and accomplish the same goal to use a different name? "initialValue" perhaps?
That probably makes sense. Although for backward compatibility, the best I could do would be to provide initialValue as an alias for sample (though probably something like "default_sample" instead of "initialValue").
- Do all accumulators support this feature? I can imagine some that
All accumulators are required to define a constructor that takes an argument pack. Whether the accumulator avails itself of a default sample if present is up to the accumulator.
might not (indeed I am implementing one). This is not mentioned in the docs either.
The docs should mention this, because it's best-practice if you want your accumulator to work with types like std::vector and std::valarray.
Second, I have a sort-of-question-but-mostly-a-kvetch about defining keywords for accumulators that need initialization parameters (e.g. tail). The library itself uses the macro BOOST_PARAMETER_NESTED_KEYWORD for this, which is not documented.
True. :-(
I do not understand what this macro does - why the name, why the alias, etc? My own accumulators need initialization parameters, and I have just been aping what the library itself does - using the macro although it's not documented, and hoping for the best. It seems to be working, but I'd like to understand if this is the right approach, whether I can rely on this undocumented macro, and what it's doing. Can you shed any light?
It exists and with the name that it does because it is very similar to the BOOST_PARAMETER_KEYWORD [1], except that it lets you define a keyword nested within an empty struct. Feature tags like tag::density inherit from these empty structs, so that you can say stuff like "tag::density::cache_size = 16" for setting parameters. None of this is documented, sadly. Can you please file a bug to add this information to the docs. I don't have time to get to it at the moment. Thanks, Eric [1] http://www.boost.org/doc/libs/1_54_0/libs/parameter/doc/html/reference.html#...
participants (2)
-
Eric Niebler
-
Gabriel Redner