在sympy中分解polys [英] Factoring polys in sympy

查看:106
本文介绍了在sympy中分解polys的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个非常简单的概率计算,即从A-Z集中获取X,Y,Z的子集(具有相应的概率x,y,z).

I'm doing a very simple probability calculations of getting subset of X, Y, Z from set of A-Z (with corresponding probabilities x, y, z).

由于公式很繁琐,为了处理它们,我正在尝试简化 (或 collect factor -我不知道确切的定义)使用符号表示这些多项式表达式.

And because of very heavy formulas, in order to handle them, I'm trying to simplify (or collect or factor - I dont know the exact definition) these polynomial expressions using sympy.

因此..(具有从具有相应概率x,y,z的A-Z集合中获取X,Y,Z的子集的非常简单的概率计算表达式)

So.. having this (a very simple probability calculation expression of getting subset of X,Y,Z from set of A-Z with corresponding probabilities x, y, z)

import sympy as sp

x, y, z = sp.symbols('x y z')

expression = (
    x * (1 - x) * y * (1 - x - y) * z +
    x * (1 - x) * z * (1 - x - z) * y +

    y * (1 - y) * x * (1 - y - x) * z +
    y * (1 - y) * z * (1 - y - z) * x +

    z * (1 - z) * y * (1 - z - y) * x +
    z * (1 - z) * x * (1 - z - x) * y
)

我想得到这样的东西

x * y * z * (6 * (1 - x - y - z) + (x + y) ** 2 + (y + z) ** 2 + (x + z) ** 2)

poly,以尽可能少的操作(+-***,...)进行重写的方式

a poly, rewritten in way to have as few operations (+, -, *, **, ...) as possible

我尝试了factor()collect()simplify().但是结果与我的预期不同.通常我会得到

I tried factor(), collect(), simplify(). But result differs from my expectations. Mostly I get

2*x*y*z*(x**2 + x*y + x*z - 3*x + y**2 + y*z - 3*y + z**2 - 3*z + 3)

我知道sympy可以组合多项式为简单形式:

I know that sympy can combine polynomials into simple forms:

sp.factor(x**2 + 2*x*y + y**2)  # gives (x + y)**2

但是如何根据上述表达式对 combine 多项式进行求偶呢?

But how to make sympy to combine polynomials from expressions above?

如果这在sympy中是不可能完成的任务,可能还有其他选择吗?

If this is impossible task in sympy, may be there are any other options?

推荐答案

这次将一些方法放在一起会给出一个很好的答案.有趣的是,看看这种策略是否比您生成的方程式更有效,或者顾名思义,这次只是幸运的结果.

Putting together some of the methods happens to give a nice answer this time. It would be interesting to see if this strategy works more often than not on the equations you generate or if, as the name implies, this is just a lucky result this time.

def iflfactor(eq):
    """Return the "I'm feeling lucky" factored form of eq."""
    e = Mul(*[horner(e) if e.is_Add else e for e in
        Mul.make_args(factor_terms(expand(eq)))])
    r, e = cse(e)
    s = [ri[0] for ri in r]
    e = Mul(*[collect(ei.expand(), s) if ei.is_Add else ei for ei in
        Mul.make_args(e[0])]).subs(r)
    return e

>>> iflfactor(eq)  # using your equation as eq
2*x*y*z*(x**2 + x*y + y**2 + (z - 3)*(x + y + z) + 3)
>>> _.count_ops()
15

顺便说一句,factor_terms和gcd_terms之间的区别在于,factor_terms在保留表达式的原始结构的同时,会更努力地提取常用术语,就像您手动进行的操作(即在Adds中寻找常用术语一样).拔出).

BTW, a difference between factor_terms and gcd_terms is that factor_terms will work harder to pull out common terms while retaining the original structure of the expression, very much like you would do by hand (i.e. looking for common terms in Adds that can be pulled out).

>>> factor_terms(x/(z+z*y)+x/z)
x*(1 + 1/(y + 1))/z
>>> gcd_terms(x/(z+z*y)+x/z)
x*(y*z + 2*z)/(z*(y*z + z))

对于它的价值,

克里斯

这篇关于在sympy中分解polys的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