Reputation: 53
I'm trying to calculate the roots for a function using the scipy function fsolve
, but an error keeps flagging:
TypeError: 'numpy.array' object is not callable
I assume it's probably easier to define the equation as a function but I've tried that a few times to no avail.
Code:
import scipy
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
# Constants
wavelength = 0.6328
ncore = 1.462420
nclad = 1.457420
a = 8.335
# Mode Order
l = 0
# Mode parameters
V = (2 * np.pi * a / wavelength) * np.sqrt(ncore**2 - nclad**2)
U = np.arange(0, V, 0.01)
W = np.sqrt(V**2-U**2)
func = U * scipy.special.jv(l+1, U) / scipy.special.jv(l, U) - W * scipy.special.kv(l+1, W) / scipy.special.kv(l, W)
from scipy.optimize import fsolve
x = fsolve(func,0)
print x
StackTrace:
Traceback (most recent call last):
File "<ipython-input-52-081a9cc9c0ea>", line 1, in <module>
runfile('/home/luke/Documents/PythonPrograms/ModeSolver_StepIndex/ModeSolver_StepIndex.py', wdir='/home/luke/Documents/PythonPrograms/ModeSolver_StepIndex')
File "/usr/lib/python2.7/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 580, in runfile
execfile(filename, namespace)
File "/home/luke/Documents/PythonPrograms/ModeSolver_StepIndex/ModeSolver_StepIndex.py", line 52, in <module>
x = fsolve(func,0)
File "/usr/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 140, in fsolve
res = _root_hybr(func, x0, args, jac=fprime, **options)
File "/usr/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 197, in _root_hybr
shape, dtype = _check_func('fsolve', 'func', func, x0, args, n, (n,))
File "/usr/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 20, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
TypeError: 'numpy.ndarray' object is not callable
Upvotes: 3
Views: 10857
Reputation: 2194
That is because fsolve takes a function as argument. Try this, Note you still will encounter some runtime error , you will have to check if your return from func is properly constructed, I will leave that for you to figure out.
import scipy
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
# Constants
wavelength = 0.6328
ncore = 1.462420
nclad = 1.457420
a = 8.335
# Mode Order
# l = 0
# Mode parameters
V = (2 * np.pi * a / wavelength) * np.sqrt(ncore**2 - nclad**2)
U = np.arange(0, V, 0.01)
W = np.sqrt(V**2-U**2)
def func(l):
return U * scipy.special.jv(l+1, U) / scipy.special.jv(l, U) - W * scipy.special.kv(l+1, W) / scipy.special.kv(l, W)
from scipy.optimize import fsolve
x = fsolve(func,0)
print x
Upvotes: 2
Reputation: 152597
You need to pass a function to fsolve
not an array
.
If I just print your func:
func
array([ -1.04882076e+01, -1.04881526e+01, -1.04879876e+01,
-1.04877125e+01, -1.04873274e+01, -1.04868321e+01,
-1.04862266e+01, -1.04855109e+01, -1.04846847e+01,
-1.04837481e+01, -1.04827008e+01, -1.04815428e+01,
-1.04802738e+01, -1.04788938e+01, -1.04774024e+01,
-1.04757996e+01, -1.04740850e+01, -1.04722585e+01,
-1.04703198e+01, -1.04682686e+01, -1.04661046e+01,
-1.04638275e+01, -1.04614371e+01, -1.04589330e+01,
-1.04563147e+01, -1.04535820e+01, -1.04507345e+01,
-1.04477718e+01, -1.04446934e+01, -1.04414988e+01,
... ]
that's an array but you want a function. Something like this works:
def linear(x):
return 2*x+4
fsolve(linear, 0)
don't know how one could define your function, though.
Upvotes: 0