Visual Computing Library
Loading...
Searching...
No Matches
random.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_MATH_RANDOM_H
24#define VCL_MATH_RANDOM_H
25
26#include "base.h"
27
28#include <vclib/concepts/space/point.h>
29
30#include <random>
31
32namespace vcl {
33
57inline int poissonRatioOfUniformsInteger(double L, std::mt19937& gen)
58{
59 // constants
60 const double SHAT1 = 2.943035529371538573; // 8/e
61 const double SHAT2 = 0.8989161620588987408; // 3-sqrt(12/e)
62
63 double u; // uniform random
64 double lf; // ln(f(x))
65 double x; // real sample
66 int k; // integer sample
67
68 double pois_a = L + 0.5; // hat center
69 int mode = (int) L; // mode
70 double pois_g = std::log(L);
71 double pois_f0 = mode * pois_g - lnOfFactorial(mode); // value at mode
72 double pois_h = std::sqrt(SHAT1 * (L + 0.5)) + SHAT2; // hat width
73 double pois_bound = (int) (pois_a + 6.0 * pois_h); // safety-bound
74
75 std::uniform_real_distribution<double> unif(0, 1);
76
77 while (1) {
78 u = unif(gen);
79 if (u == 0)
80 continue; // avoid division by 0
81 x = pois_a + pois_h * (unif(gen) - 0.5) / u;
83 continue; // reject if outside valid range
84 k = (int) (x);
86 if (lf >= u * (4.0 - u) - 3.0)
87 break; // quick acceptance
88 if (u * (u - lf) > 1.0)
89 continue; // quick rejection
90 if (2.0 * log(u) <= lf)
91 break; // final acceptance
92 }
93 return k;
94}
95
96inline int poissonRatioOfUniformsInteger(double L)
97{
98 static std::random_device rd;
99 static std::mt19937 gen(rd());
100 return poissonRatioOfUniformsInteger(L, gen);
101}
102
118inline int poissonRandomNumber(double lambda, std::mt19937& gen)
119{
120 if (lambda > 50)
122
123 std::uniform_real_distribution<double> unif(0, 1);
124
125 double L = exp(-lambda);
126 int k = 0;
127 double p = 1.0;
128 do {
129 k = k + 1;
130 p = p * unif(gen);
131 } while (p > L);
132
133 return k - 1;
134}
135
136inline int poissonRandomNumber(double lambda)
137{
138 static std::random_device rd;
139 static std::mt19937 gen(rd());
140 return poissonRatioOfUniformsInteger(lambda, gen);
141}
142
153template<Point3Concept PointType>
155{
156 using ScalarType = PointType::ScalarType;
157
158 PointType interp;
159 std::uniform_real_distribution<ScalarType> unif(0, 1);
160
161 interp[1] = unif(gen);
162 interp[2] = unif(gen);
163 if (interp[1] + interp[2] > 1.0) {
164 interp[1] = 1.0 - interp[1];
165 interp[2] = 1.0 - interp[2];
166 }
167
168 interp[0] = 1.0 - (interp[1] + interp[2]);
169 return interp;
170}
171
172template<Point3Concept PointType>
173PointType randomTriangleBarycentricCoordinate()
174{
175 static std::random_device rd;
176 static std::mt19937 gen(rd());
177 return randomTriangleBarycentricCoordinate<PointType>(gen);
178}
179
180template<typename ScalarType>
181std::vector<ScalarType> randomPolygonBarycentricCoordinate(
182 uint polySize,
183 std::mt19937& gen)
184{
185 std::vector<ScalarType> barCoord(polySize);
186 ScalarType sum = 0;
187
188 std::uniform_real_distribution<ScalarType> unif(0, 100);
189
190 for (uint i = 0; i < polySize; i++) {
191 barCoord[i] = unif(gen);
192 sum += barCoord[i];
193 }
194 for (uint i = 0; i < polySize; i++) {
195 barCoord[i] /= sum;
196 }
197 return barCoord;
198}
199
200template<typename ScalarType>
201std::vector<ScalarType> randomPolygonBarycentricCoordinate(uint polySize)
202{
203 static std::random_device rd;
204 static std::mt19937 gen(rd());
205 return randomPolygonBarycentricCoordinate<ScalarType>(polySize, gen);
206}
207
208} // namespace vcl
209
210#endif // VCL_MATH_RANDOM_H
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
PointType randomTriangleBarycentricCoordinate(std::mt19937 &gen)
Generate the barycentric coords of a random point over a triangle, with a uniform distribution over t...
Definition random.h:154
int poissonRandomNumber(double lambda, std::mt19937 &gen)
algorithm poisson random number (Knuth): init: Let L ← e^−λ, k ← 0 and p ← 1. do: k ← k + 1....
Definition random.h:118
int poissonRatioOfUniformsInteger(double L, std::mt19937 &gen)
This subfunction generates a integer with the poisson distribution using the ratio-of-uniforms reject...
Definition random.h:57
double lnOfFactorial(int n)
Computes and caches the result of the natural logarithm of n!
Definition base.h:114