Exemple #1
0
    def __init__(self, base_ring, coordinate):
        self.coordinate = coordinate

        self.Vector = flatsurf.Vector._unwrapped[self.coordinate]

        self._isomorphic_vector_space = FreeModule(base_ring, 2)
        if isinstance(base_ring, real_embedded_number_field.RealEmbeddedNumberField):
            self._isomorphic_vector_space = FreeModule(base_ring.number_field, 2)

        Parent.__init__(self, base_ring, category=FreeModules(base_ring))

        self.register_coercion(self._isomorphic_vector_space)
        self._isomorphic_vector_space.register_conversion(ConversionVectorSpace(self))
Exemple #2
0
def min_reol_maybe_with3gens(data):
    forms = data.relatively_prime_3forms_maybe()
    d = data.brackets_dict
    if forms is None:
        return None
    F = FreeModule(R, 2)
    f, g, h = forms
    e0, e1 = F.gens()

    a = d[(g, h)]
    b = -d[(f, h)]
    c = d[(f, g)]

    f = e0 * c
    g = e1 * c
    h = -(a * e0 + b * e1)

    if c.degree() > 0:
        n = smodule(f, h)
        idl = sideal(b)
        m = squotient(n, idl)
    else:
        m = smodule(f, g)
    wts = data.weight_of_basis()
    mls = list(takewhile(lambda l: any(x != 0 for x in l), slist(smres(m, 0))))
    mls = [[list(v) for v in list(l)] for l in mls]
    wts_of_mls = []
    wts_of_mls.append([degree_vec(v, wts) for v in mls[0]])
    for i, l in enumerate(mls[1:]):
        wts = wts_of_mls[i]
        wts_of_mls.append([degree_vec(v, wts) for v in l])
    return (mls, wts_of_mls, (forms[0], forms[1], c))
def is_product(n, den_tuple):
    r"""
    INPUT:

    - ``n`` - number of variables

    - ``den_tuple`` - tuple of pairs ``(vector, power)``

    TESTS::

        sage: from surface_dynamics.misc.generalized_multiple_zeta_values import is_product
        sage: is_product(3, [((1,0,0),2), ((0,1,0),5), ((1,1,0),1), ((0,0,1),3)])
        [(2, (((0, 1), 5), ((1, 0), 2), ((1, 1), 1))), (1, (((1), 3),))]
        sage: is_product(3, [((1,0,0),2), ((0,1,0),3), ((1,0,1),1), ((0,0,1),5)])
        [(2, (((0, 1), 5), ((1, 0), 2), ((1, 1), 1))), (1, (((1), 3),))]
        sage: is_product(3, [((1,1,1),3)]) is None
        True
    """
    D = DisjointSet(n)
    assert all(len(v) == n for v, p in den_tuple), (n, den_tuple)

    # 1. product structure
    for v, _ in den_tuple:
        i0 = 0
        while not v[i0]:
            i0 += 1
        i = i0 + 1
        while i < n:
            if v[i]:
                D.union(i0, i)
            i += 1
        if D.number_of_subsets() == 1:
            # no way to split variables
            return

    # split variables
    Rdict = D.root_to_elements_dict()
    keys = sorted(Rdict.keys())
    key_indices = {k: i for i, k in enumerate(keys)}
    values = [Rdict[k] for k in keys]
    values_indices = [{v: i for i, v in enumerate(v)} for v in values]
    n_list = [len(J) for J in values]
    F = [FreeModule(ZZ, nn) for nn in n_list]
    new_terms = [[] for _ in range(len(Rdict))]
    for v, p in den_tuple:
        i0 = 0
        while not v[i0]:
            i0 += 1
        i0 = D.find(i0)
        assert all(D.find(i) == i0 for i in range(n)
                   if v[i]), (i0, [D.find(i) for i in range(n) if v[i]])
        k = key_indices[i0]
        vv = F[k]()
        for i in range(n):
            if v[i]:
                vv[values_indices[k][i]] = v[i]
        vv.set_immutable()
        new_terms[k].append((vv, p))

    return list(zip(n_list, [tuple(sorted(terms)) for terms in new_terms]))
