In my situation, the objective function is a numerical process contains a root finding process for an equation by bisection method.
With certain set of parameters, the equation does not have root for a intermediate variable. I thought making the bisection root finding routine return None
can solve such problem.
As the object function with a set of date being regressed by scipy.optimize.curve_fit
with p0
separate by this situation in between, error is then stop the process.
To study this case, a simplified case is shown.
import numpy as np
#Define object function:
def f(x,a1,a2):
if a1 < 0:
return None
elif a2 < 0:
return np.inf
else:
return a1 * x**2 + a2
#Making data:
x = np.linspace(-5,5,10)
i = 0
y = np.empty_like(x)
for xi in x:
y[i] = f(xi,1,1)
i += 1
import scipy.optimize as sp
para,pvoc = sp.curve_fit(f,x,y,p0=(-1,1))
#TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'
para,pvoc = sp.curve_fit(f,x,y,p0=(1,-1))
#RuntimeError: Optimal parameters not found: Number of calls to function has reached maxfev = 600.
I also tried inf
, and it is obviously not working.
What should I return to continue the curve_fit
process?
Imagine it is trying to converge, what happen does the curve_fit
do when it meets such situation.
Additional thinking:
I tried the try...except...
to ignore the error and also simulate a case that the p0
is in a solvable range, but will pass the unsolvable segment to the true fit.
import numpy as np
def f(x,a1,a2):
if a1 < 0:
return None
elif a1 < 2:
return a1 * x**2 + a2
elif a2 < 0:
return np.inf
else:
return a1 * x**2 + a2
def ff(x,a1,a2):
output = f(x,a1,a2)
if output == None:
return 0
else:
return output
x = np.linspace(-5,5,10)
i = 0
y = np.empty_like(x)
for xi in x:
y[i] = f(xi,1,1)
i += 1
import scipy.optimize as sp
#para,pvoc = sp.curve_fit(f,x,y,p0=(-1,1))
#TypeError: unsupported operand type(s) for -: 'NoneType' and 'float':
#para,pvoc = sp.curve_fit(f,x,y,p0=(1,-1))
try:
para,pvoc = sp.curve_fit(f,x,y,p0=(-3,1))
except TypeError:
pass
Obviously error was met during converging and had been reported and was excepted.
What should I do to continue the curve_fit
with the original converging direction?
Even I can make concession, how can I tell the curve_fit
to return the last attempt to the a1
?
On the other hand, I tried put this try... except...
in the object function to return 0 when there is the error.
The result is then as I expect:
para,pvoc = sp.curve_fit(ff,x,y,p0=(-3,1))
#OptimizeWarning: Covariance of the parameters could not be estimated
category=OptimizeWarning)