如何在Numpy/Scipy中从平面获得向量的正交距离?

cos*_*taz 5 python numpy distance orthogonal scipy

我有一组向量作为一个 numpy 数组。我需要从由 2 个向量 v1 和 v2 定义的平面中获得每个的正交距离。我可以使用 Gram-Schmidt 过程轻松获得单个向量。有没有一种方法可以在许多向量中快速完成,而不必遍历每个向量或使用 np.vectorize?

谢谢!

Dav*_*ave 5

实现@Jaime答案的更明确的方法是,您可以明确投影运算符的构造:

def normalized(v):
    return v/np.sqrt( np.dot(v,v))
def ortho_proj_vec(v, uhat ):
    '''Returns the projection of the vector v  on the subspace
    orthogonal to uhat (which must be a unit vector) by subtracting off
    the appropriate multiple of uhat.
    i.e. dot( retval, uhat )==0
    '''
    return v-np.dot(v,uhat)*uhat

def ortho_proj_array( Varray, uhat ):
     ''' Compute the orhogonal projection for an entire array of vectors.
     @arg Varray:  is an array of vectors, each row is one vector
          (i.e. Varray.shape[1]==len(uhat)).
     @arg uhat: a unit vector
     @retval : an array (same shape as Varray), where each vector
               has had the component parallel to uhat removed.
               postcondition: np.dot( retval[i,:], uhat) ==0.0
               for all i. 
    ''' 
    return Varray-np.outer( np.dot( Varray, uhat), uhat )




# We need to ensure that the vectors defining the subspace are unit norm
v1hat=normalized( v1 )

# now to deal with v2, we need to project it into the subspace
# orhogonal to v1, and normalize it
v2hat=normalized( ortho_proj(v2, v1hat ) )
# TODO: if np.dot( normalized(v2), v1hat) ) is close to 1.0, we probably
# have an ill-conditioned system (the vectors are close to parallel)



# Act on each of your data vectors with the projection matrix,
# take the norm of the resulting vector.
result=np.zeros( M.shape[0], dtype=M.dtype )
for idx in xrange( M.shape[0] ):
    tmp=ortho_proj_vec( ortho_proj_vec(M[idx,:], v1hat), v2hat )             
    result[idx]=np.sqrt(np.dot(tmp,tmp))

 # The preceeding loop could be avoided via
 #tmp=orhto_proj_array( ortho_proj_array( M, v1hat), v2hat )
 #result=np.sum( tmp**2, axis=-1 )
 # but this results in many copies of matrices that are the same 
 # size as M, so, initially, I prefer the loop approach just on
 # a memory usage basis.
Run Code Online (Sandbox Code Playgroud)

这实际上只是 Gram-Schmidt 正交化过程的推广。请注意,在此过程结束时我们有np.dot(v1hat, v1hat.T)==1, np.dot(v2hat,v2hat.T)==1, np.dot(v1hat, v2hat)==0(在数值精度内)