fitting over a function with a for loop - python

Dear Stackoverflow community,
I want fit over the following function with curve_fit:
def fct(A, Ravg,sigma,pos,omega, x):
K=integrate.quad(lambda R:np.exp( - (R-Ravg)**2 / (2 * sigma**2) ),Ravg-sigma,Ravg+sigma)
data=[]
for i in range(0,len(x)):
data.append(integrate.quad(lambda R: (3*(np.sin(x[i]*R)-x[i]*R*np.cos(x[i]*R))/(x[i]*R)**3)**2*1/K[0] *np.exp( - (R-Ravg)**2 / (2 * sigma**2) ),Ravg-sigma,Ravg+sigma))
gafs=array(data)
return A*gafs[:,0]
I get from curve_fit with this code:
fitPars, covMatrix = curve_fit(fct, xaxis, yaxis)
The following error message:
TypeError: object of type 'numpy.float64' has no len()
I understand that the error comes from the for loop. Do you have an idea how can I make my function suitable for curvefit?
The full error track is:
TypeError Traceback (most recent call last)
<ipython-input-5-3e25e14bdca2> in <module>()
1
----> 2 fitPars, covMatrix = curve_fit(fct, xaxis, yaxis)
C:\Programfiles\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
734 # Remove full_output from kwargs, otherwise we're passing it in twice.
735 return_full = kwargs.pop('full_output', False)
--> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
737 popt, pcov, infodict, errmsg, ier = res
738 cost = np.sum(infodict['fvec'] ** 2)
C:\Programfiles\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
375 if not isinstance(args, tuple):
376 args = (args,)
--> 377 shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
378 m = shape[0]
379 if n > m:
C:\Programfiles\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
24 def _check_func(checker, argname, thefunc, x0, args, numinputs,
25 output_shape=None):
---> 26 res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
27 if (output_shape is not None) and (shape(res) != output_shape):
28 if (output_shape[0] != 1):
C:\Programfiles\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in func_wrapped(params)
452 if transform is None:
453 def func_wrapped(params):
--> 454 return func(xdata, *params) - ydata
455 elif transform.ndim == 1:
456 def func_wrapped(params):
<ipython-input-3-4ae12bf8a77b> in fct(A, Ravg, sigma, pos, omega, x)
52 K=integrate.quad(lambda R:np.exp( - (R-Ravg)**2 / (2 * sigma**2) ),Ravg-sigma,Ravg+sigma)
53 data=[]
---> 54 for i in range(0,len(x)):
55 data.append(integrate.quad(lambda R: (3*(np.sin(x[i]*R)-x[i]*R*np.cos(x[i]*R))/(x[i]*R)**3)**2*1/K[0] *np.exp( - (R-Ravg)**2 / (2 * sigma**2) ),Ravg-sigma,Ravg+sigma))
56 gafs=array(data)
TypeError: object of type 'numpy.float64' has no len()

Related

Scipy "masked arrays are not supported" error

