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])