Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integral fails to evaluate #17119

Open
hazcat opened this issue Jun 27, 2019 · 7 comments · Fixed by #18434
Open

Integral fails to evaluate #17119

hazcat opened this issue Jun 27, 2019 · 7 comments · Fixed by #18434

Comments

@hazcat
Copy link

hazcat commented Jun 27, 2019

Tested with sympy 1.4, issue repros on https://live.sympy.org/

integrate(x**(0.5)*(1+x))
crashes with ValueError: Non-suitable parameters.

The following both evaluate:
integrate(x**(1/2)*(1+x))
integrate( expand(x**0.5*(1+x)) )

This is the result from live.sympy.org:

>>> integrate(x**(0.5)*(1+x))
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/integrals/integrals.py", line 1477, in integrate
    return integral.doit(**doit_flags)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/integrals/integrals.py", line 541, in doit
    function, xab[0], **eval_kwargs)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/integrals/integrals.py", line 1012, in _eval_integral
    h = meijerint_indefinite(g, x)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/integrals/meijerint.py", line 1621, in meijerint_indefinite
    res = _meijerint_indefinite_1(f.subs(x, x + a), x)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/integrals/meijerint.py", line 1686, in _meijerint_indefinite_1
    r = hyperexpand(r.subs(t, a*x**b), place=place)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/simplify/hyperexpand.py", line 2491, in hyperexpand
    return f.replace(hyper, do_replace).replace(meijerg, do_meijer)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/core/basic.py", line 1483, in replace
    rv = bottom_up(self, rec_replace, atoms=True)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/simplify/simplify.py", line 1087, in bottom_up
    rv = F(rv)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/core/basic.py", line 1468, in rec_replace
    new = _value(expr, result)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/core/basic.py", line 1417, in <lambda>
    _value = lambda expr, result: value(*expr.args)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/simplify/hyperexpand.py", line 2488, in do_meijer
    allow_hyper, rewrite=rewrite, place=place)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/simplify/hyperexpand.py", line 2373, in _meijergexpand
    t, 1/z0)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/simplify/hyperexpand.py", line 2299, in do_slater
    t, premult, bh, rewrite=None)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/simplify/hyperexpand.py", line 2053, in _hyperexpand
    ops += devise_plan(func, formula.func, z0)
  File "/base/data/home/apps/s~sympy-live-hrd/57.417397408462217066/sympy/sympy/simplify/hyperexpand.py", line 1630, in devise_plan
    raise ValueError('Non-suitable parameters.')```
@oscargus
Copy link
Contributor

Not sure if it solves this, but it is generally advisable to write S(1)/2 or Rational(1, 2) as it will keep the exponent in integer/rational form. 1/2 will be evaluated into a float (0.5) before it enters SymPy. Floats have a number of potential problems associated with them when doing symbolic maths.

@hazcat
Copy link
Author

hazcat commented Jun 28, 2019

That is good advice for working around issues with SymPy. Thanks!

@oscarbenjamin
Copy link
Contributor

It's not just a question of working around the issue. SymPy deliberately treats floats as inexact numbers - you shouldn't assume that 0.5 and S(1)/2 are supposed to be equivalent.

@hazcat
Copy link
Author

hazcat commented Jun 28, 2019

I'm not assuming they're equivalent. I'm assuming SymPy shouldn't crash with reasonable input.

@oscarbenjamin
Copy link
Contributor

SymPy shouldn't crash

Good point :)

Apparently this can be evaluated for an arbitrary symbol instead of a float:

In [17]: integrate(x**a*(1+x), x)                                                                                                 
Out[17]:1log(x) -for a = -2
⎪                                x                                    
⎪                                                                     
⎪                       x + log(x)                          for a = -1
⎨                                                                     
⎪     2  a              a          2  a               a               
⎪  ax x          axx          x x           2xx                
⎪──────────── + ──────────── + ──────────── + ────────────  otherwise 
⎪ 2              2              2              2                      
⎩a  + 3a + 2   a  + 3a + 2   a  + 3a + 2   a  + 3a + 2 

In [18]: integrate(x**a*(1+x), x).subs(a, 0.5)                                                                                    
Out[18]: 
                   1.5        2.5
0.666666666666667x    + 0.4x  

I wonder if something like that might be a good general approach for integrals with floats in because some methods seem very sensitive to them.

@oscarbenjamin
Copy link
Contributor

This diff causes a few test failures but looks manageable:

diff --git a/sympy/integrals/integrals.py b/sympy/integrals/integrals.py
index 49e955d388..359c955cfb 100644
--- a/sympy/integrals/integrals.py
+++ b/sympy/integrals/integrals.py
@@ -9,7 +9,7 @@
 from sympy.core.function import diff
 from sympy.core.logic import fuzzy_bool
 from sympy.core.mul import Mul
-from sympy.core.numbers import oo, pi
+from sympy.core.numbers import oo, pi, Float
 from sympy.core.relational import Ne
 from sympy.core.singleton import S
 from sympy.core.symbol import (Dummy, Symbol, Wild)
@@ -385,6 +385,12 @@ def doit(self, **hints):
         if not hints.get('integrals', True):
             return self
 
+        if self.has(Float):
+            fvals = self.atoms(Float)
+            fsubs = {f: Dummy() for f in fvals}
+            rsubs = {s: f for f, s in fsubs.items()}
+            return self.subs(fsubs).doit(**hints).subs(rsubs)
+
         deep = hints.get('deep', True)
         meijerg = hints.get('meijerg', None)
         conds = hints.get('conds', 'piecewise')

and fixes this issue:

In [1]: integrate(x**(0.5)*(1+x)) 
   ...:                                                                                                                           
Out[1]: 
                   1.5        2.5
0.666666666666667x    + 0.4x  

There are a number of other Float/Integral issues that this might help with as well.

@oscarbenjamin
Copy link
Contributor

Also fixes #14431 (possible duplicate of this issue):

In [9]: integrate((x-t)**(-1/2)*t,(t,0,x))                                                                                        
Out[9]: 
                  1.5
1.33333333333333x 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants