CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-gmpy2

Multiple-precision arithmetic library providing fast GMP, MPFR, and MPC interfaces for Python

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

random.mddocs/

Random Numbers

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.

Capabilities

Random State Management

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

class random_state:
    def __init__(self, seed=0):
        """
        Create a random number generator state.
        
        Args:
            seed: Seed value for initialization (int, default 0)
        
        Note:
            Different seeds produce different random sequences
            Same seed produces identical sequences (reproducible)
        """

Integer Random Numbers

Functions for generating random integers with various distributions.

def mpz_random(state, n):
    """
    Generate random integer in range [0, n).
    
    Args:
        state: random_state object
        n: Upper bound (exclusive, must be positive)
    
    Returns:
        mpz: Random integer 0 <= result < n
    
    Note:
        Uniform distribution over the specified range
    """

def mpz_urandomb(state, n):
    """
    Generate random integer with exactly n random bits.
    
    Args:
        state: random_state object  
        n: Number of random bits (non-negative integer)
    
    Returns:
        mpz: Random integer in range [0, 2^n)
    
    Note:
        Each bit is independently random with probability 1/2
    """

def mpz_rrandomb(state, n):
    """
    Generate random integer with at most n bits, different distribution.
    
    Args:
        state: random_state object
        n: Maximum number of bits
    
    Returns:
        mpz: Random integer with different bit distribution than urandomb
    
    Note:
        Provides different statistical properties than urandomb
    """

Floating-Point Random Numbers

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

def mpfr_random(state):
    """
    Generate random float in [0, 1) with current precision.
    
    Args:
        state: random_state object
    
    Returns:
        mpfr: Random float 0 <= result < 1
    
    Note:
        Uses current context precision for result
        Uniform distribution over [0, 1)
    """

def mpfr_grandom(state):
    """
    Generate pair of Gaussian random numbers (Box-Muller method).
    
    Args:
        state: random_state object
    
    Returns:
        tuple: (x, y) where both are normally distributed mpfr values
    
    Note:
        Standard normal distribution (mean=0, variance=1)
        More efficient than generating two separate normal values
    """

def mpfr_nrandom(state):
    """
    Generate single normal (Gaussian) random number.
    
    Args:
        state: random_state object
    
    Returns:
        mpfr: Normally distributed random float
    
    Note:
        Standard normal distribution (mean=0, variance=1)
        Uses current context precision
    """

Complex Random Numbers

Function for generating random complex numbers.

def mpc_random(state):
    """
    Generate random complex number.
    
    Args:
        state: random_state object
    
    Returns:
        mpc: Complex number with random real and imaginary parts
    
    Note:
        Both real and imaginary parts are uniform in [0, 1)
        Uses current context precision for both parts
    """

Usage Examples

Basic Random Number Generation

import gmpy2

# Create random state with seed for reproducibility
rstate = gmpy2.random_state(12345)

# Generate random integers
print("Random integers:")
for i in range(5):
    # Random integer in range [0, 1000)
    rand_int = gmpy2.mpz_random(rstate, 1000)
    print(f"  Random [0, 1000): {rand_int}")

# Generate random integers with specific bit lengths  
print("\nRandom integers with specific bit lengths:")
for bits in [8, 16, 32]:
    rand_bits = gmpy2.mpz_urandomb(rstate, bits)
    print(f"  {bits:2d} bits: {rand_bits} (hex: {hex(rand_bits)})")

Reproducible Random Sequences

import gmpy2

def generate_sequence(seed, count=5):
    """Generate a sequence of random numbers with given seed."""
    rstate = gmpy2.random_state(seed)
    sequence = []
    for _ in range(count):
        sequence.append(gmpy2.mpz_random(rstate, 100))
    return sequence

# Same seed produces identical sequences
seed = 42
seq1 = generate_sequence(seed)
seq2 = generate_sequence(seed)

print(f"Sequence 1 (seed {seed}): {seq1}")
print(f"Sequence 2 (seed {seed}): {seq2}")
print(f"Sequences identical: {seq1 == seq2}")

# Different seed produces different sequence
seq3 = generate_sequence(seed + 1)
print(f"Sequence 3 (seed {seed + 1}): {seq3}")
print(f"Different from seq1: {seq1 != seq3}")

High-Precision Random Floating-Point Numbers

import gmpy2

# Generate random floats at different precisions
rstate = gmpy2.random_state(98765)

precisions = [24, 53, 100, 200]
print("Random floats at different precisions:")

for prec in precisions:
    with gmpy2.local_context(precision=prec):
        rand_float = gmpy2.mpfr_random(rstate)
        print(f"  {prec:3d} bits: {rand_float}")

# Generate multiple random floats
print("\nMultiple random floats (53-bit precision):")
with gmpy2.local_context(precision=53):
    for i in range(5):
        rand_float = gmpy2.mpfr_random(rstate)
        print(f"  Random [0, 1): {rand_float}")

Gaussian (Normal) Random Numbers

import gmpy2

rstate = gmpy2.random_state(54321)

# Generate individual normal random numbers
print("Individual normal random numbers:")
with gmpy2.local_context(precision=80):
    for i in range(5):
        normal = gmpy2.mpfr_nrandom(rstate)
        print(f"  N(0,1): {normal}")

# Generate pairs of normal random numbers (more efficient)
print("\nPairs of normal random numbers:")
with gmpy2.local_context(precision=80):
    for i in range(3):
        x, y = gmpy2.mpfr_grandom(rstate)
        print(f"  Pair {i+1}: ({x}, {y})")

Complex Random Numbers

import gmpy2

rstate = gmpy2.random_state(11111)