I am trying to calibrate a model using pykalman and the scipy optimiser. For some reasons scipy seem to think that my input is a masked array, but it is not. I have added the code below:
k = 0.00000000000001 #small sarting value
T = np.array([1, 2, 3, 4, 5] , dtype=int) #maturities
delta = 1e-9
x = k
transition_covariance=delta / (1 - delta) * np.eye(1)
def obj(x):
k = x[0]
Q = (1 - k) *np.eye(1)
Z = np.exp(-k*T)
Z =Z[:, None] #reshape to 2 dim
transition_covariance=delta / (1 - delta) * np.eye(1)
observation_covariance=0.001*np.eye(len(T))
kf = KalmanFilter(transition_matrices=np.eye(1)*(1-k),
observation_matrices= Z,
transition_covariance=transition_covariance,
observation_covariance=observation_covariance)
lk = kf.loglikelihood(X) # X is my observed data, 1265 rows × 5 columns
return -lk
x = np.array([k])
k =scipy.optimize.minimize(obj, x, method= 'TNC')
Running the scipy optimiser I get the error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-16-8d87c9f2ced0> in <module>
1 # method that works: TNC, Nelder-Mead
----> 2 k =scipy.optimize.minimize(obj, x, method= 'TNC')
~\Anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
618 callback=callback, **options)
619 elif meth == 'tnc':
--> 620 return _minimize_tnc(fun, x0, args, jac, bounds, callback=callback,
621 **options)
622 elif meth == 'cobyla':
~\Anaconda3\lib\site-packages\scipy\optimize\tnc.py in _minimize_tnc(fun, x0, args, jac, bounds, eps, scale, offset, mesg_num, maxCGit, maxiter, eta, stepmx, accuracy, minfev, ftol, xtol, gtol, rescale, disp, callback, finite_diff_rel_step, maxfun, **unknown_options)
373 messages = MSG_NONE
374
--> 375 sf = _prepare_scalar_function(fun, x0, jac=jac, args=args, epsilon=eps,
376 finite_diff_rel_step=finite_diff_rel_step,
377 bounds=new_bounds)
~\Anaconda3\lib\site-packages\scipy\optimize\optimize.py in _prepare_scalar_function(fun, x0, jac, args, bounds, epsilon, finite_diff_rel_step, hess)
259 # ScalarFunction caches. Reuse of fun(x) during grad
260 # calculation reduces overall function evaluations.
--> 261 sf = ScalarFunction(fun, x0, args, grad, hess,
262 finite_diff_rel_step, bounds, epsilon=epsilon)
263
~\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py in __init__(self, fun, x0, args, grad, hess, finite_diff_rel_step, finite_diff_bounds, epsilon)
74
75 self._update_fun_impl = update_fun
---> 76 self._update_fun()
77
78 # Gradient evaluation
~\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py in _update_fun(self)
164 def _update_fun(self):
165 if not self.f_updated:
--> 166 self._update_fun_impl()
167 self.f_updated = True
168
~\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py in update_fun()
71
72 def update_fun():
---> 73 self.f = fun_wrapped(self.x)
74
75 self._update_fun_impl = update_fun
~\Anaconda3\lib\site-packages\scipy\optimize\_differentiable_functions.py in fun_wrapped(x)
68 def fun_wrapped(x):
69 self.nfev += 1
---> 70 return fun(x, *args)
71
72 def update_fun():
<ipython-input-13-48731c614f15> in obj(x)
19 observation_covariance=observation_covariance)
20
---> 21 lk = kf.loglikelihood(X) # X is my observed data, 1016 rows × 17 columns
22 return -lk
~\Anaconda3\lib\site-packages\pykalman\standard.py in loglikelihood(self, X)
1470
1471 # get likelihoods for each time step
-> 1472 loglikelihoods = _loglikelihoods(
1473 observation_matrices, observation_offsets, observation_covariance,
1474 predicted_state_means, predicted_state_covariances, Z
~\Anaconda3\lib\site-packages\pykalman\standard.py in _loglikelihoods(observation_matrices, observation_offsets, observation_covariance, predicted_state_means, predicted_state_covariances, observations)
165 + observation_covariance
166 )
--> 167 loglikelihoods[t] = log_multivariate_normal_density(
168 observation[np.newaxis, :],
169 predicted_observation_mean[np.newaxis, :],
~\Anaconda3\lib\site-packages\pykalman\utils.py in log_multivariate_normal_density(X, means, covars, min_covar)
71 lower=True)
72 cv_log_det = 2 * np.sum(np.log(np.diagonal(cv_chol)))
---> 73 cv_sol = solve_triangular(cv_chol, (X - mu).T, lower=True).T
74 log_prob[:, c] = - .5 * (np.sum(cv_sol ** 2, axis=1) + \
75 n_dim * np.log(2 * np.pi) + cv_log_det)
~\Anaconda3\lib\site-packages\scipy\linalg\basic.py in solve_triangular(a, b, trans, lower, unit_diagonal, overwrite_b, debug, check_finite)
332
333 a1 = _asarray_validated(a, check_finite=check_finite)
--> 334 b1 = _asarray_validated(b, check_finite=check_finite)
335 if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]:
336 raise ValueError('expected square matrix')
~\Anaconda3\lib\site-packages\scipy\_lib\_util.py in _asarray_validated(a, check_finite, sparse_ok, objects_ok, mask_ok, as_inexact)
259 if not mask_ok:
260 if np.ma.isMaskedArray(a):
--> 261 raise ValueError('masked arrays are not supported')
262 toarray = np.asarray_chkfinite if check_finite else np.asarray
263 a = toarray(a)
ValueError: masked arrays are not supported
Maybe something to do with an update in the scipy library? It worked with a different setup, so that's all I can think. My versions are:
Python 3.8.5
Scipy 1.5.2
Pykalman 0.9.5
Thanks!
I found the solution, which involves a small change in the utils.py file in the pykalman library (line 73):
try:
cv_sol = solve_triangular(cv_chol, (X - mu).T, lower=True).T
except ValueError:
cv_sol = np.linalg.solve(cv_chol, (X - mu).T).T
Source:
https://github.com/pykalman/pykalman/issues/83

