Polynomial evaluation#
Polynomials are not polynomials if they can not be evaluated as such. In the
case of numpoly, this can be done using object call. numpoly supports
calls with both positional arguments and by name. In other words, one argument
per variable:
>>> q0, q1 = numpoly.variable(2)
>>> poly = numpoly.polynomial([1, q0**2, q0*q1])
>>> poly
polynomial([1, q0**2, q0*q1])
>>> poly(2, 1)
array([1, 4, 2])
>>> poly(q0=2, q1=1)
array([1, 4, 2])
Here the return value is a numpy.ndarray. However, it is also possible
to get a polynomial in return, given a partial evaluations:
>>> poly(3)
polynomial([1, 9, 3*q1])
>>> poly(q0=3)
polynomial([1, 9, 3*q1])
For positional evaluation, to allow for partial evaluations of variables beyond
the first, it is possible to pass a None value to the polynomial to
indicate that a variable is not to be touched in a partial evaluation. E.g.:
>>> poly(None, 2)
polynomial([1, q0**2, 2*q0])
>>> poly(q1=2)
polynomial([1, q0**2, 2*q0])
Vectorized evaluations is also allowed. Just pass any numpy.ndarray
compatible object. numpoly will expand the shape such that it ends up being
polynomial.shape+input.shape. For example:
>>> poly(q1=range(4))
polynomial([[1, 1, 1, 1],
[q0**2, q0**2, q0**2, q0**2],
[0, q0, 2*q0, 3*q0]])
It is also possible to mix both scalar and vector arguments, as long as they are broadcastable in numpy sense. For example:
>>> poly(1, [1, 2, 3])
array([[1, 1, 1],
[1, 1, 1],
[1, 2, 3]])
>>> poly([1, 2, 3], [1, 2, 3])
array([[1, 1, 1],
[1, 4, 9],
[1, 4, 9]])
Passing arguments with an other datatype than the polynomial, results in the output using the common denomination:
>>> poly(0.5)
polynomial([1.0, 0.25, 0.5*q1])
>>> poly(q1=1j)
polynomial([(1+0j), q0**2, 1j*q0])
Assuming the input you want to evaluate is a large matrix and you want an
interface where the matrix is kept intact, you can use numpoly.call(). E.g.:
>>> array = numpy.arange(12).reshape(2, 6)
>>> array
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
>>> numpoly.call(poly, array)
array([[ 1, 1, 1, 1, 1, 1],
[ 0, 1, 4, 9, 16, 25],
[ 0, 7, 16, 27, 40, 55]])
Lastly, it is also possible to pass other polynomials as arguments. This simplifies any form for variable substitution.
>>> poly
polynomial([1, q0**2, q0*q1])
>>> poly(q0=q1, q1=q0)
polynomial([1, q1**2, q0*q1])
>>> poly(None, 1-q1**3)
polynomial([1, q0**2, -q0*q1**3+q0])