or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arithmetic.mdbit-operations.mdcontext.mddata-types.mdindex.mdmath-functions.mdnumber-theory.mdrandom.mdutilities.md

random.mddocs/

0

# Random Numbers

1

2

gmpy2 provides comprehensive random number generation capabilities for all multiple-precision types. The random number system uses configurable random state objects and provides various distributions suitable for cryptographic, statistical, and mathematical applications.

3

4

## Capabilities

5

6

### Random State Management

7

8

Random state objects manage the internal state of random number generators, enabling reproducible sequences and parallel random number generation.

9

10

```python { .api }

11

class random_state:

12

def __init__(self, seed=0):

13

"""

14

Create a random number generator state.

15

16

Args:

17

seed: Seed value for initialization (int, default 0)

18

19

Note:

20

Different seeds produce different random sequences

21

Same seed produces identical sequences (reproducible)

22

"""

23

```

24

25

### Integer Random Numbers

26

27

Functions for generating random integers with various distributions.

28

29

```python { .api }

30

def mpz_random(state, n):

31

"""

32

Generate random integer in range [0, n).

33

34

Args:

35

state: random_state object

36

n: Upper bound (exclusive, must be positive)

37

38

Returns:

39

mpz: Random integer 0 <= result < n

40

41

Note:

42

Uniform distribution over the specified range

43

"""

44

45

def mpz_urandomb(state, n):

46

"""

47

Generate random integer with exactly n random bits.

48

49

Args:

50

state: random_state object

51

n: Number of random bits (non-negative integer)

52

53

Returns:

54

mpz: Random integer in range [0, 2^n)

55

56

Note:

57

Each bit is independently random with probability 1/2

58

"""

59

60

def mpz_rrandomb(state, n):

61

"""

62

Generate random integer with at most n bits, different distribution.

63

64

Args:

65

state: random_state object

66

n: Maximum number of bits

67

68

Returns:

69

mpz: Random integer with different bit distribution than urandomb

70

71

Note:

72

Provides different statistical properties than urandomb

73

"""

74

```

75

76

### Floating-Point Random Numbers

77

78

Functions for generating random floating-point numbers with various precisions and distributions.

79

80

```python { .api }

81

def mpfr_random(state):

82

"""

83

Generate random float in [0, 1) with current precision.

84

85

Args:

86

state: random_state object

87

88

Returns:

89

mpfr: Random float 0 <= result < 1

90

91

Note:

92

Uses current context precision for result

93

Uniform distribution over [0, 1)

94

"""

95

96

def mpfr_grandom(state):

97

"""

98

Generate pair of Gaussian random numbers (Box-Muller method).

99

100

Args:

101

state: random_state object

102

103

Returns:

104

tuple: (x, y) where both are normally distributed mpfr values

105

106

Note:

107

Standard normal distribution (mean=0, variance=1)

108

More efficient than generating two separate normal values

109

"""

110

111

def mpfr_nrandom(state):

112

"""

113

Generate single normal (Gaussian) random number.

114

115

Args:

116

state: random_state object

117

118

Returns:

119

mpfr: Normally distributed random float

120

121

Note:

122

Standard normal distribution (mean=0, variance=1)

123

Uses current context precision

124

"""

125

```

126

127

### Complex Random Numbers

128

129

Function for generating random complex numbers.

130

131

```python { .api }

132

def mpc_random(state):

133

"""

134

Generate random complex number.

135

136

Args:

137

state: random_state object

138

139

Returns:

140

mpc: Complex number with random real and imaginary parts

141

142

Note:

143

Both real and imaginary parts are uniform in [0, 1)

144

Uses current context precision for both parts

145

"""

146

```

147

148

## Usage Examples

149

150

### Basic Random Number Generation

151

152

```python

153

import gmpy2

154

155

# Create random state with seed for reproducibility

156

rstate = gmpy2.random_state(12345)

157

158

# Generate random integers

159

print("Random integers:")

160

for i in range(5):

161

# Random integer in range [0, 1000)

162

rand_int = gmpy2.mpz_random(rstate, 1000)

163

print(f" Random [0, 1000): {rand_int}")

164

165

# Generate random integers with specific bit lengths

166

print("\nRandom integers with specific bit lengths:")

167

for bits in [8, 16, 32]:

168

rand_bits = gmpy2.mpz_urandomb(rstate, bits)

169

print(f" {bits:2d} bits: {rand_bits} (hex: {hex(rand_bits)})")

170

```

171

172

### Reproducible Random Sequences

173

174

```python

175

import gmpy2

176

177

def generate_sequence(seed, count=5):

178

"""Generate a sequence of random numbers with given seed."""

179

rstate = gmpy2.random_state(seed)

180

sequence = []

181

for _ in range(count):

182

sequence.append(gmpy2.mpz_random(rstate, 100))

183

return sequence

184

185

# Same seed produces identical sequences

186

seed = 42

187

seq1 = generate_sequence(seed)

188

seq2 = generate_sequence(seed)

189

190

print(f"Sequence 1 (seed {seed}): {seq1}")

191

print(f"Sequence 2 (seed {seed}): {seq2}")

192

print(f"Sequences identical: {seq1 == seq2}")

193

194

# Different seed produces different sequence

195

seq3 = generate_sequence(seed + 1)

196

print(f"Sequence 3 (seed {seed + 1}): {seq3}")

197

print(f"Different from seq1: {seq1 != seq3}")

198

```

199

200

### High-Precision Random Floating-Point Numbers

201

202

```python

203

import gmpy2

204

205

# Generate random floats at different precisions

206

rstate = gmpy2.random_state(98765)

207

208

precisions = [24, 53, 100, 200]

209

print("Random floats at different precisions:")

210

211

for prec in precisions:

212

with gmpy2.local_context(precision=prec):

213

rand_float = gmpy2.mpfr_random(rstate)

214

print(f" {prec:3d} bits: {rand_float}")

215

216

# Generate multiple random floats

217

print("\nMultiple random floats (53-bit precision):")

218

with gmpy2.local_context(precision=53):

219

for i in range(5):

220

rand_float = gmpy2.mpfr_random(rstate)

221

print(f" Random [0, 1): {rand_float}")

222

```

223

224

### Gaussian (Normal) Random Numbers

225

226

```python

227

import gmpy2

228

229

rstate = gmpy2.random_state(54321)

230

231

# Generate individual normal random numbers

232

print("Individual normal random numbers:")

233

with gmpy2.local_context(precision=80):

234

for i in range(5):

235

normal = gmpy2.mpfr_nrandom(rstate)

236

print(f" N(0,1): {normal}")

237

238

# Generate pairs of normal random numbers (more efficient)

239

print("\nPairs of normal random numbers:")

240

with gmpy2.local_context(precision=80):

241

for i in range(3):

242

x, y = gmpy2.mpfr_grandom(rstate)

243

print(f" Pair {i+1}: ({x}, {y})")

244

```

245

246

### Complex Random Numbers

247

248

```python

249

import gmpy2

250

251

rstate = gmpy2.random_state(11111)

252

253

print("Random complex numbers:")

254

with gmpy2.local_context(precision=60):

255

for i in range(5):

256

rand_complex = gmpy2.mpc_random(rstate)

257

print(f" Complex: {rand_complex}")

258

print(f" Magnitude: {gmpy2.abs(rand_complex)}")

259

print(f" Phase: {gmpy2.phase(rand_complex)}")

260

```

261

262

### Statistical Analysis

263

264

```python

265

import gmpy2

266

267

def analyze_random_bits(state, bit_length, count=1000):

268

"""Analyze distribution of random bits."""

269

bit_counts = [0] * bit_length

270

271

for _ in range(count):

272

rand_num = gmpy2.mpz_urandomb(state, bit_length)

273

for bit_pos in range(bit_length):

274

if gmpy2.bit_test(rand_num, bit_pos):

275

bit_counts[bit_pos] += 1

276

277

return bit_counts

278

279

# Analyze 8-bit random numbers

280

rstate = gmpy2.random_state(99999)

281

bit_analysis = analyze_random_bits(rstate, 8, 10000)

282

283

print("Bit position analysis (8-bit random numbers, 10000 samples):")

284

for pos, count in enumerate(bit_analysis):

285

percentage = (count / 10000) * 100

286

print(f" Bit {pos}: {count:4d} set ({percentage:5.1f}%)")

287

288

# Should be approximately 50% for each bit position

289

```

290

291

### Cryptographic Random Numbers

292

293

