Tutorials › Bayesian Clinical Trials › Random Seeds And Reproducible Trial Simulations

Calibrating Operating Characteristics · Tutorial 186 of 696

Random Seeds And Reproducible Trial Simulations

Learn to make trial simulations replayable by recording the generator, seed, stream structure, and software details—not just a seed value.

Advanced 12 min read

What You'll Learn

  • Explain what a random-number generator seed determines and what it does not.
  • Distinguish reproducibility within one environment from reproducibility across environments.
  • Record the generator, seed, software versions, stream assignments, and simulation settings needed for replay.
  • Use separate, stable streams to reduce unintended changes when simulation code is modified.
  • Diagnose why rerunning a simulation may produce different trial results.

Why Reproducibility Requires More Than a Seed

Operating-characteristic simulations estimate how a specified trial procedure behaves across repeated hypothetical trials. Because the simulated trials use random numbers, rerunning the code will often produce different data and a slightly different estimated performance measure. Recording the random-number generator seed makes it possible to replay a particular sequence of pseudo-random values, which helps with debugging, review, and verification.

But a seed is not a complete recipe. The generated sequence also depends on the generator algorithm, how that algorithm turns its internal state into uniform values, how those values are transformed into trial data, and the order in which the program requests them. Software versions and numerical implementation can matter as well. Reproducibility therefore means documenting the simulation’s random-number machinery and its execution context, not merely writing down one integer.

Definition: A random-number generator (RNG) is an algorithm that produces a sequence of values intended to behave like random draws. A seed initializes the generator’s state. Given the same initial state, algorithm, and sequence of requests, a deterministic pseudo-random generator returns the same sequence of values.

For trial calibration, the simulated result is produced by a pipeline: the RNG supplies values, the data-generating mechanism turns them into hypothetical trial data, and the trial procedure maps those data to an output such as a decision or an estimated treatment effect. Reproducing the full result requires keeping these parts consistent. A replay can fail even if the seed is unchanged—for example, if a code edit changes the order of random-number requests or a software update changes the generator or a distribution-sampling routine.

How a Seed Determines a Sequence

A deterministic generator can be described using an internal state \(S_k\), a state-update rule \(g\), and an output rule \(h\). Starting at \(S_0\), it updates the state and produces values in sequence. This simple description also shows why the seed cannot identify the sequence on its own: the update and output rules must be specified too.

$$ S_{k+1}=g(S_k), \qquad U_k=h(S_k) $$

The following toy generator is small enough to calculate by hand. It is for explanation only, not for clinical-trial simulation. Let \(S_0=3\), update by \(S_{k+1}=(5S_k+1)\bmod 16\), and output \(U_k=S_k/16\) after each update. The modulus operation keeps the state between 0 and 15.

Worked Example: Replaying a Toy Generator

Starting from seed state 3, calculate the first four states and outputs using the stated toy generator.

The first update gives \(S_1=(5(3)+1)\bmod 16=16\bmod 16=0\), so \(U_1=0/16=0\). Next, \(S_2=(5(0)+1)\bmod 16=1\), giving \(U_2=1/16=0.0625\). Then \(S_3=(5(1)+1)\bmod 16=6\), giving \(U_3=6/16=0.375\). Finally, \(S_4=(5(6)+1)\bmod 16=31\bmod 16=15\), giving \(U_4=15/16=0.9375\).

The same seed and rules reproduce the same four outputs. Changing the seed or either rule can produce a different sequence. This example does not establish that the toy generator is statistically adequate; in fact, its tiny state space and short possible cycle make it unsuitable for serious simulation.

The key justification is deterministic replay. If two runs begin with the same state and use the same state-update rule, their first states after an update are equal. Applying the same rule to equal states gives equal next states; repeating this argument shows that every subsequent state—and therefore every output—is equal, provided the program requests values in the same order.

$$ S_0^{(A)}=S_0^{(B)} \quad\Longrightarrow\quad S_k^{(A)}=S_k^{(B)} \text{ for every } k $$

