Sympy 在解决“[...] 每个候选人中都发现了不可判定的集合成员资格”期间的错误是否意味着不存在解决方案?
Does Sympy's error during solve "[...] undecidable set membership is found in every candidates" mean that no solution exists?
我正在尝试求解变量 x
的以下等式(依赖于其他符号 b, c, d
):
from sympy import symbols, sin, cos, solve, solveset, S
b, c, d, x = symbols('b c d x', real=True)
expr = sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x) # find `x` such that `expr == 0`
存在适用于各种符号的附加限制,即:
0 < d < b < d+x < c
所以我尝试使用 solve
来合并这些不等式约束:
result = solve(
[
sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x),
0 < d,
d < b,
b < d+x,
d+x < c,
],
x,
)
但是,我收到以下错误:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 211, in _parallel_dict_from_expr_if_gens
monom[indices[base]] = exp
KeyError: sin(c - x)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 818, in _solve_inequality
p = Poly(expr, s)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 181, in __new__
return cls._from_expr(rep, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 310, in _from_expr
rep, opt = _dict_from_expr(rep, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 368, in _dict_from_expr
rep, gens = _dict_from_expr_if_gens(expr, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 307, in _dict_from_expr_if_gens
(poly,), gens = _parallel_dict_from_expr_if_gens((expr,), opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 216, in _parallel_dict_from_expr_if_gens
raise PolynomialError("%s contains an element of "
sympy.polys.polyerrors.PolynomialError: sin(c - x) contains an element of the set of generators.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 211, in _parallel_dict_from_expr_if_gens
monom[indices[base]] = exp
KeyError: sin(c - x)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 246, in reduce_rational_inequalities
(numer, denom), opt = parallel_poly_from_expr(
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 4414, in parallel_poly_from_expr
return _parallel_poly_from_expr(exprs, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 4467, in _parallel_poly_from_expr
reps, opt = _parallel_dict_from_expr(exprs, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 332, in _parallel_dict_from_expr
reps, gens = _parallel_dict_from_expr_if_gens(exprs, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 216, in _parallel_dict_from_expr_if_gens
raise PolynomialError("%s contains an element of "
sympy.polys.polyerrors.PolynomialError: sin(c - x) contains an element of the set of generators.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 827, in _solve_inequality
rv = reduce_rational_inequalities([[ie]], s)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 249, in reduce_rational_inequalities
raise PolynomialError(filldedent('''
sympy.polys.polyerrors.PolynomialError:
only polynomials and rational functions are supported in this context.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/test2.py", line 5, in <module>
result = solve(
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/solvers.py", line 920, in solve
return reduce_inequalities(f, symbols=symbols)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 996, in reduce_inequalities
rv = _reduce_inequalities(inequalities, symbols)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 912, in _reduce_inequalities
other.append(_solve_inequality(Relational(expr, 0, rel), gen))
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 829, in _solve_inequality
rv = solve_univariate_inequality(ie, s)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 500, in solve_univariate_inequality
frange = function_range(e, gen, domain)
File "/path/to/venv/lib/python3.9/site-packages/sympy/calculus/util.py", line 208, in function_range
for critical_point in critical_points:
File "/path/to/venv/lib/python3.9/site-packages/sympy/utilities/iterables.py", line 2881, in roundrobin
yield nxt()
File "/path/to/venv/lib/python3.9/site-packages/sympy/sets/sets.py", line 1439, in __iter__
raise TypeError(
TypeError: The computation had not completed because of the undecidable set membership is found in every candidates.
我不确定这个错误是什么意思。这是否意味着对于给定的不等式约束不存在解决方案?
(sympy 版本:1.10.1)
求解集
我也试过使用solveset
(但是,这里似乎不可能包含不等式约束):
result = solveset(
sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x),
x,
domain=S.Reals,
)
然而,经过长时间的计算,它只是returns原来的表达式:
ConditionSet(x, Eq(-sin(x)*sin(-c + 2*d + x) + sin(c - x)*sin(-2*b + 2*d + x), 0), Reals)
matlab
我也试过用Matlab解方程:
syms b c d x
eq1 = sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x) == 0;
eq2 = 0 < d;
eq3 = d < b;
eq4 = b < d+x;
eq5 = d+x < c;
result = solve([eq1 eq2 eq3 eq4 eq5], x, "Real",true, "ReturnConditions",true);
然而,结果完全不同,涉及到一个我无法理解的四阶多项式:
>> result.x
ans =
2*pi*k + atan2(y, 1) - atan2(-y, 1)
>> result.conditions
ans =
d < b & b + atan2(-y, 1) < d + atan2(y, 1) + 2*pi*k & d + atan2(y, 1) + 2*pi*k < c + atan2(-y, 1) & cos(b)*sin(b) + 2*cos(b)^2*cos(d)*sin(d) ~= cos(d)*sin(d) + 2*cos(b)*cos(d)^2*sin(b) & in(k, 'integer') & ~in(c/pi, 'integer') & in(y, 'real') & 4*y^2*cos(c - 2*d) + 2*y^3*sin(c - 2*d) + sin(2*b - 2*d)*sin(c) + y^2*cos(c - 2*b + 2*d) + 3*y^2*cos(2*b + c - 2*d) + 2*y^3*sin(2*b + c - 2*d) + y^4*sin(2*b - 2*d)*sin(c) == 2*y*sin(2*b + c - 2*d) + 2*y*sin(c - 2*d) & 0 < d
以下是如何使用 SymPy 获得类似于 Matlab 解决方案的方法(请注意,我重新定义了符号以使输出更简单):
In [19]: a, b, c, d, e, x, y = symbols('a, b, c, d, e, x, y', real=True)
In [20]: expr = sin(x)*sin(a - x) - sin(e - x)*sin(c - x)
In [21]: expr.expand(trig=True)
Out[21]:
2
sin(a)⋅sin(x)⋅cos(x) - sin(c)⋅sin(e)⋅cos (x) + sin(c)⋅sin(x)⋅cos(e)⋅cos(x) + sin(e)⋅sin(x)⋅cos(c)⋅c
2 2
os(x) - sin (x)⋅cos(a) - sin (x)⋅cos(c)⋅cos(e)
In [22]: expr2 = resultant(expr.expand(trig=True), cos(x)**2 + sin(x)**2 - 1, cos(x))
In [23]: expr2.collect(sin(x))
Out[23]:
⎛ 2 2 2 2 2
⎝- sin (a) - 2⋅sin(a)⋅sin(c)⋅cos(e) - 2⋅sin(a)⋅sin(e)⋅cos(c) - 2⋅sin (c)⋅sin (e) - sin (c)⋅cos (e)
2 2 ⎞ 2 ⎛ 2
+ 2⋅sin(c)⋅sin(e)⋅cos(a) - sin (e)⋅cos (c)⎠⋅sin (x) + ⎝sin (a) + 2⋅sin(a)⋅sin(c)⋅cos(e) + 2⋅sin(a)⋅
2 2 2 2 2 2 2
sin(e)⋅cos(c) + sin (c)⋅sin (e) + sin (c)⋅cos (e) - 2⋅sin(c)⋅sin(e)⋅cos(a) + sin (e)⋅cos (c) + cos
2 2 ⎞ 4 2 2
(a) + 2⋅cos(a)⋅cos(c)⋅cos(e) + cos (c)⋅cos (e)⎠⋅sin (x) + sin (c)⋅sin (e)
所以我们看到我们得到的是 sin(x)
中的 4 次多项式。这个比 Matlab 找到的那个更容易求解,因为它只有 sin(x)
的偶次幂。 sin(x)
的显式解决方案可以使用根找到,例如第一个是:
In [26]: r1, r2, r3, r4 = roots(expr2.subs(sin(x), y), y)
In [27]: r1
Out[27]:
_________________________________________________________________________________________
╱ ________________________________________________________________
╱ ╱
╱ ╱ 2 2 (cos(2⋅a) + cos(2⋅c
╱ ╱ - 8⋅(cos(-a + c + e) + 1)⋅sin (c)⋅sin (e) + ───────────────────
╱ ╲╱
- ╱ - ──────────────────────────────────────────────────────────────────────────────────────
╱ ⎛ 2 2 2 2
╲╱ 2⋅⎝sin (a) + 2⋅sin(a)⋅sin(c)⋅cos(e) + 2⋅sin(a)⋅sin(e)⋅cos(c) + sin (c)⋅sin (e) + sin (
___________________________________________________________________________________________________
__________________________________________________________________________________________
2
) + cos(2⋅e) - 3⋅cos(-a + c + e) + cos(a - c + e) + cos(a + c - e) + cos(a + c + e) - 3)
─────────────────────────────────────────────────────────────────────────────────────────
4
───────────────────────────────────────────────────────────────────────────────────────────────────
2 2 2 2 2
c)⋅cos (e) - 2⋅sin(c)⋅sin(e)⋅cos(a) + sin (e)⋅cos (c) + cos (a) + 2⋅cos(a)⋅cos(c)⋅cos(e) + cos (c)⋅
___________________________________________________________________________________________________
-cos(2⋅a) - cos(2⋅c) - cos(2⋅e) + 3⋅cos(-a + c + e) - cos(a - c + e) - cos(a + c - e) -
──────── + ────────────────────────────────────────────────────────────────────────────────────────
2 ⎞ 8⋅(cos(-a + c + e) + 1)
cos (e)⎠
___________________
cos(a + c + e) + 3
──────────────────
这是否真实或是否满足不等式将取决于符号参数的值,因此我怀疑不等式是否可用于在根的 4 个表达式中进行选择。不过,也许可以使用多项式 expr2 来回答不同的问题。
我正在尝试求解变量 x
的以下等式(依赖于其他符号 b, c, d
):
from sympy import symbols, sin, cos, solve, solveset, S
b, c, d, x = symbols('b c d x', real=True)
expr = sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x) # find `x` such that `expr == 0`
存在适用于各种符号的附加限制,即:
0 < d < b < d+x < c
所以我尝试使用 solve
来合并这些不等式约束:
result = solve(
[
sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x),
0 < d,
d < b,
b < d+x,
d+x < c,
],
x,
)
但是,我收到以下错误:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 211, in _parallel_dict_from_expr_if_gens
monom[indices[base]] = exp
KeyError: sin(c - x)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 818, in _solve_inequality
p = Poly(expr, s)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 181, in __new__
return cls._from_expr(rep, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 310, in _from_expr
rep, opt = _dict_from_expr(rep, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 368, in _dict_from_expr
rep, gens = _dict_from_expr_if_gens(expr, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 307, in _dict_from_expr_if_gens
(poly,), gens = _parallel_dict_from_expr_if_gens((expr,), opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 216, in _parallel_dict_from_expr_if_gens
raise PolynomialError("%s contains an element of "
sympy.polys.polyerrors.PolynomialError: sin(c - x) contains an element of the set of generators.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 211, in _parallel_dict_from_expr_if_gens
monom[indices[base]] = exp
KeyError: sin(c - x)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 246, in reduce_rational_inequalities
(numer, denom), opt = parallel_poly_from_expr(
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 4414, in parallel_poly_from_expr
return _parallel_poly_from_expr(exprs, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polytools.py", line 4467, in _parallel_poly_from_expr
reps, opt = _parallel_dict_from_expr(exprs, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 332, in _parallel_dict_from_expr
reps, gens = _parallel_dict_from_expr_if_gens(exprs, opt)
File "/path/to/venv/lib/python3.9/site-packages/sympy/polys/polyutils.py", line 216, in _parallel_dict_from_expr_if_gens
raise PolynomialError("%s contains an element of "
sympy.polys.polyerrors.PolynomialError: sin(c - x) contains an element of the set of generators.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 827, in _solve_inequality
rv = reduce_rational_inequalities([[ie]], s)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 249, in reduce_rational_inequalities
raise PolynomialError(filldedent('''
sympy.polys.polyerrors.PolynomialError:
only polynomials and rational functions are supported in this context.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/test2.py", line 5, in <module>
result = solve(
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/solvers.py", line 920, in solve
return reduce_inequalities(f, symbols=symbols)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 996, in reduce_inequalities
rv = _reduce_inequalities(inequalities, symbols)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 912, in _reduce_inequalities
other.append(_solve_inequality(Relational(expr, 0, rel), gen))
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 829, in _solve_inequality
rv = solve_univariate_inequality(ie, s)
File "/path/to/venv/lib/python3.9/site-packages/sympy/solvers/inequalities.py", line 500, in solve_univariate_inequality
frange = function_range(e, gen, domain)
File "/path/to/venv/lib/python3.9/site-packages/sympy/calculus/util.py", line 208, in function_range
for critical_point in critical_points:
File "/path/to/venv/lib/python3.9/site-packages/sympy/utilities/iterables.py", line 2881, in roundrobin
yield nxt()
File "/path/to/venv/lib/python3.9/site-packages/sympy/sets/sets.py", line 1439, in __iter__
raise TypeError(
TypeError: The computation had not completed because of the undecidable set membership is found in every candidates.
我不确定这个错误是什么意思。这是否意味着对于给定的不等式约束不存在解决方案?
(sympy 版本:1.10.1)
求解集
我也试过使用solveset
(但是,这里似乎不可能包含不等式约束):
result = solveset(
sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x),
x,
domain=S.Reals,
)
然而,经过长时间的计算,它只是returns原来的表达式:
ConditionSet(x, Eq(-sin(x)*sin(-c + 2*d + x) + sin(c - x)*sin(-2*b + 2*d + x), 0), Reals)
matlab
我也试过用Matlab解方程:
syms b c d x
eq1 = sin(x)*sin(c - 2*d - x) - sin(2*b - 2*d - x)*sin(c - x) == 0;
eq2 = 0 < d;
eq3 = d < b;
eq4 = b < d+x;
eq5 = d+x < c;
result = solve([eq1 eq2 eq3 eq4 eq5], x, "Real",true, "ReturnConditions",true);
然而,结果完全不同,涉及到一个我无法理解的四阶多项式:
>> result.x
ans =
2*pi*k + atan2(y, 1) - atan2(-y, 1)
>> result.conditions
ans =
d < b & b + atan2(-y, 1) < d + atan2(y, 1) + 2*pi*k & d + atan2(y, 1) + 2*pi*k < c + atan2(-y, 1) & cos(b)*sin(b) + 2*cos(b)^2*cos(d)*sin(d) ~= cos(d)*sin(d) + 2*cos(b)*cos(d)^2*sin(b) & in(k, 'integer') & ~in(c/pi, 'integer') & in(y, 'real') & 4*y^2*cos(c - 2*d) + 2*y^3*sin(c - 2*d) + sin(2*b - 2*d)*sin(c) + y^2*cos(c - 2*b + 2*d) + 3*y^2*cos(2*b + c - 2*d) + 2*y^3*sin(2*b + c - 2*d) + y^4*sin(2*b - 2*d)*sin(c) == 2*y*sin(2*b + c - 2*d) + 2*y*sin(c - 2*d) & 0 < d
以下是如何使用 SymPy 获得类似于 Matlab 解决方案的方法(请注意,我重新定义了符号以使输出更简单):
In [19]: a, b, c, d, e, x, y = symbols('a, b, c, d, e, x, y', real=True)
In [20]: expr = sin(x)*sin(a - x) - sin(e - x)*sin(c - x)
In [21]: expr.expand(trig=True)
Out[21]:
2
sin(a)⋅sin(x)⋅cos(x) - sin(c)⋅sin(e)⋅cos (x) + sin(c)⋅sin(x)⋅cos(e)⋅cos(x) + sin(e)⋅sin(x)⋅cos(c)⋅c
2 2
os(x) - sin (x)⋅cos(a) - sin (x)⋅cos(c)⋅cos(e)
In [22]: expr2 = resultant(expr.expand(trig=True), cos(x)**2 + sin(x)**2 - 1, cos(x))
In [23]: expr2.collect(sin(x))
Out[23]:
⎛ 2 2 2 2 2
⎝- sin (a) - 2⋅sin(a)⋅sin(c)⋅cos(e) - 2⋅sin(a)⋅sin(e)⋅cos(c) - 2⋅sin (c)⋅sin (e) - sin (c)⋅cos (e)
2 2 ⎞ 2 ⎛ 2
+ 2⋅sin(c)⋅sin(e)⋅cos(a) - sin (e)⋅cos (c)⎠⋅sin (x) + ⎝sin (a) + 2⋅sin(a)⋅sin(c)⋅cos(e) + 2⋅sin(a)⋅
2 2 2 2 2 2 2
sin(e)⋅cos(c) + sin (c)⋅sin (e) + sin (c)⋅cos (e) - 2⋅sin(c)⋅sin(e)⋅cos(a) + sin (e)⋅cos (c) + cos
2 2 ⎞ 4 2 2
(a) + 2⋅cos(a)⋅cos(c)⋅cos(e) + cos (c)⋅cos (e)⎠⋅sin (x) + sin (c)⋅sin (e)
所以我们看到我们得到的是 sin(x)
中的 4 次多项式。这个比 Matlab 找到的那个更容易求解,因为它只有 sin(x)
的偶次幂。 sin(x)
的显式解决方案可以使用根找到,例如第一个是:
In [26]: r1, r2, r3, r4 = roots(expr2.subs(sin(x), y), y)
In [27]: r1
Out[27]:
_________________________________________________________________________________________
╱ ________________________________________________________________
╱ ╱
╱ ╱ 2 2 (cos(2⋅a) + cos(2⋅c
╱ ╱ - 8⋅(cos(-a + c + e) + 1)⋅sin (c)⋅sin (e) + ───────────────────
╱ ╲╱
- ╱ - ──────────────────────────────────────────────────────────────────────────────────────
╱ ⎛ 2 2 2 2
╲╱ 2⋅⎝sin (a) + 2⋅sin(a)⋅sin(c)⋅cos(e) + 2⋅sin(a)⋅sin(e)⋅cos(c) + sin (c)⋅sin (e) + sin (
___________________________________________________________________________________________________
__________________________________________________________________________________________
2
) + cos(2⋅e) - 3⋅cos(-a + c + e) + cos(a - c + e) + cos(a + c - e) + cos(a + c + e) - 3)
─────────────────────────────────────────────────────────────────────────────────────────
4
───────────────────────────────────────────────────────────────────────────────────────────────────
2 2 2 2 2
c)⋅cos (e) - 2⋅sin(c)⋅sin(e)⋅cos(a) + sin (e)⋅cos (c) + cos (a) + 2⋅cos(a)⋅cos(c)⋅cos(e) + cos (c)⋅
___________________________________________________________________________________________________
-cos(2⋅a) - cos(2⋅c) - cos(2⋅e) + 3⋅cos(-a + c + e) - cos(a - c + e) - cos(a + c - e) -
──────── + ────────────────────────────────────────────────────────────────────────────────────────
2 ⎞ 8⋅(cos(-a + c + e) + 1)
cos (e)⎠
___________________
cos(a + c + e) + 3
──────────────────
这是否真实或是否满足不等式将取决于符号参数的值,因此我怀疑不等式是否可用于在根的 4 个表达式中进行选择。不过,也许可以使用多项式 expr2 来回答不同的问题。