Skip to content

Commit

Permalink
Merge pull request #783 from wildmeshing/mtao/lookup_switch_sequences
Browse files Browse the repository at this point in the history
Looking up switch sequences
  • Loading branch information
mtao authored Aug 17, 2024
2 parents 0485c9b + cc58bd1 commit 61cbb4d
Show file tree
Hide file tree
Showing 73 changed files with 2,482 additions and 126 deletions.
4 changes: 2 additions & 2 deletions scripts/2d_switch_tables.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@
"metadata": {},
"outputs": [],
"source": [
"autogenerate(\"../src/wmtk/autogen/tri_mesh/autogenerated_tables.{}pp\", tri_data)"
"autogenerate([\"autogenerated_data\"], tri_data)"
]
},
{
Expand All @@ -271,7 +271,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.12.3"
}
},
"nbformat": 4,
Expand Down
6 changes: 3 additions & 3 deletions scripts/3d_switch_tables.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@
"metadata": {},
"outputs": [],
"source": [
"autogenerate(\"../src/wmtk/autogen/tet_mesh/autogenerated_tables.{}pp\", tet_data)"
"autogenerate([\"autogenerated_data\"], tet_data)"
]
},
{
Expand All @@ -709,9 +709,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 4
}
164 changes: 164 additions & 0 deletions scripts/SimplexComplex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
from itertools import product

class SimplexComplex:
def __init__(self, simplices):
self.__simplices__ = list(map(lambda x: list(map(frozenset,x)), simplices))

self.__valid_indices__ = [self.get_index(t) for t in self.all_tuples() if self.valid_tuple(t)]
self.__valid_index_map__ = {k:v for v,k in enumerate(self.__valid_indices__)}

def __getitem__(self, index):
return self.__simplices__.__getitem__(index)
# Generates all possible tuples, note that some might not be valid
def all_tuples(self):
r = list(product(*map(list,map(range,map(len,self.__simplices__)))))
return r

def valid_indices(self):
return self.__valid_indices__
# Check if a tuple is valid, i.e. if the simplex of dimension d-1 is a face of a simplex of dimension d
def valid_tuple(self,t):
items = tuple(self[i][t[i]] for i in range(len(t)))
return all(a.issubset(b) for a,b in zip(items[:-1],items[1:]))

def valid_tuple_as_simplicial_set(self,t):
assert(self.valid_tuple(t))
items = tuple(self[i][t[i]] for i in range(len(t)))
x = (next(iter(items[0])),) + tuple(next(iter((b-a))) for a,b in zip(items[:-1],items[1:]))

n = len(self)
return x + (int((n * (n+1)) / 2) - sum(x),)

def simplicial_set_as_valid_tuple(self, ss):



return tuple(self.__simplices__[d].index(frozenset(ss[:d+1]))
for d in range(len(ss)-1))

def simplicial_set_as_valid_tuple_index(self,ss):
tup = self.simplicial_set_as_valid_tuple(ss)
return self.valid_tuples().index(tup)


def __len__(self):
return self.__simplices__.__len__()

# Enumerates all valid tuples similar to t, but with a different value in the slot d
# There must be 2 of them, and this function returns the one that is different than t
def switch(self,t,d):
assert(self.valid_tuple(t))
t = tuple(t)
candidates = []
left = t[:d]
right = t[d+1:]
candidates = [left + (i,) + right for i in range(len(self[d])) if i != t[d]]
valid = [x for x in candidates if self.valid_tuple(x)]
assert(len(valid) == 1)
return valid[0]


def get_index(self, t):
assert(self.valid_tuple(t))
return self.all_tuples().index(t)

def tuple_from_index(self,index):
return self.all_tuples()[index]

def valid_tuple_index(self,index):
return self.tuple_from_index(self.__valid_indices__[index])

def valid_tuple_size(self):
return len(self.__valid_indices__)

def valid_tuple_index(self, index):
return self.__valid_indices__[index]


def index_switch(self,tuple_index, d):
return self.get_index(self.switch(self.tuple_from_index(tuple_index), d))
def valid_index_switch(self,tuple_index, d):
return self.__valid_index_map__[
self.index_switch(
self.__valid_indices__[tuple_index], d)
]

def valid_tuples(self):
ts = self.all_tuples()
return [
ts[j] for j in self.__valid_indices__
]