Exemple #4
0
    def __init__(self, surface):
        if isinstance(surface, TranslationSurface):
            base_ring = surface.base_ring()
            from flatsurf.geometry.pyflatsurf_conversion import to_pyflatsurf
            self._surface = to_pyflatsurf(surface)
        else:
            from flatsurf.geometry.pyflatsurf_conversion import sage_base_ring
            base_ring, _ = sage_base_ring(surface)
            self._surface = surface

        # A model of the vector space R² in libflatsurf, e.g., to represent the
        # vector associated to a saddle connection.
        self.V2 = pyflatsurf.vector.Vectors(base_ring)

        # We construct a spanning set of edges, that is a subset of the
        # edges that form a basis of H_1(S, Sigma; Z)
        # It comes together with a projection matrix
        t, m = self._spanning_tree()
        assert set(t.keys()) == set(f[0] for f in self._faces())
        self.spanning_set = []
        v = set(t.values())
        for e in self._surface.edges():
            if e.positive() not in v and e.negative() not in v:
                self.spanning_set.append(e)
        self.d = len(self.spanning_set)
        assert 3*self.d - 3 == self._surface.size()
        assert m.rank() == self.d
        m = m.transpose()
        # projection matrix from Z^E to H_1(S, Sigma; Z) in the basis
        # of spanning edges
        self.proj = matrix(ZZ, [r for r in m.rows() if not r.is_zero()])

        self.Omega = self._intersection_matrix(t, self.spanning_set)

        self.V = FreeModule(self.V2.base_ring(), self.d)
        self.H = matrix(self.V2.base_ring(), self.d, 2)
        for i in range(self.d):
            s = self._surface.fromHalfEdge(self.spanning_set[i].positive())
            self.H[i] = self.V2._isomorphic_vector_space(self.V2(s))
        self.Hdual = self.Omega * self.H

        # Note that we don't use Sage vector spaces because they are usually
        # way too slow (in particular we avoid calling .echelonize())
        self._U = matrix(self.V2._algebraic_ring(), self.d)
        
        if self._U.base_ring() is not QQ:
            from sage.all import next_prime
            self._good_prime = self._U.base_ring().ideal(next_prime(2**30)).factor()[0][0]
            self._Ubar = matrix(self._good_prime.residue_field(), self.d)

        self._U_rank = 0

        self.update_tangent_space_from_vector(self.H.transpose()[0])
        self.update_tangent_space_from_vector(self.H.transpose()[1])
Exemple #5
0
def test_skipper_cpa_enc(skipper=Skipper4, kyber=Kyber, t=128, l=None, exhaustive=False):
    if not exhaustive:
        for i in range(t):
            pk, sk = kyber.key_gen(seed=i)
            m0 = random_vector(GF(2), kyber.n)
            c = skipper.enc(kyber, pk, m0, seed=i, l=l)
            m1 = kyber.dec(sk, c)
            assert(m0 == m1)
    else:
        # exhaustive test
        for i in range(16):
            pk, sk = kyber.key_gen(seed=i)
            for m0 in FreeModule(GF(2), kyber.n):
                c = skipper.enc(kyber, pk, m0, seed=i, l=l)
                m1 = kyber.dec(sk, c)
                assert(m0 == m1)
Exemple #6
0
    def boundaries(self):
        r"""
        Return the list of boundaries (ie sum of edges around a triangular face).

        These are elements of H_1(S, Sigma; Z).

        TESTS::

            sage: from flatsurf import polygons, similarity_surfaces
            sage: from flatsurf import GL2ROrbitClosure  # optional: pyflatsurf

            sage: from itertools import product
            sage: for a in range(1,5):  # optional: pyflatsurf
            ....:     for b in range(a, 5):
            ....:         for c in range(b, 5):
            ....:             if gcd([a, b, c]) != 1 or (a,b,c) == (1,1,2):
            ....:                 continue
            ....:             T = polygons.triangle(a, b, c)
            ....:             S = similarity_surfaces.billiard(T)
            ....:             S = S.minimal_cover(cover_type="translation")
            ....:             O = GL2ROrbitClosure(S)
            ....:             for b in O.boundaries():
            ....:                 assert (O.proj * b).is_zero()
        """
        n = self._surface.size()
        V = FreeModule(ZZ, n)
        B = []
        for (f1,f2,f3) in self._faces():
            i1 = f1.index()
            s1 = -1 if i1%2 else 1
            i2 = f2.index()
            s2 = -1 if i2%2 else 1
            i3 = f3.index()
            s3 = -1 if i3%2 else 1
            i1 = f1.edge().index()
            i2 = f2.edge().index()
            i3 = f3.edge().index()
            v = [0] * n
            v[i1] = 1
            v[i2] = s1 * s2
            v[i3] = s1 * s3
            B.append(V(v))
            B[-1].set_immutable()

        return B
def linear_forms(d):
    r"""
    EXAMPLES::

        sage: from surface_dynamics.misc.generalized_multiple_zeta_values import linear_forms

        sage: list(linear_forms(1))
        [(1)]

        sage: list(linear_forms(2))
         [(1, 0), (0, 1), (1, 1)]

        sage: L1 = list(linear_forms(3))
        sage: L2 = L1[:]
        sage: L2.sort(key = lambda x: x[::-1])
        sage: assert L1 == L2
    """
    F = FreeModule(ZZ, d)
    for n in range(1, 2**d):
        v = F(ZZ(n).digits(2, padto=d))
        v.set_immutable()
        yield v
