b2/python/docs/source/tutorials/evaluation_cyclic.rst
2025-01-14 01:15:53 +01:00

91 lines
2.6 KiB
ReStructuredText

♻️ Evaluation of cyclic-:math:`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 pybertini
import numpy
num_vars = 10
x = [None] * num_vars # preallocate the list
for ii in range(num_vars):
x[ii] = pybertini.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 :math:`n` polynomials :cite:`cyclic_n`.
::
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 = pybertini.System()
for f in cyclic(x):
sys.add_function(f)
print(sys) # long screen output, i know
We also need to associate the variables with the system. Unassociated variables are left unknown, and retain their value until elsewhere set.
::
vg = pybertini.VariableGroup()
for var in x:
vg.append(var)
sys.add_variable_group(vg)
Let's simplify this. It will modify elements of the constructed function tree, even those held externally -- Bertini uses shared pointers under the hood, so pay attention to where you re-use parts of your functions, because later modification of them without deep cloning will cause ... modification elsewhere, too.
::
pybertini.system.simplify(sys)
Now, let's evaluate it at the origin -- all zero's (0 is the default value for multiprecision complex numbers in Bertini2). The returned value should be all zero's except the last entry, which should be -1.
::
s = pybertini.multiprec.Vector()
s.resize(num_vars)
sys.eval(s)
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] = pybertini.multiprec.Complex(ii)
sys.eval(s)
There is much more one can do, too! Please write the authors, particularly Dani Brake, for more.
.. [1] This is one of the reasons we wrote Bertini2's symbolic C++ core and exposed it to Python.