SymPy:将符号/变量限制为间隔

时间:2022-11-15 00:57:46

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,我不知道为什么事情会崩溃,但是一旦你知道就很容易解决。