2016-10-15 3 views
1

마지막 문제 (Python tensor product)와 관련된 다른 질문이 있습니다. 거기서 계산에 실수를 발견했습니다. np.tensordot을 사용하면 다음 방정식을 계산합니다. enter image description here < ..> 평균을 표시해야합니다. 파이썬 코드에서이 (한국 동서 발전은 벡터이며 텐서를 재) 같이 않습니다평균 텐서 곱

q1 = numpy.tensordot(re, ewp, axes=(1, 0)) 
q2 = numpy.tensordot(q1, ewp, axes=(1, 0)) 
serc = q2 ** 2 

또는 지금 내가 무시 모두 파이썬 코드에서, 모든 가능성을 곱한 것을

serc = numpy.einsum('im, m -> i', numpy.einsum('ilm, l -> im', 
numpy.einsum('iklm, k -> ilm', numpy.einsum('ijklm, j -> iklm', 
numpy.einsum('ijk, ilm -> ijklm', re, re), ewp), ewp), ewp), ewp) 

. 물론 w_jw_kj=k과 관련이 없습니다. 이 경우 j와 k 만 같으면 < w_j*w_j*w_l*w_m> = <w_j>*<w_l>*<w_m>이됩니다. j=k=l의 경우 : < w_j*w_j*w_j*w_m> = <w_j>*<w_m>을받습니다. j=k=l=m의 경우 : < w_j*w_j*w_j*w_j> = <w_j> 모든 변수가 다른 경우에만 독립성은 true이고 우리는 < w_i*w_j*w_l*w_m> = <w_i>*<w_j>*<w_l>*<w_m>을 얻습니다. 이제 이것이 코드가 모든 가능성을 위해 수행하는 것입니다. 나는 이것이 내 문제를 이해할 수 있기를 바란다. 이제 내 질문은 내 코드에서이를 어떻게 표현할 수 있을까요?

편집 : 내가 가진 아이디어는 처음에 4dim을 만드는 것입니다. <w_j w_k w_l w_m>을 나타냅니다 텐서 :

wtensor = numpy.einsum('jkl, m -> jklm', numpy.einsum('jk, l -> jkl', 
numpy.einsum('j, k -> jk', ewp, ewp), ewp), ewp) 

은 그럼 idependent하지 않은 값을 변경해야합니다. 나는 그들이 대각선에 있어야한다고 생각하니? 그러나 나는 정말로 텐서 미적분학에 관해 많이 알지 못합니다. 그래서이 시점에서 나는 고심하고 있습니다. 승 텐서를 조작 한 후 내가 수행하여 결과를 얻을 것이다 :

serc = numpy.einsum('ijklm, jklm -> i', numpy.einsum('ijk, ilm -> 
ijklm', re, re), wtensor) 

가 Edit2가이 : 다른 포스트에서 내가 여기에 맞게 않도록 내가 4dim을 조작 할 수있는 방법을 정확하게 물었다. Fill a multidimensional array efficiently that have many if else statements

from itertools import product 

n_dims = 4 # Number of dims 
# Create 2D array of all possible combinations of X's as rows 
idx = np.sort(np.array(list(product(np.arange(gn), 
repeat=n_dims))),axis=1) 
# Get all X's indexed values from ewp array 
vals = ewp[idx] 
# Set the duplicates along each row as 1s. With the np.prod coming up 
next, 
#these 1s would not affect the result, which is the expected pattern 
here. 
vals[:,1:][idx[:,1:] == idx[:,:-1]] = 1 
# Perform product along each row and reshape into multi-dim array 
out = vals.prod(1).reshape([gn]*n_dims) 

내가 여기 얻고 배열은 지금 위의 코드에서 사용할 수있는 wtensor됩니다 :

serc = numpy.einsum('ijklm, jklm -> i', numpy.einsum('ijk, ilm -> 
ijklm', re, re), wtensor) 

이 저를 마지막으로 제공 Divakar 여기에서 볼 수있는 정말 좋은 솔루션을했다 그 결과는 내가 원했고 기본적으로 질문에 답합니다. 하나의 문제가 있지만. ewp의 길이는 또한 텐서의 크기를 정의합니다. 6보다 크면 안됩니다. 그렇지 않으면 코드가 많은 메모리를 사용하게됩니다. 내 의도는 크기가 8이 될 때까지 사용하는 것이 었으므로 불행히도 이제는 다음 문제입니다. `mewp = 한국 동서 발전/LEN (한국 동서 발전)`후 한국 동서 발전`대신`mewp`를 사용

serc = np.einsum('ilm,ilm->i',re,np.tensordot(re,wtensor,axes=[(1,2),(0,1)])) 
+0

할 일을 - – Divakar

+0

@Divakar : 미안하지만 그 점이 보이지 않습니까? 내 문제는 서로 다른 값이 서로 독립적이며 ' = '인 경우에만 해당된다는 것입니다. – HighwayJohn

답변

1

은 그럼 당신과 같이, np.tensordotnp.einsum의 조합으로 효율적으로 그렇게 할 수 `같은 코드로? 또는 단순히 최종 결과물 인`serc/(len (ewp) ** 4)`에서이 방법을 사용하면됩니까?
+0

좋아, 이거 정말 속도가 빨라.하지만 한 가지 질문이 있니? tensordot 명령의 축은 np.einsum과 어떤 관련이 있습니까? 나는 tensordot의 매뉴얼을 읽었지 만 나는 축을 어떻게 상상해야하고 어떻게 올바른 것을 결정해야하는지에 대해 다소 의문이있다. – HighwayJohn

+0

@HighwayJohn 글쎄, 나는 'einsum'해를 보지 않고서도 방정식을 계속 진행했다.첫 번째 감축 그룹은'R (i, j, k)'와'w (j, k, l, m)'사이에 있으며, 거기에 감축. 첫 번째 합계 축소는 R의 두 번째 축을 첫 번째 'w'와 함께 사용하므로 축 = [(1, ...), (0, ....)]입니다. 마찬가지로 R의 세 번째 축과'w '의 두 번째 축 사이에서 축 = [(..., 2), (...., 1)]이됩니다. 희망이 도움이! – Divakar

+0

아, 알겠습니다. 감사 :) – HighwayJohn