PetaVision  Alpha
GaussianRandom.cpp
1 /*
2  * GaussianRandom.cpp
3  *
4  * Created on: Aug 23, 2013
5  * Author: pschultz
6  */
7 
8 #include "GaussianRandom.hpp"
9 
10 namespace PV {
11 
12 GaussianRandom::GaussianRandom(int count) {
13  initialize_base();
14  initializeFromCount((unsigned int)count);
15 }
16 
17 GaussianRandom::GaussianRandom(const PVLayerLoc *locptr, bool isExtended) {
18  initialize_base();
19  initializeFromLoc(locptr, isExtended);
20 }
21 
22 GaussianRandom::GaussianRandom() { initialize_base(); }
23 
24 int GaussianRandom::initialize_base() { return PV_SUCCESS; }
25 
26 int GaussianRandom::initializeGaussian() {
27  int status = PV_SUCCESS;
28  heldValues.assign(rngArray.size(), {false, 0.0});
29  return status;
30 }
31 
32 int GaussianRandom::initializeFromCount(unsigned int count) {
33  int status = Random::initializeFromCount(count);
34  if (status == PV_SUCCESS) {
35  status = initializeGaussian();
36  }
37  return status;
38 }
39 
40 int GaussianRandom::initializeFromLoc(const PVLayerLoc *locptr, bool isExtended) {
41  int status = Random::initializeFromLoc(locptr, isExtended);
42  if (status == PV_SUCCESS) {
43  status = initializeGaussian();
44  }
45  return status;
46 }
47 
48 float GaussianRandom::gaussianDist(int localIndex) {
49  float x1, x2, y;
50  struct box_muller_data bmdata = heldValues[localIndex];
51  if (bmdata.hasHeldValue) {
52  y = bmdata.heldValue;
53  }
54  else {
55  float w;
56  do {
57  x1 = 2.0f * uniformRandom(localIndex) - 1.0f;
58  x2 = 2.0f * uniformRandom(localIndex) - 1.0f;
59  w = x1 * x1 + x2 * x2;
60  } while (w >= 1.0f);
61 
62  w = sqrtf((-2.0f * logf(w)) / w);
63  y = x1 * w;
64  bmdata.heldValue = x2 * w;
65  }
66  bmdata.hasHeldValue = !bmdata.hasHeldValue;
67 
68  return y;
69 }
70 
71 GaussianRandom::~GaussianRandom() {}
72 
73 } /* namespace PV */