LibRan  0.1
Pseudo-random number distribution generator
LRgaus.c
Go to the documentation of this file.
1 
51 /*
52  * Copyright 2019 R.K. Owen, Ph.D.
53  * License see lgpl.md (Gnu Lesser General Public License)
54  */
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 #include <math.h>
60 #include "libran.h"
61 
62 /* double */
72 double LRd_gausbm_RAN(LR_obj *o) {
73  double one = 1.0, ntwo = -2.0, twopi = 2.0 * M_PI;
74  double c, z1, z2;
75 
76  if (isnan(o->x.d)) {
77  /* generate new pair - 1-U avoids possible overflow */
78  c = sqrt(ntwo * log(one - o->ud(o)));
79  z2 = twopi * o->ud(o);
80  z1 = c * sin(z2);
81  o->x.d = z2 = c * cos(z2);
82  return o->m.d + o->s.d * z1;
83  } else {
84  /* return saved variate */
85  c = o->x.d;
86  o->x.d = NAN;
87  return o->m.d + o->s.d * c;
88  }
89 }
90 
91 /* double */
102  double one = 1.0, two = 2.0;
103  double s, z1, z2;
104 
105  if (isnan(o->x.d)) {
106  do {
107  z1 = two*o->ud(o) - one;
108  z2 = two*o->ud(o) - one;
109  s = z1*z1 + z2*z2;
110  } while (s > one);
111  s = sqrt(-two*log(s)/s);
112  o->x.d = z2 * s;
113  return o->m.d + o->s.d * z1 * s;
114  } else {
115  /* return saved variate */
116  s = o->x.d;
117  o->x.d = NAN;
118  return o->m.d + o->s.d * s;
119  }
120 }
121 
129 double LRd_gaus_PDF(LR_obj *o, double x) {
130  double one = 1.0, half = .5,
131  is = one / o->s.d,
132  cc = half * M_2_SQRTPI * M_SQRT1_2 * is,
133  xm = (x - o->m.d) * is,
134  xx = xm * xm;
135 
136  return cc * exp(-half * xx);
137 }
138 
146 double LRd_gaus_CDF(LR_obj *o, double x) {
147  double one = 1.0,
148  half = 0.5,
149  is = M_SQRT1_2 / o->s.d,
150  xm = (x - o->m.d) * is;
151 
152  return half * (one + erf(xm));
153 }
154 
155 /* float */
166  float one = 1.0, ntwo = -2.0, twopi = 2.0 * M_PI;
167  float c, z1, z2;
168 
169  if (isnan(o->x.f)) {
170  /* generate new pair - 1-U avoids possible overflow */
171  c = sqrt(ntwo * log(one - o->uf(o)));
172  z2 = twopi * o->uf(o);
173  z1 = c * sinf(z2);
174  o->x.f = z2 = c * cosf(z2);
175  return o->m.f + o->s.f * z1;
176  } else {
177  /* return saved variate */
178  c = o->x.f;
179  o->x.f = NAN;
180  return o->m.f + o->s.f * c;
181  }
182 }
183 
194  float one = 1.0, two = 2.0;
195  float s, z1, z2;
196 
197  if (isnan(o->x.f)) {
198  do {
199  z1 = two*o->ud(o) - one;
200  z2 = two*o->ud(o) - one;
201  s = z1*z1 + z2*z2;
202  } while (s > one);
203  s = sqrtf(-two*logf(s)/s);
204  o->x.f = z2 * s;
205  return o->m.f + o->s.f * z1 * s;
206  } else {
207  /* return saved variate */
208  s = o->x.f;
209  o->x.f = NAN;
210  return o->m.f + o->s.f * s;
211  }
212 }
213 
221 float LRf_gaus_PDF(LR_obj *o, float x) {
222  float one = 1.0, half = .5,
223  is = one / o->s.f,
224  cc = half * M_2_SQRTPI * M_SQRT1_2 * is,
225  xm = (x - o->m.f) * is,
226  xx = xm * xm;
227 
228  return cc * expf(-half * xx);
229 }
230 
238 float LRf_gaus_CDF(LR_obj *o, float x) {
239  float one = 1.0,
240  half = 0.5,
241  is = M_SQRT1_2 / o->s.f,
242  xm = (x - o->m.f) * is;
243 
244  return half * (one + erff(xm));
245 }
246 
247 #ifdef __cplusplus
248 }
249 #endif
float LRf_gaus_CDF(LR_obj *o, float x)
LRf_gaus_CDF(LR_obj *o, float x) - float Gaussian/Normal cumulative distribution function.
Definition: LRgaus.c:238
LR_val x
Definition: libran.h:142
double LRd_gausmar_RAN(LR_obj *o)
LRd_gausmar_RAN(LR_obj *o) - double random Gaussian/Normal distribution using the Marsaglia method wi...
Definition: LRgaus.c:101
float LRf_gaus_PDF(LR_obj *o, float x)
LRf_gaus_PDF(LR_obj *o, float x) - float Gaussian/Normal probablity distribution function.
Definition: LRgaus.c:221
double(* ud)(LR_obj *)
Definition: libran.h:154
double LRd_gaus_CDF(LR_obj *o, double x)
LRd_gaus_CDF(LR_obj *o, double x) - double Gaussian/Normal cumulative distribution function...
Definition: LRgaus.c:146
double LRd_gausbm_RAN(LR_obj *o)
LRd_gausbm_RAN(LR_obj *o) - double random Gaussian/Normal distribution using the Box-Muller method...
Definition: LRgaus.c:72
LR_val s
Definition: libran.h:141
float LRf_gausbm_RAN(LR_obj *o)
LRf_gausbm_RAN(LR_obj *o) - float random Gaussian/Normal distribution using the Box-Muller method...
Definition: LRgaus.c:165
float LRf_gausmar_RAN(LR_obj *o)
LRf_gausmar_RAN(LR_obj *o) - float random Gaussian/Normal distribution using the Marsaglia method wit...
Definition: LRgaus.c:193
double d
Definition: libran.h:87
float f
Definition: libran.h:86
float(* uf)(LR_obj *)
Definition: libran.h:153
The LibRan common header file.
double LRd_gaus_PDF(LR_obj *o, double x)
LRd_gaus_PDF(LR_obj *o, double x) - double Gaussian/Normal probablity distribution function...
Definition: LRgaus.c:129
the fundamental LibRan random variate distribution object
Definition: libran.h:134
LR_val m
Definition: libran.h:140