Reputation: 1
If I define fitting function as:
def func(a1,a2,a3,a4):
return a1*y1+a2*y2+a3*y3+a4*y4
and when i fit I want to tie my parameters:
a1**2+a2**2+a3**2+a4**2=1
I cannot find the way to do that with scipy.optimize or lmfit module.
Do you have any suggestion?
Thanks!
Upvotes: 0
Views: 429
Reputation: 7862
Just to be clear, your func()
is not actually how you write a fitting function for scipy optimize or lmfit. You have given very little context for your problem, which limits how much help can be given.
But, for constraining parameter values, the key is to recognize that there are actually three variable parameters and one parameter whose value is derived from the others, say a1
, a2
, and a3
vary and a4
is defined as
a4 = sqrt(1 - a1**2 - a2**2 - a3**2)
This can be done easily with lmfit (see docs and examples for more details):
from lmfit import Model, Parameters
def func(y1, y2, y3, y4, a1, a2, a3, a4):
return y1*a1**2 + y2*a2**2 + y3*a3**2 + y4*a4**2
model = Model(func, independent_vars=['y1', 'y2', 'y3', 'y4'])
params = Parameters()
params.add('a1', value=0.5, vary=True)
params.add('a2', value=0.5, vary=True)
params.add('a3', value=0.5, vary=True)
params.add('a4', expr='sqrt(1 - (a1**2 + a2**2 + a3**2))')
result = model.fit(params, ydata, y1=y1, y2=y2, y3=y3, y4=y4)
Of course, you may have to look out for (a1**2 + a2**2 + a3**2)
exceeding 1.0. You could, for example, place bounds on the values for parameters a1
, etc.
Upvotes: 1