random.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
40 
41 // -----------------------------------------------------------------------------
42 #include <cmath>
43 #include <ctime>
44 #include <iomanip>
45 #include <iostream>
46 
47 #include "random.hpp"
48 
49 using namespace std;
50 
51 namespace gnsstk
52 {
53  // -----------------------------------------------------------------------------
54  /* Generate random numbers uniformly distributed from 0.0 to 1.0. Mbig and
55  Mseed are large but arbitrary, but Mbig > Mseed. The 55 is not arbitrary. */
56  double Rand(long seed)
57  {
58 #define Mbig 1000000000.
59 #define Mseed 161803398.
60 #define imod(x, y) ((x) - ((x) / (y)) * (y))
61  static short iff = 0, inext, inextp;
62  static double Ma[55];
63  double mj, mk;
64  short i, ii, k;
65  if (!iff)
66  {
67  if (seed < 0)
68  {
69  seed = -seed;
70  }
71  mj = Mseed - seed;
72  mj = fmod(mj, Mbig);
73  Ma[54] = mj;
74  mk = 1.0;
75  for (i = 0; i < 55; i++)
76  {
77  ii = imod(21 * (i + 1), 55);
78  Ma[ii] = mk;
79  mk = mj - mk;
80  if (mk < 0.0)
81  {
82  mk += Mbig;
83  }
84  mj = Ma[ii];
85  }
86  for (k = 0; k < 4; k++)
87  {
88  for (i = 0; i < 55; i++)
89  {
90  Ma[i] -= Ma[imod(i + 30, 55)];
91  if (Ma[i] < 0.0)
92  {
93  Ma[i] += Mbig;
94  }
95  }
96  }
97  inext = -1;
98  inextp = 30;
99  iff = 1;
100  }
101  inext++;
102  if (inext == 55)
103  {
104  inext = 0;
105  }
106  inextp++;
107  if (inextp == 55)
108  {
109  inextp = 0;
110  }
111  mj = Ma[inext] - Ma[inextp];
112  if (mj < 0.0)
113  {
114  mj += Mbig;
115  }
116  Ma[inext] = mj;
117  return mj / Mbig;
118 #undef Mbig
119 #undef Mseed
120 #undef imod
121  }
122 
123  // -----------------------------------------------------------------------------
124  /* Generate normally distributed random numbers, zero mean and
125  sqrt of variance sigma. Uses Box-Muller and Rand() above. */
126  double RandNorm(double sigma)
127  {
128 #ifdef RAND_NORM_SAVE
129  static short iset = 0;
130  static double saved;
131  double r, v1, v2, fact;
132  if (!iset)
133  {
134  do
135  {
136  v1 = 2.0 * Rand(1) - 1.0;
137  v2 = 2.0 * Rand(1) - 1.0;
138  r = v1 * v1 + v2 * v2;
139  } while (r >= 1.0 || r == 0.0);
140  fact = sigma * sqrt(-2. * log(r) / r);
141  saved = v1 * fact;
142  iset = 1;
143  return v2 * fact;
144  }
145  iset = 0;
146  return saved;
147 #else
148  double r, v1, v2, fact;
149  do
150  {
151  v1 = 2.0 * Rand(1) - 1.0;
152  v2 = 2.0 * Rand(1) - 1.0;
153  r = v1 * v1 + v2 * v2;
154  } while (r >= 1.0 || r == 0.0);
155  fact = sigma * sqrt(-2. * log(r) / r);
156  return v2 * fact;
157 #endif
158  }
159 
160  // -----------------------------------------------------------------------------
161  /* Return random integers between low and hi. If you want a different seed,
162  call Rand(seed) before you call this. */
163  int ARand(int low, int hi)
164  {
165  double r = Rand(), d = (double)(hi - low);
166  if (d < 0.0)
167  {
168  d = -d;
169  }
170  d = r * d;
171  int i = (int)(d + 0.5) + low;
172  return i;
173  }
174 
175  /* -----------------------------------------------------------------------------
176  Return random doubles between low and hi. If you want a different seed,
177  call Rand(seed) before you call this. */
178  double ARand(double low, double hi)
179  {
180  double r = Rand(), d = (hi - low);
181  if (d < 0.0)
182  {
183  d = -d;
184  }
185  d = r * d;
186  return (low + d);
187  }
188 
189  /* -----------------------------------------------------------------------------
190  Generate a random walk sequence, given sqrt variance sigma, time step dt
191  and previous point xlast. */
192  double RandomWalk(double dt, double sigma, double xlast)
193  {
194  return xlast + RandNorm(sigma) * dt;
195  }
196 
197  /* -----------------------------------------------------------------------------
198  Generate an exponentially correlated random sequence, given time step dt,
199  sqrt variance sigma, time constant T and previous point xlast. */
200  double RandExpCor(double dt, double sigma, double T, double xlast)
201  {
202  return exp(-dt / T) * xlast + RandNorm(sigma);
203  }
204 
205  /* -----------------------------------------------------------------------------
206  integer mod function. assume arguments positive.
207  static int imod(int x, int y)
208  {
209  if(x == 0 || y == 0) return 0;
210  return (x-(x/y)*y);
211  } */
212 
213 } // namespace gnsstk
gnsstk::ARand
double ARand(double low, double hi)
Definition: random.cpp:178
random.hpp
gnsstk::Rand
double Rand(long seed)
Generate random numbers uniformly distributed from 0 to 1.
Definition: random.cpp:56
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
Mbig
#define Mbig
Mseed
#define Mseed
gnsstk::RandomWalk
double RandomWalk(double dt, double sigma, double xlast)
Definition: random.cpp:192
log
#define log
Definition: DiscCorr.cpp:625
imod
#define imod(x, y)
gnsstk::RandExpCor
double RandExpCor(double dt, double sigma, double T, double xlast)
Definition: random.cpp:200
std
Definition: Angle.hpp:142
gnsstk::RandNorm
double RandNorm(double sigma)
Definition: random.cpp:126


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:40