This reasoning applies to the generator sequence, not automatically to the entire simulation. For example, inverse-CDF sampling may use one uniform draw per simulated observation, whereas a rejection-based sampler may consume a variable number of draws. If an implementation changes, later requests can receive different values even when the initial seed is unchanged.

Reproducibility in a Trial Simulation

A simulated trial should be specified well enough that another analyst can reconstruct the random inputs and the operations applied to them. For each run, record the RNG algorithm and seed, the software and relevant package versions, the data-generating assumptions, the trial procedure, and the mapping from random values to simulated quantities. State whether the goal is exact replay in one environment or agreement across different environments.

For a simple illustration, suppose a hypothetical two-arm trial has four participants per arm. Under a specified scenario, each treatment participant has response probability \(p_T=0.60\), and each control participant has response probability \(p_C=0.40\). For this example, responses are generated independently using \(Y=1\) when \(U<p\) and \(Y=0\) otherwise, where \(U\) is uniform on \([0,1)\). This defines the response-generation rule and assumes independent responses with the stated probabilities. A hypothetical decision rule declares success when the observed treatment response proportion exceeds the control response proportion by at least 0.25. The rule is used here only to illustrate reproducible execution.

Worked Example: Replaying a Hypothetical Trial Replicate

Suppose the recorded uniform values for the treatment arm are \(0.12, 0.71, 0.44, 0.91\), and for the control arm are \(0.30, 0.58, 0.19, 0.83\). Apply the response-generation rule and the stated decision rule.

For treatment, compare each value with \(0.60\): the responses are \(1,0,1,0\), because \(0.12<0.60\), \(0.71\not<0.60\), \(0.44<0.60\), and \(0.91\not<0.60\). Thus \(\hat{p}_T=2/4=0.50\). For control, compare with \(0.40\): the responses are \(1,0,1,0\), so \(\hat{p}_C=2/4=0.50\).

The observed difference is \(\hat{p}_T-\hat{p}_C=0.50-0.50=0.00\). Since \(0.00\) is less than the required 0.25, this replicate does not meet the decision rule. If the generator, seed, trial specification, and request order reproduce the listed uniforms, the simulated responses and decision reproduce as well.

A simulation estimates an operating characteristic by aggregating replicate-level results. For instance, if two hypothetical replicates produce one success and one non-success, the estimated success frequency is \(1/2=0.50\). Replaying the same two replicates should reproduce that value. It does not make the estimate equal to the underlying operating characteristic: Monte Carlo variation remains, and a fresh seed would generally produce different replicates and a different estimate.

Managing Random Streams

A random stream is a designated sequence of pseudo-random values used for a particular part of a computation. Stream management means assigning and documenting streams deliberately, rather than allowing unrelated pieces of code to draw from an implicit shared sequence. For example, a simulation might assign one stream to trial data generation and another to a randomized treatment-allocation step. This can make the code easier to inspect and prevent a change in one component from needlessly shifting the draws used by another.

Separate streams must be generated using a method designed to create distinct streams or substreams. Simply choosing two arbitrary seeds does not, by itself, prove that the resulting sequences are independent or non-overlapping. Record how streams are created, which component uses each stream, and whether stream assignments remain fixed when code changes. If a component’s stream changes, document the change rather than silently reusing an old seed label.

Worked Example: Avoiding an Unintended Stream Shift

Suppose a shared sequence supplies four values for trial responses: \(0.12, 0.71, 0.44, 0.91\). A code edit adds an extra random draw before response generation. The response code then uses \(0.71, 0.44, 0.91\), and the next value in the sequence, rather than the original four values. Even if the seed is unchanged, the simulated responses can change because the requested values have shifted.

Now suppose response generation is assigned its own documented stream, and the additional draw belongs to a separate allocation stream. If the response stream and its request order remain unchanged, its values remain \(0.12, 0.71, 0.44, 0.91\). The edit can still change allocation, but it does not shift the response draws. This separation supports clearer debugging; it is not a guarantee that independently selected seeds produce independent streams.

