EDIT 내가 작성한 원본 코드가 올바르게 작동하지 않아 제거했습니다.
def distance(v1, v2, u) :
u = np.array(u, ndmin=2)
v = np.vstack((v1, v2))
vv = np.dot(v, v.T) # shape (2, 2)
uv = np.dot(u, v.T) # shape (n ,2)
ab = np.dot(np.linalg.inv(vv), uv.T) # shape(2, n)
w = u - np.dot(ab.T, v)
return np.sqrt(np.sum(w**2, axis=1)) # shape (n,)
가 작동하는지 확인하려면 다음을하지만 같은 생각 다음, 당신이 그것을 생각하는 시간을 보낼 경우, 크레이머의 규칙에 대한 필요가 없습니다, 다음과 같이 코드가 상당히 간소화 될 수 있으며, 아래에 설명 제대로, 나는 distance_3d
로 함수에 데이브의 코드를 포장하고 다음을 시도했다 :
>>> d, n = 3, 1000
>>> v1, v2, u = np.random.rand(d), np.random.rand(d), np.random.rand(n, d)
>>> np.testing.assert_almost_equal(distance_3d(v1, v2, u), distance(v1, v2, u))
그러나 물론 지금은 어떤 d
작동 :
>>> d, n = 1000, 3
>>> v1, v2, u = np.random.rand(d), np.random.rand(d), np.random.rand(n, d)
>>> distance(v1, v2, u)
array([ 10.57891286, 10.89765779, 10.75935644])
w
따라서
np.dot(w, v1) = np.dot(w, v2) = 0
면에 수직이고, 반면 94,922,398,581,088,243,210 당신은 당신의 벡터를 분해해야
는 v
비행기에, 그래서 v = a * v1 + b * v2
로 분해 될 수있다, 두 벡터, u = v + w
의 합에, u
를 호출 할 수 있습니다 . 당신이 u = a * v1 + b * v2 + w
를 작성하고 v1
및 v2
이 표현의 내적을 취하면
, 당신은 두 개의 미지수 두 개의 방정식을 얻을 : 그것은 단지 2 × 2 시스템이기 때문에
np.dot(u, v1) = a * np.dot(v1, v1) + b * np.dot(v2, v1)
np.dot(u, v2) = a * np.dot(v1, v2) + b * np.dot(v2, v2)
을, 우리는 Cramer's rule를 사용하여 해결할 수 있습니다 로 : 여기에서
uv1 = np.dot(u, v1)
uv2 = np.dot(u, v2)
v11 = np.dot(v1, v2)
v22 = np.dot(v2, v2)
v12 = np.dot(v1, v2)
v21 = np.dot(v2, v1)
det = v11 * v22 - v21 * v12
a = (uv1 * v22 - v21 * uv2)/det
b = (v11 * uv2 - uv1 * v12)/det
, 당신은 얻을 수 있습니다 :
w = u - v = u - a * v1 - b * v2
이고 평면까지의 거리는 모듈 w
입니다.
(수치의 정밀도 이내)의 문서화 문자열이 지적 하듯
np.dot(v1hat, v1hat.T)==1
는'np.vectorize'가 매우 빠르고, 결코이 있는지 확인하십시오. –