Skip to content

Commit 1944578

Browse files
committed
modified the index substitution logic to correctly handle ListIndex
1 parent 8084e8a commit 1944578

2 files changed

Lines changed: 28 additions & 12 deletions

File tree

gem/gem.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -730,23 +730,27 @@ class ListIndex(IndexBase):
730730
Option 2: tensor[list_index] is tensor[list_index.index_array[list_index.free_index]]
731731
"""
732732

733-
__slots__ = ('index_array', 'free_index')
733+
__slots__ = ('index_array', 'free_index', 'name')
734734

735-
def __init__(self, index_array, name=None):
735+
def __init__(self, index_array, name=None, free_index=None):
736736
index_array = numpy.asarray(index_array)
737737
assert numpy.issubdtype(index_array.dtype, numpy.integer)
738-
739738
# Wraps a free index together with the index array
740739
self.index_array = index_array
741-
self.free_index = Index(extent=len(index_array), name=name)
742-
743-
# super().__init__(name=name, extent=len(index_array))
740+
if free_index is not None:
741+
self.free_index = free_index
742+
else:
743+
self.free_index = Index(extent=len(index_array), name=name)
744744

745745
def __str__(self):
746-
return f"{self.index_array.tolist()}[i_{self.free_index}]"
746+
if self.free_index.name:
747+
return f"{self.index_array.tolist()}[i_{self.free_index.name}]"
748+
return f"{self.index_array.tolist()}[i_{self.free_index.count}]"
747749

748750
def __repr__(self):
749-
return f"ListIndex({self.index_array.tolist()}, {self.free_index})"
751+
if self.free_index.name:
752+
return f"ListIndex({self.index_array.tolist()}, Index({self.free_index.name}))"
753+
return f"ListIndex({self.index_array.tolist()}, Index({self.free_index.count}))"
750754

751755
# def __eq__(self, other):
752756
# if type(self) is not type(other):
@@ -804,9 +808,16 @@ def __new__(cls, aggregate, multiindex):
804808
kk = B.multiindex
805809
ff = C.free_indices
806810
if not any((j in ff) for j in jj):
807-
# Only replace indices that are not present in C
811+
# Only replace indices in kk that are in jj
808812
rep = dict(zip(jj, ii))
809-
ll = tuple(rep.get(k, k) for k in kk)
813+
def _replace(k):
814+
if isinstance(k, ListIndex) and k.free_index in rep:
815+
replacement = rep[k.free_index]
816+
if isinstance(replacement, int):
817+
return int(k.index_array[replacement])
818+
return ListIndex(k.index_array, free_index=rep[k.free_index])
819+
return rep.get(k,k)
820+
ll = tuple(_replace(k) for k in kk)
810821
aggregate = C
811822
multiindex = ll
812823

@@ -1508,4 +1519,4 @@ def Piecewise(*args):
15081519
expr = Literal(float("nan"))
15091520
for v, c in reversed(pieces):
15101521
expr = Conditional(c, v, expr)
1511-
return expr
1522+
return expr

gem/optimise.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ def _replace_indices_atomic(i, self, subst):
102102
return i if new_expr == i.expression else VariableIndex(new_expr)
103103
else:
104104
substitute = dict(subst)
105-
return substitute.get(i, i)
105+
if isinstance(i, ListIndex) and i.free_index in substitute:
106+
replacement = substitute[i.free_index]
107+
if isinstance(replacement, int):
108+
return int(i.index_array[replacement])
109+
return ListIndex(i.index_array, free_index=substitute[i.free_index])
110+
return substitute.get(i,i)
106111

107112

108113
@replace_indices.register(Delta)

0 commit comments

Comments
 (0)