Using SymPy, is it possible to limit the possible values of a symbol/variable to a certain range? I now I can set some properties while defining symbols, like positive=True
, but I need more control, i.e. I need to set it to be in the interval [0,1]. This assumption should then be used for solving, simplifying etc.
使用SymPy,是否可以将符号/变量的可能值限制在一定范围内?我现在可以在定义符号时设置一些属性,例如positive = True,但我需要更多的控制,即我需要将它设置为区间[0,1]。然后应该使用这个假设来解决,简化等。
4 个解决方案
#1
5
You can specify the bounds as inequalities such as x >= lb
and x <= ub
, for example:
您可以将边界指定为不等式,例如x> = lb和x <= ub,例如:
from sympy.solvers import solve
from sympy import Symbol
x = Symbol('x')
solve([x >= 0.5, x <= 3, x**2 - 1], x)
Here we search for a solution of equation x**2 == 1
such that x
is in the interval [0.5, 3]
.
在这里,我们搜索方程x ** 2 == 1的解,使得x在区间[0.5,3]中。
#2
4
As for simplification, you want refine
. Unfortunately, it doesn't yet support using inequality syntax, so you'll have to use Q.positive
or Q.negative
(or Q.nonpositive
or Q.nonnegative
for non-strict inequalities). The most common simplification that it handles is sqrt(x**2) = x
if x >= 0
.
至于简化,你想要精炼。不幸的是,它还不支持使用不等式语法,所以你必须使用Q.positive或Q.negative(或Q.nonpositive或Q.nonnegative用于非严格的不等式)。它处理的最常见的简化是sqrt(x ** 2)= x,如果x> = 0。
>>> refine(sqrt((x - 1)**2), Q.positive(x - 1))
x - 1
>>> refine(sqrt((x - 1)**2), Q.positive(x))
Abs(x - 1)
Note in the second case you still get a simpler answer because it at least knows that x - 1
is real under the given assumptions.
请注意,在第二种情况下,您仍然可以得到一个更简单的答案,因为它至少知道在给定的假设下x - 1是真实的。
If your assumptions are as simple as "x
is positive" or "x
is negative", the best chance for success is to define it on the Symbol itself, like
如果你的假设像“x是正的”或“x是负的”一样简单,那么成功的最好机会就是在符号本身上定义它,就像
>>> Symbol('x', positive=True)
>>> sqrt(x**2)
x
#3
2
Now you can use solveset
现在你可以使用solveset了
In [3]: solveset(x**2 - 1, x, Interval(0.5, 3)) Out[3]: {1}
在[3]中:solveset(x ** 2 - 1,x,Interval(0.5,3))Out [3]:{1}
#4
0
In sympy 1.1.1 I found that this works. It can be easily adapted to your case.
在同情1.1.1我发现这是有效的。它可以很容易地适应您的情况。
>>> x = Symbol('x', domain=S.Reals)
>>> solve_domain = And(0 <= x, x < 2*pi).as_set()
>>> solve_domain
[0, 2⋅π)
# solve_domain must be evaluated before solveset call
>>> solveset(sin(x), x, solve_domain)
{0, π}
I don't know why things fall apart if you don't evaluate solve_domain before calling solveset, but it's easy to work around once you know.
如果你在调用solveset之前没有评估solve_domain,我不知道为什么事情会崩溃,但是一旦你知道就很容易解决。
#1
5
You can specify the bounds as inequalities such as x >= lb
and x <= ub
, for example:
您可以将边界指定为不等式,例如x> = lb和x <= ub,例如:
from sympy.solvers import solve
from sympy import Symbol
x = Symbol('x')
solve([x >= 0.5, x <= 3, x**2 - 1], x)
Here we search for a solution of equation x**2 == 1
such that x
is in the interval [0.5, 3]
.
在这里,我们搜索方程x ** 2 == 1的解,使得x在区间[0.5,3]中。
#2
4
As for simplification, you want refine
. Unfortunately, it doesn't yet support using inequality syntax, so you'll have to use Q.positive
or Q.negative
(or Q.nonpositive
or Q.nonnegative
for non-strict inequalities). The most common simplification that it handles is sqrt(x**2) = x
if x >= 0
.
至于简化,你想要精炼。不幸的是,它还不支持使用不等式语法,所以你必须使用Q.positive或Q.negative(或Q.nonpositive或Q.nonnegative用于非严格的不等式)。它处理的最常见的简化是sqrt(x ** 2)= x,如果x> = 0。
>>> refine(sqrt((x - 1)**2), Q.positive(x - 1))
x - 1
>>> refine(sqrt((x - 1)**2), Q.positive(x))
Abs(x - 1)
Note in the second case you still get a simpler answer because it at least knows that x - 1
is real under the given assumptions.
请注意,在第二种情况下,您仍然可以得到一个更简单的答案,因为它至少知道在给定的假设下x - 1是真实的。
If your assumptions are as simple as "x
is positive" or "x
is negative", the best chance for success is to define it on the Symbol itself, like
如果你的假设像“x是正的”或“x是负的”一样简单,那么成功的最好机会就是在符号本身上定义它,就像
>>> Symbol('x', positive=True)
>>> sqrt(x**2)
x
#3
2
Now you can use solveset
现在你可以使用solveset了
In [3]: solveset(x**2 - 1, x, Interval(0.5, 3)) Out[3]: {1}
在[3]中:solveset(x ** 2 - 1,x,Interval(0.5,3))Out [3]:{1}
#4
0
In sympy 1.1.1 I found that this works. It can be easily adapted to your case.
在同情1.1.1我发现这是有效的。它可以很容易地适应您的情况。
>>> x = Symbol('x', domain=S.Reals)
>>> solve_domain = And(0 <= x, x < 2*pi).as_set()
>>> solve_domain
[0, 2⋅π)
# solve_domain must be evaluated before solveset call
>>> solveset(sin(x), x, solve_domain)
{0, π}
I don't know why things fall apart if you don't evaluate solve_domain before calling solveset, but it's easy to work around once you know.
如果你在调用solveset之前没有评估solve_domain,我不知道为什么事情会崩溃,但是一旦你知道就很容易解决。