โป๏ธ Evaluation of cyclic-\(n\) polynomialsยถ
Bertini is software for algebraic geometry. This means we work with systems of polynomials, a critical component of which is system and function evaluation.
Bertini2 allows us to set up many kinds of functions, and thus systems, by exploting operator overloading.
Make some symbolsยถ
Letโs start by making some variables, programmatically [1].
import bertini
import numpy
num_vars = 10
x = [None] * num_vars # preallocate the list
for ii in range(num_vars):
x[ii] = bertini.Variable('x' + str(ii))
Huzzah, we have num_vars variables! This was hard to do in Bertini 1โs classic style input files. Now we can do it directly! ๐ฏ
Write a function to produce the cyclic \(n\) polynomials [DKK03].
def cyclic(vars):
n = len(vars)
f = [None] * len(vars)
y = []
for ii in range(2):
for x in vars:
y.append(x)
for ii in range(n-1):
f[ii] = numpy.sum( [numpy.prod(y[jj:jj+ii+1]) for jj in range(n)] )
# the last one is minus one
f[-1] = numpy.prod(vars)-1
return f
Now we will make a System, and put the cyclic polynomials into it.
sys = bertini.System()
for f in cyclic(x):
sys.add_function(f)
print(sys) # long screen output, i know
...
10 functions:
f_0 = x0+x1+x2+x3+x4+x5+x6+x7+x8+x9
...
f_9 = x0*x1*x2*x3*x4*x5*x6*x7*x8*x9-1
...
We also need to associate the variables with the system. Unassociated variables are left unknown, and retain their value until elsewhere set.
vg = bertini.VariableGroup()
for var in x:
vg.append(var)
sys.add_variable_group(vg)
Now, letโs evaluate it at the origin โ all zeroโs. The returned value should be all zeroโs except the last entry, which should be -1.
s = numpy.zeros((10,), dtype=bertini.multiprec.complex_mp)
result = sys.eval(s)
assert complex(result[-1]) == -1 # last cyclic function is (prod x) - 1
assert all(complex(v) == 0 for v in result[:-1]) # the rest vanish at the origin
Yay, all zeros, except the last one is \(-1\). Huzzah.
Letโs change the values of our vector, and re-evaluate.
for ii in range(num_vars):
s[ii] = bertini.multiprec.complex_mp(ii)
result = sys.eval(s)
There is much more one can do, too! Check out the other tutorials. This is one of the older ones.
Complete exampleยถ
The whole tutorial as one runnable script:
"""Bertini 2 tutorial: Evaluation of cyclic-n polynomials.
Assembles all code fragments from the tutorial into one runnable program.
Run: python evaluation_cyclic.py
"""
import bertini
import numpy
def make_symbols(num_vars=10):
"""Programmatically create num_vars variables x0..x{n-1}."""
x = [None] * num_vars # preallocate the list
for ii in range(num_vars):
x[ii] = bertini.Variable('x' + str(ii))
return x
def cyclic(vars):
"""Produce the cyclic-n polynomials from a list of variables."""
n = len(vars)
f = [None] * len(vars)
y = []
for ii in range(2):
for x in vars:
y.append(x)
for ii in range(n - 1):
f[ii] = numpy.sum([numpy.prod(y[jj:jj + ii + 1]) for jj in range(n)])
# the last one is minus one
f[-1] = numpy.prod(vars) - 1
return f
def build_system(x):
"""Make a System and put the cyclic polynomials into it."""
sys = bertini.System()
for f in cyclic(x):
sys.add_function(f)
print(sys) # long screen output, i know
return sys
def associate_variables(sys, x):
"""Associate the variables with the system via a VariableGroup."""
vg = bertini.VariableGroup()
for var in x:
vg.append(var)
sys.add_variable_group(vg)
def simplify_system(sys):
"""Simplify the system in place (modifies the shared function tree)."""
bertini.system.simplify(sys)
def evaluate_at_origin(sys):
"""Evaluate at the origin; all zeros except the last entry, which is -1."""
s = numpy.zeros((10,), dtype=bertini.multiprec.complex_mp)
result = sys.eval(s)
assert complex(result[-1]) == -1 # last cyclic function is (prod x) - 1
assert all(complex(v) == 0 for v in result[:-1]) # the rest vanish at the origin
return s
def evaluate_at_new_point(sys, s, num_vars=10):
"""Change the values of the vector and re-evaluate."""
for ii in range(num_vars):
s[ii] = bertini.multiprec.complex_mp(ii)
result = sys.eval(s)
return result
def main():
num_vars = 10
x = make_symbols(num_vars)
sys = build_system(x)
associate_variables(sys, x)
simplify_system(sys)
s = evaluate_at_origin(sys)
evaluate_at_new_point(sys, s, num_vars)
if __name__ == '__main__':
main()