For nested procedures, distinguish the randomness used to generate trial data from any randomness used inside the analysis. If a decision procedure itself uses simulation, it may draw from a second stream. Record both streams and their roles. Otherwise, a change in the analysis code may alter the random values used for trial generation, making it harder to identify what caused a changed result.

What to Record and How to Diagnose a Failed Replay

A practical simulation record should include enough detail to identify both the random sequence and the computation that consumed it. Useful items include:

  • The RNG algorithm, seed or initial state, and method used to create any additional streams.
  • The programming language, software version, and versions of packages that generate random values or distributions.
  • The simulation code version, scenario settings, sample sizes, and data-generating rules.
  • The order in which streams are assigned and the components that consume each stream.
  • The requested level of reproducibility: identical generated values, identical decisions, or only statistically consistent summaries.

If results do not match, check the layers in order. First compare the recorded seed and generator. Then compare software versions and stream assignments. Next confirm that the scenario, model inputs, and number of requested draws are the same. Finally, check whether the code’s execution order changed, including conditional branches that may consume different numbers of values. Saving selected replicate-level inputs and outputs can help locate the first point of divergence.

Exact bit-for-bit agreement is a stronger requirement than obtaining scientifically similar summaries. Different libraries may transform uniform values into binomial, normal, or other random variates using different algorithms. Floating-point arithmetic, hardware, or execution settings can also affect results. Thus, using the same seed across two environments does not necessarily reproduce identical simulated trials. If exact cross-environment replay is essential, specify and preserve the full computational environment or save the generated random inputs or replicate-level data needed for the comparison.

Common Pitfalls and Alternatives

A common mistake is to say, “The seed is the same, so the simulation must be identical.” That conclusion leaves out the generator, stream structure, software implementation, and order of random-number requests. The correction is to treat the seed as one element of a reproducibility record, then verify that the rest of the simulation pipeline is also held fixed.

ApproachStrengthLimitation
Record only the seedSimple and often sufficient for a quick rerun in unchanged code and software.Does not identify the generator, software implementation, or stream use.
Record a full simulation manifestDocuments the seed, generator, environment, code, scenario, and stream assignments.Exact results can still differ if relevant implementation details are omitted or changed.
Save generated inputs or replicate-level outputsAllows direct inspection and comparison without relying only on regenerating a sequence.Requires storage and careful linkage to the code and scenario that produced them.

Reproducibility is an audit and debugging property, not a way to eliminate Monte Carlo uncertainty. A seed does not make a simulation more accurate, validate its data-generating assumptions, or guarantee that a different seed will produce the same estimate. The assumptions and trial procedure still determine what the simulation estimates; reproducibility makes the calculation traceable.

Key takeaway: A seed can replay a pseudo-random sequence only when the generator and its use are specified. For reliable trial-simulation reproducibility, record the seed together with the algorithm, software environment, stream assignments, simulation settings, and code version.

Check Your Understanding

Answer each question, then compare your reasoning with the solutions below.

  1. Why does recording a seed alone not guarantee the same simulated trial in two software environments?
  2. A data-generation component uses four values from a shared RNG sequence. A code edit adds one random draw before that component runs. What may happen to the generated trial data?
  3. In the hypothetical response model, a control participant has \(p_C=0.40\) and receives \(U=0.37\). What response is generated, and why?
  4. Name two details, other than the seed, that should be recorded to support reproducibility.

Solutions. (1) The environments may use different RNG algorithms, distribution-sampling implementations, software versions, or random-number request orders; the seed does not specify these details. (2) The component may receive later values in the sequence, changing its simulated data even though the seed has not changed. (3) The response is 1 because \(0.37<0.40\), under the stated rule \(Y=1\) when \(U<p_C\). (4) Examples include the RNG algorithm, software and package versions, stream assignments, code version, and scenario settings.

Clinical Biostats