Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Thank you for reporting this problem. I can reproduce the issue, but am not sure what is causing it. There is a current ticket (#27261) about memory leaks with polynomial evaluation, which might be connected to this problem.

For now, there are at least two faster workarounds.

Define the evaluation homomorphism at the point vec and evaluate it at a polynomial f:

def ev1(f, vec):
    P = f.parent()
    phi = P.hom(list(vec), P.base_ring())
    return phi(f)

Or, compute the residue of f modulo the point ideal J corresponding to the vector. As the result is a constant polynomial, we can convert it to the base ring.

def ev2(f, vec):
    P = f.parent()
    J = P.ideal([x-v for x, v in zip(P.gens(), vec)])
    return P.base_ring()(J.reduce(f))

Timings:

For reproducibility, I ran

set_random_seed(0)

before executing your code snippet.

sage: vec = workload[0][0]
sage: %timeit representativeSetPoly(*vec)
3.99 s ± 127 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
sage: %timeit ev1(representativeSetPoly, vec)
120 ms ± 230 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
sage: %timeit ev2(representativeSetPoly, vec)
7.06 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

This shows that ev2 is the fastest. Maybe this is not unexpected as homomorphisms and evaluation/substitution can be used in more general contexts than reduction modulo an ideal.

Thank you for reporting this problem. I can reproduce the issue, but am not sure what is causing it. There is a current ticket (#27261) about memory leaks with polynomial evaluation, which might be connected to this problem.

For now, there are at least two faster workarounds.

Define the evaluation homomorphism at the point vec and evaluate it at a polynomial f:

def ev1(f, vec):
    P = f.parent()
    phi = P.hom(list(vec), P.base_ring())
    return phi(f)

Or, compute the residue of f modulo the point ideal J corresponding to the vector. As the result is a constant polynomial, we can convert it to the base ring.

def ev2(f, vec):
    P = f.parent()
    J = P.ideal([x-v for x, v in zip(P.gens(), vec)])
    return P.base_ring()(J.reduce(f))

Timings:

For reproducibility, I ran

set_random_seed(0)

before executing your code snippet. (This does not work with numpy.random.)

sage: vec = workload[0][0]
sage: %timeit representativeSetPoly(*vec)
3.99 s ± 127 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
sage: %timeit ev1(representativeSetPoly, vec)
120 ms ± 230 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
sage: %timeit ev2(representativeSetPoly, vec)
7.06 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

This shows that ev2 is the fastest. Maybe this is not unexpected as homomorphisms and evaluation/substitution can be used in more general contexts than reduction modulo an ideal.

Thank you for reporting this problem. I can reproduce the issue, but am not sure what is causing it. There is a current ticket (#27261) about memory leaks with polynomial evaluation, which might be connected to this problem.

For now, there are at least two faster workarounds.

Define the evaluation homomorphism at the point vec and evaluate it at a polynomial f:

def ev1(f, vec):
    P = f.parent()
    phi = P.hom(list(vec), P.base_ring())
    return phi(f)

Or, compute the residue of f modulo the point ideal J corresponding to the vector. As the result is a constant polynomial, we can convert it to the base ring.

def ev2(f, vec):
    P = f.parent()
    J = P.ideal([x-v for x, v in zip(P.gens(), vec)])
    return P.base_ring()(J.reduce(f))

Timings:

For reproducibility, I ran

set_random_seed(0)
np.random.seed(0)

before executing your code snippet. (This does not work with numpy.random.)

sage: vec = workload[0][0]
sage: %time representativeSetPoly(*vec)
CPU times: user 14.6 s, sys: 20.2 ms, total: 14.6 s
Wall time: 14.6 s
0
sage: %timeit representativeSetPoly(*vec)
3.99 s ev1(representativeSetPoly, vec)
213 ms ± 127 1.04 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
sage: %timeit ev1(representativeSetPoly, ev2(representativeSetPoly, vec)
120 11 ms ± 230 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
sage: %timeit ev2(representativeSetPoly, vec)
7.06 ms ± 112 156 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

This shows that ev2 is the fastest. Maybe this is not unexpected as homomorphisms and evaluation/substitution can be used in more general contexts than reduction modulo an ideal.