Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 2954 was 2794, checked in by swagner, 15 years ago

Operator architecture refactoring (#95)

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