python - 如何重新排列包含关系运算符的 sympy 表达式

标签 python sympy

我有包含关系运算符、符号和常量的表达式。我想重新排列表达式,以便(在可能的范围内)所有常数项都在关系运算符的一侧,而其余项在另一侧。例如,我想重新排列:

x - 5 > y - z

到:

x - y + z > 5

是否有现有的 sympy 方法来执行此操作?如果没有,我应该从哪里开始扩展 sympy?

最佳答案

有点令人惊讶的是,我找不到一种“开箱即用”的方法。您可以使用this question中的方法使任何一个变量成为不等式左侧 (LHS) 的唯一主语,但我似乎无法使常数项成为主语。

因此,我编写了自己的版本并在下面重现。我已经在给定的示例和其他几个示例中对其进行了测试。它试图根据可选参数使右侧 (RHS) 由零或仅包含常数项组成。很可能存在失败的极端情况 - 谨慎使用/修改。

代码:

import sympy
from sympy.core.relational import Relational

mult_by_minus_one_map = {
    None: '==',
    '==': '==',
    'eq': '==',
    '!=': '!=',
    '<>': '!=',
    'ne': '!=',
    '>=': '<=',
    'ge': '<=',
    '<=': '>=',
    'le': '>=',
    '>': '<',
    'gt': '<',
    '<': '>',
    'lt': '>',
}

def move_inequality_constants(ineq, zero_on_right=False):
    l = ineq.lhs
    r = ineq.rhs
    op = ineq.rel_op
    all_on_left = l - r
    if zero_on_right:
        return Relational(all_on_left, sympy.sympify(0), op)
    else:
        coeff_dict = all_on_left.as_coefficients_dict()
        var_types = coeff_dict.keys()
        new_rhs = sympy.sympify(0)
        for s in var_types:
            if s == 1:
                all_on_left = all_on_left - coeff_dict[s]
                new_rhs = new_rhs - coeff_dict[s]
        if new_rhs < 0:
            all_on_left = all_on_left * -1
            new_rhs = new_rhs * -1
            op = mult_by_minus_one_map[op]
        return Relational(all_on_left,new_rhs,op)

# test code to demo function below    
from sympy.abc import x,y,z

test_ineqs = [ x - 5 > y - z,
               x**2 + x - 5 > y + x**2 - z,
               x + 5 > y - z,
               x**3 + y**2 >= x + 5*y - z - 15]

for k in test_ineqs:
    print('Re-arranging '+ str(k))
    kn = move_inequality_constants(k)
    print('Gives '+str(kn))
    print('Or equivalently ' + str(move_inequality_constants(k, True)))
    print('====')

输出:

Re-arranging x - 5 > y - z
Gives x - y + z > 5
Or equivalently x - y + z - 5 > 0
====
Re-arranging x**2 + x - 5 > x**2 + y - z
Gives x - y + z > 5
Or equivalently x - y + z - 5 > 0
====
Re-arranging x + 5 > y - z
Gives -x + y - z < 5
Or equivalently x - y + z + 5 > 0
====
Re-arranging x**3 + y**2 >= x + 5*y - z - 15
Gives -x**3 + x - y**2 + 5*y - z <= 15
Or equivalently x**3 - x + y**2 - 5*y + z + 15 >= 0

关于python - 如何重新排列包含关系运算符的 sympy 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30225348/

相关文章:

python - 尽管存在此 urllib2 错误,但在 Python 2.7 中不在代理后面时如何部署我的 Google App Engine 项目?

python - 将符号矩阵传递给 sympy.lambdify

python - 如何使用 Python API 获取 Azure 批处理中的作业和任务统计信息?

python - 在 python 中比较并从列表中提取字符串

python - 为什么 Python list() 并不总是具有相同的顺序?

python - 如何从 python 中的 ODE 获取常量?

python - Sympysolve不会返回答案

python - 同情错误?即使使用 `evaluate=False` 方程也会自动处理

math - 我们如何截断幂级数并将其转换为 sympy 中的多项式?

Python - 将字符串和转义的十六进制字符串数据转换为整数的更好方法?