当尝试将分段函数与非理性指数相结合时,我偶然发现了以下问题:
import sympy as sym
x, y = sym.symbols(['x', 'y'])
pdf = sym.Piecewise((0, x < 1),
(x ** -2.5, x < 2),
(0, True))
cdf = sym.integrate(pdf, (x, -sym.oo, y))
这会出现以下错误:
ValueError Traceback (most recent call last)
<ipython-input-3-c1f460aac84e> in <module>()
5 (x ** -2.5, x < 2),
6 (0, True))
----> 7 cdf = sym.integrate(pdf, (x, -sym.oo, y))
8 print(cdf)
~/.local/lib/python3.6/site-packages/sympy/integrals/integrals.py in integrate(*args, **kwargs)
1293 if isinstance(integral, Integral):
1294 return integral.doit(deep=False, meijerg=meijerg, conds=conds,
-> 1295 risch=risch, manual=manual)
1296 else:
1297 return integral
~/.local/lib/python3.6/site-packages/sympy/integrals/integrals.py in doit(self, **hints)
551 for f in integrals])
552 try:
--> 553 evalued = Add(*others)._eval_interval(x, a, b)
554 function = uneval + evalued
555 except NotImplementedError:
~/.local/lib/python3.6/site-packages/sympy/functions/elementary/piecewise.py in _eval_interval(self, sym, a, b)
229 rep = b
230 val = e._eval_interval(sym, mid, b)
--> 231 val += self._eval_interval(sym, a, mid)
232 elif (a > upper) == True:
233 mid = upper
~/.local/lib/python3.6/site-packages/sympy/functions/elementary/piecewise.py in _eval_interval(self, sym, a, b)
282 super(Piecewise, expr)._eval_interval(sym, Max(a, int_a), Min(b, int_b)))
283 else:
--> 284 ret_fun += expr._eval_interval(sym, Max(a, int_a), Min(b, int_b))
285 return mul * ret_fun
286
~/.local/lib/python3.6/site-packages/sympy/core/expr.py in _eval_interval(self, x, a, b)
832 else:
833 domain = Interval(b, a)
--> 834 singularities = list(solveset(self.cancel().as_numer_denom()[1], x, domain = domain))
835 for s in singularities:
836 if a < s < b:
~/.local/lib/python3.6/site-packages/sympy/solvers/solveset.py in solveset(f, symbol, domain)
919 return result
920
--> 921 return _solveset(f, symbol, domain, _check=True)
922
923
~/.local/lib/python3.6/site-packages/sympy/solvers/solveset.py in _solveset(f, symbol, domain, _check)
709 result += solns
710 else:
--> 711 lhs, rhs_s = inverter(f, 0, symbol)
712 if lhs == symbol:
713 # do some very minimal simplification since
~/.local/lib/python3.6/site-packages/sympy/solvers/solveset.py in <lambda>(f, rhs, symbol)
677 else:
678 inverter_func = invert_complex
--> 679 inverter = lambda f, rhs, symbol: inverter_func(f, rhs, symbol, domain)
680
681 result = EmptySet()
~/.local/lib/python3.6/site-packages/sympy/solvers/solveset.py in invert_real(f_x, y, x, domain)
116 the domain to ``S.Reals`` before inverting.
117 """
--> 118 return _invert(f_x, y, x, domain)
119
120
~/.local/lib/python3.6/site-packages/sympy/solvers/solveset.py in _invert(f_x, y, x, domain)
98
99 if domain.is_subset(S.Reals):
--> 100 x1, s = _invert_real(f_x, FiniteSet(y), x)
101 else:
102 x1, s = _invert_complex(f_x, FiniteSet(y), x)
~/.local/lib/python3.6/site-packages/sympy/solvers/solveset.py in _invert_real(f, g_ys, symbol)
184 else:
185 if not base.is_positive:
--> 186 raise ValueError("x**w where w is irrational is not "
187 "defined for negative x")
188 return _invert_real(base, res, symbol)
ValueError: x**w where w is irrational is not defined for negative x
但是,如果我只使用指数的部分并将其集成,它就可以正常工作:
pdf = x ** -2.5
cdf = sym.integrate(pdf, (x, -sym.oo, y))
print(cdf)
这给出了:
-0.666666666666667*_y**(-1.5)
问题:
如何集成第一个Piecewise功能?
我尝试了什么:
将y
指定为非负:
y = sym.Symbol('y', nonnegative=True)
像这样我不会得到第一个错误,但结果变得很奇怪:
0.666666666666667*Min(1, y)**(-1.5) - 0.666666666666667*Min(2, y)**(-1.5)
我以后不能使用:
eq = sym.Eq(x, cdf)
inverse_solutions = sym.solve(eq, y, rational=False)
给出:
NotImplementedError: multiple generators [Min(1, y)**1.5, Min(2, y)**1.5]
No algorithms are implemented to solve equation x - 0.666666666666667*Min(1, y)**(-1.5) + 0.666666666666667*Min(2, y)**(-1.5)
答案 0 :(得分:2)
看起来我找到了解决方法
我只需要按sympy.nsimplify
简化pdf
,错误就消失了:
import sympy as sym
x, y = sym.symbols(['x', 'y'])
pdf = sym.Piecewise((0, x < 1),
(x ** -2.5, x < 2),
(0, True))
pdf = sym.nsimplify(pdf)
print(pdf)
cdf = sym.integrate(pdf, (x, -sym.oo, y))
print(cdf)
给出:
Piecewise((0, x < 1), (x**(-5/2), x < 2), (0, True))
Piecewise((0, y < 1), (2/3 - 2/(3*y**(3/2)), y < 2), (-sqrt(2)/6 + 2/3, True))