python-3.xsympyintegralmpmath

mpmath : cannot create mpf


I would like to use mpmath.quad to evaluate an integral value of a function simplified by sympy.

Then I used the following code

from sympy import *
import mpmath as mp
r = symbols("r")
f = 4**(-r)*r*(0.115391565000863*2**r + 693.147180559945)*exp(-0.000332949677174323*2**r)
mp.quad(lambda r:f,[0,1])

but get this error message

    ---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-8-715cd610bbdb> in <module>()
      3 r = symbols("r")
      4 f = 4**(-r)*r*(0.115391565000863*2**r + 693.147180559945)*exp(-0.000332949677174323*2**r)
----> 5 mp.quad(lambda r:f,[0,1])

5 frames

/usr/local/lib/python3.6/dist-packages/mpmath/ctx_mp.py in _convert_fallback(ctx, x, strings)
    632             else:
    633                 raise ValueError("can only create mpf from zero-width interval")
--> 634         raise TypeError("cannot create mpf from " + repr(x))
    635 
    636     def mpmathify(ctx, *args, **kwargs):

TypeError: cannot create mpf from 4**(-r)*r*(0.115391565000863*2**r + 693.147180559945)*exp(-0.000332949677174323*2**r)

I tried another simple function

from sympy import *
import mpmath as mp
x = symbols("x")
f = x*2
mp.quad(lambda x:f,[1,2])

and get the same error msg too

TypeError: cannot create mpf from 2*x

Can anyone know what caused this error msg and how to use quad function correctly?


Solution

  • lambda r:f does not create a callable that is what you think it is. You would have to copy and paste the definition of f on the rhs or substitute in the function's call value:

    >>> f = r + 1
    >>> (lambda r:f)(1)
    r + 1
    >>> (lambda r: r + 1)(1)
    2
    >>> (lambda v:f.subs(r,v))(1)
    2