```python

294

import gmpy2

295

296

def generate_large_random_prime_candidate(bits, rstate):

297

"""Generate a large random odd number (prime candidate)."""

298

# Generate random number with specified bits

299

candidate = gmpy2.mpz_urandomb(rstate, bits)

300

301

# Ensure it's odd (required for prime)

302

candidate = gmpy2.bit_set(candidate, 0)

303

304

# Ensure high bit is set (full bit length)

305

candidate = gmpy2.bit_set(candidate, bits - 1)

306

307

return candidate

308

309

# Generate potential cryptographic prime candidates

310

rstate = gmpy2.random_state(12345678)

311

312

print("Large prime candidates for cryptographic use:")

313

for key_size in [512, 1024, 2048]:

314

candidate = generate_large_random_prime_candidate(key_size, rstate)

315

316

# Quick primality check

317

is_prime = gmpy2.is_prime(candidate, 25)

318

319

print(f"\n{key_size}-bit candidate:")

320

print(f" Hex: {hex(candidate)[:50]}...")

321

print(f" Bit length: {gmpy2.bit_length(candidate)}")

322

print(f" Is prime: {is_prime}")

323

324

if is_prime:

325

print(f" Found prime!")

326

break # In practice, you'd save this prime

327

```

328

329

### Random Range Operations

330

331

```python

332

import gmpy2

333

334

def random_in_range(state, min_val, max_val):

335

"""Generate random number in specific range [min_val, max_val]."""

336

if min_val >= max_val:

337

raise ValueError("min_val must be less than max_val")

338

339

range_size = max_val - min_val + 1

340

return gmpy2.mpz_random(state, range_size) + min_val

341

342

# Generate random numbers in custom ranges

343

rstate = gmpy2.random_state(777)

344

345

ranges = [

346

(100, 200), # Small range

347

(1000, 9999), # 4-digit numbers

348

(2**30, 2**31), # Large range

349

]

350

351

print("Random numbers in custom ranges:")

352

for min_val, max_val in ranges:

353

for _ in range(3):

354

rand_val = random_in_range(rstate, min_val, max_val)

355

print(f" [{min_val}, {max_val}]: {rand_val}")

356

```

357

358

### Monte Carlo Simulation

359

360

```python

361

import gmpy2

362

363

def estimate_pi_monte_carlo(n_points, precision=100):

364

"""Estimate π using Monte Carlo method with high precision."""

365

rstate = gmpy2.random_state(314159)

366

inside_circle = 0

367

368

with gmpy2.local_context(precision=precision):

369

for _ in range(n_points):

370

# Generate point in unit square [0,1) × [0,1)

371

x = gmpy2.mpfr_random(rstate)

372

y = gmpy2.mpfr_random(rstate)

373

374

# Check if point is inside unit circle

375

if x*x + y*y < 1:

376

inside_circle += 1

377

378

# Estimate π = 4 × (points inside circle) / (total points)

379

pi_estimate = 4 * gmpy2.mpfr(inside_circle) / n_points

380

return pi_estimate

381

382

# Estimate π with different sample sizes

383

print("Monte Carlo estimation of π:")

384

for n in [1000, 10000, 100000]:

385

pi_est = estimate_pi_monte_carlo(n, precision=80)

386

actual_pi = gmpy2.const_pi(precision=80)

387

error = abs(pi_est - actual_pi)

388

389

print(f" {n:6d} points: {pi_est}")

390

print(f" Error: {error}")

391

```

392

393

### Parallel Random Number Generation

394

395

```python

396

import gmpy2

397

398

def create_independent_generators(master_seed, count):

399

"""Create multiple independent random number generators."""

400

generators = []

401

402

# Use master generator to create seeds for independent generators

403

master_rstate = gmpy2.random_state(master_seed)

404

405

for i in range(count):

406

# Generate a unique seed for each generator

407

seed = gmpy2.mpz_random(master_rstate, 2**32)

408

generators.append(gmpy2.random_state(int(seed)))

409

410

return generators

411

412

# Create independent generators for parallel use

413

generators = create_independent_generators(123456, 4)

414

415

print("Independent random number generators:")

416

for i, gen in enumerate(generators):

417

sequence = []

418

for _ in range(5):

419

sequence.append(gmpy2.mpz_random(gen, 1000))

420

print(f" Generator {i}: {sequence}")

421

422

# Verify independence (sequences should be different)

423

all_sequences = []

424

for gen in generators:

425

seq = [gmpy2.mpz_random(gen, 100) for _ in range(10)]

426

all_sequences.append(seq)

427

428

print(f"\nAll sequences different: {len(set(map(tuple, all_sequences))) == len(all_sequences)}")

429

```