J. Serra
J. Serra

Reputation: 490

Evaluation and plot of Sympy expression at discrete points

I need to plot a function given by a fairly large expression:

x = sym.symbols('x')
myExpression          # This is a sympy.core.mul.Mul object

enter image description here

The function shall be evaluated at several locations, say xx.

xx = np.linspace(-2, 2, 100)
npFunction = sym.lambdify(x, myExpression, 'numpy')    # Returns a numpy-ready function
yy = npFunction(xx)                                    # npFunction evaluated at xx

> --------------------------------------------------------------------------- AttributeError                            Traceback (most recent call
> last) AttributeError: 'float' object has no attribute 'sqrt'
> 
> The above exception was the direct cause of the following exception:
> 
> TypeError                                 Traceback (most recent call
> last) <ipython-input-125-c1419d5b446d> in <module>
>       3 npFunction = sym.lambdify(x, myExpression, 'numpy')    # Returns a numpy-ready function
>       4 
> ----> 5 yy = npFunction(xx)                  # npFunction evaluated at xx
> 
> <lambdifygenerated-289> in _lambdifygenerated(x)
>       1 def _lambdifygenerated(x):
> ----> 2     return (-sqrt((320725082215391709755025*x**33 - 815422810503339070188975*x**32 - 1193164908737087748974400*x**31 +
> 18560901327587253919468800*x**30 + 512047920200188971110400*x**29 -
> 127260011757049326412185600*x**28 + 306772243802105606125977600*x**27
> + 1070548851848211221210726400*x**26 - 1961736173650180102867124224*x**25 -
> 2043216442426554791067910144*x**24 +
> 20778411631353349207247290368*x**23 +
> 16419727423460480613177360384*x**22 -
> 66868981841519012898775498752*x**21 +
> 67300051166011139997189537792*x**20 +
> 501457285381778570989390528512*x**19 +
> 58984656008435300127576424448*x**18 -
> 770564128787015129334013755392*x**17 +
> 2383958940411190086665689366528*x**16 +
> 6680747916713488973675806851072*x**15 +
> 503828111007578114462098391040*x**14 -
> 2034404207870885321852376317952*x**13 +
> 30465381943482129786499667853312*x**12 +
> 59161051678387568374654370316288*x**11 +
> 22656488686277206871130236780544*x**10 +
> 25867916241733015054414793146368*x**9 +
> 197755683253795159275985170333696*x**8 +
> 342754876018815970343942545735680*x**7 +
> 243094537594392980163602530959360*x**6 +
> 205865801906815623280028886761472*x**5 +
> 569403883326394857936120214192128*x**4 +
> 951945434951209699659257330270208*x**3 +
> 826990214251602314720389336399872*x**2 +
> 375422648073841563687008008667136*x +
> 72196663091123377632116924743680)/(320725082215391709755025*x**32 -
> 1136147892718730779944000*x**31 - 57017016018356969030400*x**30 +
> 18617918343605610888499200*x**29 - 18105870423405421917388800*x**28 -
> 109154141333643904494796800*x**27 + 415926385135749510620774400*x**26
> + 650043217739693276371353600*x**25 - 2599613121056318867661389824*x**24 + 562394515222247038758420480*x**23
> + 20025142331250461800019263488*x**22 - 3571036809095361690970619904*x**21 -
> 62317425686762007867684814848*x**20 +
> 127057289683979840164347248640*x**19 +
> 367603862071831402168945999872*x**18 -
> 297587003931102575412494991360*x**17 -
> 465179510051631596016974692352*x**16 +
> 2752388157125925508448274874368*x**15 +
> 3849951183506387395294443601920*x**14 -
> 3149101257277365518368833011712*x**13 +
> 920748397656278579501516980224*x**12 +
> 28188364693143617825236787920896*x**11 +
> 30335736114672592269485361070080*x**10 -
> 6638321976039230113499383332864*x**9 +
> 29451390533998320848280584454144*x**8 +
> 158594220779076065717198788755456*x**7 +
> 178182786085519359475770250493952*x**6 +
> 64903893188814670694539396644864*x**5 +
> 128047726690656602860146049155072*x**4 +
> 409455196193065444920428750438400*x**3 +
> 514739646382493706461483636883456*x**2 +
> 303225984982718186054891083923456*x +
> 72196663091123377632116924743680)))
> 
> TypeError: loop of ufunc does not support argument 0 of type float
> which has no callable sqrt method

However, I am obtaining the error above. I wonder whether this is caused by numerical difficulties? This piece of code is inside a loop, and myExpression gets incrementally larger every cycle. For the first few cycles the procedure above works fine.

Upvotes: 0

Views: 245

Answers (1)

hpaulj
hpaulj

Reputation: 231738

For a simpler expr involving sqrt and powers of x, lambdify works

In [46]: expr = sqrt(x**2 + x**3 + 4)

In [47]: f = lambdify(x, expr, 'numpy')

In [48]: f(np.arange(4).reshape(2,2))
Out[48]: 
array([[2.        , 2.44948974],
       [4.        , 6.32455532]])

The error tells me that your expression has something more going on, beyond what I can see in your image or the error. The argument to np.sqrt is apparently an object dtype array. sqrt on an object dtype array tries to do element.sqrt() for each element, resulting in your error.

You might try taking the sqrt out of the expression, and seeing what sort of array you get. The large integer values could very well be producing the error. Python int can be arbitrarily large, but numpy ints are restricted to int64 size.

With just one of your terms:

In [16]: def foo(x):
    ...:    return (16419727423460480613177360384*x**22)
    ...: 
    ...: 

In [17]: foo(2)
Out[17]: 68869328411129987677772255368052736

In [18]: foo(np.arange(-2,3))
Out[18]: 
array([68869328411129987677772255368052736, 16419727423460480613177360384,
       0, 16419727423460480613177360384,
       68869328411129987677772255368052736], dtype=object)

Note the the object dtype.

np.sqrt(Out[18]) raises this error

TypeError: loop of ufunc does not support argument 0 of type int 
   which has no callable sqrt method

Similar question a month ago

Big numbers in lambdify

Upvotes: 2

Related Questions