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.

You can download a *Mathematica* notebook containing these definitions and tests here.