How to generate a symbolic multivariate polynomial of a given dimension in SymPy?

独自空忆成欢 提交于 2019-12-24 06:44:06

问题


I want to use power series to approximate some PDEs. The first step I need to generate symbolic multivariate polynomials, given a numpy ndarray.

Consider the polynomial below:

I want to take a m dimensional ndarray of D=[d1,...,dm] where djs are non-negative integers, and generate a symbolic multivariate polynomial in the form of symbolic expression. The symbolic expression consists of monomials of the form:

Fo example if D=[2,3] the output should be

For this specific case I could nest two for loops and add the expressions. But I don't know what to do for Ds with arbitrary length. If I could generate the D dimensional ndarrays of A and X without using for loops, then I could use np.sum(np.multiply(A,X)) as Frobenius inner product to get what I need.


回答1:


I would use symarray and itertools.product for this:

from sympy import *
import itertools
D = (3, 4, 2, 3)
a = symarray("a", D)
x = symarray("x", len(D))
prod_iterator = itertools.product(*map(range, D))
result = Add(*[a[p]*Mul(*[v**d for v, d in zip(x, p)]) for p in prod_iterator])

The result being

a_0_0_0_0 + a_0_0_0_1*x_3 + a_0_0_0_2*x_3**2 + a_0_0_1_0*x_2 + a_0_0_1_1*x_2*x_3 + a_0_0_1_2*x_2*x_3**2 + a_0_1_0_0*x_1 + a_0_1_0_1*x_1*x_3 + a_0_1_0_2*x_1*x_3**2 + a_0_1_1_0*x_1*x_2 + a_0_1_1_1*x_1*x_2*x_3 + a_0_1_1_2*x_1*x_2*x_3**2 + a_0_2_0_0*x_1**2 + a_0_2_0_1*x_1**2*x_3 + a_0_2_0_2*x_1**2*x_3**2 + a_0_2_1_0*x_1**2*x_2 + a_0_2_1_1*x_1**2*x_2*x_3 + a_0_2_1_2*x_1**2*x_2*x_3**2 + a_0_3_0_0*x_1**3 + a_0_3_0_1*x_1**3*x_3 + a_0_3_0_2*x_1**3*x_3**2 + a_0_3_1_0*x_1**3*x_2 + a_0_3_1_1*x_1**3*x_2*x_3 + a_0_3_1_2*x_1**3*x_2*x_3**2 + a_1_0_0_0*x_0 + a_1_0_0_1*x_0*x_3 + a_1_0_0_2*x_0*x_3**2 + a_1_0_1_0*x_0*x_2 + a_1_0_1_1*x_0*x_2*x_3 + a_1_0_1_2*x_0*x_2*x_3**2 + a_1_1_0_0*x_0*x_1 + a_1_1_0_1*x_0*x_1*x_3 + a_1_1_0_2*x_0*x_1*x_3**2 + a_1_1_1_0*x_0*x_1*x_2 + a_1_1_1_1*x_0*x_1*x_2*x_3 + a_1_1_1_2*x_0*x_1*x_2*x_3**2 + a_1_2_0_0*x_0*x_1**2 + a_1_2_0_1*x_0*x_1**2*x_3 + a_1_2_0_2*x_0*x_1**2*x_3**2 + a_1_2_1_0*x_0*x_1**2*x_2 + a_1_2_1_1*x_0*x_1**2*x_2*x_3 + a_1_2_1_2*x_0*x_1**2*x_2*x_3**2 + a_1_3_0_0*x_0*x_1**3 + a_1_3_0_1*x_0*x_1**3*x_3 + a_1_3_0_2*x_0*x_1**3*x_3**2 + a_1_3_1_0*x_0*x_1**3*x_2 + a_1_3_1_1*x_0*x_1**3*x_2*x_3 + a_1_3_1_2*x_0*x_1**3*x_2*x_3**2 + a_2_0_0_0*x_0**2 + a_2_0_0_1*x_0**2*x_3 + a_2_0_0_2*x_0**2*x_3**2 + a_2_0_1_0*x_0**2*x_2 + a_2_0_1_1*x_0**2*x_2*x_3 + a_2_0_1_2*x_0**2*x_2*x_3**2 + a_2_1_0_0*x_0**2*x_1 + a_2_1_0_1*x_0**2*x_1*x_3 + a_2_1_0_2*x_0**2*x_1*x_3**2 + a_2_1_1_0*x_0**2*x_1*x_2 + a_2_1_1_1*x_0**2*x_1*x_2*x_3 + a_2_1_1_2*x_0**2*x_1*x_2*x_3**2 + a_2_2_0_0*x_0**2*x_1**2 + a_2_2_0_1*x_0**2*x_1**2*x_3 + a_2_2_0_2*x_0**2*x_1**2*x_3**2 + a_2_2_1_0*x_0**2*x_1**2*x_2 + a_2_2_1_1*x_0**2*x_1**2*x_2*x_3 + a_2_2_1_2*x_0**2*x_1**2*x_2*x_3**2 + a_2_3_0_0*x_0**2*x_1**3 + a_2_3_0_1*x_0**2*x_1**3*x_3 + a_2_3_0_2*x_0**2*x_1**3*x_3**2 + a_2_3_1_0*x_0**2*x_1**3*x_2 + a_2_3_1_1*x_0**2*x_1**3*x_2*x_3 + a_2_3_1_2*x_0**2*x_1**3*x_2*x_3**2

Remarks:

  1. symarray depends on NumPy, but this does not seem to be an issue for you. If it was, I would create symbols one by one using itertools.product
  2. The format Add(*[...]) is more efficient than sum([...]) for forming symbolic sums with a large number of terms, see SymPy issue 13945.


来源:https://stackoverflow.com/questions/51628270/how-to-generate-a-symbolic-multivariate-polynomial-of-a-given-dimension-in-sympy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!