
Thijs van den Berg wrote:
I was playing around with implementing the (simple) Laplace distribution to get some feeling with "math/distributions" code and concepts.
A lot of non-member functions for statistical distributions (like pdf, cdf) make a local copy of the distribution internal variables, and validate those local variables. An alternative would be to move the checking to member function of the distribution.
instead of
// CREATE LOCAL COPY OF DISTRIBUTION VARIABLES RealType sd = dist.standard_deviation(); RealType mean = dist.mean(); ... // VALIDATE THOSE LOCAL VARIABLES RealType result; if(false == detail::check_scale(function, sd, &result, Policy())) { return result; } if(false == detail::check_location(function, mean, &result, Policy())) { return result; }
do it like this
// VALIDATE DISTRIBUTION RealType result; if(false == dist.check()) { return result; } // CREATE LOCAL COPY OF VALID DISTRIBUTION VARIABLES RealType sd = dist.standard_deviation(); RealType mean = dist.mean();
I see two benefits: * the code is more compact this way and repeated code in most of the non member functions is centralized (into the distribution)
Nod.
* for multivariate distributions, the checking can be expensive (a covariance matrix of a multivariate normal needs to be semi positive definite). We could do the checking only once in the constructor & cache the result.
Nod.
What do you think? We might turn "having valid parameters" into a property of *all* distribution. As an alternative, we might add a non member function bool valid<distributionType... but that wouldn't allow for caching validation in e.g. a constructor
Sounds fine to me.
In general (but in the scope of the constructs used in math/distributions & its non member functions): what are the arguments for placing code in either member or non-member functions ?
For implementation details, use whatever works best, for interfaces non-members that operate uniformly on a range of types seem to work best. John.