Update.
authorFrançois Fleuret <francois@fleuret.org>
Wed, 24 May 2023 14:51:49 +0000 (16:51 +0200)
committerFrançois Fleuret <francois@fleuret.org>
Wed, 24 May 2023 14:51:49 +0000 (16:51 +0200)
eingather.py

index 2310c55..f8b3e89 100755 (executable)
@@ -10,32 +10,35 @@ import re, torch
 #####################
 
 
-def eingather(op, src, index):
+def eingather(op, src, *indexes):
     s_src, s_dst = re.search("^([^ ]*) *-> *(.*)", op).groups()
-    s_index = re.search("\(([^)]*)\)", s_src).group(1)
+    s_indexes = re.findall("\(([^)]*)\)", s_src)
     s_src = re.sub("\([^)]*\)", "_", s_src)
 
     shape = tuple(src.size(s_src.index(v)) for v in s_dst)
 
     idx = []
-
-    for i in range(index.dim()):
-        v = s_index[i]
-        j = s_dst.index(v)
-        a = (
-            torch.arange(index.size(i))
-            .reshape((1,) * j + (-1,) + (1,) * (len(s_dst) - j - 1))
-            .expand(shape)
-        )
-        idx.append(a)
-
-    index = index[idx]
-
-    idx = []
+    n_index = 0
 
     for i in range(src.dim()):
         v = s_src[i]
         if v == "_":
+            index, s_index = indexes[n_index], s_indexes[n_index]
+            n_index += 1
+
+            sub_idx = []
+
+            for i in range(index.dim()):
+                v = s_index[i]
+                j = s_dst.index(v)
+                a = (
+                    torch.arange(index.size(i))
+                    .reshape((1,) * j + (-1,) + (1,) * (len(s_dst) - j - 1))
+                    .expand(shape)
+                )
+                sub_idx.append(a)
+
+            index = index[sub_idx]
             idx.append(index)
         else:
             j = s_dst.index(v)
@@ -51,12 +54,13 @@ def eingather(op, src, index):
 
 #######################
 
-src = torch.rand(3, 5, 7, 11)
-index = torch.randint(src.size(2), (src.size(3), src.size(1), src.size(3)))
+src = torch.rand(3, 5, 7, 11, 13)
+index1 = torch.randint(src.size(2), (src.size(4), src.size(1), src.size(4)))
+index2 = torch.randint(src.size(3), (src.size(1),))
 
-# I want result[a,c,e]=src[c,a,index[e,a,e],e]
+# I want result[a, c, e] = src[c, a, index1[e, a, e], index2[a], e]
 
-result = eingather("ca(eae)e -> ace", src, index)
+result = eingather("ca(eae)(a)e -> ace", src, index1, index2)
 
 # Check
 
@@ -65,6 +69,6 @@ error = 0
 for a in range(result.size(0)):
     for c in range(result.size(1)):
         for e in range(result.size(2)):
-            error += (result[a, c, e] - src[c, a, index[e, a, e], e]).abs()
+            error += (result[a, c, e] - src[c, a, index1[e, a, e], index2[a], e]).abs()
 
 print(error.item())