简体   繁体   中英

numpy.einsum 'ij,kl->ik' how to do this by numpy.tensordot

I have two matrix , 5x4 and 3x2. I want to get a 5x3 matrix from them.

>>>theta_ic = np.random.randint(5,size=(5,4))
>>>psi_tr  = np.random.randint(5,size=(3,2))

I can do this by

>>>np.einsum('ij,kl->ik',theta_ic,psi_tr).shape
(5,3)

But I don't know how to do this by numpy.tensordot I tried this

>>>np.tensordot(theta_ic,psi_tr,((1),(1)))

I get an error

ValueError: shape-mismatch for sum

The math behind is

z_ij = \sum_{c=1}^4{x_{ic}}\sum_{d=1}^{2}{y_{jd}}
where i=[1,...,5], j=[1...3]

Why I need to migrate einsum to tensordot ?

Because i'm doing my research using pymc3 package which use theano as backend to accelerate computation.

However, theano.tensor doesn't support einsum , and it only support tensordot , the same grammar as np.tensordot .

The fact that your einsum formula

'ij,kl->ik'

uses the indices j and l once means you can sum over them before the operation.

theta_ic2 = np.sum(theta_ic, axis=1)
psi_tr2 = np.sum(psi_tr, axis=1)

and you end up with

'i,k->ik'

which is simply the outer product

theta_ic2[:, None] * psi_tr2

or in one line

np.sum(theta_ic, axis=1)[:, None] * np.sum(psi_tr, axis=1)

And in np.tensordot , setting axes=0 will produce the outer product:

np.tensordot(np.sum(theta_ic, axis=1), np.sum(psi_tr, axis=1), axes=0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM