How to evaluate SymPy PurePoly for given Matrix?

Viewed 123

Say I have a SymPy PurePoly, how can I evaluate its value for a given square matrix? Just passing it to eval raises an exception. Here's what I have tried:

import sympy as sp
from sympy.matrices import Matrix
from sympy.polys.polytools import PurePoly

x = sp.symbols('x')
P = PurePoly(x**2 + 3 * x + 4, x)
M = Matrix([[1,2],[3,4]])
P.eval(M) # does not work!

I know that this is possible for an expression built from MatrixSymbols, but I do not know how to transform a PurePoly into this representation.

2 Answers

Do you mean you want to calculate P at each value of the matrix? If so

>>> M.applyfunc(P)
Matrix([
[ 8, 14],
[22, 32]])

Here's one way I found that works by monkey patching PurePoly. Admittedly this solution is a bit ugly.

from sympy.matrices import eye
from sympy.polys.polytools import PurePoly
from sympy.polys.polyutils import basic_from_dict

def pure_poly_eval_matrix(self, M):
    if M.rows != M.cols:
        raise ValueError("matrix must be square")

    if (len(self.gens) != 1):
        raise ValueError("one free variable expected")

    # note: in newer versions of sympy this reduces to self.expr()
    expr = basic_from_dict(self.rep.to_sympy_dict(), *self.gens)

    const, non_const = expr.as_independent(self.gens[0])

    return non_const.subs(self.gens[0], M).doit() + const * eye(M.rows)

PurePoly.eval_matrix = pure_poly_eval_matrix

We can then simply call P.eval_matrix(M).

Related