I am trying to implement a tensor network kind of calculation using np.einsum.
The goal of the calculation is to have a local 2x2 matrix act sequentially on a tensor of size (2,2,2,...,2,2,2) where the number of dimensions can be arbitrary (as long as memory allows).
I have a working naive implementation for a tensor of size (2,2,2)
X = np.array([[1,2],[3,4]])
Y = np.ones(2**3).reshape((2,2,2))
Aijk = np.einsum('zi,zjk', X, Y)
Bijk = np.einsum('zi,jzk', X, Aijk)
Cijk = np.einsum('zi,jkz', X, Bijk)
As can be seen, the index to be summed over should move to the right for each subsequent calculation. I could generate the appropriate explicit string but I'm wondering if it possible to implement this using ellipses but I am not sure how to specify the index position if the index is not the left- or rightmost index.
X = np.array([[1,2],[3,4]])
Y = np.ones(2**n).reshape(shape) # where shape is the appropriate n-tuple
A = np.einsum('a...,a...', X, Y)
B = np.einsum('b...,...b...', X, A) # how do I specify that the summed index of A is the second one?
...
N = np.einsum('l...,...l', X, M)
I hope it is clear what I'm trying to achieve.
Let's take small steps to add ellipsis to your example.
Making the RHS explicit:
Replace the repeated
jkwith ellipsis:And trying that with other
Yshapes (always keeping first dimension,2to match onz:I think I could use 'zi,z...->...i', 'zi,jz...->ij...', 'zi,jz...->i...j'. (but I haven't tested them). But I'm pretty sure I can't use '...i...'. And in general can't use ellispis to specify the relative location of the summing 'z' dimension.