def valid_tuple_product(self, t1, t2):
s1 = self.valid_tuple_as_simplicial_set(t1)
s2 = self.valid_tuple_as_simplicial_set(t2)

sp = tuple(s1[i] for i in s2)

return self.simplicial_set_as_valid_tuple(sp)

def valid_tuple_index_product(self, i1, i2):
vt = self.valid_tuples()
return vt.index(self.valid_tuple_product(
vt[i1],
vt[i2]
))


def valid_switch_table(sc):
return [[sc.valid_index_switch(i,d) for d in range(len(sc))] for i in range(sc.valid_tuple_size())]


def valid_switch_product_table(sc):
size = sc.valid_tuple_size()
return [[sc.valid_tuple_index_product(i1,i2) for i2 in range(size)] for i1 in range(size)]

def valid_switch_inverse_table(sc):
table = valid_switch_product_table(sc)
size = sc.valid_tuple_size()
identity_valid_index = sc.simplicial_set_as_valid_tuple_index(tuple(range(len(sc)+1)))
return [table[i].index(identity_valid_index) for i in range(size)]


def switches_plus_identity(sc):
identity = tuple(range(len(sc)+1))
print("Identity: ", identity)
def s(i):
x = list(identity)
print("1:",x)
x[i],x[i+1] = x[i+1],x[i]
print("2:",x)
return tuple(x)
sss = tuple(s(i) for i in range(len(sc))) + (identity,)
print(sss)
return tuple(map(sc.simplicial_set_as_valid_tuple_index,sss))


def switch_normal_subgroup_table(sc, subgroup_sc):
assert(len(sc) >= len(subgroup_sc))

valid_tuples = sc.valid_tuples()
valid_subtuples = subgroup_sc.valid_tuples()
tail = tuple(range(len(subgroup_sc)+1,len(sc)+1))

subgroup_to_group = [-1 for _ in range(subgroup_sc.valid_tuple_size())]
group_to_subgroup = [-1 for _ in range(sc.valid_tuple_size())]

for subindex, subtup in enumerate(valid_subtuples):
sub_ss = subgroup_sc.valid_tuple_as_simplicial_set(subtup)
ss = sub_ss + tail

index = sc.simplicial_set_as_valid_tuple_index(ss)
subgroup_to_group[subindex] = index
group_to_subgroup[index] = subindex

pass


assert(all(x != -1 for x in subgroup_to_group))

return tuple(group_to_subgroup),tuple(subgroup_to_group)




34 changes: 22 additions & 12 deletions scripts/autogenerate.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# ]
# }

def autogenerate(path_format, data):
def autogenerate(files, data, use_clang_format = False, clang_format_binary = "clang-format", autogen_path="../src/wmtk/autogen/"):
environment = jinja2.Environment(loader=jinja2.FileSystemLoader("./"))


Expand All @@ -38,18 +38,28 @@ def to_list_or_int(dat):
table_dict["data"] = to_list_or_int(table_dict["data"])
# convert table dict data to be lists

data["local_header_path"] = os.path.basename(path_format.format("h"))

def write(char,template):

with open(path_format.format(char),"w") as hpp_file:
hpp_file.write(template.render(data))
cpp_template = environment.get_template("autogenerated_tables.cpp.template")
write("c",cpp_template)

hpp_template = environment.get_template("autogenerated_tables.hpp.template")
write("h",hpp_template)

def write(path, template):
with open(path,"w") as file:
file.write(template.render(data))
if use_clang_format:
import subprocess
try:
subprocess.Popen([clang_format_binary,"-i",path])
except FileNotFoundError:
print("Warning: autogenerate failed to run clang-format due to FileNotFoundError - please make sure the autogenerated files are properly formatted before committing them")

for file in files:
data["filename"] = file
for extension in ("hpp","cpp","hxx"):
output_filename = f"{file}.{extension}"
template_path = os.path.join("templates",output_filename + ".template")
if os.path.exists(template_path):
template = environment.get_template(template_path)
output_path = os.path.join(autogen_path, data["namespace"], output_filename)
write(output_path, template)




Expand All @@ -70,4 +80,4 @@ def write(char,template):
]
}

autogenerate("/tmp/test.{}pp", array_data)
autogenerate(["autogenerated_tables"], array_data, autogen_path="/tmp")
Loading

0 comments on commit 61cbb4d

Please sign in to comment.