Usage

Depending on the intended usage, choose one of the MVPoly subclasses: at present these are

  • MVPolyCube, which uses a numpy.ndarray for efficient storage of dense polynomials; or

  • MVPolyDict, which uses a dictionary for a sparse representation.

Import the required subclass in the usual way, for example

from mvpoly.cube import MVPolyCube

If you are not sure which subclass you want then something like

from mvpoly.cube import MVPolyCube as Poly

would allow you to switch classes by a single-line edit.

Construction

Assignment of coefficients

The coefficients of an MVPoly object can be accessed and assigned by index; so one can create a polynomial by assigning the coefficients one-by-one

p = MVPolyCube.zero()
p[0, 0] = 3
p[2, 2] = 2

The zero() method returns the representation of the zero polynomial, and the get/set operations ignore trailing zeros, so p[2, 2, 0] is 2 in the above.

Variables

For a more symbolic method of creating polynomial we can generate MVPoly variables and combine them using the standard arithmetic operators

x, y, z = MVPolyCube.variables(3)
p = (x + y + z**2)**2 - 3

Note, however, that such manipulation is relatively slow.

By direct access

One can create a polynomials from the underlying data structure via the main class constructor

import numpy

coefs = numpy.eye(2)
p = MVPolyCube(coefs)

or by assigning the coefficient

p = MVPolyCube.zero()
p.coef = coef

Naturally, such code is dependant on the subclass used.

From another subclass

Finally, one can create a polynomial of one subclass from one of any other just by passing it to the subclass constructor; equivalently one can use the asclass() method

from mvpoly.cube import MVPolyCube
from mvpoly.dict import MVPolyDict

p = MVPolyDict.zero(dtype=int)
p[3, 2] = 7
# these are the same thing
q = MVPolyCube(p)
q = p.asclass(MVPolyCube)

Data types

Constructor methods take an optional argument which specifies the datatype of the coefficient representation

x, y, z = MVPolyCube.variables(3, dtype=int)

Any Python or numpy dtype can be used with numpy.double being the default. A polynomial’s dtype() method can be used to interrogate the datatype, and one can convert to other types with the astype() method

p = MVPolyDict.zero(dtype=int)
p[3, 2] = 7
q = p.astype(float)

Manipulation

One can add, subtract and multiply MVPoly polynomials, by other polynomials (of the same class) or by numbers.

One can compose polynomials

x, y = MVPolyCube.variables(2)
p = x * y
q = p.compose(x + y, x - y)

and the polynomial call operator uses this method when the arguments are polynomials, so

q = p(x + y, x - y)

will give the same result.

The diff() and int() methods return the differential and indefinite integral of a polynomial.

Evaluation

A polynomial can be evaluated at a point

x, y = MVPolyCube.variables(2)
p = (x - y)**2
val = p.eval(3, 3)

or on an array (specified by as many arrays as the polynomial has variables, each array of the same shape)

L = np.linspace(0, 1, 50)
Gx, Gy = np.meshgrid(L, L)
Gp = p.eval(Gx, Gy)

Note that the polynomial call operator uses this method when the arguments are all scalars or arrays, so

Gp = p(Gx, Gy)

will give the same result.

Other functions

One can find the (total-, homogeneous-) degree with the property degree(), the degree of each variable (and so the number of variables) with degrees()

p = MVPolyDict.zero(dtype=int)
p[3, 2] = 7
numvar = len(p.degrees)
d = p.degree

The indefinite integral with intd(): pass the intervals over which to integrate, one for each variable, as 2-element lists

x, y = MVPolyDict.variables(2)
p = (x + y)**2
val = p.intd([0, 1], [0, 1])

To extract the coefficients in a uniform manner (i.e., independent of the underlying data representation) use the nonzero() property. This returns a list of index-coefficient pairs for the non-zero coefficients.