I am attempting to fit 2 graphs to 2 different functions that share parameters. The functions are quite complicated, involve atan, ln and fractions. Symfit seemed to provide functionality for this kind of fitting but the fit runns into
RuntimeWarning: invalid value encountered in sqrt return np.sqrt(self.variance(param))
and does not finish.
Is there another fitting function that works more numerically or is there a scipy function that achieves the same functionality?
# parameters
mag, theta, phi, mode_angle = parameters('mag, theta, phi, mode_angle')
# setting initial parameter values and ranges
phi.max = math.radians(360)
phi.min = 0
theta.max = math.radians(180)
theta.min = 0
theta.value = math.radians(70)
mode_angle.value = 0.4
mode_angle.min = 0.39
mode_angle.max = 0.47
mag.value = 1e-14
mag.max = 1e-10
mag.min = 1e-18
q0.value = 1e-9
q0.max = 1e-4
q0.min = 1e-13
# variables from two graphs that share the same x axis
x1, y1, y2 = variables('x1, y1, y2')
x = np.linspace(-108, 501-108, 501)
# model includes two functions that share the same parameters and x
model = {
y1: func1(mag, theta, phi, mode_angle, x1),
y2: func2(mag, theta, phi, mode_angle, x1)
}
# calling the fit
fit = Fit(model,
x1 = x,
y1 = graph1_ydata,
y2 = graph2_ydata,
minimizer = DifferentialEvolution
)
# fit execution
fit_result = fit.execute()
While the following snipplet is extremely simple as division by zero (singularity) can be spotted quickly and resolved, it should illustrate the problem. Same problems (division by zero or maybe neg. root) can also appear in the std. dev. calculation. With many parameters it gets more complicated to find these problem points.
# Generating data
data_to_be_fitted=[]
xx = np.linspace(0.00001,12.00001, 400)
for i in range(0, len(xx)):
data_to_be_fitted.append( 1/xx[i])
q, a = parameters('q, a')
x1, y= variables('x1, y')
# Model
model = {
y: q/x1 # works with q / (x-a)
}
# Parameters
q.value = 1
q.min = -1
q.max = 1
a.value = 1
a.min = -1
a.max = 1
# Fitting
x = np.linspace(0,12, 400)
fit = Fit(model,
x1 = x,
y = data_to_be_fitted
)
fit_result = fit.execute()
print(fit_result)
I expect the fits to provide me with the fitting parameters. I assume, the fit runs into a singularity. O. K. I avoided division by zero by excluding some fitting variables, x. That however requires examination on the fitting functions. I am still wondering, if some package solutions exist.