Written and maintained by CASRAI Editorial Board
Last updated
The randn function in MATLAB generates arrays of pseudorandom numbers drawn from a standard normal distribution with a mean of zero (μ = 0), a variance of one (σ² = 1), and a standard deviation of one (σ = 1). In scientific computing, simulation modeling, and data analysis, randn provides the core engine for creating Gaussian variables, simulating physical noise processes, and executing stochastic algorithms.
What it is used for in research
Researchers across physical, biological, engineering, and social sciences rely on randn to model natural variability and evaluate systems under uncertainty. While the companion function rand in MATLAB draws values from a uniform distribution over the open interval (0, 1), randn produces values that follow the characteristic bell-shaped Gaussian probability density curve, with approximately 68.27% of values falling within [-1, 1], 95.45% within [-2, 2], and 99.73% within [-3, 3].
Primary research applications include:
- Monte Carlo Simulations: Evaluating high-dimensional integrals, probabilistic risk assessments, and parameter sensitivity in computational physics and financial economics.
- Stochastic Differential Equations: Simulating continuous-time Brownian motion and diffusion processes in computational chemistry and biological kinetics.
- Additive White Gaussian Noise (AWGN): Modeling thermal noise and measurement disturbance in signal analysis in MATLAB, radar tracking, and digital telecommunication channels.
- Statistical Testing and Synthetic Controls: Generating synthetic null distributions, bootstrapping confidence intervals, and validating statistical classifiers against ground-truth parameters.
- Machine Learning and Optimization: Initializing neural network weight matrices and generating random perturbations for simulated annealing or genetic algorithms.
Install or access (official source only)
The randn function is a built-in core capability of the MATLAB environment developed by MathWorks. It requires no specialized toolbox, add-on package, or secondary library.
Authorized access routes include:
- MATLAB Desktop: Installed on Windows, macOS, or Linux via an institutional, individual, or academic license acquired through the official MathWorks portal (mathworks.com).
- MATLAB Online: Browser-accessible cloud environment provided directly by MathWorks, supporting identical
randnsyntax without local installation. - MATLAB Drive and Mobile: Mobile execution platforms synced through official MathWorks cloud licensing.
Step-by-step task
This tutorial walks through creating normally distributed random arrays, transforming them to arbitrary target means and variances, ensuring computational reproducibility, and generating complex noise.
Step 1: Generate Standard Normal Scalars, Vectors, and Matrices
The randn function offers flexible syntax to define array dimensions. By default, all generated arrays contain 64-bit double-precision floating-point numbers.
% 1. Generate a single random scalar
val = randn;
% 2. Generate a 1-by-5 row vector
row_vec = randn(1, 5);
% 3. Generate a 5-by-1 column vector
col_vec = randn(5, 1);
% 4. Generate a 3-by-4 matrix (2D array)
mat_2d = randn(3, 4);
% 5. Generate a 2-by-3-by-4 multi-dimensional tensor (3D array)
tensor_3d = randn(2, 3, 4);
% 6. Match dimensions to an existing array A
A = zeros(4, 6);
matched_array = randn(size(A));
Step 2: Transform to Custom Mean and Variance
Because randn strictly outputs values from the standard normal distribution $mathcal{N}(0, 1)$, generating values from an arbitrary normal distribution $mathcal{N}(mu, sigma^2)$ requires a linear transformation. Multiply the generated output by the desired standard deviation (σ) and add the desired mean (μ):
% Define target parameters
target_mu = 100; % Desired mean (μ)
target_variance = 25; % Desired variance (σ²)
target_sigma = sqrt(target_variance); % Standard deviation (σ = 5)
% Generate 10,000 samples with mean 100 and variance 25
samples = target_mu + target_sigma * randn(10000, 1);
% Confirm empirical parameters
empirical_mean = mean(samples);
empirical_std = std(samples);
fprintf('Mean: %.3f (Target: %d)n', empirical_mean, target_mu);
fprintf('Std Dev: %.3f (Target: %d)n', empirical_std, target_sigma);
Step 3: Ensure Reproducibility Using RNG Seeds
Scientific rigor demands that stochastic simulations produce reproducible results across script executions and peer replication studies. In MATLAB, the global pseudorandom generator is controlled using the rng function rather than deprecated function-level syntax.
% Set a deterministic seed using the standard Mersenne Twister algorithm
rng(42, 'twister');
first_run = randn(1, 4);
% Reset the exact same seed to reproduce identical values
rng(42, 'twister');
second_run = randn(1, 4);
% Verify equality
isequal(first_run, second_run) % Returns logical 1 (true)
% Save current generator state before temporary operations
saved_state = rng;
% Re-seed based on system clock for non-repeatable exploratory runs
rng('shuffle');
% Restore previous deterministic state
rng(saved_state);
Step 4: Generate Complex Gaussian Noise for Signal Modeling
In telecommunications, radar, and magnetic resonance imaging (MRI), researchers frequently model circularly symmetric complex Gaussian noise. To produce zero-mean complex noise with unit total variance $mathbb{E}[|Z|^2] = 1$, scale two independent standard normal vectors by $1/sqrt{2}$:
% Sample count
N = 100000;
% Real and imaginary independent components
X = randn(N, 1);
Y = randn(N, 1);
% Complex circular Gaussian noise with unit total power
Z = (X + 1i * Y) / sqrt(2);
% Check empirical power: mean(|Z|^2) should approach 1.0
noise_power = mean(abs(Z).^2);
fprintf('Total complex noise power: %.4fn', noise_power);
To optimize execution speed across massive arrays, combine this pattern with techniques to vectorize array operations in MATLAB.
Step 5: Reduce Memory Overhead with Single Precision
By default, double-precision arrays consume 8 bytes per element. For large-scale Monte Carlo trials requiring tens of millions of samples, generating single-precision floats (4 bytes per element) halves memory requirements.
% Generate a 10,000,000-element vector in single precision (approx. 40 MB vs 80 MB)
single_data = randn(1e7, 1, 'single');
% Match precision and data type to an existing prototype array
prototype = single(ones(100, 100));
matched_data = randn(size(prototype), 'like', prototype);
Output and how to read it
The output of randn is a dense numeric array matching the dimensions requested. To interpret and validate the statistical characteristics of the generated output, evaluate sample moments and distribution histograms:
% Generate sample dataset
data = randn(100000, 1);
% 1. Evaluate sample mean (theoretical value: 0)
m = mean(data);
% 2. Evaluate sample standard deviation (theoretical value: 1)
s = std(data);
% 3. Evaluate sample variance (theoretical value: 1)
v = var(data);
% 4. Evaluate skewness and kurtosis
sk = skewness(data); % Approaches 0 for normal distribution
kt = kurtosis(data); % Approaches 3 for normal distribution
To inspect distribution shape visually, use histogram in MATLAB with probability density normalization and overlay the theoretical normal curve:
figure;
h = histogram(data, 100, 'Normalization', 'pdf');
hold on;
% Theoretical Gaussian probability density function overlay
x_grid = linspace(-4, 4, 200);
y_pdf = (1 / sqrt(2 * pi)) * exp(-0.5 * x_grid.^2);
plot(x_grid, y_pdf, 'r-', 'LineWidth', 2);
xlabel('Value');
ylabel('Probability Density');
title('Standard Normal Distribution (Empirical vs. Theoretical)');
legend('Empirical Sample', 'Theoretical N(0,1)');
grid on;
When matrix transformations or spatial groupings are required after generation, rearrange dimensions without duplicating memory using the MATLAB reshape function.
Troubleshooting
1. The Single-Argument Dimension Trap
Symptom: Calling randn(10) produces a 10-by-10 matrix containing 100 values instead of a 10-element vector.
Cause: In MATLAB matrix conventions, passing a single integer scalar $N$ to generator functions like randn(N), rand(N), or zeros(N) defaults to creating an $N times N$ square matrix.
Fix: Explicitly specify two dimensions: pass randn(10, 1) for a column vector or randn(1, 10) for a row vector.
2. Scaling by Variance Instead of Standard Deviation
Symptom: The generated data displays an unexpectedly wide spread, with empirical variance much larger than the desired target.
Cause: Multiplying directly by variance $sigma^2$ (for example, var_val * randn(...)) squares the scaling effect, resulting in an effective variance of $(sigma^2)^2 = sigma^4$.
Fix: Always take the square root of the target variance before scaling: y = mu + sqrt(var_val) * randn(...).
3. Parallel Loop Stream Correlation in parfor
Symptom: Parallel workers in a parfor loop yield correlated or identical random sequences, corrupting Monte Carlo estimates.
Cause: Setting rng(seed) outside a parfor loop does not automatically create independent pseudorandom streams for separate client workers.
Fix: Configure independent parallel substreams using RandStream.create or pass a Parallel.Pool random stream to ensure uncorrelated pseudorandom sequences across workers.
4. Out of Memory on Massive Synthetic Allocations
Symptom: MATLAB throws an Out of memory error during large array generation.
Cause: Requesting large contiguous multidimensional arrays exceeds available system RAM or process address limits.
Fix: Specify 'single' precision to cut memory usage by 50%, or divide sample generation into manageable batch blocks processed sequentially.
Free alternatives (table)
Researchers conducting scientific analyses without proprietary MATLAB licenses can utilize fully compatible open-source environments and scientific computing packages:
| Tool / Environment | Function Syntax | Key Syntax Difference | RNG Seeding Command | License Model |
|---|---|---|---|---|
| GNU Octave | randn(m, n) |
Drop-in identical syntax and argument conventions to MATLAB | randn('state', 0) or rand('state', 0) |
GNU General Public License (GPLv3) |
| Python (NumPy) | rng.standard_normal((m, n)) |
Modern Generator takes a tuple of dimensions; legacy np.random.randn(m, n) mirrors MATLAB |
rng = np.random.default_rng(seed) |
BSD 3-Clause (Open Source) |
| R | rnorm(n, mean, sd) |
1D vector length specified as total count; custom mean and standard deviation built directly into arguments | set.seed(seed) |
GNU General Public License (GPL-2 / GPL-3) |
| Julia | randn(m, n) |
Fast native generator taking variable dimension arguments; supports in-place mutation with randn!(A) |
Random.seed!(seed) |
MIT License (Open Source) |
| Scilab | rand(m, n, 'normal') |
Normal distribution specified via secondary mode argument string or grand function |
grand('setsd', seed) |
CeCILL (GPL-compatible open source) |
FAQ
What does randn do in MATLAB?
In MATLAB, randn generates arrays of pseudorandom numbers drawn from a standard normal (Gaussian) distribution characterized by a mean of zero (μ = 0) and a standard deviation of one (σ = 1). It uses the Mersenne Twister algorithm paired with the Ziggurat transformation method to generate continuous values.
What is the difference between rand and randn in MATLAB?
The primary distinction is the underlying probability distribution. The rand function draws numbers from a continuous uniform distribution strictly bounded between 0 and 1, where every sub-interval of equal length has equal probability. In contrast, randn draws numbers from an unbounded standard normal distribution, producing values centered at zero with decreasing probability toward positive and negative extremes.
How do I generate random numbers with a specific mean and standard deviation?
To generate values with an arbitrary mean (μ) and standard deviation (σ), scale the output of randn by multiplying by σ and adding μ: y = mu + sigma * randn(m, n). If starting with a specified variance (σ²), take the square root first: sigma = sqrt(variance).
Why does randn(10) create a 10×10 matrix instead of a vector?
MATLAB follows classic matrix algebra conventions where passing a single integer $N$ to array creation functions defaults to creating an $N times N$ square matrix. To create an $N$-element vector, pass two dimensions explicitly: randn(10, 1) for a column vector or randn(1, 10) for a row vector.
How do I make randn results reproducible in MATLAB?
To ensure repeatable simulation results, set the random seed before calling randn using rng(seed, 'twister'), where seed is a non-negative integer. To restore non-repeatable behavior based on the system clock, call rng('shuffle').
How do I generate complex Gaussian noise in MATLAB?
To generate circularly symmetric complex Gaussian noise with unit total power (variance = 1), generate two independent standard normal vectors for the real and imaginary components and divide the sum by $sqrt{2}$: Z = (randn(N, 1) + 1i * randn(N, 1)) / sqrt(2).
Sources (official docs)
- MathWorks. randn: Normally distributed pseudorandom numbers. MathWorks MATLAB Documentation. https://www.mathworks.com/help/matlab/ref/randn.html (Accessed November 9, 2026).
- MathWorks. rng: Control random number generator. MathWorks MATLAB Documentation. https://www.mathworks.com/help/matlab/ref/rng.html (Accessed November 9, 2026).
- GNU Octave. Special Utility Matrices: randn. GNU Octave Documentation. https://docs.octave.org/latest/Special-Utility-Matrices.html (Accessed November 9, 2026).
- NumPy Developers. numpy.random.Generator.standard_normal and numpy.random.randn. NumPy Reference Manual. https://numpy.org/doc/stable/reference/random/generated/numpy.random.randn.html (Accessed November 9, 2026).