def is_reducible(n, den_tuple):
    r"""
    If (x1+x2+...+xd) is not present, use a linear relation to create it. Then
    try to kill using other forms. Then try to write as P(x1,x2,...,x_{d-1}) (x1+x2+...+xd) and recurse.

    Should solve all Tonrheim

    EXAMPLES::

        sage: from surface_dynamics.misc.generalized_multiple_zeta_values import linear_forms, is_reducible
        sage: va, vb, vd, vc, ve, vf, vg = linear_forms(3)
        sage: is_reducible(3, ((va,3),(vb,3),(vc,3)))
        [(1, (((0, 0, 1), 3), ((0, 1, 1), 3), ((1, 1, 1), 3))),
         (1, (((0, 1, 0), 3), ((0, 1, 1), 3), ((1, 1, 1), 3))),
         (3, (((0, 0, 1), 2), ((0, 1, 1), 4), ((1, 1, 1), 3))),
         (3, (((0, 1, 0), 2), ((0, 1, 1), 4), ((1, 1, 1), 3))),
        ...
         (90, (((1, 0, 0), 1), ((1, 0, 1), 1), ((1, 1, 1), 7))),
         (90, (((0, 1, 0), 1), ((1, 1, 0), 1), ((1, 1, 1), 7))),
         (90, (((1, 0, 0), 1), ((1, 1, 0), 1), ((1, 1, 1), 7)))]
    """
    F = FreeModule(ZZ, n)
    vmax = F([1] * n)
    vmax.set_immutable()

    if len(den_tuple) == 1:
        return

    # force the max vector (1,1,...,1) to appear
    imax = None
    for i, (v, p) in enumerate(den_tuple):
        if v == vmax:
            imax = i
            break
    if imax is None:
        imax = len(den_tuple)
        den_tuple = den_tuple + ((vmax, 0), )
    if imax != len(den_tuple) - 1:
        den_tuple = list(den_tuple)
        den_tuple.append(den_tuple.pop(imax))
        den_tuple = tuple(den_tuple)
        imax = len(den_tuple) - 1

    assert den_tuple[imax][0] == vmax

    M = matrix(QQ, [v for v, p in den_tuple if v != vmax])
    try:
        relation = M.solve_left(vmax)
    except ValueError:
        if den_tuple[-1][1] == 0:
            return
        den_tuple2 = den_tuple[:-1]
        variables = set().union(*[[i for i in range(n) if v[i]]
                                  for v, p in den_tuple2])
        if len(variables) == n:
            return
        killed = [(1, den_tuple)]
    else:
        killed = kill_relation(n, den_tuple, imax, list(relation) + [0])

    ans = defaultdict(QQ)
    for coeff, den_tuple2 in killed:
        assert den_tuple2[-1][0] == vmax
        pmax = den_tuple2[-1][1]
        assert pmax
        den_tuple2 = den_tuple2[:-1]

        variables = set().union(*[[i for i in range(n) if v[i]]
                                  for v, p in den_tuple2])
        if len(variables) == n:
            # removing the maximal vector (1,1,...,1) is not enough to make a variable disappear
            data = is_reducible(n, den_tuple2)
            if data is None:
                data = [(1, den_tuple2)]
        else:
            # less variables!
            nn = len(variables)
            variables = sorted(variables)
            new_indices = {j: i for i, j in enumerate(variables)}
            G = FreeModule(ZZ, nn)
            new_den_tuple2 = []
            for v, p in den_tuple2:
                vv = G([v[i] for i in variables])
                vv.set_immutable()
                new_den_tuple2.append((vv, p))
            new_den_tuple2 = tuple(new_den_tuple2)
            data = is_reducible(nn, new_den_tuple2)
            if data is None:
                data = [(1, new_den_tuple2)]

            # lift to the n variables version
            new_data = []
            for coeff3, den_tuple3 in data:
                den_tuple3 = [(F([
                    v[new_indices[j]] if j in new_indices else 0
                    for j in range(n)
                ]), p) for v, p in den_tuple3]
                for v, p in den_tuple3:
                    v.set_immutable()
                new_data.append((coeff3, tuple(sorted(den_tuple3))))
            data = new_data

        # update the answer
        for coeff3, den_tuple3 in data:
            imax = None
            for i, (v, p) in enumerate(den_tuple3):
                if v == vmax:
                    imax = i
                    break
            if imax is None:
                den_tuple3 = den_tuple3 + ((vmax, pmax), )
            else:
                den_tuple3 = den_tuple3[:imax] + (
                    (vmax,
                     den_tuple3[imax][1] + pmax), ) + den_tuple3[imax + 1:]
            ans[den_tuple3] += coeff * coeff3

    if len(ans) > 1:
        return [(coeff, den_tuple) for den_tuple, coeff in ans.items()]