ORTHO_GROUP
Overview
The ORTHO_GROUP function generates random orthogonal matrices drawn from the O(N) Haar distribution, the unique uniform distribution over the orthogonal group. An orthogonal matrix Q is a square matrix whose transpose equals its inverse, satisfying the fundamental property:
Q^T Q = Q Q^T = I
where I is the identity matrix. This constraint ensures that orthogonal transformations preserve lengths and angles, making them essential in applications involving rotations, reflections, and coordinate transformations.
The orthogonal group O(N) consists of all N \times N orthogonal matrices, which have determinants of either +1 or −1. Matrices with determinant +1 belong to the special orthogonal group SO(N) and represent pure rotations, while those with determinant −1 include reflections. The O(N) group is a compact Lie group with dimension \frac{N(N-1)}{2}.
This implementation uses scipy.stats.ortho_group, which employs the algorithm described by Mezzadri in “How to generate random matrices from the classical compact groups” (Notices of the AMS, 2007). The algorithm applies QR decomposition to a matrix of standard normal random variables, with careful numerical handling to ensure the resulting matrices are uniformly distributed according to the Haar measure—the unique probability measure on O(N) that is invariant under group multiplication.
Random orthogonal matrices are widely used in numerical linear algebra, machine learning (for weight initialization and random projections), Monte Carlo simulations in physics, and testing the robustness of algorithms to coordinate system changes. For applications requiring only rotation matrices (determinant +1), see the related special_ortho_group distribution in SciPy.
This example function is provided as-is without any representation of accuracy.
Excel Usage
=ORTHO_GROUP(dim, size)
dim(int, required): Dimension of the orthogonal matrices to generate. Must be a positive integer.size(int, optional, default: 1): Number of orthogonal matrices to generate. Must be a positive integer.
Returns (list[list]): 2D list of float values representing the orthogonal matrix (or matrices), or error message (str) if input is invalid.
Examples
Example 1: Basic 2x2 orthogonal matrix
Inputs:
| dim |
|---|
| 2 |
Excel formula:
=ORTHO_GROUP(2)
Expected output:
"non-error"
Example 2: 3x3 orthogonal matrix with size=1
Inputs:
| dim | size |
|---|---|
| 3 | 1 |
Excel formula:
=ORTHO_GROUP(3, 1)
Expected output:
"non-error"
Example 3: Two 4x4 orthogonal matrices
Inputs:
| dim | size |
|---|---|
| 4 | 2 |
Excel formula:
=ORTHO_GROUP(4, 2)
Expected output:
"non-error"
Example 4: Three 5x5 orthogonal matrices
Inputs:
| dim | size |
|---|---|
| 5 | 3 |
Excel formula:
=ORTHO_GROUP(5, 3)
Expected output:
"non-error"
Python Code
import numpy as np
from scipy.stats import ortho_group as scipy_ortho_group
def ortho_group(dim, size=1):
"""
Draws random samples of orthogonal matrices from the O(N) Haar distribution using scipy.stats.ortho_group.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ortho_group.html
This example function is provided as-is without any representation of accuracy.
Args:
dim (int): Dimension of the orthogonal matrices to generate. Must be a positive integer.
size (int, optional): Number of orthogonal matrices to generate. Must be a positive integer. Default is 1.
Returns:
list[list]: 2D list of float values representing the orthogonal matrix (or matrices), or error message (str) if input is invalid.
"""
def to_int(x):
"""Convert to int, accepting floats that are whole numbers."""
if isinstance(x, bool):
return None
if isinstance(x, int):
return x
if isinstance(x, float) and x.is_integer():
return int(x)
return None
# Validate dim
dim_int = to_int(dim)
if dim_int is None or dim_int < 1:
return "Invalid input: dim must be a positive integer."
dim = dim_int
# Validate size
size_int = to_int(size)
if size_int is None or size_int < 1:
return "Invalid input: size must be a positive integer."
size = size_int
try:
result = scipy_ortho_group.rvs(dim=dim, size=size)
except Exception as e:
return f"scipy.stats.ortho_group error: {e}"
# Convert numpy array to 2D list
if size == 1:
if isinstance(result, np.ndarray) and result.ndim == 2:
return result.tolist()
else:
return "Invalid output: result is not a 2D array."
elif isinstance(result, np.ndarray) and result.ndim == 3:
# Flatten to 2D list: concatenate matrices vertically
return [row.tolist() for matrix in result for row in matrix]
else:
return "Invalid output: result is not a 3D array for multiple samples."