Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Random/3.3/NormalDistributedRandom.cs @ 2476

Last change on this file since 2476 was 1823, checked in by epitzer, 16 years ago

Namespace refactoring: rename formatters & decomposers -> primitive and composite serializers. (#603)

File size: 14.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using HeuristicLab.Core;
26using System.Xml;
27using System.Globalization;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Random {
31
32  /// <summary>
33  /// Normally distributed random variable.
34  /// Uses the Ziggurat transform to efficiently generate normal distributed random numbers.
35  /// See "The Ziggurat Method for Generating Random Variables" (G. Marsaglia and W.W. Tsang 2000).
36  /// </summary>
37  public class NormalDistributedRandom : ItemBase, IRandom {
38
39    [Storable]
40    private double mu;
41    /// <summary>
42    /// Gets or sets the value for µ.
43    /// </summary>
44    public double Mu {
45      get { return mu; }
46      set { mu = value; }
47    }
48
49    [Storable]
50    private double sigma;
51    /// <summary>
52    /// Gets or sets the value for sigma.
53    /// </summary>
54    public double Sigma {
55      get { return sigma; }
56      set { sigma = value; }
57    }
58
59    [Storable]
60    private IRandom uniform;
61
62    private double[] w = new double[] {
63      1.7290404664e-09,
64      1.2680928529e-10,
65      1.6897518107e-10,
66      1.9862687883e-10,
67      2.2232431174e-10,
68      2.4244936614e-10,
69      2.6016130916e-10,
70      2.7611987696e-10,
71      2.9073962682e-10,
72      3.0429969655e-10,
73      3.1699795566e-10,
74      3.2898020419e-10,
75      3.4035738117e-10,
76      3.5121602848e-10,
77      3.6162509098e-10,
78      3.7164057942e-10,
79      3.8130856805e-10,
80      3.9066758162e-10,
81      3.9975012189e-10,
82      4.0858399997e-10,
83      4.1719308563e-10,
84      4.2559822333e-10,
85      4.3381759296e-10,
86      4.4186720949e-10,
87      4.4976131153e-10,
88      4.5751258337e-10,
89      4.6513240481e-10,
90      4.7263104541e-10,
91      4.8001774777e-10,
92      4.8730097735e-10,
93      4.9448850570e-10,
94      5.0158732723e-10,
95      5.0860404777e-10,
96      5.1554460700e-10,
97      5.2241466708e-10,
98      5.2921933502e-10,
99      5.3596349581e-10,
100      5.4265170135e-10,
101      5.4928817050e-10,
102      5.5587695558e-10,
103      5.6242188684e-10,
104      5.6892646150e-10,
105      5.7539412124e-10,
106      5.8182819673e-10,
107      5.8823168558e-10,
108      5.9460769641e-10,
109      6.0095900478e-10,
110      6.0728838625e-10,
111      6.1359850534e-10,
112      6.1989202660e-10,
113      6.2617133700e-10,
114      6.3243904558e-10,
115      6.3869737277e-10,
116      6.4494881657e-10,
117      6.5119559745e-10,
118      6.5744004685e-10,
119      6.6368432972e-10,
120      6.6993072201e-10,
121      6.7618144417e-10,
122      6.8243871665e-10,
123      6.8870464887e-10,
124      6.9498151678e-10,
125      7.0127148533e-10,
126      7.0757677495e-10,
127      7.1389966161e-10,
128      7.2024242126e-10,
129      7.2660727435e-10,
130      7.3299660786e-10,
131      7.3941280876e-10,
132      7.4585826404e-10,
133      7.5233547170e-10,
134      7.5884698525e-10,
135      7.6539541372e-10,
136      7.7198347714e-10,
137      7.7861395109e-10,
138      7.8528972214e-10,
139      7.9201378789e-10,
140      7.9878920145e-10,
141      8.0561923799e-10,
142      8.1250728368e-10,
143      8.1945689123e-10,
144      8.2647166888e-10,
145      8.3355555791e-10,
146      8.4071272166e-10,
147      8.4794732347e-10,
148      8.5526402627e-10,
149      8.6266754851e-10,
150      8.7016316375e-10,
151      8.7775620106e-10,
152      8.8545243360e-10,
153      8.9325818964e-10,
154      9.0117996399e-10,
155      9.0922497309e-10,
156      9.1740082198e-10,
157      9.2571583732e-10,
158      9.3417884539e-10,
159      9.4279972718e-10,
160      9.5158891877e-10,
161      9.6055785548e-10,
162      9.6971930486e-10,
163      9.7908692265e-10,
164      9.8867602993e-10,
165      9.9850361313e-10,
166      1.0085882129e-09,
167      1.0189509236e-09,
168      1.0296150599e-09,
169      1.0406069340e-09,
170      1.0519566329e-09,
171      1.0636980186e-09,
172      1.0758701707e-09,
173      1.0885182755e-09,
174      1.1016947354e-09,
175      1.1154610569e-09,
176      1.1298901814e-09,
177      1.1450695947e-09,
178      1.1611052120e-09,
179      1.1781275955e-09,
180      1.1962995039e-09,
181      1.2158286600e-09,
182      1.2369856250e-09,
183      1.2601323318e-09,
184      1.2857697129e-09,
185      1.3146201905e-09,
186      1.3477839955e-09,
187      1.3870635751e-09,
188      1.4357403044e-09,
189      1.5008658760e-09,
190      1.6030947680e-09
191    };
192    private long[] k = new long[] {
193      1991057938,
194      0,
195      1611602771,
196      1826899878,
197      1918584482,
198      1969227037,
199      2001281515,
200      2023368125,
201      2039498179,
202      2051788381,
203      2061460127,
204      2069267110,
205      2075699398,
206      2081089314,
207      2085670119,
208      2089610331,
209      2093034710,
210      2096037586,
211      2098691595,
212      2101053571,
213      2103168620,
214      2105072996,
215      2106796166,
216      2108362327,
217      2109791536,
218      2111100552,
219      2112303493,
220      2113412330,
221      2114437283,
222      2115387130,
223      2116269447,
224      2117090813,
225      2117856962,
226      2118572919,
227      2119243101,
228      2119871411,
229      2120461303,
230      2121015852,
231      2121537798,
232      2122029592,
233      2122493434,
234      2122931299,
235      2123344971,
236      2123736059,
237      2124106020,
238      2124456175,
239      2124787725,
240      2125101763,
241      2125399283,
242      2125681194,
243      2125948325,
244      2126201433,
245      2126441213,
246      2126668298,
247      2126883268,
248      2127086657,
249      2127278949,
250      2127460589,
251      2127631985,
252      2127793506,
253      2127945490,
254      2128088244,
255      2128222044,
256      2128347141,
257      2128463758,
258      2128572095,
259      2128672327,
260      2128764606,
261      2128849065,
262      2128925811,
263      2128994934,
264      2129056501,
265      2129110560,
266      2129157136,
267      2129196237,
268      2129227847,
269      2129251929,
270      2129268426,
271      2129277255,
272      2129278312,
273      2129271467,
274      2129256561,
275      2129233410,
276      2129201800,
277      2129161480,
278      2129112170,
279      2129053545,
280      2128985244,
281      2128906855,
282      2128817916,
283      2128717911,
284      2128606255,
285      2128482298,
286      2128345305,
287      2128194452,
288      2128028813,
289      2127847342,
290      2127648860,
291      2127432031,
292      2127195339,
293      2126937058,
294      2126655214,
295      2126347546,
296      2126011445,
297      2125643893,
298      2125241376,
299      2124799783,
300      2124314271,
301      2123779094,
302      2123187386,
303      2122530867,
304      2121799464,
305      2120980787,
306      2120059418,
307      2119015917,
308      2117825402,
309      2116455471,
310      2114863093,
311      2112989789,
312      2110753906,
313      2108037662,
314      2104664315,
315      2100355223,
316      2094642347,
317      2086670106,
318      2074676188,
319      2054300022,
320      2010539237
321   };
322    private double[] f = new double[] {
323      1.0000000000e+00,
324      9.6359968185e-01,
325      9.3628269434e-01,
326      9.1304361820e-01,
327      8.9228165150e-01,
328      8.7324303389e-01,
329      8.5550057888e-01,
330      8.3878362179e-01,
331      8.2290720940e-01,
332      8.0773830414e-01,
333      7.9317700863e-01,
334      7.7914607525e-01,
335      7.6558417082e-01,
336      7.5244158506e-01,
337      7.3967725039e-01,
338      7.2725689411e-01,
339      7.1515148878e-01,
340      7.0333611965e-01,
341      6.9178915024e-01,
342      6.8049186468e-01,
343      6.6942769289e-01,
344      6.5858197212e-01,
345      6.4794182777e-01,
346      6.3749545813e-01,
347      6.2723249197e-01,
348      6.1714339256e-01,
349      6.0721951723e-01,
350      5.9745317698e-01,
351      5.8783704042e-01,
352      5.7836467028e-01,
353      5.6902998686e-01,
354      5.5982738733e-01,
355      5.5075180531e-01,
356      5.4179835320e-01,
357      5.3296267986e-01,
358      5.2424055338e-01,
359      5.1562821865e-01,
360      5.0712203979e-01,
361      4.9871864915e-01,
362      4.9041482806e-01,
363      4.8220765591e-01,
364      4.7409430146e-01,
365      4.6607214212e-01,
366      4.5813870430e-01,
367      4.5029163361e-01,
368      4.4252872467e-01,
369      4.3484783173e-01,
370      4.2724698782e-01,
371      4.1972434521e-01,
372      4.1227802634e-01,
373      4.0490642190e-01,
374      3.9760786295e-01,
375      3.9038079977e-01,
376      3.8322380185e-01,
377      3.7613546848e-01,
378      3.6911445856e-01,
379      3.6215949059e-01,
380      3.5526937246e-01,
381      3.4844297171e-01,
382      3.4167915583e-01,
383      3.3497685194e-01,
384      3.2833510637e-01,
385      3.2175290585e-01,
386      3.1522938609e-01,
387      3.0876362324e-01,
388      3.0235484242e-01,
389      2.9600214958e-01,
390      2.8970485926e-01,
391      2.8346219659e-01,
392      2.7727350593e-01,
393      2.7113807201e-01,
394      2.6505529881e-01,
395      2.5902456045e-01,
396      2.5304529071e-01,
397      2.4711695313e-01,
398      2.4123899639e-01,
399      2.3541094363e-01,
400      2.2963231802e-01,
401      2.2390270233e-01,
402      2.1822164953e-01,
403      2.1258877218e-01,
404      2.0700371265e-01,
405      2.0146611333e-01,
406      1.9597564638e-01,
407      1.9053204358e-01,
408      1.8513499200e-01,
409      1.7978426814e-01,
410      1.7447963357e-01,
411      1.6922089458e-01,
412      1.6400785744e-01,
413      1.5884037316e-01,
414      1.5371830761e-01,
415      1.4864157140e-01,
416      1.4361007512e-01,
417      1.3862377405e-01,
418      1.3368265331e-01,
419      1.2878671288e-01,
420      1.2393598258e-01,
421      1.1913054436e-01,
422      1.1437050998e-01,
423      1.0965602100e-01,
424      1.0498725623e-01,
425      1.0036443919e-01,
426      9.5787845552e-02,
427      9.1257803142e-02,
428      8.6774669588e-02,
429      8.2338899374e-02,
430      7.7950984240e-02,
431      7.3611505330e-02,
432      6.9321118295e-02,
433      6.5080583096e-02,
434      6.0890771449e-02,
435      5.6752663106e-02,
436      5.2667401731e-02,
437      4.8636294901e-02,
438      4.4660862535e-02,
439      4.0742866695e-02,
440      3.6884389818e-02,
441      3.3087886870e-02,
442      2.9356317595e-02,
443      2.5693291798e-02,
444      2.2103304043e-02,
445      1.8592102453e-02,
446      1.5167297795e-02,
447      1.1839478277e-02,
448      8.6244847625e-03,
449      5.5489949882e-03,
450      2.6696291752e-03
451    };
452
453    /// <summary>
454    /// Initializes a new instance of <see cref="NormalDistributedRandom"/> with µ = 0 and sigma = 1
455    /// and a new random number generator.
456    /// </summary>
457    public NormalDistributedRandom() {
458      this.mu = 0.0;
459      this.sigma = 1.0;
460      this.uniform = new MersenneTwister();
461    }
462
463    /// <summary>
464    /// Initializes a new instance of <see cref="NormalDistributedRandom"/> with the given parameters.
465    /// <note type="caution"> No CopyConstructor! The random number generator is not copied!</note>
466    /// </summary>   
467    /// <param name="uniformRandom">The random number generator.</param>
468    /// <param name="mu">The value for µ.</param>
469    /// <param name="sigma">The value for sigma.</param>
470    public NormalDistributedRandom(IRandom uniformRandom, double mu, double sigma) {
471      this.mu = mu;
472      this.sigma = sigma;
473      this.uniform = uniformRandom;
474    }
475
476    #region IRandom Members
477
478    /// <inheritdoc cref="IRandom.Reset()"/>
479    public void Reset() {
480      uniform.Reset();
481    }
482
483    /// <inheritdoc cref="IRandom.Reset(int)"/>
484    public void Reset(int seed) {
485      uniform.Reset(seed);
486    }
487
488    /// <summary>
489    /// TODO: The method is not implemented.
490    /// </summary>
491    /// <returns>TODO</returns>
492    public int Next() {
493      throw new Exception("The method or operation is not implemented.");
494    }
495
496    /// <summary>
497    /// TODO: The method is not implemented.
498    /// </summary>
499    /// <param name="maxVal">TODO</param>
500    /// <returns>TODO</returns>
501    public int Next(int maxVal) {
502      throw new Exception("The method or operation is not implemented.");
503    }
504
505    /// <summary>
506    /// TODO: The method is not implemented.
507    /// </summary>
508    /// <param name="minVal">TODO</param>
509    /// <param name="maxVal">TODO</param>
510    /// <returns>TODO</returns>
511    public int Next(int minVal, int maxVal) {
512      throw new Exception("The method or operation is not implemented.");
513    }
514
515    /// <summary>
516    /// Generates a new double random number.
517    /// </summary>
518    /// <returns>A double random number.</returns>
519    public double NextDouble() {
520      double signFactor = uniform.Next() % 2 == 0 ? 1.0 : -1.0;
521      return sigma * signFactor * NextPositiveDouble() + mu;
522    }
523
524    private double NextPositiveDouble() {
525      int j = uniform.Next();
526      int i = (j & 127);
527      if (Math.Abs(j) < k[i]) {
528        return j * w[i];
529      } else {
530        double r = 3.442620;
531        double x, y;
532        x = j * w[i];
533        if (i == 0) {
534          do {
535            x = -Math.Log(ScaledUniform()) * 0.2904764;
536            y = -Math.Log(ScaledUniform());
537          } while (y + y < x * x);
538          return (j > 0) ? r + x : -r - x;
539        }
540        if (f[i] + ScaledUniform() * (f[i - 1] - f[i]) < Math.Exp(-0.5 * x * x)) {
541          return x;
542        } else {
543          // recurse
544          return (NextPositiveDouble());
545        }
546      }
547    }
548
549    private double ScaledUniform() {
550      return 0.5 + uniform.Next() * 0.2328306e-9;
551    }
552
553
554    #endregion
555
556    /// <summary>
557    /// Clones the current instance (deep clone).
558    /// </summary>
559    /// <remarks>Deep clone through <see cref="Auxiliary.Clone"/> method of helper class
560    /// <see cref="Auxiliary"/>.</remarks>
561    /// <param name="clonedObjects">Dictionary of all already cloned objects. (Needed to avoid cycles.)</param>
562    /// <returns>The cloned object as <see cref="NormalDistributedRandom"/>.</returns>
563    public override object Clone(IDictionary<Guid, object> clonedObjects) {
564      NormalDistributedRandom clone = new NormalDistributedRandom((IRandom)Auxiliary.Clone(uniform, clonedObjects), mu, sigma);
565      clonedObjects.Add(Guid, clone);
566      return clone;
567    }
568  }
569}
Note: See TracBrowser for help on using the repository browser.