Need help with boost parameter library, multiple deduced defaults.

I am currently working on a mathematical library for the simulation of stochastic processes. I am a researcher in Statistics, hence my limited skills in c++ programming :) Let me introduce the framework briefly. The part of the library I am interested with is very similar to the boost random library. I need to implement it because I need to extend some functionality and I am not confident in modifying the boost random library to extend its behaviour (too complicated for me :P). We have (lazy syntax): PseudoRng<TImpl> //A particular pseduo random number generator QuasiRng<TImpl> // A particualr quasi random number generator GaussianDistribution // A particular statistical distribution Sampler<GaussianDistribution> // The interface (for other components of the library) of a sampler of random numbers distributed as a GaussianDistribution Then I consider: template < class TGenerator, class TDistribution, typename TDistribution::variate_t (TDistribution::*algorithm)( const TGenerator& ) const = &TDistribution::sample_default > class VariateSampler : public Sampler<TDistribution> { ... } Here TGenerator can be PseudoRng<TImpl> or QuasiRng<TImpl>, TDistribution can be GaussianDistribution and the pointer to member function algorithm select the algorithm used to sample. While constructing VariateSampler I would like to: 1) Automatically deduce the type of TGenerator and TDistribution 2) Automatically select a different default for algorithm, for particular TDistribution (like GaussianDistribution,PoissonDistribution....) depending on the fact that TGenerator is of type PseudoRng<TImpl> or QuasiRng<Timpl>. So for every TDistribution two different defaults for algorithm. I think that boost parameter should solve my problem, but I am quite confused about how to implement it, expecially the second point. Could you help me with the basic steps I need to consider? Thank you very much in advance. Regards StephQ

on Sun Nov 18 2007, StephQ <pelux-AT-ngi.it> wrote:
I am currently working on a mathematical library for the simulation of stochastic processes. I am a researcher in Statistics, hence my limited skills in c++ programming :)
Let me introduce the framework briefly. The part of the library I am interested with is very similar to the boost random library. I need to implement it because I need to extend some functionality and I am not confident in modifying the boost random library to extend its behaviour (too complicated for me :P).
We have (lazy syntax):
PseudoRng<TImpl> //A particular pseduo random number generator QuasiRng<TImpl> // A particualr quasi random number generator GaussianDistribution // A particular statistical distribution
Sampler<GaussianDistribution> // The interface (for other components of the library) of a sampler of random numbers distributed as a GaussianDistribution
Then I consider:
template < class TGenerator, class TDistribution, typename TDistribution::variate_t (TDistribution::*algorithm)( const TGenerator& ) const = &TDistribution::sample_default >
class VariateSampler : public Sampler<TDistribution> { ... }
Here TGenerator can be PseudoRng<TImpl> or QuasiRng<TImpl>, TDistribution can be GaussianDistribution and the pointer to member function algorithm select the algorithm used to sample.
While constructing VariateSampler I would like to: 1) Automatically deduce the type of TGenerator and TDistribution
From what information and by what rules?
2) Automatically select a different default for algorithm, for particular TDistribution (like GaussianDistribution,PoissonDistribution....) depending on the fact that TGenerator is of type PseudoRng<TImpl> or QuasiRng<Timpl>. So for every TDistribution two different defaults for algorithm.
I think that boost parameter should solve my problem, but I am quite confused about how to implement it, expecially the second point. Could you help me with the basic steps I need to consider?
Because Boost.Parameter is geared towards template type parameters, it might be easier to approach this problem by starting with a different interface for VariateSampler. Let's say: template < class TGenerator, class TDistribution, class Algorithm
struct _VariateSampler : Sampler<TDistribution> { }; where Algorithm is required to be a function (object) callable with TDistribution and TGenerator arguments. You can easily map it onto the default you've specified using: template <class TDistribution, class TGenerator> struct default_algorithm { typename TDistribution::variate_t operator()(TDistribution const& d, TGenerator const& g) const { return d->sample_default(g); } }; Default selection might be done through a simple metafunction: template <class T> struct is_PseudoRng; template <class U> struct is_PseudoRng<PseudoRng<U> > : boost::mpl::true_ {}; ... mpl::if_<is_PseudoRng<some_generator>, default1, default2>::type ... HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams <dave <at> boost-consulting.com> writes:
Because Boost.Parameter is geared towards template type parameters, it might be easier to approach this problem by starting with a different interface for VariateSampler. Let's say:
template < class TGenerator, class TDistribution, class Algorithm
struct _VariateSampler : Sampler<TDistribution> {
};
where Algorithm is required to be a function (object) callable with TDistribution and TGenerator arguments. You can easily map it onto the default you've specified using:
template <class TDistribution, class TGenerator> struct default_algorithm { typename TDistribution::variate_t operator()(TDistribution const& d, TGenerator const& g) const { return d->sample_default(g); } };
Default selection might be done through a simple metafunction:
template <class T> struct is_PseudoRng;
template <class U> struct is_PseudoRng<PseudoRng<U> > : boost::mpl::true_ {};
... mpl::if_<is_PseudoRng<some_generator>, default1, default2>::type ...
HTH,
Thank you very much for your help. However, I am a little confused about some details: I suppose you meant using mpl::if_<...> to select one of the two following funcion objects this way: typedef mpl::if_<is_PseudoRng<TGenerator>, default_pseudo<TDistribution,TGenerator>, default_quasi<TGenerator,TGenerator> >::type myAlgorithm; ... return myAlgorithm( ...,... ); template <class TDistribution, class TGenerator> struct default_pseudo; and template <class TDistribution, class TGenerator> struct default_quasi; which calls respectively the member functions sample_pseudo and sample_quasi (and these obviously different depending on the TDistribution they belong to). But where should this selection happens? Inside the class _VariateSampler, or in the implementation of the boost::parameter technique for _VariateSampler? And in any case, how can I override this selection, in case the user has invoked the _VariateSampler specifying a particular function object Algorithm ? Finally, would it be possible to extend this selection to multiple different types mapping to multiple defaults? I suppose you should use is_same_ or something like that, but I do not have much experience with mpl. Could you suggest me some introductory references on this particular topic (algorithms selection depending on complicated rules depending on types). Thank you again for your time. Best Regards StephQ
participants (2)
-
David Abrahams
-
StephQ