NEST  2.6.0,not_revisioned_source_dir@0
clipped_randomdev.h
Go to the documentation of this file.
1 /*
2  * clipped_randomdev.h
3  *
4  * This file is part of NEST.
5  *
6  * Copyright (C) 2004 The NEST Initiative
7  *
8  * NEST is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * NEST is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef CLIPPED_RANDOMDEV_H
24 #define CLIPPED_RANDOMDEV_H
25 
26 #include <cmath>
27 #include <limits>
28 #include "randomgen.h"
29 #include "randomdev.h"
30 #include "dictutils.h"
31 #include "sliexceptions.h"
32 #include "config.h"
33 
34 namespace librandom {
35 
36 /*BeginDocumentation
37 Name: rdevdict::*_clipped - clipped random deviate generators.
38 
39 Description: Generate random numbers from an underlying distribution,
40 but restricted to a certain interval.
41 
42 For continuous distributions,
43 
44  low < random < high
45 
46 will hold true, i.e., numbers are restricted to the open interval (low, high).
47 If the distribution itself is restricted to, e.g., positiv numbers, setting
48 low < 0 will still only return positive numbers. Clipping only excludes numbers
49 outside (low, high).
50 
51 For discrete distribtions, numbers are limited to {low, low+1, ... high}, i.e.,
52 in this case min and max are included.
53 
54 Numbers are clipped by re-drawing any number outside (low, high), until
55 a number in (log, high) is drawn. The actual distribution of random
56 numbers drawn will be a distorted version of the underlying
57 distribution.
58 
59 Parameters:
60 /low lower bound (default: -inf)
61 /high upper bound (default: +inf)
62 
63 Note:
64 - Clipped generators can be very inefficient if there is little probability
65 mass in (low, high).
66 - For continuous distributions, the probability of actually drawing
67 min or max is approximately 2^-62 ~ 2e-19, i.e., negligible. Therefore,
68 one can only clip to open intervals.
69 - There are also *_clipped_to_boundary versions of the generators. These
70 return the respective boundary value if a value outside the interval is
71 drawn. These versions are mainly provided to allow reproduction of
72 publications that used this strategy.
73 
74 SeeAlso: CreateRDV, rdevdict
75 Author: Hans Ekkehard Plesser
76 */
77 
84  template <typename BaseRDV>
85  class ClippedRedrawContinuousRandomDev : public BaseRDV
86  {
87 
88  public:
89 
90  // accept only lockPTRs for initialization,
91  // otherwise creation of a lock ptr would
92  // occur as side effect---might be unhealthy
95 
96 #if not defined(HAVE_XLC_ICE_ON_USING)
97  using RandomDev::operator();
98 #endif
99 
100  double operator()(void);
101  double operator()(RngPtr) const; // threaded
102 
104  void set_status(const DictionaryDatum&);
105 
107  void get_status(DictionaryDatum&) const;
108 
109  private:
110  double min_;
111  double max_;
112 
113  };
114 
115  template <typename BaseRDV>
117  BaseRDV(r),
118  min_(-std::numeric_limits<double>::infinity()),
119  max_(std::numeric_limits<double>::infinity())
120  {
121  assert(not BaseRDV::has_ldev()); // ensure underlying distribution is continuous
122  }
123 
124  template <typename BaseRDV>
126  BaseRDV(),
127  min_(-std::numeric_limits<double>::infinity()),
128  max_(std::numeric_limits<double>::infinity())
129  {
130  assert(not BaseRDV::has_ldev()); // ensure underlying distribution is continuous
131  }
132 
133  template <typename BaseRDV>
135  {
136  BaseRDV::set_status(d);
137 
138  double new_min = min_;
139  double new_max = max_;
140 
141  updateValue<double>(d, "low", new_min);
142  updateValue<double>(d, "high", new_max);
143 
144  if ( new_min >= new_max )
145  throw BadParameterValue("Clipped RDVs require low < high.");
146 
147  min_ = new_min;
148  max_ = new_max;
149  }
150 
151  template <typename BaseRDV>
153  {
154  BaseRDV::get_status(d);
155 
156  def<double>(d, "low", min_);
157  def<double>(d, "high", max_);
158  }
159 
160  template <typename BaseRDV>
161  inline
163  {
164  return (*this)(this->rng_);
165  }
166 
167  template <typename BaseRDV>
168  inline
170  {
171  double value;
172 
173  do {
174  value = BaseRDV::operator()(r);
175  } while ( value <= min_ || max_ <= value );
176 
177  return value;
178  }
179 
180  // ----------------------------------------------------------
181 
188  template <typename BaseRDV>
189  class ClippedRedrawDiscreteRandomDev : public BaseRDV
190  {
191 
192  public:
193 
194  // accept only lockPTRs for initialization,
195  // otherwise creation of a lock ptr would
196  // occur as side effect---might be unhealthy
198  ClippedRedrawDiscreteRandomDev(); // threaded
199 
200  // Forwarding operators are explicitly defined here,
201  // to ensure that they forward to the clipped generator.
202  // Null-pointer checking is done in the underlying generator.
203 
204 #if not defined(HAVE_XLC_ICE_ON_USING)
205  using RandomDev::operator();
206  using RandomDev::ldev;
207 #endif
208 
209  double operator()(void);
210  double operator()(RngPtr) const; // threaded
211 
212  long ldev(void);
213  long ldev(RngPtr) const;
214 
215 
217  void set_status(const DictionaryDatum&);
218 
220  void get_status(DictionaryDatum&) const;
221 
222  private:
223  long min_;
224  long max_;
225  };
226 
227  template <typename BaseRDV>
229  BaseRDV(r),
230  min_(std::numeric_limits<long>::min()),
231  max_(std::numeric_limits<long>::max())
232  {
233  assert(BaseRDV::has_ldev()); // ensure underlying distribution is discrete
234  }
235 
236  template <typename BaseRDV>
238  BaseRDV(),
239  min_(std::numeric_limits<long>::min()),
240  max_(std::numeric_limits<long>::max())
241  {
242  assert(BaseRDV::has_ldev()); // ensure underlying distribution is discrete
243  }
244 
245  template <typename BaseRDV>
247  {
248  BaseRDV::set_status(d);
249 
250  long new_min = min_;
251  long new_max = max_;
252 
253  updateValue<long>(d, "low", new_min);
254  updateValue<long>(d, "high", new_max);
255 
256  if ( new_min >= new_max )
257  throw BadParameterValue("Clipped RDVs require low < high.");
258 
259  min_ = new_min;
260  max_ = new_max;
261  }
262 
263  template <typename BaseRDV>
265  {
266  BaseRDV::get_status(d);
267 
268  def<long>(d, "low", min_);
269  def<long>(d, "high", max_);
270  }
271 
272  template <typename BaseRDV>
273  inline
275  {
276  return (*this)(this->rng_);
277  }
278 
279  template <typename BaseRDV>
280  inline
282  {
283  double value;
284 
285  do {
286  value = BaseRDV::operator()(r);
287  } while ( value < min_ || max_ < value );
288 
289  return value;
290  }
291 
292  template <typename BaseRDV>
293  inline
295  {
297  }
298 
299  template <typename BaseRDV>
300  inline
302  {
303  long value;
304 
305  do {
306  value = BaseRDV::ldev(r);
307  } while ( value < min_ || max_ < value );
308 
309  return value;
310  }
311 
312  // -------------------------------------------------------------------
313 
324  template <typename BaseRDV>
326  {
327 
328  public:
329 
330  // accept only lockPTRs for initialization,
331  // otherwise creation of a lock ptr would
332  // occur as side effect---might be unhealthy
335 
336 #if not defined(HAVE_XLC_ICE_ON_USING)
337  using RandomDev::operator();
338 #endif
339 
340  double operator()(void);
341  double operator()(RngPtr) const; // threaded
342 
344  void set_status(const DictionaryDatum&);
345 
347  void get_status(DictionaryDatum&) const;
348 
349  private:
350  double min_;
351  double max_;
352 
353  };
354 
355  template <typename BaseRDV>
357  BaseRDV(r),
358  min_(-std::numeric_limits<double>::infinity()),
359  max_(std::numeric_limits<double>::infinity())
360  {
361  assert(not BaseRDV::has_ldev()); // ensure underlying distribution is continuous
362  }
363 
364  template <typename BaseRDV>
366  BaseRDV(),
367  min_(-std::numeric_limits<double>::infinity()),
368  max_(std::numeric_limits<double>::infinity())
369  {
370  assert(not BaseRDV::has_ldev()); // ensure underlying distribution is continuous
371  }
372 
373  template <typename BaseRDV>
375  {
376  BaseRDV::set_status(d);
377 
378  double new_min = min_;
379  double new_max = max_;
380 
381  updateValue<double>(d, "low", new_min);
382  updateValue<double>(d, "high", new_max);
383 
384  if ( new_min >= new_max )
385  throw BadParameterValue("Clipped RDVs require low < high.");
386 
387  min_ = new_min;
388  max_ = new_max;
389  }
390 
391  template <typename BaseRDV>
393  {
394  BaseRDV::get_status(d);
395 
396  def<double>(d, "low", min_);
397  def<double>(d, "high", max_);
398  }
399 
400  template <typename BaseRDV>
401  inline
403  {
404  return (*this)(this->rng_);
405  }
406 
407  template <typename BaseRDV>
408  inline
410  {
411  const double value = BaseRDV::operator()(r);
412  if ( value < min_ )
413  return min_;
414  if ( value > max_ )
415  return max_;
416  return value;
417  }
418 
419  // ----------------------------------------------------------
420 
431  template <typename BaseRDV>
432  class ClippedToBoundaryDiscreteRandomDev : public BaseRDV
433  {
434 
435  public:
436 
437  // accept only lockPTRs for initialization,
438  // otherwise creation of a lock ptr would
439  // occur as side effect---might be unhealthy
442 
443  // Forwarding operators are explicitly defined here,
444  // to ensure that they forward to the clipped generator.
445  // Null-pointer checking is done in the underlying generator.
446 
447 #if not defined(HAVE_XLC_ICE_ON_USING)
448  using RandomDev::operator();
449  using RandomDev::ldev;
450 #endif
451 
452  double operator()(void);
453  double operator()(RngPtr) const; // threaded
454 
455  long ldev(void);
456  long ldev(RngPtr) const;
457 
458 
460  void set_status(const DictionaryDatum&);
461 
463  void get_status(DictionaryDatum&) const;
464 
465  private:
466  long min_;
467  long max_;
468  };
469 
470  template <typename BaseRDV>
472  BaseRDV(r),
473  min_(std::numeric_limits<long>::min()),
474  max_(std::numeric_limits<long>::max())
475  {
476  assert(BaseRDV::has_ldev()); // ensure underlying distribution is discrete
477  }
478 
479  template <typename BaseRDV>
481  BaseRDV(),
482  min_(std::numeric_limits<long>::min()),
483  max_(std::numeric_limits<long>::max())
484  {
485  assert(BaseRDV::has_ldev()); // ensure underlying distribution is discrete
486  }
487 
488  template <typename BaseRDV>
490  {
491  BaseRDV::set_status(d);
492 
493  long new_min = min_;
494  long new_max = max_;
495 
496  updateValue<long>(d, "low", new_min);
497  updateValue<long>(d, "high", new_max);
498 
499  if ( new_min >= new_max )
500  throw BadParameterValue("Clipped RDVs require low < high.");
501 
502  min_ = new_min;
503  max_ = new_max;
504  }
505 
506  template <typename BaseRDV>
508  {
509  BaseRDV::get_status(d);
510 
511  def<long>(d, "low", min_);
512  def<long>(d, "high", max_);
513  }
514 
515  template <typename BaseRDV>
516  inline
518  {
519  return (*this)(this->rng_);
520  }
521 
522  template <typename BaseRDV>
523  inline
525  {
526  const double value = BaseRDV::operator()(r);
527  if ( value < min_ )
528  return min_;
529  if ( value > max_ )
530  return max_;
531  return value;
532  }
533 
534  template <typename BaseRDV>
535  inline
537  {
539  }
540 
541  template <typename BaseRDV>
542  inline
544  {
545  const long value = BaseRDV::ldev(r);
546  if ( value < min_ )
547  return min_;
548  if ( value > max_ )
549  return max_;
550  return value;
551  }
552 
553 } // namespace librandom
554 
555 # endif
556 
557 
558 
559 
560 
561 
562 
563 
564 
565 
566 
567 
568 
569 
570 
571 
572 
573 
Exception to be thrown if a parameter value is not acceptable.
Definition: sliexceptions.h:220
void set_status(const DictionaryDatum &)
set distribution parameters from SLI dict
Definition: clipped_randomdev.h:134
void get_status(DictionaryDatum &) const
get distribution parameters from SLI dict
Definition: clipped_randomdev.h:264
const Name d("d")
Specific to Izhikevich 2003.
Definition: nest_names.h:83
void set_status(const DictionaryDatum &)
set distribution parameters from SLI dict
Definition: clipped_randomdev.h:489
ClippedToBoundaryDiscreteRandomDev()
Definition: clipped_randomdev.h:480
Wrapper template turning any discrete RDV into a clipped RDV.
Definition: clipped_randomdev.h:189
void set_status(const DictionaryDatum &)
set distribution parameters from SLI dict
Definition: clipped_randomdev.h:246
ClippedToBoundaryContinuousRandomDev()
Definition: clipped_randomdev.h:365
double operator()(void)
Definition: clipped_randomdev.h:274
double max_
upper bound
Definition: clipped_randomdev.h:351
long max_
largest value
Definition: clipped_randomdev.h:467
double operator()(void)
Definition: clipped_randomdev.h:402
ClippedRedrawContinuousRandomDev()
Definition: clipped_randomdev.h:125
void get_status(DictionaryDatum &) const
get distribution parameters from SLI dict
Definition: clipped_randomdev.h:507
Wrapper template turning any continuous RDV into a clipped-to-boundary RDV.
Definition: clipped_randomdev.h:325
double max_
upper bound
Definition: clipped_randomdev.h:111
assert(pNet!=0)
const Name std("std")
Miscellaneous parameters.
Definition: nest_names.h:265
void get_status(DictionaryDatum &) const
get distribution parameters from SLI dict
Definition: clipped_randomdev.h:152
double operator()(void)
Definition: clipped_randomdev.h:517
ClippedRedrawDiscreteRandomDev()
Definition: clipped_randomdev.h:237
Wrapper template turning any discrete RDV into a clipped-to-boundary RDV.
Definition: clipped_randomdev.h:432
double operator()(void)
Definition: clipped_randomdev.h:162
long min_
smallest value
Definition: clipped_randomdev.h:466
void get_status(DictionaryDatum &) const
get distribution parameters from SLI dict
Definition: clipped_randomdev.h:392
long min_
smallest value
Definition: clipped_randomdev.h:223
const Name min("min")
Definition: topology_names.h:74
Wrapper template turning any continuous RDV into a clipped RDV.
Definition: clipped_randomdev.h:85
const Name max("max")
Definition: topology_names.h:75
long ldev(void)
Definition: clipped_randomdev.h:294
virtual long ldev(void)
integer valued functions for discrete distributions
Definition: randomdev.h:206
long max_
largest value
Definition: clipped_randomdev.h:224
long ldev(void)
Definition: clipped_randomdev.h:536
double min_
lower bound
Definition: clipped_randomdev.h:350
double min_
lower bound
Definition: clipped_randomdev.h:110
void set_status(const DictionaryDatum &)
set distribution parameters from SLI dict
Definition: clipped_randomdev.h:374