Skip to main content
`Ctrl`+`K`
scipy.linalg.

# subspace_angles

scipy.linalg.subspace_angles(A, B)

  Compute the subspace angles between two matrices.

  The documentation is written assuming array arguments are of specified “core” shapes. However, array argument(s) of this function may have additional “batch” dimensions prepended to the core shape. In this case, the array is treated as a batch of lower-dimensional slices; see Batched Linear Operations for details. Note that calls with zero-size batches are unsupported and will raise a `ValueError`.

  Parameters:
    A(M, N) array_like

      The first input array.

    B(M, K) array_like

      The second input array.

  Returns:
    angles ndarray, shape (min(N, K),)

      The subspace angles between the column spaces of A and B in descending order.

  See also

  `orth`
  `svd`

  Notes

  This computes the subspace angles according to the formula provided in [1]. For equivalence with MATLAB and Octave behavior, use `angles[0]`.

  Added in version 1.0.

  References

  [1]

  Knyazev A, Argentati M (2002) Principal Angles between Subspaces in an A-Based Scalar Product: Algorithms and Perturbation Estimates. SIAM J. Sci. Comput. 23:2008-2040.

  Examples

  A Hadamard matrix, which has orthogonal columns, so we expect that the subspace angle to be \(\frac{\pi}{2}\):

      >>> import numpy as np
      >>> from scipy.linalg import hadamard, subspace_angles
      >>> rng = np.random.default_rng()
      >>> H = hadamard(4)
      >>> print(H)
      [[ 1  1  1  1]
       [ 1 -1  1 -1]
       [ 1  1 -1 -1]
       [ 1 -1 -1  1]]
      >>> np.rad2deg(subspace_angles(H[:, :2], H[:, 2:]))
      array([ 90.,  90.])

  And the subspace angle of a matrix to itself should be zero:

      >>> subspace_angles(H[:, :2], H[:, :2]) <= 2 * np.finfo(float).eps
      array([ True,  True], dtype=bool)

  The angles between non-orthogonal subspaces are in between these extremes:

      >>> x = rng.standard_normal((4, 3))
      >>> np.rad2deg(subspace_angles(x[:, :2], x[:, [2]]))
      array([ 55.832])  # random