-1

I have read this SO post which says namespace conflict is one reason for this error. I am falling to this error frequently. So, I'd like to learn what exactly is happening here? What is expected by the library?

EDIT: fun = lambda x: 4*x*(np.sin(x**2) - 3)*np.cos(x**2) comes from a test case, so practically I am bound to use it as function 'fun'. Sorry for missing that information. Kindly discuss respecting this constraint.

EDIT2: This is an error reproducing code, not the full script. Task is to calculate differentiation of an input function that can evaluate numpy arrays by using a forward difference approximation with a perturbation ∆=10 −8.

Code:

import sympy
import numpy as np 

# TESTING...
x = sympy.Symbol('x')
fun = lambda x:  4*x*(np.sin(x**2) - 3)*np.cos(x**2)  
print fun
h = 10e-8  #perturbation
print fun(x)
print fun(x+h)
df = (fun(x+h) - fun(x)) / h
print "diff is:", df

Error:

<function <lambda> at 0x000000001068E2E8>
Traceback (most recent call last):

  File "<ipython-input-75-0582d8ebb11b>", line 1, in <module>
    runfile('D:/test_hw3.py', wdir='D:')

  File "D:\anaconda\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
    execfile(filename, namespace)

  File "D:\anaconda\lib\site-packages\spyder\utils\site\sitecustomize.py", line 87, in execfile
    exec(compile(scripttext, filename, 'exec'), glob, loc)

  File "D:/test_hw3.py", line 23, in <module>
    print fun(x)

  File "D:/test_hw3.py", line 20, in <lambda>
    fun = lambda x:  4*x*(np.sin(x**2) - 3)*np.cos(x**2)
AttributeError: 'Pow' object has no attribute 'sin'
Community
  • 1
  • 1
devautor
  • 2,506
  • 4
  • 21
  • 31

2 Answers2

2

You are supposed to use sympy.sin/cos instead of np.sin/cos. Numpy does not know how to work with sympy expressions.

fun = lambda x: 4 * x * (sympy.sin(x**2) - 3) * sumpy.cos(x**2)  

On the other hand, if you must keep np.sin, then you should not send a sympy variable to fun. Instead, df should become a function itself.

fun = lambda x:  4*x*(np.sin(x**2) - 3)*np.cos(x**2)  
h = 1e-8

df = lambda x: (fun(x+h) - fun(x)) / h

# usage:
df( np.array([1.0, 2.0, 3.0, 4.0]) )

BTW, sympy already has a diff function to compute the derivative.

df = sympy.diff(fun(x), x)
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
0

Function fun uses np.sin and np.cos, which are numpy functions that accept as arguments only data types recognized by numpy. When you do fun(x) you are giving as argument to numpy functions a sympy object, which numpy does not recognize, raising this "cryptic" error message.

Note that when you define fun using the statement lambda x:..., x is treated in the definition as a dummy variable name for a valid data type (even though you have defined x above as a sympy symbol).

Stelios
  • 5,271
  • 1
  • 18
  • 32