发现试图将表达式与具有偏见的输入匹配的怪异问题,而无需评估(Sympy)

发布于 2025-02-12 04:07:14 字数 1098 浏览 1 评论 0原文

我已经详细介绍了本期线程 https://github.com/sympy.com/sympy/sympy/sympy/sympy/sympy/issues/issues/sissues/sissues /23709

但要点是我试图以形式的方程式获得一个方程的系数:

parsed_input = 7*x + 4*(10*x + 6) >= 8*x + 15

我使用的模式:

x = Wild("x",  properties=[lambda x: isinstance(x, Symbol)])
a = Wild("a",  properties=[lambda x: isinstance(x, Integer)])
p = Wild("p",  properties=[lambda x: isinstance(x, Integer)])
q = Wild("q",  properties=[lambda x: isinstance(x, Integer)])
b = Wild("b",  properties=[lambda x: isinstance(x, Integer)])
c = Wild("c",  properties=[lambda x: isinstance(x, Integer)])
r = Wild("r",  properties=[lambda x: isinstance(x, Integer)])
s = Wild("s",  properties=[lambda x: isinstance(x, Integer)])

expected_output = Ge(Mul(a, (p*x + q)) +b*x + c,  r*x + s)

但是当我这样做时:

matching = parsed_input.match(expected_output)

我大多得到a = 1,p = 40,q = 24我有时会得到a = 4,p = 10,q = 6

我如何获得a = 4,p = 10,q = 6?

I have gone into detail in this issue thread https://github.com/sympy/sympy/issues/23709

but the gist is that I am trying to get the coefficients of an equation in the form:

parsed_input = 7*x + 4*(10*x + 6) >= 8*x + 15

I am using the pattern:

x = Wild("x",  properties=[lambda x: isinstance(x, Symbol)])
a = Wild("a",  properties=[lambda x: isinstance(x, Integer)])
p = Wild("p",  properties=[lambda x: isinstance(x, Integer)])
q = Wild("q",  properties=[lambda x: isinstance(x, Integer)])
b = Wild("b",  properties=[lambda x: isinstance(x, Integer)])
c = Wild("c",  properties=[lambda x: isinstance(x, Integer)])
r = Wild("r",  properties=[lambda x: isinstance(x, Integer)])
s = Wild("s",  properties=[lambda x: isinstance(x, Integer)])

expected_output = Ge(Mul(a, (p*x + q)) +b*x + c,  r*x + s)

But when I do:

matching = parsed_input.match(expected_output)

I am mostly getting a=1 , p=40, q=24 and some other times I get a=4,p=10, q=6

How can I get a=4,p=10, q=6 everytime?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌路黄昏 2025-02-19 04:07:15

有时,自定义解析器可以提供帮助:

def parse(eq,x=None):
    from sympy import Add, ordered
    from sympy.utilities.iterables import sift
    if x is None:
        from sympy.abc import x
    bcxd, axe = sift(Add.make_args(eq), lambda _: _.has(Add), binary=True)
    if len(bcxd) == 2:
        axe, bcxd = [[i] for i in bcxd]
        if axe[0].is_Mul:
            axe, bcxd = bcxd, axe
    assert len(bcxd) < 2
    assert len(axe) < 3
    e, ax = Add(*axe).as_coeff_Add()
    if not ax:
        a = 0
    else:
        a,X = ax.as_coeff_Mul()
        assert X == x
    if not bcxd:
        b=c=d=0    
    else:
        bcxd = bcxd.pop()
        if bcxd.is_Add:
            b = 1
            cxd = bcxd
        else:
            b,cxd = ordered(bcxd.args)
        if cxd.is_Mul:
            d = 0
            cx = cxd
        else:
            d,cx = ordered(cxd.args)
        c,X = cx.as_independent(x, as_Add=False)
        if X == 1:
            c,d=0,c
        else:
            assert X == x
    return dict(zip('abcde',(a,b,c,d,e)))

from sympy import S
from sympy.abc import x
assert parse(S(3)) == {'a': 0, 'b': 0, 'c': 0, 'd': 0, 'e': 3}
assert parse(x) == {'a': 1, 'b': 0, 'c': 0, 'd': 0, 'e': 0}
assert parse(3*x) == {'a': 3, 'b': 0, 'c': 0, 'd': 0, 'e': 0}
assert parse(3*x+4) == {'a': 3, 'b': 0, 'c': 0, 'd': 0, 'e': 4}
assert parse(3*x+4+Mul(1,x+7,evaluate=False)) == {'a': 3, 'b': 1, 'c': 1, 'd': 7, 'e': 4}
assert parse(3*x+4+Mul(1,2*x+7,evaluate=False)) == {'a': 3, 'b': 1, 'c': 2, 'd': 7, 'e': 4}
assert parse(3*x+4+Mul(6,2*x+7,evaluate=False)) == {'a': 3, 'b': 6, 'c': 2, 'd': 7, 'e': 4}
with evaluate(False):
    eq = 2+3*x+4*(5*x+6)

assert parse(eq) == dict(zip('abcde', (3,4,5,6,2)))

Sometimes a custom parser can help:

def parse(eq,x=None):
    from sympy import Add, ordered
    from sympy.utilities.iterables import sift
    if x is None:
        from sympy.abc import x
    bcxd, axe = sift(Add.make_args(eq), lambda _: _.has(Add), binary=True)
    if len(bcxd) == 2:
        axe, bcxd = [[i] for i in bcxd]
        if axe[0].is_Mul:
            axe, bcxd = bcxd, axe
    assert len(bcxd) < 2
    assert len(axe) < 3
    e, ax = Add(*axe).as_coeff_Add()
    if not ax:
        a = 0
    else:
        a,X = ax.as_coeff_Mul()
        assert X == x
    if not bcxd:
        b=c=d=0    
    else:
        bcxd = bcxd.pop()
        if bcxd.is_Add:
            b = 1
            cxd = bcxd
        else:
            b,cxd = ordered(bcxd.args)
        if cxd.is_Mul:
            d = 0
            cx = cxd
        else:
            d,cx = ordered(cxd.args)
        c,X = cx.as_independent(x, as_Add=False)
        if X == 1:
            c,d=0,c
        else:
            assert X == x
    return dict(zip('abcde',(a,b,c,d,e)))

from sympy import S
from sympy.abc import x
assert parse(S(3)) == {'a': 0, 'b': 0, 'c': 0, 'd': 0, 'e': 3}
assert parse(x) == {'a': 1, 'b': 0, 'c': 0, 'd': 0, 'e': 0}
assert parse(3*x) == {'a': 3, 'b': 0, 'c': 0, 'd': 0, 'e': 0}
assert parse(3*x+4) == {'a': 3, 'b': 0, 'c': 0, 'd': 0, 'e': 4}
assert parse(3*x+4+Mul(1,x+7,evaluate=False)) == {'a': 3, 'b': 1, 'c': 1, 'd': 7, 'e': 4}
assert parse(3*x+4+Mul(1,2*x+7,evaluate=False)) == {'a': 3, 'b': 1, 'c': 2, 'd': 7, 'e': 4}
assert parse(3*x+4+Mul(6,2*x+7,evaluate=False)) == {'a': 3, 'b': 6, 'c': 2, 'd': 7, 'e': 4}
with evaluate(False):
    eq = 2+3*x+4*(5*x+6)

assert parse(eq) == dict(zip('abcde', (3,4,5,6,2)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文