how can i draw implicit function with sin, cos function and find root in pyhton?

i have a function like this
cos(x) - sin(y) + 0.2 = 0
i want to draw this function in plt.plot and find root (x,y) when function = 0
and this is my code
from scipy import optimize
import numpy as np
def func_2(x):
return np.cos(x[0])-np.sin(x[1])+0.2
result = optimize.root(func_2, [1])
and i got error
IndexError Traceback (most recent call last)
<ipython-input-366-6d13d246d69c> in <module>
14
15 result = optimize.root(func_1, [1])
---> 16 result1 = optimize.root(func_2, [1])
~\anaconda3\lib\site-packages\scipy\optimize\_root.py in root(fun, x0, args, method, jac, tol, callback, options)
185
186 if meth == 'hybr':
--> 187 sol = _root_hybr(fun, x0, args=args, jac=jac, **options)
188 elif meth == 'lm':
189 sol = _root_leastsq(fun, x0, args=args, jac=jac, **options)
~\anaconda3\lib\site-packages\scipy\optimize\minpack.py in _root_hybr(func, x0, args, jac, col_deriv, xtol, maxfev, band, eps, factor, diag, **unknown_options)
211 if not isinstance(args, tuple):
212 args = (args,)
--> 213 shape, dtype = _check_func('fsolve', 'func', func, x0, args, n, (n,))
214 if epsfcn is None:
215 epsfcn = finfo(dtype).eps
~\anaconda3\lib\site-packages\scipy\optimize\minpack.py in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
24 def _check_func(checker, argname, thefunc, x0, args, numinputs,
25 output_shape=None):
---> 26 res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
27 if (output_shape is not None) and (shape(res) != output_shape):
28 if (output_shape[0] != 1):
<ipython-input-366-6d13d246d69c> in func_2(x)
11
12 def func_2(x):
---> 13 return np.cos(x[0])-np.sin(x[1])+0.2
14
15 result = optimize.root(func_1, [1])
IndexError: index 1 is out of bounds for axis 0 with size 1

Getting TypeError while using fmin_l_bfgs_b() function

