Swarm-NG  1.1
random.hpp
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2009-2010 by Eric Ford & the Swarm-NG Development Team *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 3 of the License. *
7  * *
8  * This program is distributed in the hope that it will be useful, *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11  * GNU General Public License for more details. *
12  * *
13  * You should have received a copy of the GNU General Public License *
14  * along with this program; if not, write to the *
15  * Free Software Foundation, Inc., *
16  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17  ************************************************************************/
18 
25 #ifndef H_SWARM_RANDOM
26 
27 #include <cstdlib>
28 #include <cmath>
29 
30 namespace swarm {
31 
32 double draw_uniform01();
33 double draw_std_normal();
34 double draw_value_from_config(const swarm::config& cfg, const std::string& name, const int bod, double min, double max);
35 
36 double draw_uniform01()
37 { return static_cast<double>(rand())/static_cast<double>(RAND_MAX); }
38 
39 double draw_std_normal()
40 {
41  // Box–Muller algorithm
42  double rn1 = draw_uniform01();
43  double rn2 = draw_uniform01();
44  return sqrt(-2.*std::log(rn1))*cos(2.*M_PI*(rn2));
45 }
46 
48 double draw_value_from_config(const swarm::config& cfg, const std::string& name, const int bod, double min, double max)
49 {
50  double val;
51  std::stringstream s;
52 
53  s.str(""); s << name << '_' << bod << "_min";
54  if(cfg.count(s.str()))
55  {
56  double min_val = atof(cfg.at(s.str()).c_str());
57  min = std::max(min,min_val);
58  }
59  s.str(""); s << name << '_' << bod << "_max";
60  if(cfg.count(s.str()))
61  {
62  double max_val = atof(cfg.at(s.str()).c_str());
63  max = std::min(max,max_val);
64  }
65 
66  s.str(""); s << name << '_' << bod;
67  if(cfg.count(s.str()))
68  {
69  val = atof(cfg.at(s.str()).c_str());
70  if((val<min)||(val>max))
71  {
72  std::cerr << "# " << s.str() << ": " << val << " ["<< min << ", " << max << "]\n";
73  }
74  assert(val>=min);
75  assert(val<=max);
76 
77  s.str(""); s << name << '_' << bod << "_sigma";
78  if(cfg.count(s.str()))
79  {
80  double mean = val;
81  double sigma = atof(cfg.at(s.str()).c_str());
82  if(sigma)
83  {
84  do {
85  val = mean + sigma*draw_std_normal();
86  } while((val<min)||(val>max));
87  }
88  else
89  { val = mean; }
90  }
91  }
92  else
93  {
94  val = min + (max-min)*draw_uniform01();
95  }
96  return val;
97 }
98 
100 double draw_value_from_config(const swarm::config& cfg, const std::string& name, double min, double max)
101 {
102  double val;
103  std::stringstream s;
104 
105  s.str(""); s << name << "_min";
106  if(cfg.count(s.str()))
107  {
108  double min_val = atof(cfg.at(s.str()).c_str());
109  min = std::max(min,min_val);
110  }
111  s.str(""); s << name << "_max";
112  if(cfg.count(s.str()))
113  {
114  double max_val = atof(cfg.at(s.str()).c_str());
115  max = std::min(max,max_val);
116  }
117 
118  s.str(""); s << name;
119  if(cfg.count(s.str()))
120  {
121  val = atof(cfg.at(s.str()).c_str());
122  if((val<min)||(val>max))
123  {
124  std::cerr << "# " << s.str() << ": " << val << " ["<< min << ", " << max << "]\n";
125  }
126  assert(val>=min);
127  assert(val<=max);
128 
129  s.str(""); s << name << "_sigma";
130  if(cfg.count(s.str()))
131  {
132  double mean = val;
133  double sigma = atof(cfg.at(s.str()).c_str());
134  if(sigma)
135  {
136  do {
137  val = mean + sigma*draw_std_normal();
138  } while((val<min)||(val>max));
139  }
140  else
141  { val = mean; }
142  }
143  }
144  else
145  {
146  val = min + (max-min)*draw_uniform01();
147  }
148  return val;
149 }
150 
151 
152 }
153 
154 #endif