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."

Online Calculator