I want to create a function 'residual' which computes the residual of another function of interest. When calling the 'residual' function with least_squares, I get the error "TypeError: 'numpy.ndarray' object is not callable"
Here is what I have tried:
import numpy as np
from scipy.optimize import least_squares
### define my function of interest
def linear(x,params):
a=params[0]
b=params[1]
y=a*x+b
return y
#### define function for computing residual
def residual(func,x,y,params):
args=(x,params)
func_x = func(*args)
return func_x - y
#### initialize variables
data_x=np.arange(1,11)
data_y=np.array([3,4,7,9,12,14,16,19,18,21])
init_params=[2,1]
### option 1: calculate the computing residual of 'linear' using 'residual':
res1=residual(linear,data_x,data_y,init_params)
### option 2: call 'residual' with least_squares including the 'linear function in the arguments:
fit_result= least_squares(residual, init_params, args=(linear,data_x,data_y))
#
When I try option 1, the function residual works just fine. However, in the option 2, where I want to call 'residual' with 'least_squares', I get the error "TypeError: 'numpy.ndarray' object is not callable".
I was stumped as well and the documentation on least_squares was making my head spin. But apparently you just had an issue with the arrangement of the arguments in your function definitions. I modified it a little bit and the error disappeared:
import numpy as np
from scipy.optimize import least_squares
### define my function of interest
#def linear(x,params):
def linear(params,x):
a=params[0]
b=params[1]
y=a*x+b
return y
#### define function for computing residual
# def residual(func,x,y,params):
def residual(params,func,x,y):
args=(params,x)
# args=(x,params)
func_x = func(*args)
return func_x - y
#### initialize variables
data_x=np.arange(1,11)
data_y=np.array([3,4,7,9,12,14,16,19,18,21])
init_params=[2,1]
def callable_params(input):
return float(input)
data_linear = linear(data_x,init_params)
print(data_x)
print(data_y)
print(data_linear)
### option 1: calculate the computing residual of 'linear' using 'residual':
res1=residual(init_params,linear,data_x,data_y)
print(res1)
### option 2: call 'residual' with least_squares including the 'linear function in the arguments:
fit_result= least_squares(fun=residual, x0=init_params, args=(linear,data_x,data_y))
print(fit_result)
# fit_result= least_squares(residual, init_params, args=(linear,data_x,data_y))
#
And the output (Windows command line) running the script:
[ 1 2 3 4 5 6 7 8 9 10]
[ 3 4 7 9 12 14 16 19 18 21]
[4 3]
[ 0 1 0 0 -1 -1 -1 -2 1 0]
active_mask: array([0., 0.])
cost: 3.793939393939392
fun: array([-0.05454545, 1.02424242, 0.1030303 , 0.18181818, -0.73939394,
-0.66060606, -0.58181818, -1.5030303 , 1.57575758, 0.65454545])
grad: array([-3.45811628e-08, -4.44089210e-15])
jac: array([[ 1.00000001, 1. ],
[ 2. , 1. ],
[ 2.99999999, 1. ],
[ 4. , 1. ],
[ 5.00000001, 1. ],
[ 5.99999997, 1. ],
[ 6.99999999, 1. ],
[ 8. , 1. ],
[ 8.99999996, 1. ],
[10.00000003, 1. ]])
message: '`xtol` termination condition is satisfied.'
nfev: 3
njev: 2
optimality: 3.458116282217816e-08
status: 3
success: True
x: array([2.07878788, 0.86666667])
Hope it helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.