print("Random complex numbers:")
with gmpy2.local_context(precision=60):
    for i in range(5):
        rand_complex = gmpy2.mpc_random(rstate)
        print(f"  Complex: {rand_complex}")
        print(f"    Magnitude: {gmpy2.abs(rand_complex)}")
        print(f"    Phase: {gmpy2.phase(rand_complex)}")

Statistical Analysis

import gmpy2

def analyze_random_bits(state, bit_length, count=1000):
    """Analyze distribution of random bits."""
    bit_counts = [0] * bit_length
    
    for _ in range(count):
        rand_num = gmpy2.mpz_urandomb(state, bit_length)
        for bit_pos in range(bit_length):
            if gmpy2.bit_test(rand_num, bit_pos):
                bit_counts[bit_pos] += 1
    
    return bit_counts

# Analyze 8-bit random numbers
rstate = gmpy2.random_state(99999)
bit_analysis = analyze_random_bits(rstate, 8, 10000)

print("Bit position analysis (8-bit random numbers, 10000 samples):")
for pos, count in enumerate(bit_analysis):
    percentage = (count / 10000) * 100
    print(f"  Bit {pos}: {count:4d} set ({percentage:5.1f}%)")

# Should be approximately 50% for each bit position

Cryptographic Random Numbers

import gmpy2

def generate_large_random_prime_candidate(bits, rstate):
    """Generate a large random odd number (prime candidate)."""
    # Generate random number with specified bits
    candidate = gmpy2.mpz_urandomb(rstate, bits)
    
    # Ensure it's odd (required for prime)
    candidate = gmpy2.bit_set(candidate, 0)
    
    # Ensure high bit is set (full bit length)
    candidate = gmpy2.bit_set(candidate, bits - 1)
    
    return candidate

# Generate potential cryptographic prime candidates
rstate = gmpy2.random_state(12345678)

print("Large prime candidates for cryptographic use:")
for key_size in [512, 1024, 2048]:
    candidate = generate_large_random_prime_candidate(key_size, rstate)
    
    # Quick primality check
    is_prime = gmpy2.is_prime(candidate, 25)
    
    print(f"\n{key_size}-bit candidate:")
    print(f"  Hex: {hex(candidate)[:50]}...")
    print(f"  Bit length: {gmpy2.bit_length(candidate)}")
    print(f"  Is prime: {is_prime}")
    
    if is_prime:
        print(f"  Found prime!")
        break  # In practice, you'd save this prime

Random Range Operations

import gmpy2

def random_in_range(state, min_val, max_val):
    """Generate random number in specific range [min_val, max_val]."""
    if min_val >= max_val:
        raise ValueError("min_val must be less than max_val")
    
    range_size = max_val - min_val + 1
    return gmpy2.mpz_random(state, range_size) + min_val

# Generate random numbers in custom ranges
rstate = gmpy2.random_state(777)

ranges = [
    (100, 200),      # Small range
    (1000, 9999),    # 4-digit numbers
    (2**30, 2**31),  # Large range
]

print("Random numbers in custom ranges:")
for min_val, max_val in ranges:
    for _ in range(3):
        rand_val = random_in_range(rstate, min_val, max_val)
        print(f"  [{min_val}, {max_val}]: {rand_val}")

Monte Carlo Simulation

import gmpy2

def estimate_pi_monte_carlo(n_points, precision=100):
    """Estimate π using Monte Carlo method with high precision."""
    rstate = gmpy2.random_state(314159)
    inside_circle = 0
    
    with gmpy2.local_context(precision=precision):
        for _ in range(n_points):
            # Generate point in unit square [0,1) × [0,1)
            x = gmpy2.mpfr_random(rstate)
            y = gmpy2.mpfr_random(rstate)
            
            # Check if point is inside unit circle
            if x*x + y*y < 1:
                inside_circle += 1
        
        # Estimate π = 4 × (points inside circle) / (total points)
        pi_estimate = 4 * gmpy2.mpfr(inside_circle) / n_points
        return pi_estimate

# Estimate π with different sample sizes
print("Monte Carlo estimation of π:")
for n in [1000, 10000, 100000]:
    pi_est = estimate_pi_monte_carlo(n, precision=80)
    actual_pi = gmpy2.const_pi(precision=80)
    error = abs(pi_est - actual_pi)
    
    print(f"  {n:6d} points: {pi_est}")
    print(f"    Error: {error}")

Parallel Random Number Generation

import gmpy2

def create_independent_generators(master_seed, count):
    """Create multiple independent random number generators."""
    generators = []
    
    # Use master generator to create seeds for independent generators
    master_rstate = gmpy2.random_state(master_seed)
    
    for i in range(count):
        # Generate a unique seed for each generator
        seed = gmpy2.mpz_random(master_rstate, 2**32)
        generators.append(gmpy2.random_state(int(seed)))
    
    return generators

# Create independent generators for parallel use
generators = create_independent_generators(123456, 4)

print("Independent random number generators:")
for i, gen in enumerate(generators):
    sequence = []
    for _ in range(5):
        sequence.append(gmpy2.mpz_random(gen, 1000))
    print(f"  Generator {i}: {sequence}")

# Verify independence (sequences should be different)
all_sequences = []
for gen in generators:
    seq = [gmpy2.mpz_random(gen, 100) for _ in range(10)]
    all_sequences.append(seq)

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

Install with Tessl CLI

npx tessl i tessl/pypi-gmpy2

docs

arithmetic.md

bit-operations.md

context.md

data-types.md

index.md

math-functions.md

number-theory.md

random.md

utilities.md

tile.json