Ticket #3383: TestNoise.mo

File TestNoise.mo, 32.2 KB (added by martin.otter@…, 9 years ago)
Line 
1within ;
2package TestNoise
3
4  model ExampleModel
5
6    GenericNoise genericNoise(samplePeriod=0.1)
7      annotation (Placement(transformation(extent={{-60,0},{-40,20}})));
8    inner GlobalSeedWithoutC globalSeed
9      annotation (Placement(transformation(extent={{-60,40},{-40,60}})));
10    annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
11          coordinateSystem(preserveAspectRatio=false)));
12  end ExampleModel;
13
14  model GlobalSeedWithoutC
15    "Defines global settings for the blocks of sublibrary Noise, especially a global seed value is defined"
16    parameter Boolean enableNoise = true
17      "= true, if noise blocks generate noise as output; = false, if they generate a constant output"
18      annotation(choices(checkBox=true));
19    parameter Boolean useAutomaticSeed = false
20      "= true, choose a seed by system time and process id; = false, use fixedSeed"
21      annotation(choices(checkBox=true));
22    parameter Integer fixedSeed = 67867967
23      "Fixed global seed for random number generators (if useAutomaticSeed = false)"
24        annotation(Dialog(enable=not useAutomaticSeed));
25    final parameter Integer seed = if useAutomaticSeed then
26                                      TestNoise.Utilities.automaticGlobalSeed()
27                                    else fixedSeed "Actually used global seed";
28
29    function random = TestNoise.Utilities.impureRandom(final id=id_impure)
30      "Impure random number generator function";
31    function randomInteger =
32        TestNoise.Utilities.impureRandomInteger(final id=id_impure)
33      "Impure Integer random number generator function";
34
35  protected
36    parameter Integer id_impure = TestNoise.Utilities.initializeImpureRandom(seed);
37
38    annotation (
39      defaultComponentName="globalSeed",
40      defaultComponentPrefixes="inner",
41      missingInnerMessage="
42Your model is using an outer \"globalSeed\" component but
43an inner \"globalSeed\" component is not defined and therefore
44a default inner \"globalSeed\" component is introduced by the tool.
45To change the default setting, drag Noise.GlobalSeed
46into your model and specify the seed.
47",  Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,100}}),
48                           graphics={Ellipse(
49            extent={{-100,100},{100,-100}},
50            lineColor={0,0,127},
51            fillColor={255,255,255},
52            fillPattern=FillPattern.Solid),
53                                          Text(
54          extent={{-150,150},{150,110}},
55          textString="%name",
56          lineColor={0,0,255}),
57          Line(visible = enableNoise,
58               points={{-73,-15},{-59,-15},{-59,1},{-51,1},{-51,-47},{-43,-47},{-43,
59                -25},{-35,-25},{-35,59},{-27,59},{-27,27},{-27,27},{-27,-33},{-17,-33},{-17,-15},{-7,-15},{-7,-43},{3,
60                -43},{3,39},{9,39},{9,53},{15,53},{15,-3},{25,-3},{25,9},{31,9},{31,
61                -21},{41,-21},{41,51},{51,51},{51,17},{59,17},{59,-49},{69,-49}},
62              color={215,215,215}),
63          Text(visible=enableNoise and not useAutomaticSeed,
64            extent={{-90,-4},{88,-30}},
65            lineColor={255,0,0},
66            fillColor={255,255,255},
67            fillPattern=FillPattern.Solid,
68            textString="%fixedSeed"),
69          Line(visible = not enableNoise,
70            points={{-80,-4},{84,-4}},
71            color={215,215,215}),
72          Text(visible=enableNoise and not useAutomaticSeed,
73            extent={{-84,34},{94,8}},
74            lineColor={255,0,0},
75            fillColor={255,255,255},
76            fillPattern=FillPattern.Solid,
77            textString="fixedSeed =")}),
78      Documentation(revisions="<html>
79<p>
80<table border=1 cellspacing=0 cellpadding=2>
81<tr><th>Date</th> <th align=\"left\">Description</th></tr>
82
83<tr><td valign=\"top\"> June 22, 2015 </td>
84    <td valign=\"top\">
85
86<table border=0>
87<tr><td valign=\"top\">
88         <img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Noise/dlr_logo.png\">
89</td><td valign=\"bottom\">
90         Initial version implemented by
91         A. Kl&ouml;ckner, F. v.d. Linden, D. Zimmer, M. Otter.<br>
92         <a href=\"http://www.dlr.de/rmc/sr/en\">DLR Institute of System Dynamics and Control</a>
93</td></tr></table>
94</td></tr>
95
96</table>
97</p>
98</html>",   info="<html>
99<p>
100When using one of the blocks of sublibrary <a href=\"modelica://Modelica_Noise.Blocks.Noise\">Noise</a>,
101on the same or a higher hierarchical level, Noise.GlobalSeed
102must be dragged resulting in a declaration
103</p>
104
105<pre>
106   <b>inner</b> Modelica_Noise.Blocks.Noise.GlobalSeed globalSeed;
107</pre>
108
109<p>
110The GlobalSeed block provides global options for all Noise blocks of the same or a lower
111hierarchical level. The following options can be selected:
112</p>
113
114<blockquote>
115<p>
116<table border=1 cellspacing=0 cellpadding=2>
117<tr><th>Icon</th>
118    <th>Description</th></tr>
119
120<tr><td> <img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Noise/GlobalSeed_FixedSeed.png\"> </td>
121    <td> <b>useAutomaticSeed=false</b> (= default):<br>
122         A fixed global seed is defined with Integer parameter fixedSeed. The value of fixedSeed
123         is displayed in the icon. By default all Noise blocks use fixedSeed for initialization of their
124         pseudo random number generators, in combination with a local seed defined for every instance
125         separately. Therefore, whenever a simulation is performed with the
126         same fixedSeed exactly the same noise is generated in all instances of the Noise
127         blocks (provided the settings of these blocks are not changed as well).<br>
128         This option can be used (a) to design a control system (e.g. by parameter optimization) and keep the same
129         noise for all simulations, or (b) perform Monte Carlo Simulations where
130         fixedSeed is changed from the environment for every simulation, in order to
131         produce different noise at every simulation run.</td></tr>
132
133<tr><td> <img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Noise/GlobalSeed_AutomaticSeed.png\"> </td>
134    <td> <b>useAutomaticSeed=true</b>:<br>
135         An automatic global seed is computed by using the ID of the process in which the
136         simulation takes place and the current local time. As a result, the global seed
137         is changed automatically for every new simulation, including parallelized
138         simulation runs. This option can be used to perform Monte Carlo Simulations
139         with minimal effort (just performinng many simulation runs) where
140         every simulation run uses a different noise.</td></tr>
141
142
143<tr><td> <img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Noise/GlobalSeed_NoNoise.png\"> </td>
144    <td> <b>enableNoise=false</b>:<br>
145         The noise in all Noise instances is switched off and the blocks output a constant
146         signal all the time (usually zero). This option is useful, if a model shall be
147         tested without noise and the noise shall be quickly turned off or on.</td></tr>
148</table>
149</p></blockquote>
150
151<p>
152Additionally, the globalSeed instance provides the following impure functions
153</p>
154
155<ul>
156<li> <b>random</b>():<br>
157     This function uses the <a href=\"modelica://Modelica_Noise.Math.Random.Generators.Xorshift1024star\">xorshift1024*</a>
158     pseudo random number generator to produce random numbers in the range 0 &lt; random numbers &le; 1.
159     It is initialized with the global seed defined in globalSeed
160     (so either with parameter fixedSeed, or automatically computed by process ID and local time).
161     Since random() is an impure function, it should only be called in a when-clause (so at an event).</li>
162<li> <b>randomInteger</b>(imin=1,imax=Modelica.Constants.Integer_inf):<br>
163     This function uses the random() pseudo random number generator and maps the returned random value
164     into the Integer range imin ... imax. By default, imin=1 and imax=Modelica.Constants.Integer_inf.
165     Since randomInteger() is an impure function, it should only be called in a when-clause
166     (so at an event).</li>
167</ul>
168
169<p>
170Note, the usage of this block is demonstrated with examples
171<a href=\"modelica://Modelica_Noise.Blocks.Examples.NoiseExamples.AutomaticSeed\">AutomaticSeed</a> and
172<a href=\"modelica://Modelica_Noise.Blocks.Examples.NoiseExamples.ImpureGenerator\">ImpureGenerator</a>.
173</p>
174
175<p>
176Remark: The \"xorshift1024\" pseudo-random number generator has an internal state of 33 Integers.
177This state is initialized in the following way: The pseudo-random number generator
178<a href=\"modelica://Modelica_Noise.Math.Random.Generators.Xorshift64star\">Xorshift64star</a>
179is used to compute these 33 Integers. This random number generator has a state of 2 Integers which
180is initialized with the global and local seed integers. Afterwards, random values are produced
181with this random number generator and utilized as values for the internal state of
182the Xorshift1024star random number generator.
183</p>
184</html>"));
185  end GlobalSeedWithoutC;
186
187
188  block GenericNoise "Noise generator for arbitrary distributions"
189    import generator = TestNoise.Generator;
190
191    extends Modelica.Blocks.Interfaces.SO;
192
193    // Main dialog menu
194    parameter Modelica.SIunits.Time samplePeriod(start=0.01)
195      "Period for sampling the raw random numbers"
196      annotation(Dialog(enable=enableNoise));
197    parameter Real y_min=0 "Lower limit of y";
198    parameter Real y_max=1 "Upper limit of y";
199  /*
200  replaceable partial function distribution =
201    Modelica_Noise.Math.Distributions.Interfaces.partialQuantile
202    "Random number distribution"
203    annotation(choicesAllMatching=true, Dialog(enable=enableNoise));
204*/
205
206    // Advanced dialog menu: Noise generation
207    parameter Boolean enableNoise = true
208      "=true: y = noise, otherwise y = y_off"
209      annotation(choices(checkBox=true),Dialog(tab="Advanced",group="Noise generation"));
210    parameter Real y_off = 0.0
211      "y = y_off if enableNoise=false (or time<startTime, see below)"
212      annotation(Dialog(tab="Advanced",group="Noise generation"));
213
214    // Advanced dialog menu: Initialization
215    parameter Boolean useGlobalSeed = true
216      "= true: use global seed, otherwise ignore it"
217      annotation(choices(checkBox=true),Dialog(tab="Advanced",group = "Initialization",enable=enableNoise));
218    parameter Boolean useAutomaticLocalSeed = true
219      "= true: use automatic local seed, otherwise use fixedLocalSeed"
220      annotation(choices(checkBox=true),Dialog(tab="Advanced",group = "Initialization",enable=enableNoise));
221    parameter Integer fixedLocalSeed = 1 "Local seed (any Integer number)"
222      annotation(Dialog(tab="Advanced",group = "Initialization",enable=enableNoise and not useAutomaticLocalSeed));
223    parameter Modelica.SIunits.Time startTime = 0.0
224      "Start time for sampling the raw random numbers"
225      annotation(Dialog(tab="Advanced", group="Initialization",enable=enableNoise));
226
227    // Advanced dialog menu: Random number properties
228  /* 
229  replaceable package generator =
230      Modelica_Noise.Math.Random.Generators.Xorshift128plus constrainedby
231    Modelica_Noise.Math.Random.Interfaces.PartialGenerator
232    "Random number generator"
233    annotation(choicesAllMatching=true, Dialog(tab="Advanced",group="Random number generator",enable=enableNoise));
234*/
235
236    discrete Integer localSeed "The actual localSeed";
237
238  protected
239    outer TestNoise.GlobalSeedWithoutC globalSeed
240      "Definition of global seed via inner/outer";
241    parameter Integer actualGlobalSeed = if useGlobalSeed then globalSeed.seed else 0
242      "The global seed, which is atually used";
243    parameter Boolean generateNoise = enableNoise and globalSeed.enableNoise
244      "= true if noise shall be generated, otherwise no noise";
245
246    // Declare state and random number variables
247    Integer state[4] "Internal state of random number generator";
248    discrete Real r "Random number according to the desired distribution";
249    discrete Real r_raw "Uniform random number in the range (0,1]";
250
251  initial equation
252     pre(state) = generator.initialState(localSeed, actualGlobalSeed);
253     r_raw = generator.random(pre(state));
254     r = r_raw;
255
256  equation
257    when initial() then
258      localSeed = if useAutomaticLocalSeed then globalSeed.randomInteger() else fixedLocalSeed;
259    end when;
260
261    // Draw random number at sample times
262    when generateNoise and sample(startTime, samplePeriod) then
263      (r_raw, state) = generator.random(pre(state));
264      r  = r_raw;
265    end when;
266
267    // Generate noise if requested
268    y = if not generateNoise or time < startTime then y_off else r;
269
270      annotation(Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},
271              {100,100}}), graphics={
272          Polygon(
273            points={{-76,90},{-84,68},{-68,68},{-76,90}},
274            lineColor={192,192,192},
275            fillColor={192,192,192},
276            fillPattern=FillPattern.Solid),
277          Line(points={{-76,68},{-76,-80}}, color={192,192,192}),
278          Line(points={{-86,0},{72,0}}, color={192,192,192}),
279          Polygon(
280            points={{94,0},{72,8},{72,-8},{94,0}},
281            lineColor={192,192,192},
282            fillColor={192,192,192},
283            fillPattern=FillPattern.Solid),
284          Line(visible = enableNoise,
285             points={{-75,-13},{-61,-13},{-61,3},{-53,3},{-53,-45},{-45,-45},{-45,
286                -23},{-37,-23},{-37,61},{-29,61},{-29,29},{-29,29},{-29,-31},{-19,
287                -31},{-19,-13},{-9,-13},{-9,-41},{1,-41},{1,41},{7,41},{7,55},{13,
288                55},{13,-1},{23,-1},{23,11},{29,11},{29,-19},{39,-19},{39,53},{49,
289                53},{49,19},{57,19},{57,-47},{67,-47}}),
290          Text(visible=enableNoise,
291            extent={{-150,-110},{150,-150}},
292            lineColor={0,0,0},
293            fillColor={192,192,192},
294            fillPattern=FillPattern.Solid,
295            textString="%samplePeriod s"),
296          Line(visible=not enableNoise,
297            points={{-76,56},{72,56}}),
298          Text(visible=not enableNoise,
299            extent={{-75,50},{95,10}},
300            lineColor={0,0,0},
301            fillColor={192,192,192},
302            fillPattern=FillPattern.Solid,
303            textString="%y_off"),
304          Text(visible=enableNoise and not useAutomaticLocalSeed,
305            extent={{-98,-55},{98,-95}},
306            lineColor={238,46,47},
307            textString="%fixedLocalSeed")}),
308      Documentation(info="<html>
309<p>
310A summary of the properties of the noise blocks is provided
311in the documentation of package
312<a href=\"modelica://Modelica_Noise.Blocks.Noise\">Blocks.Noise</a>.
313This GenericNoise block generates reproducible, random noise at its output.
314By default, two or more instances produce different, uncorrelated noise at the same time instant.
315The block can only be used if on the same or a higher hierarchical level,
316model <a href=\"modelica://Modelica_Noise.Blocks.Noise.GlobalSeed\">Blocks.Noise.GlobalSeed</a>
317is dragged to provide global settings for all instances.
318</p>
319
320
321<h4>Parameters that need to be defined</h4>
322
323<p>
324When using this block, at a minimum the following parameters must be defined:
325</p>
326
327<blockquote>
328<p>
329<table border=1 cellspacing=0 cellpadding=2>
330<tr><th>Parameter</th>
331    <th>Description</th></tr>
332
333<tr><td> samplePeriod </td>
334    <td> Random values are drawn periodically at the sample rate in [s]
335         defined with this parameter (time events are generated at the sample instants).
336         Between sample instants, the output y is kept constant.</td></tr>
337
338<tr><td> distribution </td>
339    <td> Defines the random number distribution to map the drawn random numbers
340         from the range 0.0 ... 1.0, to the desired range and distribution.
341         Basically, <b>distribution</b> is a replaceable function that
342         provides the quantile (= inverse cumulative distribution function)
343         of a random distribution. For simulation models
344         <a href=\"modelica://Modelica_Noise.Math.Distributions\">truncated distributions</a>
345         are of special interest, because the returned random values are guaranteed
346         to be in a defined band y_min ... y_max. Often used distributions are:
347         <ul>
348         <li> <a href=\"modelica://Modelica_Noise.Math.Distributions.Uniform\">Uniform distribution</a>:
349              The random values are mapped <b>uniformly</b> to the band
350              y_min ... y_max.</li>
351         <li> <a href=\"modelica://Modelica_Noise.Math.Distributions.TruncatedNormal\">Truncated normal distribution</a>:
352              The random values have a <b>normal</b> distribution that
353              is truncated to y_min ... y_max. Measurement noise has often this distribution form.
354              By default, the standard parameters of the truncated normal distribution are derived from
355              y_min ... y_max: mean value = (y_max + y_min)/2, standard deviation
356              = (y_max - y_min)/6 (= 99.7 % of the non-truncated normal distribution are
357              within y_min ... y_max).</li>
358         </ul>
359         </td></tr>
360</table>
361</p></blockquote>
362
363<p>
364As a simple demonstration, see example <a href=\"modelica://Modelica_Noise.Blocks.Examples.NoiseExamples.GenericNoise\">Blocks.Examples.NoiseExamples.GenericNoise</a>.
365In the next diagram, a simulation result is shown for samplePeriod=0.02 s and uniform distribution with
366y_min=-1, y_max=3:
367</p>
368<p><blockquote>
369<img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Examples/NoiseExamples/GenericNoise.png\">
370</blockquote>
371</p>
372
373<h4>Advanced tab: General settings</h4>
374<p>
375In the <b>Advanced</b> tab of the parameter menu, further options can be set
376as shown in the next table:
377</p>
378
379<blockquote>
380<p>
381<table border=1 cellspacing=0 cellpadding=2>
382<tr><th>Parameter</th>
383    <th>Description</th></tr>
384
385<tr><td> enableNoise </td>
386    <td> = true, if noise is generated at the output of the block (this is the default).<br>
387         = false, if noise generation is switched off and the constant value
388         y_off is provided as output.</td></tr>
389<tr><td> y_off </td>
390    <td> If enableNoise = false, the output of the block instance has the
391         value y_off. Default is y_off = 0.0.
392         Furthermore, if enableNoise = true and time&lt;startTime, the output of the block is also
393         y_off (see description of parameter startTime below).</td></tr>
394</table>
395</p></blockquote>
396
397
398
399<h4>Advanced tab: Initialization</h4>
400
401<p>
402For every block instance, the internally used pseudo random number generator
403has its own state. This state must be properly initialized, depending on
404the desired situation. For this purpose the following parameters can be defined:
405</p>
406
407<blockquote>
408<p>
409<table border=1 cellspacing=0 cellpadding=2>
410<tr><th>Parameter</th>
411    <th>Description</th></tr>
412
413<tr><td> useGlobalSeed </td>
414    <td> = true, if the seed (= Integer number) defined in the \"inner GlobalSeed globalSeed\"
415         component is used for the initialization of the random number generator used in this
416         instance of block GenericNoise.
417         Therefore, whenever the globalSeed defines a different number, the noise at every
418         instance is changing. This is the default setting and therefore the globalSeed component
419         defines whether every new simulation run shall provide the same noise
420         (e.g. for a parameter optimization of controller parameters), or
421         whether every new simulation run shall provide different noise
422         (e.g. for a Monte Carlo simulation).<br>
423         = false, if the seed defined by globalSeed is ignored. For example, if
424         aerodynamic turbulence is modelled with a noise block and this turbulence
425         model shall be used for all simulation runs of a Monte Carlo simulation, then
426         useGlobalSeed has to be set to false.</td></tr>
427
428<tr><td> useAutomaticLocalSeed </td>
429    <td> An Integer number, called local seed, is needed to initalize the random number
430         generator for a specific block instance. Instances using the same local seed
431         produce exactly the same random number values (so the same noise, if the other settings
432         of the instances are the same).<br>
433         If <b>useAutomaticLocalSeed = true</b>, the
434         local seed is determined automatically from an impure random number generator that
435         produces Integer random values (= calling function globalSeed.randomInteger()).
436         This is the default.
437         Note, this means that the noise might change if function randomInteger() is called
438         more or less often in the overall model (e.g. because an additional noise block is
439         introduced or removed). It is planned to change the automatic local seed function
440         in a future version of package Modelica, once Modelica Language 3.3 language elements
441         can be used (by using a hash value of the instance name of the model that is
442         inquired with the Modelica Language 3.3 function getInstanceName()).<br>
443         If <b>useAutomaticLocalSeed = false</b>, the local seed is defined
444         explicitly by parameter fixedLocalSeed. It is then guaranteed that the generated noise
445         remains always the same (provided the other parameter values are the same).</td></tr>
446
447<tr><td> fixedLocalSeed </td>
448    <td> If useAutomaticLocalSeed = false, the local seed to be used.
449         fixedLocalSeed can be any Integer number (including zero or a negative number).
450         The initialization algorithm produces a meaningful initial state of the random
451         number generator from fixedLocalSeed and (if useAutomaticGlobalSeed=true) from globalSeed even for
452         bad seeds such as 0 or 1, so the subsequently drawing of random numbers produce always statistically
453         meaningful numbers.</td></tr>
454
455<tr><td> startTime </td>
456    <td> The time instant at which noise shall be generated at the output y. The default
457         startTime = 0.
458         For time&lt;startTime, y = y_off. In some cases it is meaningful to simulate
459         a certain duration until an approximate steady-state is reached. In such a case
460         startTime should be set to a time instant after this duration.</td></tr>
461</table>
462</p></blockquote>
463
464<h4>Advanced tab: Random number generator</h4>
465<p>
466The (pseudo) random number generator to be used is defined here.
467The default is random number generator algorithm \"xorshift128+\".
468This random number generator has a period of 2^128,
469has an internal state of 4 Integer elements, and has
470excellent statistical properties.
471If the default algorithm is not desired, the
472following parameter can be set:
473</p>
474
475<blockquote>
476<p>
477<table border=1 cellspacing=0 cellpadding=2>
478<tr><th>Parameter</th>
479    <th>Description</th></tr>
480
481<tr><td> generator </td>
482    <td> Defines the pseudo random number generator to be used. This is
483         a replaceable package. Meaningful random number generators are provided in
484         package <a href=\"modelica://Modelica_Noise.Math.Random.Generators\">Math.Random.Generators</a>.
485         Properties of the various generators are described in the package
486         description of the Generators package.</td></tr>
487</table>
488</p></blockquote>
489</html>",   revisions="<html>
490<p>
491<table border=1 cellspacing=0 cellpadding=2>
492<tr><th>Date</th> <th align=\"left\">Description</th></tr>
493
494<tr><td valign=\"top\"> June 22, 2015 </td>
495    <td valign=\"top\">
496
497<table border=0>
498<tr><td valign=\"top\">
499         <img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Noise/dlr_logo.png\">
500</td><td valign=\"bottom\">
501         Initial version implemented by
502         A. Kl&ouml;ckner, F. v.d. Linden, D. Zimmer, M. Otter.<br>
503         <a href=\"http://www.dlr.de/rmc/sr/en\">DLR Institute of System Dynamics and Control</a>
504</td></tr></table>
505</td></tr>
506
507</table>
508</p>
509</html>"));
510  end GenericNoise;
511
512  package Utilities
513
514    function impureRandomInteger
515      "Impure random number generator for integer values (with hidden state vector)"
516      input Integer id
517        "Identification number from initializeImpureRandom(..) function (is needed for correct sorting)";
518      input Integer imin = 1 "Minimum integer to generate";
519      input Integer imax = Modelica.Constants.Integer_inf
520        "Maximum integer to generate";
521      output Integer y
522        "A random number with a uniform distribution on the interval [imin,imax]";
523    protected
524      Real r "Impure Real random number";
525    algorithm
526      r := id/(id+1);
527      y  := integer(r*imax) + integer((1-r)*imin);
528      y  := min(imax, max(imin, y));
529
530      annotation (Documentation(info="<html>
531<h4>Syntax</h4>
532<blockquote><pre>
533r = <b>impureRandomInteger</b>(id, imin=1, imax=Modelica.Constants.Integer_inf);
534</pre></blockquote>
535
536<h4>Description</h4>
537<p>
538Returns an Integer random number in the range imin &le; random &le; imax with the xorshift1024* algorithm,
539(the random number in the range 0 ... 1 returned by the xorshift1024* algorithm is mapped to
540an Integer number in the range imin ... imax).
541The dummy input Integer argument id must be the output argument of a call to function
542<a href=\"modelica://Modelica_Noise.Math.Random.Utilities.initializeImpureRandom\">initializeImpureRandom</a>,
543in order that the sorting order is correct (so that impureRandomInteger is always called
544after initializeImpureRandom). For every call of impureRandomInteger(id), a different random number
545is returned, so the function is impure.
546</p>
547
548<h4>See also</h4>
549<p>
550<a href=\"modelica://Modelica_Noise.Math.Random.Utilities.initializeImpureRandom\">initializeImpureRandom</a>,
551<a href=\"modelica://Modelica_Noise.Math.Random.Generators\">Random.Generators</a>
552</p>
553<h4>Note</h4>
554<p>This function is impure!</p>
555</html>"));
556    end impureRandomInteger;
557
558    function initializeImpureRandom
559      "Initializes the internal state of the impure random number generator"
560      input Integer seed
561        "The input seed to initialize the impure random number generator";
562      output Integer id
563        "Identification number to be passed as input to function impureRandom, in order that sorting is correct";
564    algorithm
565      id :=seed*3;
566
567      annotation (Documentation(info="<html>
568<h4>Syntax</h4>
569<blockquote><pre>
570id = <b>initializeImpureRandom</b>(seed);
571</pre></blockquote>
572
573<h4>Description</h4>
574
575<p>
576Generates a hidden initial state vector for the
577<a href=\"modelica://Modelica_Noise.Math.Random.Generators.Xorshift1024star\">Xorshift1024star</a>
578random number generator (= xorshift1024* algorithm), from Integer input argument seed. Argument seed
579can be given any value (including zero or negative number). The function returns the
580dummy Integer number id. This number needs to be passed as input to function
581<a href=\"modelica://Modelica_Noise.Math.Random.Utilities.impureRandom\">impureRandom</a>,
582in order that the sorting order is correct (so that impureRandom is always called
583after initializeImpureRandom). The function stores a reasonable initial state vector
584in a C-static memory by using the
585<a href=\"modelica://Modelica_Noise.Math.Random.Generators.Xorshift64star\">Xorshift64start</a>
586random number generator to fill the internal state vector with 64 bit random numbers.
587</p>
588
589<h4>Example</h4>
590<blockquote><pre>
591  <b>parameter</b> Integer seed;
592  Real r;
593  <b>function</b> random = impureRandom (<b>final id=id);
594<b>protected </b>
595  Integer id;
596<b>equation</b>
597  // Initialize the random number generator
598  <b>when</b> initial() <b>then</b>
599    id = initializeImpureRandom(seed);
600  <b>end when</b>;
601
602  // Use the random number generator
603  <b>when</b> sample(0,0.001) <b>then</b>
604     r = random();
605  <b>end when</b>;
606</pre></blockquote>
607
608<h4>See also</h4>
609<p>
610<a href=\"modelica://Modelica_Noise.Math.Random.Utilities.impureRandom\">Utilities.impureRandom</a>,
611<a href=\"modelica://Modelica_Noise.Math.Random.Generators\">Random.Generators</a>
612</p>
613</html>",     revisions="<html>
614<p>
615<table border=1 cellspacing=0 cellpadding=2>
616<tr><th>Date</th> <th align=\"left\">Description</th></tr>
617
618<tr><td valign=\"top\"> June 22, 2015 </td>
619    <td valign=\"top\">
620
621<table border=0>
622<tr><td valign=\"top\">
623         <img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Noise/dlr_logo.png\">
624</td><td valign=\"bottom\">
625         Initial version implemented by
626         A. Kl&ouml;ckner, F. v.d. Linden, D. Zimmer, M. Otter.<br>
627         <a href=\"http://www.dlr.de/rmc/sr/en\">DLR Institute of System Dynamics and Control</a>
628</td></tr></table>
629</td></tr>
630
631</table>
632</p>
633</html>"));
634    end initializeImpureRandom;
635
636    function automaticGlobalSeed
637      "Creates an automatic integer seed from the current time and process id (= impure function)"
638      output Integer seed "Automatically generated seed";
639    algorithm
640      seed :=3893456;
641
642     annotation (Documentation(info="<html>
643<h4>Syntax</h4>
644<blockquote><pre>
645seed = Utilities.<b>automaticGlobalSeed</b>();
646</pre></blockquote>
647
648<h4>Description</h4>
649<p>Returns an automatically computed seed (Integer) from:</p>
650<ol>
651<li> The current localtime by computing the number of milli-seconds up to the current hour</li>
652<li> The process id (added to the first part by multiplying it with the prime number 6007).</li>
653</ol>
654<p>Check that worst case combination can be included in an Integer:</p>
655<blockquote>
656<p>1000*60*60 = 3.6e6 &LT; 2^31 = 2147483648 (2.1e9)</p>
657</blockquote>
658<p>
659Everything is added to 1, in order to guard against the very unlikely case that the sum is zero.
660</p>
661
662<p>
663Note, this is an impure function that returns always a different value, when it is newly called.
664This function should be only called once during initialization.
665</p>
666
667<h4>Example</h4>
668<blockquote><pre>
669  <b>parameter</b> Boolean useAutomaticSeed = false;
670  <b>parameter</b> Integer fixedSeed = 67867967;
671  <b>final parameter</b> Integer seed = <b>if</b> useAutomaticSeed <b>then</b>
672                                    Random.Utilities.automaticGlobalSeed()
673                                 <b>else</b> fixedSeed;
674</pre></blockquote>
675
676<h4>See also</h4>
677<p>
678<a href=\"modelica://Modelica_Noise.Math.Random.Utilities.automaticLocalSeed\">automaticLocalSeed</a>.
679</p>
680<h4>Note</h4>
681<p>This function is impure!</p>
682</html>",     revisions="<html>
683<p>
684<table border=1 cellspacing=0 cellpadding=2>
685<tr><th>Date</th> <th align=\"left\">Description</th></tr>
686
687<tr><td valign=\"top\"> June 22, 2015 </td>
688    <td valign=\"top\">
689
690<table border=0>
691<tr><td valign=\"top\">
692         <img src=\"modelica://Modelica_Noise/Resources/Images/Blocks/Noise/dlr_logo.png\">
693</td><td valign=\"bottom\">
694         Initial version implemented by
695         A. Kl&ouml;ckner, F. v.d. Linden, D. Zimmer, M. Otter.<br>
696         <a href=\"http://www.dlr.de/rmc/sr/en\">DLR Institute of System Dynamics and Control</a>
697</td></tr></table>
698</td></tr>
699
700</table>
701</p>
702</html>"));
703    end automaticGlobalSeed;
704
705    function impureRandom
706      "Impure random number generator (with hidden state vector)"
707      input Integer id
708        "Identification number from initializeImpureRandom(..) function (is needed for correct sorting)";
709      output Real y
710        "A random number with a uniform distribution on the interval (0,1]";
711    algorithm
712      y :=id/(id + 1);
713    end impureRandom;
714  end Utilities;
715
716  package Generator
717
718    function initialState
719      input Integer localSeed
720        "The local seed to be used for generating initial states";
721      input Integer globalSeed
722        "The global seed to be combined with the local seed";
723      output Integer[4] state "The generated initial states";
724    algorithm
725      state[1] :=localSeed;
726      state[2] :=globalSeed;
727      state[3] :=localSeed;
728      state[4] :=globalSeed;
729    end initialState;
730
731    function random
732          input Integer[4] stateIn
733        "The internal states for the random number generator";
734        output Real result
735        "A random number with a uniform distribution on the interval (0,1]";
736        output Integer[4] stateOut
737        "The new internal states of the random number generator";
738    algorithm
739      result :=stateIn[1] + stateIn[2] + stateIn[3] + stateIn[4];
740      stateOut[1] :=stateIn[2]*stateIn[1];
741      stateOut[2] :=stateIn[3]*stateIn[2];
742      stateOut[3] :=stateIn[4]*stateIn[3];
743      stateOut[4] :=stateIn[1]*stateIn[4];
744    end random;
745  end Generator;
746
747  annotation (uses(Modelica(version="3.2.1")));
748end TestNoise;