Beispiel #1
0
def symmGB_F2_python(G, deg_bound=1000000000000, over_deg_bound=0,
        use_faugere=False, use_noro=False, opt_lazy=True, opt_red_tail=True,
        max_growth=2.0, step_factor=1.0, implications=False, prot=False,
        full_prot=False, selection_size=1000, opt_exchange=True,
        opt_allow_recursion=False, ll=False,
        opt_linear_algebra_in_last_block=True, max_generators=None,
        red_tail_deg_growth=True, matrix_prefix='mat',
        modified_linear_algebra=True, draw_matrices=False,
        easy_linear_polynomials=True):
    if use_noro and use_faugere:
        raise ValueError('both use_noro and use_faugere specified')

    def add_to_basis(strat, p):
        if p.is_zero():
            if prot:
                print("-")
        else:
            if prot:
                if full_prot:
                    print(p)
                print("Result: ", "deg:", p.deg(), "lm: ", p.lead(), "el: ", p
                    .elength())
            if easy_linear_polynomials and p.lead_deg() > 2:
                lin = easy_linear_polynomials_func(p)
                for q in lin:
                    strat.add_generator_delayed(q)
            old_len = len(strat)
            strat.add_as_you_wish(p)
            new_len = len(strat)
            if new_len == 1 + old_len:
                high_probability_polynomials_trick(p, strat)

            if prot:
                print("#Generators:", len(strat))

    if isinstance(G, list):
        if not G:
            return []
        G = [Polynomial(g) for g in G]
        current_ring = G[0].ring()
        strat = GroebnerStrategy(current_ring)
        strat.reduction_strategy.opt_red_tail = opt_red_tail
        strat.opt_lazy = opt_lazy
        strat.opt_exchange = opt_exchange
        strat.opt_allow_recursion = opt_allow_recursion
        strat.enabled_log = prot
        strat.reduction_strategy.opt_ll = ll
        strat.opt_modified_linear_algebra = modified_linear_algebra
        strat.opt_linear_algebra_in_last_block = (
            opt_linear_algebra_in_last_block)
        strat.opt_red_by_reduced = False  # True
        strat.reduction_strategy.opt_red_tail_deg_growth = red_tail_deg_growth

        strat.opt_draw_matrices = draw_matrices
        strat.matrix_prefix = matrix_prefix

        for g in G:
            if not g.is_zero():
                strat.add_generator_delayed(g)
    else:
        strat = G

    if prot:
        print("added delayed")
    i = 0
    try:
        while strat.npairs() > 0:
            if max_generators and len(strat) > max_generators:
                raise GeneratorLimitExceeded(strat)
            i = i + 1
            if prot:
                print("Current Degree:", strat.top_sugar())
            if (strat.top_sugar() > deg_bound) and (over_deg_bound <= 0):
                return strat
            if (strat.top_sugar() > deg_bound):
                ps = strat.some_spolys_in_next_degree(over_deg_bound)
                over_deg_bound -= len(ps)
            else:
                ps = strat.some_spolys_in_next_degree(selection_size)

            if ps and ps[0].ring().has_degree_order():
                ps = [strat.reduction_strategy.cheap_reductions(p) for p in ps]
                ps = [p for p in ps if not p.is_zero()]
                if ps:
                    min_deg = min((p.deg() for p in ps))
                new_ps = []
                for p in ps:
                    if p.deg() <= min_deg:
                        new_ps.append(p)
                    else:
                        strat.add_generator_delayed(p)
                ps = new_ps

            if prot:
                print("(", strat.npairs(), ")")
            if prot:
                print("start reducing")
                print("Chain Crit. : ", strat.chain_criterions, "VC:", strat.
                    variable_chain_criterions, "EASYP", strat.
                    easy_product_criterions, "EXTP", strat.
                    extended_product_criterions)
                print(len(ps), "spolys added")

            if use_noro or use_faugere:
                v = BoolePolynomialVector()

                for p in ps:
                    if not p.is_zero():
                        v.append(p)
                if use_noro:
                    res = strat.noro_step(v)
                else:
                    res = strat.faugere_step_dense(v)

            else:
                v = BoolePolynomialVector()
                for p in ps:
                    p = Polynomial(mod_mon_set(BooleSet(p.set()),
                                        strat.reduction_strategy.monomials))
                    if not p.is_zero():
                        v.append(p)
                if len(v) > 100:
                    res = parallel_reduce(v, strat, int(step_factor * 10),
                                          max_growth)
                elif len(v) > 10:
                    res = parallel_reduce(v, strat, int(step_factor * 30),
                                          max_growth)
                else:
                    res = parallel_reduce(v, strat, int(step_factor * 100),
                                          max_growth)

            if prot:
                print("end reducing")

            if res and res[0].ring().has_degree_order():
                res_min_deg = min([p.deg() for p in res])
                new_res = []
                for p in res:
                    if p.deg() == res_min_deg:
                        new_res.append(p)
                    else:
                        strat.add_generator_delayed(p)
                res = new_res

            def sort_key(p):
                return p.lead()
            res_cp = sorted(res, key=sort_key)

            for p in res_cp:
                old_len = len(strat)
                add_to_basis(strat, p)
                if implications and old_len == len(strat) - 1:
                    strat.implications(len(strat) - 1)
                if p.is_one():
                    if prot:
                        print("GB is 1")
                    return strat
                if prot:
                    print("(", strat.npairs(), ")")

            strat.clean_top_by_chain_criterion()
        return strat
    except KeyboardInterrupt:
        raise
Beispiel #2
0
if __name__ == '__main__':
    from .blocks import declare_ring, Block
    r = declare_ring([Block("x", 10000)], globals())
    print(list(all_monomials_of_degree_d(0, [Variable(i) for i in range(100)])))
    print(list(all_monomials_of_degree_d(1, [Variable(i) for i in range(10)])))
    print(list(all_monomials_of_degree_d(2, [Variable(i) for i in range(4)])))
    print(list(all_monomials_of_degree_d(3, [Variable(i) for i in range(4)])))
    print(list(all_monomials_of_degree_d(4, [Variable(i) for i in range(4)])))
    print(list(all_monomials_of_degree_d(0, [])))
    print(list(all_monomials_of_degree_d(1, [])))
    print(list(power_set([Variable(i) for i in range(2)])))
    print(list(power_set([Variable(i) for i in range(4)])))
    print(list(power_set([])))
    # every monomial in the first 8 var, which is at most linear in the first 5
    print(list(mod_mon_set(power_set([Variable(i) for i in range(8)]),
        all_monomials_of_degree_d(2, [Variable(i) for i in range(5)]))))

    # specialized normal form computation
    print(Polynomial(
        mod_mon_set(
            (x(1) * x(2) + x(1) + 1).set(),
            all_monomials_of_degree_d(2, [Variable(i) for i in range(1000)]))))
    print(list(mod_mon_set(power_set([Variable(i) for i in range(50)]),
        all_monomials_of_degree_d(2, [Variable(i) for i in range(1000)]))))


def monomial_from_indices(ring, indices):
    res = Monomial(ring)
    for i in sorted(indices, reverse=True):
        res = res * ring.variable(i)
    return res