Sign in Join
Wiki copytemporary

Generating Random Numbers/pl: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-<figure>
2-<img src="fpc_source_logo.png" title="fpc_source_logo.png" />
3-<figcaption>fpc_source_logo.png</figcaption>
4-</figure>
1+![](/wiki-images/8/84/Fpc_source_logo.png)
52
63**Liczby losowe** są ważnymi zasobami do zastosowań naukowych, edukacji, tworzenia gier i wizualizacji. Odgrywają kluczową rolę w symulacji numerycznej.
74
85Liczby losowe generowane przez algorytm to liczby pseudolosowe. Należą do (dużego) zbioru powtarzających się liczb, których kolejność jest niemożliwa lub przynajmniej trudna do przewidzenia. W przeciwieństwie do Delphi, który używa liniowego generatora kongruencjalnego (patrz [[Delphi compatible LCG Random|LCG Random kompatybilny z Delphi]]), Free Pascal używa algorytmu MersenneTwister dla swojej standardowej funkcji losowej [[doc:rtl/system/random.html|random]] zdefiniowanej w RTL. Przed pierwszym użyciem generator liczb losowych FPC musi zostać zainicjowany pojedynczym wywołaniem funkcji [[doc:rtl/system/randomize.html|randomize]], która ustawia ziarno generatora. Najlepiej jest to zrobić w fazie uruchamiania programu.
96
107Alternatywnie w systemach opartych na systemach Unix i Linux dostępne są urządzenia wirtualne [[Dev random|/dev/random]] i `/dev/urandom`. Generują liczby (pseudo) losowe na podstawie sprzętu.
118
129Trzecią możliwością jest użycie liczb losowych ze źródeł zewnętrznych, albo ze specjalistycznych urządzeń sprzętowych, albo ze źródeł publicznych, np. na podstawie danych dotyczących rozpadu promieniotwórczego.
1310
1411## Jednorodny rozkład
1512
1613Ciągły rozkład jednorodny (nazywany również rozkładem prostokątnym) reprezentuje rodzinę symetrycznych rozkładów prawdopodobieństwa. Tutaj dla każdego członka rodziny wszystkie przedziały tej samej długości na nośniku rozkładu są jednakowo prawdopodobne.
1714
1815Standardowa funkcja [[RTL]] [[doc:rtl/system/random.html|random]] generuje liczby losowe, które mają jednolity rozkład. Jeśli zostanie wywoływana bez parametru zwróci pseudolosową liczbę zmiennoprzecinkową w przedziale \[0, 1), tj. 0 \<= wynik \< 1. Jeśli random jest wywoływana z argumentem longint L, dostarcza losową liczbę zmiennoprzecinkową w przedziale \[0, L).
1916
2017Kolejny zestaw generatorów liczb losowych o równomiernym rozkładzie jest przedstawiony w [[Marsaglia&|generatorach liczb pseudolosowych Marsaglii]].
2118
2219Jednolicie rozmieszczone liczby losowe nie są przydatne w żadnej aplikacji. Do tworzenia liczb losowych z innych rozkładów potrzebne są specjalne algorytmy:
2320
2421## Normal (Gaussian) Distribution
2522
2623One of the more common algorithms to produce normally distributed random numbers from uniformly distributed random numbers is the [Box-Müller approach](http://en.wikipedia.org/wiki/Box–Muller_transform). The following function calculates Gaussian-distributed random numbers:
2724
2825``` pascal
2926 function rnorm (mean, sd: real): real;
3027 {Calculates Gaussian random numbers according to the Box-Müller approach}
3128 var
3229 u1, u2: real;
3330 begin
3431 u1 := random;
3532 u2 := random;
3633 rnorm := mean * abs(1 + sqrt(-2 * (ln(u1))) * cos(2 * pi * u2) * sd);
3734 end;
3835```
3936
4037The same algorithm is used by the [[doc:rtl/math/randg.html|randg]] randg function from the [[RTL]] [[doc:rtl/math/index.html|math]] unit:
4138
4239``` pascal
4340function randg(mean,stddev: float): float;
4441```
4542
4643## Exponential Distribution
4744
4845An exponential distribution occurs frequently in real-world problems. A classical example is the distribution of waiting times between independent Poisson-random events, e.g. the radioactive decay of nuclei \[Press et al. 1989\].
4946
5047The following function delivers a single real random number out of an exponential distribution. *Rate* is the inverse of the mean, and the constant *RESOLUTION* determines the granularity of generated random numbers.
5148
5249``` pascal
5350function randomExp(a, rate: real): real;
5451const
5552 RESOLUTION = 1000;
5653var
5754 unif: real;
5855begin
5956 if rate = 0 then
6057 randomExp := NaN
6158 else
6259 begin
6360 repeat
6461 unif := random(RESOLUTION) / RESOLUTION;
6562 until unif <> 0;
6663 randomExp := a - rate * ln(unif);
6764 end;
6865end;
6966```
7067
7168## Gamma Distribution
7269
7370The gamma distribution is a two-parameter family of continuous random distributions. It is a generalization of both the exponential distribution and the Erlang distribution. Possible applications of the gamma distribution include modelling and simulation of waiting lines, or queues, and actuarial science.
7471
7572The following function delivers a single real random number out of a gamma distribution. The shape of the distribution is defined by the parameters *a*, *b* and *c*. The function makes use of the function **randomExp** as defined above.
7673
7774``` pascal
7875function randomGamma(a, b, c: real): real;
7976const
8077 RESOLUTION = 1000;
8178 T = 4.5;
8279 D = 1 + ln(T);
8380var
8481 unif: real;
8582 A2, B2, C2, Q, p, y: real;
8683 p1, p2, v, w, z: real;
8784 found: boolean;
8885begin
8986 A2 := 1 / sqrt(2 * c - 1);
9087 B2 := c - ln(4);
9188 Q := c + 1 / A2;
9289 C2 := 1 + c / exp(1);
9390 found := False;
9491 if c < 1 then
9592 begin
9693 repeat
9794 repeat
9895 unif := random(RESOLUTION) / RESOLUTION;
9996 until unif > 0;
10097 p := C2 * unif;
10198 if p > 1 then
10299 begin
103100 repeat
104101 unif := random(RESOLUTION) / RESOLUTION;
105102 until unif > 0;
106103 y := -ln((C2 - p) / c);
107104 if unif <= power(y, c - 1) then
108105 begin
109106 randomGamma := a + b * y;
110107 found := True;
111108 end;
112109 end
113110 else
114111 begin
115112 y := power(p, 1 / c);
116113 if unif <= exp(-y) then
117114 begin
118115 randomGamma := a + b * y;
119116 found := True;
120117 end;
121118 end;
122119 until found;
123120 end
124121 else if c = 1 then
125122 { Gamma distribution becomes exponential distribution, if c = 1 }
126123 begin
127124 randomGamma := randomExp(a, b);
128125 end
129126 else
130127 begin
131128 repeat
132129 repeat
133130 p1 := random(RESOLUTION) / RESOLUTION;
134131 until p1 > 0;
135132 repeat
136133 p2 := random(RESOLUTION) / RESOLUTION;
137134 until p2 > 0;
138135 v := A2 * ln(p1 / (1 - p1));
139136 y := c * exp(v);
140137 z := p1 * p1 * p2;
141138 w := B2 + Q * v - y;
142139 if (w + D - T * z >= 0) or (w >= ln(z)) then
143140 begin
144141 randomGamma := a + b * y;
145142 found := True;
146143 end;
147144 until found;
148145 end;
149146end;
150147```
151148
152149## Erlang Distribution
153150
154151The Erlang distribution is a two parameter family of continuous probability distributions. It is a generalization of the exponential distribution and a special case of the gamma distribution, where *c* is an integer. The Erlang distribution has been first described by Agner Krarup Erlang in order to model the time interval between telephone calls. It is used for queuing theory and for simulating waiting lines.
155152
156153``` pascal
157154 function randomErlang(mean: real; k: integer): real;
158155 const
159156 RESOLUTION = 1000;
160157 var
161158 i: integer;
162159 unif, prod: real;
163160 begin
164161 if (mean <= 0) or (k < 1) then
165162 randomErlang := NaN
166163 else
167164 begin
168165 prod := 1;
169166 for i := 1 to k do
170167 begin
171168 repeat
172169 unif := random(RESOLUTION) / RESOLUTION;
173170 until unif <> 0;
174171 prod := prod * unif;
175172 end;
176173 randomErlang := -mean * ln(prod);
177174 end;
178175 end;
179176```
180177
181178## Poisson Distribution
182179
183180The Poisson distribution applies to integer values. It represents the probability of *k* successes, when the probability of a success in each trial is small and the rate of occurrence (the mean value) is constant.
184181
185182``` pascal
186183function randomPoisson(mean: integer): integer;
187184{ Generator for Poisson distribution (Donald Knuth's algorithm) }
188185const
189186 RESOLUTION = 1000;
190187var
191188 k: integer;
192189 b, l: real;
193190begin
194191 assert(mean > 0, 'mean < 1');
195192 k := 0;
196193 b := 1;
197194 l := exp(-mean);
198195 while b > l do
199196 begin
200197 k := k + 1;
201198 b := b * random(RESOLUTION) / RESOLUTION;
202199 end;
203200 randomPoisson := k - 1;
204201end;
205202```
206203
207204## t Distribution
208205
209206The t distribution (also referred to a Student's t distribution, since it was published by William Sealy Gosset in 1908 under the pseudonym *Student*) is a continuous probability distribution. Its shape is defined by one parameter, the degrees of freedom (*df*). In statistics, many estimators are t distributed. Therefore, Student's t-distribution plays a major role in a number of widely used statistical analyses, including Student's t-test for assessing the statistical significance of the difference between two sample means, the construction of confidence intervals for the difference between two population means, and in linear regression analysis. The t-distribution also arises in Bayesian analysis of data from a normal family.
210207
211208The following algorithm depends on the [[RTL]] function [[doc:rtl/system/random.html|random]] and on the **randomChisq** function
212209
213210``` pascal
214211function randomT(df: integer): real;
215212{ Generator for Student's t distribution }
216213begin
217214 if df < 1 then
218215 randomT := NaN
219216 else begin
220217 randomT := randg(0, 1) / sqrt(randomChisq(df) / df);
221218 end;
222219end;
223220```
224221
225222## Chi Squared Distribution
226223
227224The chi squared distribution is a continuous distribution of random numbers with *df* degrees of freedom. It is the distribution of a sum of the squares of *df* independent standard normal random variables. The chi squared distribution has numerous applications in inferential statistics, e.g. in estimating variances and for chi-squared tests. It is a special gamma distribution with *c* = *df*/ 2 and *b* = 2. Therefore the following function depends on the function **randomGamma**.
228225
229226``` pascal
230227function randomChisq(df: integer): real;
231228begin
232229 if df < 1 then
233230 randomChisq := NaN
234231 else
235232 randomChisq := randomGamma(0, 2, 0.5 * df);
236233end;
237234```
238235
239236## F Distribution
240237
241238The F distribution, also referred to as Fisher-Snedecor distribution, is a continuous probability distribution. It is used for F Test and ANOVA. It has two degrees of freedom that serve as shape parameters *v* and *w* and that are positive integers. The following function **randomF** makes use of **randomChisq**.
242239
243240``` pascal
244241function randomF(v, w: integer): real;
245242begin
246243 if (v < 1) or (w < 1) then
247244 randomF := NaN
248245 else
249246 randomF := randomChisq(v) / v / (randomChisq(w) / w);
250247end;
251248```
252249
253250## See also
254251
255252- [[Dev random]]
256253- [[Functions for descriptive statistics]]
257254- [[Marsaglia&|Marsaglia's pseudo random number generators]]
258255- [[A simple implementation of the Mersenne twister]]
259256- [[Delphi compatible LCG Random]]
260257- [[EverettRandom]]
261258
262259## References
263260
2642611. [G. E. P. Box and Mervin E. Muller, *A Note on the Generation of Random Normal Deviates*, The Annals of Mathematical Statistics (1958), Vol. 29, No. 2 pp. 610–611](http://projecteuclid.org/DPubS/Repository/1.0/Disseminate?view=body&id=pdf_1&handle=euclid.aoms/1177706645)
2652622. Dietrich, J. W. (2002). [Der Hypophysen-Schilddrüsen-Regelkreis](http://openlibrary.org/books/OL24586469M/Der_Hypophysen-Schilddrüsen-Regelkreis). Berlin, Germany: Logos-Verlag Berlin. ISBN 978-3-89722-850-4. OCLC 50451543.
2662633. Press, W. H., B. P. Flannery, S. A. Teukolsky, W. T. Vetterling (1989). [Numerical Recipes in Pascal](http://openlibrary.org/works/OL16807779W/). The Art of Scientific Computing, Cambridge University Press, ISBN 0-521-37516-9.
2672644. Richard Saucier, [Computer Generation of Statistical Distributions](http://ftp.arl.mil/random/random.pdf), ARL-TR-2168, US Army Research Laboratory, Aberdeen Proving Ground, MD, 21005-5068, March 2000.
2682655. R.U. Seydel, Generating Random Numbers with Specified Distributions. In: Tools for Computational Finance, Universitext, [DOI 10.1007/978-1-4471-2993-6_2](http://dx.doi.org/10.1007/978-1-4471-2993-6_2), © Springer-Verlag London Limited 2012
2692666. Christian Walck, Hand-book on STATISTICAL DISTRIBUTIONS for experimentalists, Internal Report SUF–PFY/96–01, University of Stockholm 2007
270-
271-\
272267
273268---
274269*From the Free Pascal wiki, page "Generating Random Numbers/pl", as it stood on 2020-11-08 after a change by Slawek, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history