아인슈타인 합계에 대한 이해가 올바르지 않습니다. 작성한 첨자 조작은 곱셈이 올바르지 만 합계가 잘못된 축 위에 있습니다.
이것이 의미하는 바를 생각해보십시오 : np.einsum('i,ij->i', A, B)
.
A
는 (i,)
모양을 가지고 있으며, B
는 (i, j)
모양이있다.
B
의 모든 열에 A
을 곱하십시오.
B
의 두 번째 축, 즉 j
이라고 표시된 축 위에 합계합니다. 당신의 첨자 표기법 모양 (j,) == (4,)
의 출력을 제공하는 동안
이는 모양 (i,) == (3,)
의 출력을 제공합니다. 잘못된 축을 합산 한 것입니다.
더 자세히 :
는 곱셈이 항상 먼저 일어나는 것을 기억하십시오. 왼쪽 첨자는 입력 배열의 행/열/등이 서로 곱해질 함수 인 np.einsum
을 알려줍니다. 이 단계의 출력은 항상 최고 차원 입력 배열과 동일한 모양을 갖습니다. 즉,이 시점에서 가상 "중간"배열의 모양은 (3, 4) == B.shape
입니다.
곱셈 후에는 합계가 있습니다. 이것은 오른쪽에서 이 생략 된 인 첨자에 의해 제어됩니다. 이 경우 j
은 생략되며 이는 배열의 첫 번째 축을 따라 합계 함을 의미합니다. (0을 따라 합산 한 것입니다.)
대신 np.einsum('i,ij->ij', A, B)
이라고 쓰면 첨자가 생략되지 않으므로 은이 될 것입니다. 따라서 질문이 끝나면 얻은 배열을 얻을 수 있습니다.
예 1 :
없음 생략 첨자, 그래서 아무 요약 여기
은 몇 가지 예입니다.
B
열에
A
을 곱하면됩니다. 이것이 여러분이 작성한 마지막 어레이입니다.
>>> (np.einsum('i,ij->ij', A, B) == (A[:, None] * B)).all()
True
예 2 : 예를 들어
동일합니다. 열을 곱한 다음 출력의 열을 합합니다.
>>> (np.einsum('i,ij->i', A, B) == (A[:, None] * B).sum(axis=-1)).all()
True
예 3 :
위를 작성한으로 합계. 열을 곱한 다음 출력의 행을 합계 행으로 합계합니다.
>>> (np.einsum('i,ij->j', A, B) == (A[:, None] * B).sum(axis=0)).all()
True
예 4 : 우리는 단지 전체 배열에 걸쳐 총 합계를 얻기 위해, 마지막에 모든 축를 생략 할 수 있습니다
참고.
>>> np.einsum('i,ij->', A, B)
98
예 5 : 우리가 입력 라벨 'i'
을 반복하기 때문에 요약이 정말로 일어나는 것을
참고. 우리가 대신 입력 배열의 각 축에 대해 서로 다른 라벨을 사용하는 경우, 우리는 크로네 커 제품에 비슷한 일을 계산할 수 있습니다 :
>>> np.einsum('i,jk', A, B).shape
(3, 3, 4)
편집 아인슈타인 합계의 NumPy와 구현이 전통에서 약간의 차이가
정의. 기술적으로, 아인슈타인 총액에는 "출력 라벨"에 대한 아이디어가 없습니다. 그것들은 반복 된 입력 레이블에 항상 내포되어 있습니다.
docs : "Whenever a label is repeated, it is summed."
전통적으로 우리는 np.einsum('i,ij', A, B)
과 같은 것을 쓸 것입니다. 이것은 np.einsum('i,ij->j', A, B)
과 같습니다. i
이 반복되므로 축이 j
인 채로 합산됩니다. 을 지정하지 않은 경우 출력 레이블은 입력에서 반복되지 않는 레이블 만 지정하는 것과 같다고 생각할 수 있습니다. 즉, 레이블 'i,ij'
은 'i,ij->j'
과 동일합니다.
출력 레이블은 NumPy에서 구현 된 확장 또는 확대 기능으로, 발신자가 축에서 합계를 강제 적용하거나 에 합계를 적용 할 수 있습니다. 문서에서 : "The output can be controlled by specifying output subscript labels as well. This specifies the label order, and allows summing to be disallowed or forced when desired."
사실 내가 가지고있는 문제는 "다른 사람의 stackoverflow 대답에서도 찾을 수있는 곱셈이 항상 발생한다는 것을 기억하십시오. 문서에서 이것이 적절하게 설명 된 곳입니까? "왼쪽 아래 첨자는 입력 배열의 행/열/등이 서로 곱해질 np.einsum 함수에 알려줍니다." – FenryrMKIII
"곱셈은 항상 먼저 발생합니다"라고 말하는 것은 실제로 문서에 없습니다. 표기법의 정의에서 온 것입니다. 자세한 내용은 Wikipedia 페이지 (https://en.wikipedia.org/wiki/Einstein_notation#Statement_of_convention)를 참조하고 문서에서 출력 첨자 아이디어에 대한 설명을 자세히 읽으십시오. – bnaecker
나는 아인슈타인의 표기법을 이해한다. 유체 역학에서 많이 사용됩니다. 편집에서 말한 것처럼 구현이 전통적인 아인슈타인 표기법에서 벗어난 것처럼 보입니다. 당신이 말했듯이, 아인슈타인 표기법은 'ij, i'일 뿐이며, 그러면 j를 변화시키면서 i를 합한 것입니다. 그래서 "i, ij-> i"는 전통적인 아인슈타인 표기법과 관련이 있습니까? 그것은 무엇을합니까? 그것은 i 이상의 합계를 억제합니까? – FenryrMKIII