Esempio n. 1
0
 def set_diff(cls, gen_name: str, diff: Union[None, set, "GbDga"]):
     """Define the differential of gen_name."""
     for i, gen in enumerate(cls.generators):
         if gen.name == gen_name:
             break
     else:
         raise BA.MyKeyError(f"generator {gen_name} not found")
     if i is not None:
         if type(diff) is not set and diff is not None:
             diff = diff.data
         if diff and (not cls(diff).is_homo() or cls.deg3d_data(diff) - gen.deg3d != cls.deg_diff):
             raise BA.MyDegreeError("inconsistent differential degree")
         gen = cls.generators[i]
         cls.generators[i] = DgaGen(gen.index, gen.name, gen.deg, gen.deg3d, diff)
Esempio n. 2
0
 def determine_diff(cls, g: Union[str, int], basis: dict, image_gens=None):
     """Determine differentials by relations."""
     if type(g) is str:
         for gen in cls.generators:
             if gen.name == g:
                 break
         else:
             raise BA.MyKeyError(f"generator {g} not found")
     else:
         gen = cls.get_gen(g)
         g = gen.name
     deg_target = gen.deg3d + cls.deg_diff
     if deg_target not in basis:
         cls.set_diff(g, set())
         print(f"set d({g})=0")
         return
     # print("Possible summands:")
     # for m in basis[deg_target]:
     #     print(cls(m))
     rels = []
     cls.set_diff(g, set())
     for m in cls.rels:
         if cls.is_differentiable_mon(m) and all(map(cls.is_differentiable_mon, cls.rels[m])):
             if cls.contains_gen_mon(m, gen.index) or any(map(cls.contains_gen_mon, cls.rels[m], repeat(gen.index))):
                 rels.append({m} | cls.rels[m])
     possible_diffs = []
     for n in range(1 << len(basis[deg_target])):
         data = {basis[deg_target][i] for i in two_expansion(n)}
         if all(map(cls.is_differentiable_mon, data)) and cls(data).diff():
             continue
         cls.set_diff(g, data)
         compatible = True
         for rel in rels:
             if cls(rel).diff():
                 compatible = False
                 break
         if image_gens and image_gens[gen.name].is_differentiable() and\
                 cls(data).evaluation(image_gens) != image_gens[gen.name].diff():
             compatible = False
         if compatible:
             possible_diffs.append(data)
     if len(possible_diffs) == 1:
         cls.set_diff(g, possible_diffs[0])
         print(f"set d({g})={cls(possible_diffs[0])}")
     elif len(possible_diffs) == 0:
         raise BA.MyClassError(f"Invalid DGA. d({g})=?")
     else:
         for data in possible_diffs:
             print(f"d({g})={cls(data)} is possible.")
         cls.set_diff(g, None)
Esempio n. 3
0
 def gen(cls, k: str):
     """Return a generator."""
     for gen in cls.generators:
         if gen.name == k:
             m = ((gen.index, -1),)
             return cls(m).simplify() if cls.auto_simplify else cls(m)
     else:
         raise BA.MyKeyError(f"No generator named {k}")
Esempio n. 4
0
 def add_gen(cls, name: str, deg, deg3d=(0, 0, 0), diff=None):
     """Add a new generator and return it."""
     index = cls.generators[-1][0] + 1 if cls.generators else 0
     if diff is None:
         diff = set()
     elif type(diff) is not set:
         diff = diff.data
     if diff and cls.deg3d_data(diff) - deg3d != cls.deg_diff:
         raise BA.MyDegreeError("inconsistent differential degree")
     cls.generators.append(DgaGen(index, name, deg, Vector(deg3d), diff))
     m = ((index, -1),)
     return cls(m).simplify() if cls.auto_simplify else cls(m)
Esempio n. 5
0
 def new_alg(*, key=None, pred=None, deg_diff=None) -> "Type[GbDga]":
     """Return a dynamically created subclass of GbDga."""
     cls = GbDga
     class_name = f"GbAlgMod2_{cls._name_index}"
     cls._name_index += 1
     if deg_diff is not None:
         deg_diff = Vector(deg_diff)
     else:
         raise BA.MyDegreeError("degree of differential not supplied")
     dct = {'generators': [], 'rels': {}, '_rels_gen_leads': set(), '_rels_cache': [],
            'key': key, 'pred': pred or GbAlgMod2.pred_default, 'auto_simplify': True, 'deg_diff': deg_diff}
     # noinspection PyTypeChecker
     return type(class_name, (cls,), dct)
Esempio n. 6
0
 def d0_inv_data(cls, data: set):
     """Find a cycle $c$ such that $d_0c = data$."""
     data = data.copy()
     result = set()
     while data:
         mon = max(data, key=cls.key_mon)
         i = cls._get_i(mon)
         if i is None:
             raise BA.MyValueError("Not d0 invertible")
         m_d0_inv = mon[:i] + (DualSteenrodDense.mul_mons(
             mon[i + 1], mon[i]), ) + mon[i + 2:]
         assert m_d0_inv not in result
         result ^= {m_d0_inv}
         data ^= cls(m_d0_inv).d0().data
         BA.Monitor.print(len(data))
     return result
Esempio n. 7
0
 def load_alg(cls, filename) -> Union[Type["GbAlgMod2"], Type["GbDga"]]:
     """Create an algebra from a pickle file."""
     with open(filename, 'rb') as file:
         init_list = pickle.load(file)
         if cls is GbAlgMod2:
             class_name = f"GbAlgMod2_{cls._name_index}"
         elif cls is GbDga:
             class_name = f"GbDga_{cls._name_index}"
         else:
             raise BA.MyKeyError("cls should be either GbAlgMod2 or GbDga.")
         cls._name_index += 1
         if init_list[0] == "5-11-2020":
             dct = {attr: init_v for attr, init_v in zip(cls._attributes, init_list[1:])}
         else:
             raise ValueError("file version not recognized")
         # noinspection PyTypeChecker
         return type(class_name, (cls,), dct)
Esempio n. 8
0
 def get_gen_by_name(cls, name: str) -> Union[Gen, DgaGen]:
     for gen in cls.generators:
         if gen.name == name:
             return gen
     raise BA.MyKeyError(f"generator {name} not found")