I recently needed to emulate the random number generator internally used by Texas Instruments calculators in Mathematica. Thanks to this United-TI forum post, I found that the algorithm being used is a combined multiplicative linear congruential generator due to Pierre L’Ecuyer. The particular generator used is listed on page 747 of the article; as noted there, the combined MLCG has a period of .
I figured this might be useful to other people, so I’m posting the routines needed to get RandomReal[]
and related functions to emulate the rand()
function (and ilk) on TI calculators:
TexasInstruments /: Random`InitializeGenerator[TexasInstruments, ___] := TexasInstruments[12345, 67890]
TexasInstruments[___]["GeneratesRealsQ"] := True;
TexasInstruments[___]["GeneratesIntegersQ"] := True;
TexasInstruments[___]["SeedGenerator"[seed_]] := If[seed == 0, TexasInstruments[12345, 67890],
TexasInstruments[Mod[40014 seed, 2147483563],
Mod[seed, 2147483399]]];
TexasInstruments[s1_, s2_]["GenerateReals"[n_, {a_, b_}, prec_]] :=
Module[{p = s1, q = s2, temp},
{a + (b - a) Table[p = Mod[40014 p, 2147483563]; q = Mod[40692 q, 2147483399]; temp = (p - q)/2147483563; If[temp < 0, temp += 1]; temp, {n}], TexasInstruments[p, q]}
]
TexasInstruments[s1_, s2_]["GenerateIntegers"[n_, {a_, b_}]] :=
Module[{p = s1, q = s2, temp},
{a + Floor[(b - a + 1) Table[p = Mod[40014 p, 2147483563]; q = Mod[40692 q, 2147483399]; temp = (p - q)/2147483563; If[temp < 0, temp += 1]; temp, {n}]], TexasInstruments[p, q]}
]
This is based on the PRNG method plug-in framework in Mathematica that is described here. For instance, here is the Mathematica equivalent of executing 0→rand:rand(10)
(for Zilog Z80 calculators like the TI-83 Plus) or RandSeed 0:rand()
(for Motorola 68k calculators like the TI-89):
(* 0→rand:rand(10) *)
BlockRandom[SeedRandom[0, Method -> TexasInstruments];
RandomReal[{0, 1}, 10, WorkingPrecision -> 20]]
Here’s corresponding code for randInt()
and randM()
on the Z80 calculators:
(* 0->rand:randInt(1,10,10) *)
BlockRandom[SeedRandom[0, Method -> TexasInstruments];
RandomInteger[{1, 10}, 10]]
(* 0->rand:randM(3,3) *)
BlockRandom[SeedRandom[0, Method -> TexasInstruments];
Reverse[Reverse /@ RandomInteger[{-9, 9}, {3, 3}]]]
Due to differences in precision, there is bound to be some discrepancy in the least significant figures of the results from the calculators and the results from the Mathematica emulation; still, I believe that this is a serviceable fake.
What computer language is this coded in?
It’s in Mathematica, as noted in the post. :)