I am using fmin_l_bfgs_b function while doing neural style transfer and keep getting
TypeError: 'numpy.float32' object is not callable
Details of the error block are:
TypeError Traceback (most recent call last)
<ipython-input-10-4699dceebbd9> in <module>()
----> 1 generate_art('/content/nst_images/5.jpg', '/content/nst_images/a.jpg',1, img_height=400)
4 frames
<ipython-input-9-67cbbed20548> in generate_art(content_image_path, style_image_path, iterations, img_height)
38 for i in range(iterations):
39
---> 40 x, min_val, info = fmin_l_bfgs_b(evaluator.loss(x,img_height,img_width,fetch_loss_and_grads),x, fprime=evaluator.grads, maxfun=20)
41 img = x.copy().reshape((img_height, img_width, 3))
42 img = deprocess_image(img)
/usr/local/lib/python3.6/dist-packages/scipy/optimize/lbfgsb.py in fmin_l_bfgs_b(func, x0, fprime, args, approx_grad, bounds, m, factr, pgtol, epsilon, iprint, maxfun, maxiter, disp, callback, maxls)
197
198 res = _minimize_lbfgsb(fun, x0, args=args, jac=jac, bounds=bounds,
--> 199 **opts)
200 d = {'grad': res['jac'],
201 'task': res['message'],
/usr/local/lib/python3.6/dist-packages/scipy/optimize/lbfgsb.py in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, **unknown_options)
343 # until the completion of the current minimization iteration.
344 # Overwrite f and g:
--> 345 f, g = func_and_grad(x)
346 elif task_str.startswith(b'NEW_X'):
347 # new iteration
/usr/local/lib/python3.6/dist-packages/scipy/optimize/lbfgsb.py in func_and_grad(x)
293 else:
294 def func_and_grad(x):
--> 295 f = fun(x, *args)
296 g = jac(x, *args)
297 return f, g
/usr/local/lib/python3.6/dist-packages/scipy/optimize/optimize.py in function_wrapper(*wrapper_args)
325 def function_wrapper(*wrapper_args):
326 ncalls[0] += 1
--> 327 return function(*(wrapper_args + args))
328
329 return ncalls, function_wrapper
TypeError: 'numpy.float32' object is not callable
Any suggestions on how to troubleshoot this? thanks!
This was a silly error. for fmin_l_bfgs_b, arguments of the loss function have to be passed separately as args = ()

ValueError in calling fmin_l_bfgs_b

I'm passing my fmin this way:
position, value, dictionary =fmin_l_bfgs_b(func =self.objective,x0=wcb,fprime = self.objective_grad,args=(X,y),disp = 10)
This seems pretty standard: objective returns a scalar, objective gradient returns an ndarray of size 2n+1.
I am getting the following error:
<ipython-input-35-6a424a7ec22a> in fit(self, X, y)
35 wcb = np.asarray(wcb)
36 print(wcb)
---> 37 position, value, dictionary =fmin_l_bfgs_b(func =self.objective,x0=wcb,fprime = self.objective_grad,args=(X,y),disp = 10)
38
39
~\Anaconda3\envs\smc\lib\site-packages\scipy\optimize\lbfgsb.py in fmin_l_bfgs_b(func, x0, fprime, args, approx_grad, bounds, m, factr, pgtol, epsilon, iprint, maxfun, maxiter, disp, callback, maxls)
197
198 res = _minimize_lbfgsb(fun, x0, args=args, jac=jac, bounds=bounds,
--> 199 **opts)
200 d = {'grad': res['jac'],
201 'task': res['message'],
~\Anaconda3\envs\smc\lib\site-packages\scipy\optimize\lbfgsb.py in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, **unknown_options)
326 _lbfgsb.setulb(m, x, low_bnd, upper_bnd, nbd, f, g, factr,
327 pgtol, wa, iwa, task, iprint, csave, lsave,
--> 328 isave, dsave, maxls)
329 task_str = task.tostring()
330 if task_str.startswith(b'FG'):
ValueError: failed to initialize intent(inout) array -- input 'O' not compatible to 'd'
Any idea how to get rid of it?

passing additional arguments to scipy.optimize.curve_fit

