Reputation: 1867
I have a 3D tensor factored as three 2D matrices, like equation 22 in this paper: http://www.iro.umontreal.ca/~memisevr/pubs/pami_relational.pdf
My question is, if I want to calculate the tensor explicitly, is there a better way than this in numpy?
W = np.zeros((100,100,100))
for i in range(100):
for j in range(100):
for k in range(100):
W[i,j,k] = np.sum([wxf[i,f]*wyf[j,f]*wzf[k,f] for f in range(100)])
Upvotes: 1
Views: 82
Reputation: 353059
I tend to use einsum
for this stuff, just because it's usually the easiest to write:
def fast(wxf, wyf, wzf):
return np.einsum('if,jf,kf->ijk', wxf, wyf, wzf)
def slow(wxf, wyf, wzf):
N = len(wxf)
W = np.zeros((N, N, N))
for i in range(N):
for j in range(N):
for k in range(N):
W[i,j,k] = np.sum([wxf[i,f]*wyf[j,f]*wzf[k,f] for f in range(N)])
return W
def gen_ws(N):
wxf = np.random.random((N,N))
wyf = np.random.random((N,N))
wzf = np.random.random((N,N))
return wxf, wyf, wzf
gives
>>> ws = gen_ws(25)
>>> via_slow = slow(*ws)
>>> via_fast = fast(*ws)
>>> np.allclose(via_slow, via_fast)
True
and
>>> ws = gen_ws(100)
>>> %timeit fast(*ws)
10 loops, best of 3: 91.6 ms per loop
Upvotes: 2
Reputation: 58895
Your example makes it very straightforward to propose a solution using np.einsum()
:
W = np.einsum('ij,jf,kf->ijk', wxf, wyf, wzf)
Upvotes: 1