00001 #ifndef _RANDOM_HPP
00002 #define _RANDOM_HPP
00003
00004 #include <iostream>
00005 #include <assert.h>
00006 #include <gsl/gsl_rng.h>
00007 #include <gsl/gsl_randist.h>
00008 #include "geometry.hpp"
00009
00010 namespace Arak {
00011 namespace Util {
00012
00019 class Random {
00020
00021 protected:
00022
00026 gsl_rng* r;
00027
00028 public:
00029
00037 Random() {
00038 const gsl_rng_type * T;
00039 gsl_rng_env_setup();
00040 T = gsl_rng_default;
00041 r = gsl_rng_alloc (T);
00042 }
00043
00049 Random(const Random& other) : r(gsl_rng_clone(other.r)) { }
00050
00054 ~Random() {
00055 gsl_rng_free(r);
00056 }
00057
00061 double uniform() {
00062 return gsl_rng_uniform(r);
00063 }
00064
00068 double uniform(double a, double b) {
00069 assert(a < b);
00070 double x = gsl_rng_uniform(r);
00071 return x * a + (1 - x) * b;
00072 }
00073
00077 unsigned long int uniform(unsigned long int n) {
00078 return gsl_rng_uniform_int(r, n);
00079 }
00080
00085 bool bernoulli(double p = 0.5) {
00086 return (uniform() < p);
00087 }
00088
00093 unsigned int binomial(double p, unsigned int n) {
00094 return gsl_ran_binomial(r, p, n);
00095 }
00096
00104 inline Geometry::Point uniform(const Geometry::Point& source,
00105 const Geometry::Point& target) {
00106 Geometry::Vector a(CGAL::ORIGIN, source);
00107 Geometry::Vector b(CGAL::ORIGIN, target);
00108 Geometry::Kernel::FT x(uniform());
00109 Geometry::Vector u = (a * x) + b - (b * x);
00110 Geometry::Point p(u.x(), u.y());
00111 #ifdef SANITY_CHECK
00112 assert(CGAL::collinear_are_ordered_along_line(s.source(), p, s.target()));
00113 #endif
00114 return p;
00115 }
00116
00123 inline Geometry::Point uniform(const Geometry::Segment& s) {
00124 return uniform(s.source(), s.target());
00125 }
00126
00135 inline Geometry::Point uniform(const Geometry::Triangle& t) {
00136
00137 double r1 = uniform();
00138 double r2 = uniform();
00139
00140 double sqrt_r1 = sqrt(r1);
00141 double alpha = 1.0 - sqrt_r1;
00142 double beta = (1.0 - r2) * sqrt_r1;
00143 double gamma = r2 * sqrt_r1;
00144
00145 return CGAL::ORIGIN
00146 + (Geometry::Vector(CGAL::ORIGIN, t[0]) * alpha)
00147 + (Geometry::Vector(CGAL::ORIGIN, t[1]) * beta)
00148 + (Geometry::Vector(CGAL::ORIGIN, t[2]) * gamma);
00149 }
00150
00155 void write(std::ostream& out) const {
00156 out << gsl_rng_name(r)
00157 << " (with seed " << gsl_rng_default_seed << ")";
00158 }
00159 };
00160
00165 extern Random default_random;
00166
00167 }
00168 }
00169
00170 inline std::ostream& operator<<(std::ostream& out,
00171 const Arak::Util::Random& r) {
00172 r.write(out);
00173 return out;
00174 }
00175
00176 #endif