There is an answer to this very question here however the solution doesn't seem to work for me.
my function is the following:
def slopefunction_cf(xin,amp,phase,off,freq,intercept,t):
fitted =np.zeros((4,12))
for im in t:
fitted[:,im-1] = intercept[im-1]+[amp*np.sin(freq*(im)+phase)+off]*xin
return fitted.ravel()
where intercept and t are additional arguments, that in leastsq I would pass as args=
I tried:
popt, pcov = curve_fit(slopefunction_cf, np.arange(0,4), datain, p0=paramin, args=(intercept,t) )
and get the error:
TypeError: func_wrapped() takes exactly 1 argument (3 given)
Then I tried what suggested in the answer I linked and transformed it to:
def define_var_args(interceptin,tin):
def slopefunction_cf(xin,amp,phase,off,freq):
intercept = interceptin
t = tin
fitted =np.zeros((4,12))
for im in t:
fitted[:,im-1] = intercept[im-1]+[amp*np.sin(freq*(im)+phase)+off]*xin
return fitted.ravel()
and then called curve_fit:
popt, pcov = curve_fit(define_var_args(intercept, t), np.arange(0,4), datain, p0=paramin )
but I get the following error (i copied everything)
--> 115 popt, pcov = curve_fit(define_var_args(interceptconus, t), np.arange(0,4), datain.ravel(), p0=paramin )
116
117 print popt
/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
734 # Remove full_output from kwargs, otherwise we're passing it in twice.
735 return_full = kwargs.pop('full_output', False)
--> 736 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
737 popt, pcov, infodict, errmsg, ier = res
738 cost = np.sum(infodict['fvec'] ** 2)
/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
375 if not isinstance(args, tuple):
376 args = (args,)
--> 377 shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
378 m = shape[0]
379 if n > m:
/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
24 def _check_func(checker, argname, thefunc, x0, args, numinputs,
25 output_shape=None):
---> 26 res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
27 if (output_shape is not None) and (shape(res) != output_shape):
28 if (output_shape[0] != 1):
/software/centos6/x86_64/canopy-1.7.4/Canopy_64bit/User/lib/python2.7/site-packages/scipy/optimize/minpack.pyc in func_wrapped(params)
452 if transform is None:
453 def func_wrapped(params):
--> 454 return func(xdata, *params) - ydata
455 elif transform.ndim == 1:
456 def func_wrapped(params):
TypeError: 'NoneType' object is not callable
I am not even sure what the error is - if the code or something in my data? it's a bit obscure.
Is there another way to pass additional parameters?
EDIT: Adding some data and slight change to the above function
t = np.arange(1,13)
paramin = [0.40569370873086791, 1, -0.88134718450091365, 0.5]
datain = [-3.45083921, -3.405628 , -2.57401114, -1.7632551 , -1.29342567,
-1.44200248, -2.05366981, -2.51467815, -2.79597983, -2.95528074,
-2.90766603, -3.60850134, -3.90036107, -3.87760971, -3.18549774,
-2.43304533, -2.1734368 , -2.43953997, -3.1183866 , -3.57696154,
-3.72915335, -3.67344888, -3.29697388, -4.10385938, -4.88945667,
-4.82385939, -4.10568684, -3.50093464, -3.26766599, -3.78206157,
-4.51782818, -4.95149472, -4.93689182, -4.75850421, -4.22849458,
-4.91811193, -5.34080606, -5.40676402, -4.66050702, -4.29447163,
-4.16430688, -4.75008652, -5.57106708, -5.58801663, -5.96637981,
-5.51549722, -4.94026303, -5.42975354]
intercept = [-3.39651633, -3.33601661, -2.55447417, -1.69869584, -1.26867791,
-1.41340658, -2.02249291, -2.56860547, -2.74926044, -2.91082705,
-2.78895263, -3.57335517]
I already "raveled" datain, so I modified the function at the beginning of my question.
using these data I reproduce my error in a new notebook.
SOLUTION:
I had two issues in my code:
1) I was not returning the nested function
2) I did not put xin as an argument of the nested function
3) I had to put the star before the p
this now works
def define_extravar(interceptin,tin):
def slopefunction_cf(xin,*p):
intercept = interceptin
t = tin
fitted =np.zeros((4,12))
amp,phase,off,freq = p
for im in t:
fitted[:,im-1] = intercept[im-1]+[amp*np.sin(freq*(im)+phase)+off]*xin
return fitted.ravel()
return slopefunction_cf

Categories