mutlugazete.com

Generating Normally Distributed Random Numbers in Python

Written on

Understanding Normal Random Number Simulation

This document explores the simulation of normal random numbers in Python through the Box-Muller method.

"Inverse Sampling can be applied to various probability distributions, but it is crucial that the cumulative distribution function can be expressed in a closed-form and is invertible."

For normal random variables, the probability density function is represented as follows:

Probability Density Function of Normal Distribution

The error function, denoted as erf(x), plays a significant role in this context. We can also express this function as:

Alternative Expression of the Probability Density Function

Next, we would typically seek an inverse function for ?(z). However, since erf(x) lacks a closed-form inverse, utilizing this method for sampling normally distributed numbers becomes problematic. So, what alternatives do we have?

Polar Coordinate Representation

According to the Box-Muller method, if A and B are two independent uniformly distributed random numbers (e.g., A~Uniform(0,1), B~Uniform(0,1)), you can generate normally distributed random numbers X and Y as follows:

Box-Muller Transformation Formula

While the theoretical underpinnings are intricate and beyond the scope of this discussion, let's see how this works in practice. The following Python script demonstrates this process:

# Generating Normal Random Numbers

# Author: Oscar A. Nieves

# Last updated: July 01, 2021

import matplotlib.pyplot as plt

import numpy as np

plt.close('all')

np.random.seed(0) # Setting the random seed

# Inputs

mu = 0.5

sigma = 0.75

samples = 100000

# Random samples (Uniformly distributed)

A = np.random.rand(samples, 1)

B = np.random.rand(samples, 1)

# Normal random numbers N(mu, sigma^2)

X = np.sqrt(-2 * np.log(A)) * np.cos(2 * np.pi * B)

Y = np.sqrt(-2 * np.log(A)) * np.sin(2 * np.pi * B)

# Compute statistics

EX = round(np.mean(X), 2)

VarX = round(np.var(X), 2)

EY = round(np.mean(Y), 2)

VarY = round(np.var(Y), 2)

# Plot histograms

bins = 50

plt.subplot(1, 2, 1)

plt.hist(X, bins)

plt.xlabel('X ~ N(mu = ' + str(EX) + ', sigma^2 = ' + str(VarX) + ')', fontsize=16)

plt.ylabel('frequency', fontsize=16)

plt.subplot(1, 2, 2)

plt.hist(Y, bins)

plt.xlabel('Y ~ N(mu = ' + str(EY) + ', sigma^2 = ' + str(VarY) + ')', fontsize=16)

plt.ylabel('frequency', fontsize=16)

Upon executing this code, the resulting plots are:

Histogram of Generated Normal Random Variables

Here, we observe that both X and Y exhibit a mean of 0 and a variance of 1, indicating that they conform to a standard normal distribution, as anticipated by the method.

Now, the pressing question is: how can we generate X and Y to have specific means and variances other than 0 and 1? This can be achieved by leveraging the properties of normal random variables. If Z is normally distributed with mean μ and variance σ², we can express this as:

Relationship Between Normal Variables

Consequently, for our scenario, we can express X and Y as:

Adjusted Normal Variable Expressions

By modifying our Python code accordingly:

# Normal random numbers N(mu, sigma^2)

X = mu + sigma * np.sqrt(-2 * np.log(A)) * np.cos(2 * np.pi * B)

Y = mu + sigma * np.sqrt(-2 * np.log(A)) * np.sin(2 * np.pi * B)

we can now achieve:

Histogram of Adjusted Normal Random Variables

Both variables now have a mean of μ = 0.5 and a variance of 0.56 (corresponding to our σ = 0.75).

Now, you are equipped with the knowledge to sample normally distributed random numbers using only uniformly distributed random numbers. Enjoy your exploration!

Chapter 2: Additional Resources

To deepen your understanding, refer to the following videos:

This video explains how to generate random numbers in Python using NumPy, including both floats and integers.

Learn how to generate random numbers in Python, with practical examples and clear explanations.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Unlocking Your Potential: A Journey to Achieving Your Goals

Discover the essential truth for achieving your goals and transforming your life through personal growth and mindset shifts.

Write Freely: Unleash Your Creativity Without Fear of Judgment

Discover how to write without fear of judgment and embrace your unique voice in the world of creativity.

Unlocking the Speed of Python 3.11: What You Need to Know

Discover how Python 3.11 outpaces its predecessor, 3.10, with significant speed enhancements and optimizations.