SciPy - subspace_angles() Function



The SciPy's subspace_angles() method is used to calculate the angle between two subspaces of matrices A and B in radians. These angles are useful for understanding the similarity or differences between two subspaces in linear algebra.

The values of the angles lie in the range 0 (identical subspaces) to /2 (orthogonal subspaces). This method is particularly useful in domains like signal processing, data analysis, and machine learning where understanding the alignment of vector spaces is important.

In real world applications like facial recognition, the subspace_angles() method is useful to compare the angles derived from two datasets where one data set containing images of faces captured indoors and another captured outdoors.

Small angle difference between these subspaces indicates that the datasets underlying similar features, which means model trained on one dataset could perform well on another. If the angle between the subspaces are large it indicates further adjustments of the model to perform well.

Syntax

The syntax for the SciPy subspace_angles() method is as follows −

subspace_angles(A, B)

Parameters

This method accepts the following parameters −

  • A (ndarray) − An m x n matrix whose columns define the first subspace.

  • B (ndarray) − An m x p matrix whose columns define the second subspace.

Return Value

angles (ndarray) − A 1D array of angles(in radians) between the subspaces. If k = min(n,p), the output is an array of K angles. These angles are sorted in ascending order.

Example 1

This is the basic example of using subspace_angles() method where, we have created two sub spaces and computed the angles between them in degrees and radians for better interpretation.

import numpy as np
from scipy.linalg import subspace_angles

# Define two subspaces A and B
A = np.array([[1, 0], [0, 1], [1, 1]])  # Subspace A
B = np.array([[1, 1], [-1, 1], [0, 0]])  # Subspace B

# Compute the subspace angles
angles = subspace_angles(A, B)

# Convert angles from radians to degrees and round to one decimal place
angles_in_degrees = np.degrees(angles)
angles_rounded = np.round(angles_in_degrees, 1)

print("Angles (radians):", angles)
print("Angles (degrees):", angles_rounded)

When we run above program, it produces following result

Angles (radians): [9.55316618e-01 3.65002415e-08]
Angles (degrees): [54.7  0. ]

Example 2

The hadamard matrix will have entries of either +1 or -1 and has the property of being orthogonal. This means the dotproduct of any two rows is zero. In the context of subspaces, orthogonality implies that the angle between these subspaces is 90 degree.

In this example we utilize the subspace_angles() function to calculate the angles between two subspaces generated by the Hadamard matrix. The code verifies if the angle between two subspaces (generated by the first 3 columns and the last 3 columns) is 90, thus verifying its property of orthogonality.

import numpy as np
from scipy.linalg import hadamard, subspace_angles

H = hadamard(8)
print("Hadamard Matrix (first 8x8):\n", H)

# Compute the subspace angles between the first 3 and last 3 columns of H
angles_hadamard_rad = subspace_angles(H[:, :3], H[:, 5:8])
angles_hadamard_deg = np.rad2deg(angles_hadamard_rad)

print("\nSubspace angles between the first 3 and last 3 columns of Hadamard matrix:")
print("Angles in degrees:", angles_hadamard_deg)

Following is an output of the above code −

Hadamard Matrix (first 8x8):
 [[ 1  1  1  1  1  1  1  1]
 [ 1 -1  1 -1  1 -1  1 -1]
 [ 1  1 -1 -1  1  1 -1 -1]
 [ 1 -1 -1  1  1 -1 -1  1]
 [ 1  1  1  1 -1 -1 -1 -1]
 [ 1 -1  1 -1 -1  1 -1  1]
 [ 1  1 -1 -1 -1 -1  1  1]
 [ 1 -1 -1  1 -1  1  1 -1]]

Subspace angles between the first 3 and last 3 columns of Hadamard matrix:
Angles in degrees: [90. 90. 90.]

Example 3

The following example calculates the subspace angles between the first two columns and the last two columns of a random 64 matrix. This matrix follows the standard normal distribution.

Angles of 80.45 and 66.86 degrees show that the subspaces are neither fully aligned nor orthogonal, This helps to assess how similar or different the subspaces are, which comes useful for things like making data smaller or grouping it.

import numpy as np
from scipy.linalg import hadamard, subspace_angles

rng = np.random.default_rng()
x = rng.standard_normal((6, 4))  # Random matrix with 6 rows and 4 columns

# Compute the angles between the first 2 columns and the last 2 columns
angles_random_rad = subspace_angles(x[:, :2], x[:, 2:])
angles_random_deg = np.rad2deg(angles_random_rad)

print("\nSubspace angles between random subspaces:")
print("Angles in degrees:", angles_random_deg)

Output of the above code is as follows

Subspace angles between random subspaces:
Angles in degrees: [80.4453178  66.86295424]
scipy_linalg.htm
Advertisements