在 Python 中完成或扩展正交基

Complete or Extend Orthonormal Basis in Python

我有几个正交向量。我想将这个二维基础扩展到更大的基础。使用 NumPy 在 Python 中执行此操作的最快方法是什么?

我的想法如下:生成所需大小的随机向量 (new_dimension > 2),通过用前两个减去缩放点积来执行 Gram-Schmidt。重复。我怀疑这是最快的方法...

您没有指定 space 的尺寸。 如果是3,那么你可以简单地使用你的两个向量的cross product。如果不是,请看下面。

3-D 示例

# 1. setup: an orthonormal basis of two vectors a, b
np.random.seed(0)
a, b = np.random.uniform(size=(2,3))
a /= np.linalg.norm(a)
b -= a.dot(b)*a
b /= np.linalg.norm(b)

# 2. check:
>>> np.allclose([1,1,0,0], [a.dot(a), b.dot(b), a.dot(b), b.dot(a)])
True

然后,制作一个新的矢量:

# 3. solve
c = np.cross(a, b)

# 4. checks
>>> np.allclose([1,0,0], [c.dot(c), c.dot(a), c.dot(b)])
True

如果向量的维数更高,那么您可以选择不在 a,b 定义的平面内的任何向量并减去该投影,归一化。

更高维度的示例

# 1. setup
n = 5
np.random.seed(0)
a, b = np.random.uniform(size=(2, n))
a /= np.linalg.norm(a)
b -= a.dot(b)*a
b /= np.linalg.norm(b)

# 2. check
assert np.allclose([1,1,0,0], [a.dot(a), b.dot(b), a.dot(b), b.dot(a)])

然后:

# 3. solve
ab = np.c_[a, b]
c = np.roll(a + b, 1)  # any vector unlikely to be 0 or some
                       # linear combination of a and b
c -= (c @ ab) @ ab.T
c /= np.linalg.norm(c)

# 4. check
abc = np.c_[a, b, c]
>>> np.allclose(np.eye(3), abc.T @ abc)
True

泛化:在 n-D space

中补充 m-基础

n 维 space 中,给定 (n, m) 正交基 xm s.t。 1 <= m < n(换句话说,n 维 space 中的 m 个向量放在一起作为 x 的列):找到 n - m 个向量是正交的,并且都与 x.

正交

我们可以使用 SVD 一次完成。

# 1. setup
#    we use SVD for the setup as well, for convenience,
#    but it's not necessary at all. It is sufficient that
#    x.T @ x == I

n, m = 6, 2  # for example
x, _, _ = np.linalg.svd(np.random.uniform(size=(n, m)))
x = x[:, :m]

# 2. check
>>> np.allclose(x.T @ x, np.eye(m))
True

>>> x.shape
(6, 2)

所以,在这一点上,x 是标准正交的并且形状为 (n, m)

发现 y 是与 x 正交的(可能有许多)正交基之一:

# 3. solve
u, s, v = np.linalg.svd(x)
y = u[:, m:]

# 4. check
>>> np.allclose(y.T @ y, np.eye(n-m))
True

>>> np.allclose(x.T @ y, 0)
True