def __pow__(self, other): if isinstance(other, Integral): return PLoop(mat24.pow_ploop(self.value, other & 3)) elif isinstance(other, PLoop): comm = mat24.ploop_comm(self.value, other.value) << 12 return PLoop(self.value ^ comm) elif isinstance(other, Parity): if mat24.gcode_weight(self.value) & 1: raise ValueError("Parker Loop element has order > 2") return PLoop(mat24.pow_ploop(self.value, other.value)) else: return NotImplemented
def divide_atom(self, g, tag, data): """Auxiliary method for method mul() """ v = g.data if tag == "d": mm_group_n_mul_inv_delta_pi(v, data, 0) elif tag == "p": mm_group_n_mul_inv_delta_pi(v, 0, data) elif tag == 'x': mm_group_n_mul_x(v, pow_ploop(data, 3)) elif tag == 'y': mm_group_n_mul_y(v, pow_ploop(data, 3)) elif tag == 't': mm_group_n_mul_t(v, -int(data) % 3) else: raise TypeError("Illegal tag %s in group word" % t)
def mul_Xp(tag, d, i, g): eps, pi, rep = g.cocode, g.perm, g.rep d1 = m24.op_ploop_autpl(d, rep) i1 = pi[i] s = d1 >> 12 if eps & 0x800: # if eps is odd: s ^= m24.scalar_prod(d, m24.vect_to_cocode(1 << i)) s ^= m24.pow_ploop(d, 2) >> 12 return s, tag, d1 & 0x7ff, i1
def __rtruediv__(self, other): if isinstance(other, Integral): if abs(other) == 1: inv = mat24.pow_ploop(self.value, 3) return PLoop(inv ^ ((other & 2) << 11)) else: raise TypeError("Can only divide unit by Parker loop element") else: return NotImplemented
def rule_yp(group, word): global n_rules n_rules += 1 y, p = word[0], word[1] pl = mat24.op_ploop_autpl(y.pl, p.rep) if p.cocode & 0x800: pl = mat24.pow_ploop(pl, 3) return [p, xy_Atom('y', pl), xy_Atom('x', pl)] else: return [p, xy_Atom('y', pl)]
def rule_yt(group, word): global n_rules n_rules += 1 y, t = word[0], word[1] assert t.exp in [1, 2] if t.exp == 1: pl = mat24.pow_ploop(y.pl, 3) x, y = xy_Atom('x', pl), xy_Atom('y', pl) return [t, y, x] else: x = xy_Atom('x', y.pl) return [t, x]
def rule_xt(group, word): global n_rules n_rules += 1 x, t = word[0], word[1] assert t.exp in [1, 2] if t.exp == 2: pl = mat24.pow_ploop(x.pl, 3) x, y = xy_Atom('x', pl), xy_Atom('y', pl) return [t, y, x] else: y = xy_Atom('y', x.pl) return [t, y]
def __truediv__(self, other): if isinstance(other, PLoop): return PLoop( mat24.mul_ploop(self.value, mat24.pow_ploop(other.value, 3))) elif isinstance(other, Integral): if abs(other) == 1: return PLoop(self.value ^ ((other & 2) << 11)) elif abs(other) == 2: return Parity(0) elif abs(other) == 4: return Parity(mat24.gcode_weight(self.value) & 1) else: raise TypeError(ERR_DIV4 % type(self)) else: return NotImplemented
def sign_t_ZX(d, i): return m24.pow_ploop(d, 2) >> 12
def sign_t_YZ(d, i): return (m24.scalar_prod(d, m24.vect_to_cocode(1 << i)) ^ (m24.pow_ploop(d, 2)) >> 12)
def mul_Zx(tag, d, i, g): e = g.pl ed = m24.mul_ploop(m24.pow_ploop(e, 3), d) s = m24.scalar_prod(e, m24.vect_to_cocode(1 << i)) s = (ed >> 12) return s & 1, Z, ed & 0x7ff, i
def iter_inv_xy(group, atom): global n_inv n_inv += 1 res = mat24.pow_ploop(atom.pl, 3) yield xy_Atom(atom.tag, res)
def gen_z(tag, r="r"): pl = randint(0, 0x1fff) if isinstance(r, str) else r & 0x1fff pl = mat24.pow_ploop(pl, 3) yield xy_Atom('y', pl) yield xy_Atom('x', pl)
def iter_z(tag, r): pl = pow_ploop(gen_ploop_element(tag, r), 3) yield tag_dict['x'] + pl yield tag_dict['y'] + pl