Generating Random Variables From A Uniform Distribution

Generating Random Variables From A Uniform Distribution#

The most general technique for generating random variables with a specified distribution involves starting with a uniformly distributed random variable \( \mathbf{u} \) over the interval \([0, 1]\).

Then, you perform the transformation:

\[ \mathbf{x} = F_{\mathbf{x}}^{-1}(u) \]

where \( F_{\mathbf{x}} \) is the cumulative distribution function (CDF) of \( \mathbf{x} \).

Example: Exponential Random Variable Generation from Uniform Distribution#

To generating an exponential random variable from a uniform distribution, we follow these steps:

Start with a Uniform Random Variable

Let \( u \) be a random variable uniformly distributed between 0 and 1, denoted as \( \mathbf{u} \sim U(0, 1) \). This means that \( u \) can take any value in the interval \([0, 1]\) with equal probability.

Define the PDF of the Target Distribution

Assume that we want to generate a random variable \( \mathbf{x} \) that follows an exponential distribution. The probability density function (PDF) of an exponentially distributed random variable with rate parameter \( \lambda = 1 \) is:

\[ p_{\mathbf{x}}(x) = e^{-x}, \quad x \geq 0 \]

This PDF describes the likelihood of different values of \( x \) occurring. The parameter \( \lambda \) controls the rate at which the distribution decays; here, \( \lambda = 1 \) for simplicity.

Determine the CDF of the Target Distribution

The cumulative distribution function (CDF) \( F_{\mathbf{x}}(x) \) gives the probability that the random variable \( \mathbf{x} \) is less than or equal to a specific value \( x \). For an exponential distribution, the CDF is:

\[ F_{\mathbf{x}}(x) = 1 - e^{-x}, \quad x \geq 0 \]

This function accumulates the probabilities from the PDF and represents the total probability up to a certain point \( x \).

Use the Inverse CDF Transformation

To generate a value of \( \mathbf{x} \) from a given uniform random variable \( u \), we use the inverse CDF transformation. The inverse CDF method transforms the uniform random variable into a random variable with the desired distribution. For this example, we set the CDF equal to the uniform variable \( u \) and solve for \( x \):

\[ u = F_{\mathbf{x}}(x) = 1 - e^{-x} \]

Rearrange the equation to solve for \( x \):

\[ e^{-x} = 1 - u \]
\[ -x = \ln(1 - u) \]
\[ x = -\ln(1 - u) \]

Thus, the transformation \( x = -\ln(1 - u) \) converts the uniformly distributed random variable \( u \) into an exponentially distributed random variable \( x \).

Generate the Exponential Random Variable

To generate a sample \( x \), we first generate a sample \( u \) from the uniform distribution \( U(0, 1) \). Then, apply the transformation \( x = -\ln(1 - u) \) to obtain the corresponding value from the exponential distribution.

This process can be repeated to generate multiple samples from the exponential distribution, each time starting with a new independent uniform random variable \( u \).

Simulation#

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import expon

# Set the seed for reproducibility
np.random.seed(0)

# Number of samples to generate
n_samples = 10000

# Method 1: Generate from uniform distribution and transform using inverse CDF
u = np.random.uniform(0, 1, n_samples)
x_empirical = -np.log(1 - u)

# Method 2: Using built-in exponential distribution generator
x_builtin = np.random.exponential(scale=1.0, size=n_samples)

# Plot the histograms
plt.figure(figsize=(12, 6))

# Histogram of empirical x
plt.hist(x_empirical, bins=50, density=True, alpha=0.3, label='Empirical $x$ from $u$')

# Histogram of built-in x
plt.hist(x_builtin, bins=100, density=True, alpha=0.3, label='Built-in $x$ from numpy')


# Generate the x values
x_vals = np.linspace(0, 10, 1000)

# Theoretical PDF using scipy
pdf_scipy = expon.pdf(x_vals)

# Theoretical PDF using the expression p_x(x) = e^{-x}
pdf_expr = np.exp(-x_vals)

# Plot the scipy.stats.expon PDF
plt.plot(x_vals, pdf_scipy, 'b-', lw=2, label='Theoretical PDF (scipy.stats.expon)')

# Plot the PDF using the expression p_x(x) = e^{-x}
plt.plot(x_vals, pdf_expr, 'r--', lw=2, label='$p_{\\mathbf{x}}(x) = e^{-x}$')

# Labels and title
plt.xlabel('x')
plt.ylabel('Density')
plt.title('Comparison of Exponential Distribution Generation Methods')
plt.legend()
plt.grid(True)
plt.show()
_images/39a392af03c6ddd48c4b3a38a03c13335dac20d55945b9ad7cc5128eadfc0834.png

Schonhoff’s Method#

import numpy as np

def exprv(num):
    """
    Generate exponentially distributed random variables.

    Parameters:
    num (int): Number of random variables to generate.

    Returns:
    numpy.ndarray: Array of exponentially distributed random variables.
    """
    # Set the random seed for reproducibility
    np.random.seed(0)
    
    # Generate uniformly distributed random variables in the range (0, 1)
    u = np.random.rand(num)
    
    # Transform to exponentially distributed random variables using -log(u)
    ex = -np.log(u)
    
    return ex

# Example usage
num = 5  # Number of random variables to generate
exponential_rvs = exprv(num)
print("Exponentially distributed random variables:", exponential_rvs)
Exponentially distributed random variables: [0.5999966  0.33520792 0.50623057 0.60718385 0.85883631]
import numpy as np
import matplotlib.pyplot as plt

def ete(num):
    """
    Theoretical and Empirical PDFs of Exponentially distributed random numbers.

    Parameters:
    num (int): Number of random variables (RVs) to generate.

    Outputs:
    Displays the theoretical PDF and the empirical PDF.
    """
    # Generate uniformly distributed random variables
    u = np.random.rand(num)
    
    # Convert to exponentially distributed random variables
    z = -np.log(u)
    
    # Create a range for x values
    x = np.arange(0, 10.1, 0.1)
    
    # Compute the empirical PDF using histogram
    et, bin_edges = np.histogram(z, bins=x, density=False)
    
    # Normalize the empirical PDF
    n10 = num / 10
    nznorm = et / n10
    
    # Plot the empirical PDF
    plt.plot(bin_edges[:-1], nznorm, 'b', label='Empirical PDF')
    
    # Compute and plot the theoretical PDF
    y = np.exp(-x)
    plt.plot(x, y, 'r', label='Theoretical PDF')
    
    # Add labels, grid, and legend
    plt.xlabel('x')
    plt.ylabel('PDF')
    plt.grid(True)
    plt.legend()
    
    # Display the plot
    plt.show()

# Example usage
ete(1000)  # Generate and plot the PDFs using 1000 random variables
_images/746645bb46aea7c91d675bc240f47b9c6264cbc0ba6a8695d0680bdc3b923dd9.png