annotate DEPENDENCIES/generic/include/boost/random/uniform_on_sphere.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /* boost random/uniform_on_sphere.hpp header file
Chris@16 2 *
Chris@16 3 * Copyright Jens Maurer 2000-2001
Chris@16 4 * Copyright Steven Watanabe 2011
Chris@16 5 * Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 * accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 *
Chris@16 9 * See http://www.boost.org for most recent version including documentation.
Chris@16 10 *
Chris@101 11 * $Id$
Chris@16 12 *
Chris@16 13 * Revision history
Chris@16 14 * 2001-02-18 moved to individual header files
Chris@16 15 */
Chris@16 16
Chris@16 17 #ifndef BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP
Chris@16 18 #define BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP
Chris@16 19
Chris@16 20 #include <vector>
Chris@16 21 #include <algorithm> // std::transform
Chris@16 22 #include <functional> // std::bind2nd, std::divides
Chris@16 23 #include <boost/assert.hpp>
Chris@16 24 #include <boost/random/detail/config.hpp>
Chris@16 25 #include <boost/random/detail/operators.hpp>
Chris@16 26 #include <boost/random/normal_distribution.hpp>
Chris@16 27
Chris@16 28 namespace boost {
Chris@16 29 namespace random {
Chris@16 30
Chris@16 31 /**
Chris@16 32 * Instantiations of class template uniform_on_sphere model a
Chris@16 33 * \random_distribution. Such a distribution produces random
Chris@16 34 * numbers uniformly distributed on the unit sphere of arbitrary
Chris@16 35 * dimension @c dim. The @c Cont template parameter must be a STL-like
Chris@16 36 * container type with begin and end operations returning non-const
Chris@16 37 * ForwardIterators of type @c Cont::iterator.
Chris@16 38 */
Chris@16 39 template<class RealType = double, class Cont = std::vector<RealType> >
Chris@16 40 class uniform_on_sphere
Chris@16 41 {
Chris@16 42 public:
Chris@16 43 typedef RealType input_type;
Chris@16 44 typedef Cont result_type;
Chris@16 45
Chris@16 46 class param_type
Chris@16 47 {
Chris@16 48 public:
Chris@16 49
Chris@16 50 typedef uniform_on_sphere distribution_type;
Chris@16 51
Chris@16 52 /**
Chris@16 53 * Constructs the parameters of a uniform_on_sphere
Chris@16 54 * distribution, given the dimension of the sphere.
Chris@16 55 */
Chris@16 56 explicit param_type(int dim_arg = 2) : _dim(dim_arg)
Chris@16 57 {
Chris@16 58 BOOST_ASSERT(_dim >= 0);
Chris@16 59 }
Chris@16 60
Chris@16 61 /** Returns the dimension of the sphere. */
Chris@16 62 int dim() const { return _dim; }
Chris@16 63
Chris@16 64 /** Writes the parameters to a @c std::ostream. */
Chris@16 65 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
Chris@16 66 {
Chris@16 67 os << parm._dim;
Chris@16 68 return os;
Chris@16 69 }
Chris@16 70
Chris@16 71 /** Reads the parameters from a @c std::istream. */
Chris@16 72 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
Chris@16 73 {
Chris@16 74 is >> parm._dim;
Chris@16 75 return is;
Chris@16 76 }
Chris@16 77
Chris@16 78 /** Returns true if the two sets of parameters are equal. */
Chris@16 79 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
Chris@16 80 { return lhs._dim == rhs._dim; }
Chris@16 81
Chris@16 82 /** Returns true if the two sets of parameters are different. */
Chris@16 83 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
Chris@16 84
Chris@16 85 private:
Chris@16 86 int _dim;
Chris@16 87 };
Chris@16 88
Chris@16 89 /**
Chris@16 90 * Constructs a @c uniform_on_sphere distribution.
Chris@16 91 * @c dim is the dimension of the sphere.
Chris@16 92 *
Chris@16 93 * Requires: dim >= 0
Chris@16 94 */
Chris@16 95 explicit uniform_on_sphere(int dim_arg = 2)
Chris@16 96 : _container(dim_arg), _dim(dim_arg) { }
Chris@16 97
Chris@16 98 /**
Chris@16 99 * Constructs a @c uniform_on_sphere distribution from its parameters.
Chris@16 100 */
Chris@16 101 explicit uniform_on_sphere(const param_type& parm)
Chris@16 102 : _container(parm.dim()), _dim(parm.dim()) { }
Chris@16 103
Chris@16 104 // compiler-generated copy ctor and assignment operator are fine
Chris@16 105
Chris@16 106 /** Returns the dimension of the sphere. */
Chris@16 107 int dim() const { return _dim; }
Chris@16 108
Chris@16 109 /** Returns the parameters of the distribution. */
Chris@16 110 param_type param() const { return param_type(_dim); }
Chris@16 111 /** Sets the parameters of the distribution. */
Chris@16 112 void param(const param_type& parm)
Chris@16 113 {
Chris@16 114 _dim = parm.dim();
Chris@16 115 _container.resize(_dim);
Chris@16 116 }
Chris@16 117
Chris@16 118 /**
Chris@16 119 * Returns the smallest value that the distribution can produce.
Chris@16 120 * Note that this is required to approximate the standard library's
Chris@16 121 * requirements. The behavior is defined according to lexicographical
Chris@16 122 * comparison so that for a container type of std::vector,
Chris@16 123 * dist.min() <= x <= dist.max() where x is any value produced
Chris@16 124 * by the distribution.
Chris@16 125 */
Chris@16 126 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
Chris@16 127 {
Chris@16 128 result_type result(_dim);
Chris@16 129 if(_dim != 0) {
Chris@16 130 result.front() = RealType(-1.0);
Chris@16 131 }
Chris@16 132 return result;
Chris@16 133 }
Chris@16 134 /**
Chris@16 135 * Returns the largest value that the distribution can produce.
Chris@16 136 * Note that this is required to approximate the standard library's
Chris@16 137 * requirements. The behavior is defined according to lexicographical
Chris@16 138 * comparison so that for a container type of std::vector,
Chris@16 139 * dist.min() <= x <= dist.max() where x is any value produced
Chris@16 140 * by the distribution.
Chris@16 141 */
Chris@16 142 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
Chris@16 143 {
Chris@16 144 result_type result(_dim);
Chris@16 145 if(_dim != 0) {
Chris@16 146 result.front() = RealType(1.0);
Chris@16 147 }
Chris@16 148 return result;
Chris@16 149 }
Chris@16 150
Chris@16 151 /**
Chris@16 152 * Effects: Subsequent uses of the distribution do not depend
Chris@16 153 * on values produced by any engine prior to invoking reset.
Chris@16 154 */
Chris@101 155 void reset() {}
Chris@16 156
Chris@16 157 /**
Chris@16 158 * Returns a point uniformly distributed over the surface of
Chris@16 159 * a sphere of dimension dim().
Chris@16 160 */
Chris@16 161 template<class Engine>
Chris@16 162 const result_type & operator()(Engine& eng)
Chris@16 163 {
Chris@101 164 using std::sqrt;
Chris@101 165 switch(_dim)
Chris@101 166 {
Chris@101 167 case 0: break;
Chris@101 168 case 1:
Chris@101 169 {
Chris@101 170 if(uniform_01<RealType>()(eng) < 0.5) {
Chris@101 171 *_container.begin() = -1;
Chris@101 172 } else {
Chris@101 173 *_container.begin() = 1;
Chris@101 174 }
Chris@101 175 }
Chris@101 176 case 2:
Chris@101 177 {
Chris@101 178 uniform_01<RealType> uniform;
Chris@101 179 RealType sqsum;
Chris@101 180 RealType x, y;
Chris@101 181 do {
Chris@101 182 x = uniform(eng) * 2 - 1;
Chris@101 183 y = uniform(eng) * 2 - 1;
Chris@101 184 sqsum = x*x + y*y;
Chris@101 185 } while(sqsum == 0 || sqsum > 1);
Chris@101 186 RealType mult = 1/sqrt(sqsum);
Chris@101 187 typename Cont::iterator iter = _container.begin();
Chris@101 188 *iter = x * mult;
Chris@101 189 iter++;
Chris@101 190 *iter = y * mult;
Chris@101 191 break;
Chris@101 192 }
Chris@101 193 case 3:
Chris@101 194 {
Chris@101 195 uniform_01<RealType> uniform;
Chris@101 196 RealType sqsum;
Chris@101 197 RealType x, y;
Chris@101 198 do {
Chris@101 199 x = uniform(eng) * 2 - 1;
Chris@101 200 y = uniform(eng) * 2 - 1;
Chris@101 201 sqsum = x*x + y*y;
Chris@101 202 } while(sqsum > 1);
Chris@101 203 RealType mult = 2 * sqrt(1 - sqsum);
Chris@101 204 typename Cont::iterator iter = _container.begin();
Chris@101 205 *iter = x * mult;
Chris@101 206 ++iter;
Chris@101 207 *iter = y * mult;
Chris@101 208 ++iter;
Chris@101 209 *iter = 2 * sqsum - 1;
Chris@101 210 break;
Chris@101 211 }
Chris@101 212 default:
Chris@101 213 {
Chris@101 214 detail::unit_normal_distribution<RealType> normal;
Chris@101 215 RealType sqsum;
Chris@101 216 do {
Chris@101 217 sqsum = 0;
Chris@101 218 for(typename Cont::iterator it = _container.begin();
Chris@101 219 it != _container.end();
Chris@101 220 ++it) {
Chris@101 221 RealType val = normal(eng);
Chris@101 222 *it = val;
Chris@101 223 sqsum += val * val;
Chris@101 224 }
Chris@101 225 } while(sqsum == 0);
Chris@101 226 // for all i: result[i] /= sqrt(sqsum)
Chris@101 227 std::transform(_container.begin(), _container.end(), _container.begin(),
Chris@101 228 std::bind2nd(std::multiplies<RealType>(), 1/sqrt(sqsum)));
Chris@101 229 }
Chris@16 230 }
Chris@16 231 return _container;
Chris@16 232 }
Chris@16 233
Chris@16 234 /**
Chris@16 235 * Returns a point uniformly distributed over the surface of
Chris@16 236 * a sphere of dimension param.dim().
Chris@16 237 */
Chris@16 238 template<class Engine>
Chris@16 239 result_type operator()(Engine& eng, const param_type& parm) const
Chris@16 240 {
Chris@16 241 return uniform_on_sphere(parm)(eng);
Chris@16 242 }
Chris@16 243
Chris@16 244 /** Writes the distribution to a @c std::ostream. */
Chris@16 245 BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_on_sphere, sd)
Chris@16 246 {
Chris@16 247 os << sd._dim;
Chris@16 248 return os;
Chris@16 249 }
Chris@16 250
Chris@16 251 /** Reads the distribution from a @c std::istream. */
Chris@16 252 BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_on_sphere, sd)
Chris@16 253 {
Chris@16 254 is >> sd._dim;
Chris@16 255 sd._container.resize(sd._dim);
Chris@16 256 return is;
Chris@16 257 }
Chris@16 258
Chris@16 259 /**
Chris@16 260 * Returns true if the two distributions will produce identical
Chris@16 261 * sequences of values, given equal generators.
Chris@16 262 */
Chris@16 263 BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_on_sphere, lhs, rhs)
Chris@101 264 { return lhs._dim == rhs._dim; }
Chris@16 265
Chris@16 266 /**
Chris@16 267 * Returns true if the two distributions may produce different
Chris@16 268 * sequences of values, given equal generators.
Chris@16 269 */
Chris@16 270 BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_on_sphere)
Chris@16 271
Chris@16 272 private:
Chris@16 273 result_type _container;
Chris@16 274 int _dim;
Chris@16 275 };
Chris@16 276
Chris@16 277 } // namespace random
Chris@16 278
Chris@16 279 using random::uniform_on_sphere;
Chris@16 280
Chris@16 281 } // namespace boost
Chris@16 282
Chris@16 283 #endif // BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP