如何使用Python和SymPy解决多元不等式?

11

我刚开始使用Python和Sympy,但在使用Sympy解决多元不等式时遇到问题。

假设我在文件中有很多这样的函数:

    cst**(sqrt(x)/2)/cst
    exp(sqrt(cst*x**(1/4)))
    log(log(sqrt(cst + exp(x))))
    (y**(1/4) + y)**cst
    sqrt(y/log(x))/cst
    sqrt(cst**log(cst) + x)
    (y**2)**(x/4)
    sqrt(y*sqrt(cst**y))
    log(sqrt(2)*sqrt(cst)*x)

我需要对它们进行求导,设置常数的值并检查每个函数f是否

    df/dx > 0
    df/dy < 0 

当 x 属于 [0, +oo),y 属于 [0, 1] 时。

为求导,我使用:

    dx = diff(f, x)
    dy = diff(f, y)

然后当我尝试:

    cst = 2 #(for example) 
    solve(dx > 0) 

我遇到了这个错误:

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python2.7/dist-packages/sympy/solvers/solvers.py", line 634, in solve
symbols=symbols)
    File "/usr/local/lib/python2.7/dist-packages/sympy/solvers/inequalities.py", line 374, in reduce_inequalities
    raise NotImplementedError("only univariate inequalities are supported")
    NotImplementedError: only univariate inequalities are supported

但是如果我尝试那样做:

    x=Symbol('x', real=True, postive=True, nonzero=True)
    y=Symbol('y', real=True, postive=True, nonzero=True)
    solve(x**2+y > 0)

我得到了:

    True

有哪种方法可以解决多元不等式并总是得到可行的答案?例如,我想要得到:
solve(x**2-y>0)
Or(x>-sqrt(y), x>sqrt(y))

哪种方法可以获得好的和可行的答案?是否有办法解决多元不等式?


1
欢迎!在这里提问的礼仪是要说明你尝试过什么以及为什么不起作用。 - Krastanov
哎呀,下次我不会忘记了!我尝试了和你一样的代码...但是得到了相同的答案:"NotImplementedError"。 - sloan
2个回答

9
当尝试使用SymPy解决此问题时,您会收到一个非常明确的错误消息:NotImplementedError: only univariate inequalities are supported。请注意,这意味着如果您能贡献出解决此问题的算法,SymPy团队将非常高兴。
现在清楚了sympy.solve不够强大,您可以尝试另一种方法。最近(在0.7.2中),SymPy添加了一种隐式绘图例程,可以绘制表达式评估为True的位置。遗憾的是,它只是一个数值解,而不是您可以从solve得到的符号解,但可能足够:
从图像中可以看出,只有一条线在表达式改变符号的地方,因此解决expr==0可能会给您想要的结果。事实上,确实如此。

谢谢回答,但这不符合我的需求。我需要生成所有可能的函数f(x,y),例如使用10个字符,然后评估所有导数以检查:df/dx > 0 和 df/dy < 0。有太多的可能性需要我自己检查...你有什么想法吗? - sloan
我真的不明白你在评论中问的与你在上面提出的问题有任何关系。请随意提出新问题,或者如果您坚持修改原始问题以清楚表达您的意图。如果您发现答案有用,请点赞。 - Krastanov
非常出色和全面的回答。这个解释对我的博弈论核心分配计算有所帮助。 - hobs

4

mystic中有一个多元不等式求解器,它是建立在sympy之上的。它使用优化和集合的(数学)映射来提供此功能。它并不完美,但适用于许多情况。

>>> equations = '''
... 2*A + 3*B >= C
... A*B > D
... C < 4*A    
... D == 0
... '''
>>> 
>>> import mystic.symbolic as ms
>>> var = list('ABCD')
>>> eqns = ms.simplify(equations, variables=var)
>>> print eqns
D == 0
B > 0
A > C/4
A >= -3*B/2 + C/2
A > D/B
>>> 
>>> # generate a constraints function, which maps one space to another
>>> constrain = ms.generate_constraint(ms.generate_solvers(eqns, var))
>>> solution = constrain([1,2,3,4])
>>> print solution
[1, 2, 3, 0] 
>>> # here's the solution...
>>> dict(zip(var,solution))
{'A': 1, 'C': 3, 'B': 2, 'D': 0}
>>>
>>> A=1; C=3; B=2; D=0
>>> 2*A + 3*B >= C
True
>>> A*B > D
True
>>> C < 4*A
True
>>> D == 0
True
>>> 

让我们再次进行测试,使用建议的测试:
>>> equations = """x**2 - y >= 0
... x + y = 0
... """
>>> eqns = ms.simplify(equations, variables=var)
>>> constrain = ms.generate_constraint(ms.generate_solvers(eqns, var))
>>> solution = constrain([1,3])
>>> solution
[-3, 3]
>>> dict(zip(var, solution))
{'y': 3, 'x': -3}
>>> y=3; x=-3
>>> x**2 - y >= 0
True
>>> x+y == 0
True
>>>

mystic 使用 sympy 和数值优化相结合的方法来简化不等式; 当提供初始解时,它可以(大多数情况下,但并非总是)生成符合方程的有效解。 mystic 不会真正地去“解决”这些不等式,但通常会生成一个有效的解。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接