XML: Random Number Generators

From FSDeveloper Wiki
Jump to: navigation, search

Two RNG Macros:

In the 'For What It's Worth' category, here's another XML Random Number generator. This one is based on a multiplicative linear congruential generator method described by Pierre L'Ecuyer in a 1988 Association for Computing Machinery paper. The code below generates a random number between, but not equal to, 0 and 1. It has a period of 2.30584 X 10^18, meaning that at an Update cycle rate of 18, the pattern will not repeat for a little over 4 billion years.

1) Multiplicative linear congruential method Pierre L'Ecuyer (XML courtesy of Robbie McElrath)

<Macro Name="XMLRandom">
  (L:RandomSeed1,number) 0 == (L:RandomSeed2,number) 0 == ||
     (P:Absolute Time,seconds) abs d 2147483563 % (>L:RandomSeed1,number) 
     sqrt d d * * abs 2147483599 % (>L:RandomSeed2,number) 
  (L:RandomSeed1,number) 40014 * 2147483563 % (>L:RandomSeed1,number) 
  (L:RandomSeed2,number) 40692 * 2147483399 % (>L:RandomSeed2,number) 
  (L:RandomSeed1,number) (L:RandomSeed2,number) - 2147483563 / s1 
  l1 0 < if{ l1 ++ s1 } l1

and calling it in an Update section:

 @XMLRandom (>L:RandomNumber,number)

The < in the last line of the macro is supposed to be the "less than" operator "&lt ;" (with no spaces) but the parser in this wiki engine turns it into <

The algorithm reference is: L'Ecuyer, Pierre, 1988, Efficient and Portable Combined Random Number Generators, Association for Computing Machinery.

Acknowledgements are owed to Ron Freimuth, Nike Pike, and Tom Aguilo who have posted xml random number code in Flight Sim forums before. The MLCG code above is another variety. Acknowledgement also to Robbie McElrath for writing the xml snippet based on the L'Ecuyer paper.

2) Method proposed by Tom Aguilo:

<Macro Name="Rand31">
  (L:INSRandFact31,number) 0 ==
      (P:Absolute Time,seconds) abs 10 / int (>L:INSRandFact31,number) 
  767789427 (L:INSRandFact31,number) * 4711345623 + 2000000000 % d (>L:INSRandFact31,number)
  20000000000 / 1 % abs 10 *

generates a random number between, but not equal to, 0 and 10. For random number between 0 and 1, the last line should be:

  20000000000 / 1 % abs