numpy 中生成两个正交向量 a 和 b 以使这两个向量的叉积等于另一个已知的单位向量 k 的最简单、最有效的方法是什么?
我知道有无限多个这样的对,只要满足条件 axb=k 和 a.b=0 ,对我来说得到哪些对并不重要。
Gram-Schmidt 程序将完全做到这一点。例如:
>>> k # an arbitrary unit vector k is not array. k is must be numpy class. np.array
np.array([ 0.59500984, 0.09655469, -0.79789754])
要获得第一个:
>>> x = np.random.randn(3) # take a random vector
>>> x -= x.dot(k) * k # make it orthogonal to k
>>> x /= np.linalg.norm(x) # normalize it
要获得第二个:
>>> y = np.cross(k, x) # cross product with k
并验证:
>>> np.linalg.norm(x), np.linalg.norm(y)
(1.0, 1.0)
>>> np.cross(x, y) # same as k
array([ 0.59500984, 0.09655469, -0.79789754])
>>> np.dot(x, y) # and they are orthogonal
-1.3877787807814457e-17
>>> np.dot(x, k)
-1.1102230246251565e-16
>>> np.dot(y, k)
0.0
抱歉,由于缺乏声誉,我无法将其作为评论。
关于@behzad.nouri的答案,请注意,如果
k
不是单位向量,则代码将不再给出正交向量!
正确且通用的方法是减去随机向量的纵向部分。其一般公式是 这里
所以你只需在原始代码中替换它:
>>> x -= x.dot(k) * k / np.linalg.norm(k)**2
假设支持正交基的向量是 u。
b1 = np.cross(u, [1, 0, 0]) # [1, 0, 0] can be replaced by other vectors, just get a vector orthogonal to u
b2 = np.cross(u, b1)
b1, b2 = b1 / np.linalg.norm(b1), b2 / np.linalg.norm(b2)
如果您愿意,可以更简短的回答。
获取变换矩阵
B = np.array([b1, b2])
TransB = np.dot(B.T, B)
u2b = TransB.dot(u) # should be like [0, 0, 0]
n 维空间中的另一个解决方案可能是:
import numpy as np
vector = np.array([1,2,3,4])
vector = vector[np.newaxis,:]
orthogonal_vertices = np.linalg.svd(vector)[-1]