X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Frandom%2Funiform_on_sphere.hpp;h=04071dc2b681259d6a918e62ad973a2bc435f29f;hp=c5c7280696fb7c319e032a670b6100f906b74eff;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/random/uniform_on_sphere.hpp b/boost/random/uniform_on_sphere.hpp index c5c7280..04071dc 100644 --- a/boost/random/uniform_on_sphere.hpp +++ b/boost/random/uniform_on_sphere.hpp @@ -1,13 +1,14 @@ /* boost random/uniform_on_sphere.hpp header file * * Copyright Jens Maurer 2000-2001 + * Copyright Steven Watanabe 2011 * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org for most recent version including documentation. * - * $Id: uniform_on_sphere.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $ + * $Id: uniform_on_sphere.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ * * Revision history * 2001-02-18 moved to individual header files @@ -19,10 +20,13 @@ #include #include // std::transform #include // std::bind2nd, std::divides +#include #include +#include #include namespace boost { +namespace random { /** * Instantiations of class template uniform_on_sphere model a @@ -30,72 +34,196 @@ namespace boost { * numbers uniformly distributed on the unit sphere of arbitrary * dimension @c dim. The @c Cont template parameter must be a STL-like * container type with begin and end operations returning non-const - * ForwardIterators of type @c Cont::iterator. Each invocation of the - * @c UniformRandomNumberGenerator shall result in a floating-point - * value in the range [0,1). + * ForwardIterators of type @c Cont::iterator. */ template > class uniform_on_sphere { public: - typedef RealType input_type; - typedef Cont result_type; - - /** - * Constructs a @c uniform_on_sphere distribution. - * @c dim is the dimension of the sphere. - */ - explicit uniform_on_sphere(int dim = 2) : _container(dim), _dim(dim) { } - - // compiler-generated copy ctor and assignment operator are fine - - void reset() { _normal.reset(); } - - template - const result_type & operator()(Engine& eng) - { - RealType sqsum = 0; - for(typename Cont::iterator it = _container.begin(); - it != _container.end(); - ++it) { - RealType val = _normal(eng); - *it = val; - sqsum += val * val; + typedef RealType input_type; + typedef Cont result_type; + + class param_type + { + public: + + typedef uniform_on_sphere distribution_type; + + /** + * Constructs the parameters of a uniform_on_sphere + * distribution, given the dimension of the sphere. + */ + explicit param_type(int dim_arg = 2) : _dim(dim_arg) + { + BOOST_ASSERT(_dim >= 0); + } + + /** Returns the dimension of the sphere. */ + int dim() const { return _dim; } + + /** Writes the parameters to a @c std::ostream. */ + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm) + { + os << parm._dim; + return os; + } + + /** Reads the parameters from a @c std::istream. */ + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm) + { + is >> parm._dim; + return is; + } + + /** Returns true if the two sets of parameters are equal. */ + BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs) + { return lhs._dim == rhs._dim; } + + /** Returns true if the two sets of parameters are different. */ + BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type) + + private: + int _dim; + }; + + /** + * Constructs a @c uniform_on_sphere distribution. + * @c dim is the dimension of the sphere. + * + * Requires: dim >= 0 + */ + explicit uniform_on_sphere(int dim_arg = 2) + : _container(dim_arg), _dim(dim_arg) { } + + /** + * Constructs a @c uniform_on_sphere distribution from its parameters. + */ + explicit uniform_on_sphere(const param_type& parm) + : _container(parm.dim()), _dim(parm.dim()) { } + + // compiler-generated copy ctor and assignment operator are fine + + /** Returns the dimension of the sphere. */ + int dim() const { return _dim; } + + /** Returns the parameters of the distribution. */ + param_type param() const { return param_type(_dim); } + /** Sets the parameters of the distribution. */ + void param(const param_type& parm) + { + _dim = parm.dim(); + _container.resize(_dim); + } + + /** + * Returns the smallest value that the distribution can produce. + * Note that this is required to approximate the standard library's + * requirements. The behavior is defined according to lexicographical + * comparison so that for a container type of std::vector, + * dist.min() <= x <= dist.max() where x is any value produced + * by the distribution. + */ + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const + { + result_type result(_dim); + if(_dim != 0) { + result.front() = RealType(-1.0); + } + return result; + } + /** + * Returns the largest value that the distribution can produce. + * Note that this is required to approximate the standard library's + * requirements. The behavior is defined according to lexicographical + * comparison so that for a container type of std::vector, + * dist.min() <= x <= dist.max() where x is any value produced + * by the distribution. + */ + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const + { + result_type result(_dim); + if(_dim != 0) { + result.front() = RealType(1.0); + } + return result; + } + + /** + * Effects: Subsequent uses of the distribution do not depend + * on values produced by any engine prior to invoking reset. + */ + void reset() { _normal.reset(); } + + /** + * Returns a point uniformly distributed over the surface of + * a sphere of dimension dim(). + */ + template + const result_type & operator()(Engine& eng) + { + RealType sqsum = 0; + for(typename Cont::iterator it = _container.begin(); + it != _container.end(); + ++it) { + RealType val = _normal(eng); + *it = val; + sqsum += val * val; + } + using std::sqrt; + // for all i: result[i] /= sqrt(sqsum) + std::transform(_container.begin(), _container.end(), _container.begin(), + std::bind2nd(std::divides(), sqrt(sqsum))); + return _container; + } + + /** + * Returns a point uniformly distributed over the surface of + * a sphere of dimension param.dim(). + */ + template + result_type operator()(Engine& eng, const param_type& parm) const + { + return uniform_on_sphere(parm)(eng); } -#ifndef BOOST_NO_STDC_NAMESPACE - using std::sqrt; -#endif - // for all i: result[i] /= sqrt(sqsum) - std::transform(_container.begin(), _container.end(), _container.begin(), - std::bind2nd(std::divides(), sqrt(sqsum))); - return _container; - } - -#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const uniform_on_sphere& sd) - { - os << sd._dim; - return os; - } - - template - friend std::basic_istream& - operator>>(std::basic_istream& is, uniform_on_sphere& sd) - { - is >> std::ws >> sd._dim; - sd._container.resize(sd._dim); - return is; - } -#endif + + /** Writes the distribution to a @c std::ostream. */ + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_on_sphere, sd) + { + os << sd._dim; + return os; + } + + /** Reads the distribution from a @c std::istream. */ + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_on_sphere, sd) + { + is >> sd._dim; + sd._container.resize(sd._dim); + return is; + } + + /** + * Returns true if the two distributions will produce identical + * sequences of values, given equal generators. + */ + BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_on_sphere, lhs, rhs) + { return lhs._dim == rhs._dim && lhs._normal == rhs._normal; } + + /** + * Returns true if the two distributions may produce different + * sequences of values, given equal generators. + */ + BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_on_sphere) private: - normal_distribution _normal; - result_type _container; - int _dim; + normal_distribution _normal; + result_type _container; + int _dim; }; +} // namespace random + +using random::uniform_on_sphere; + } // namespace boost #endif // BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP