I would like to develop a power law model using lmfit (or another library). Is there any way I can apply a constraint or bound to the model so that it has to pass through a specific data point (exp. the point (1, 2))
plm = models.PowerLawModel()
params = plm.guess(y_data, x=x_data)
result = plm.fit(y_data, params, x=x_data, )
const = round(result.best_values['amplitude'], 3)
exp = round(result.best_values['exponent'], 3)
best = result.best_fit
For a Power Law model, which is just y = Amplitude * x**Exponent
, it would be pretty easy to write a constraint to force the model to always go through a point (x0, y0)
. You want Amplitude
to be such that
y0 = Amplitude*x0**Exponent
for any value of Exponent
. That is
Amplitude = y0*x0**(-Exponent)
You can specify that in lmfit
with something like
plm = models.PowerLawModel()
params = plm.guess(y_data, x=x_data)
params['amplitude'].expr = '{0:g}*{1:g}**(-exponent)'.format(y0, x0)
This will make amplitude
not vary independently from exponent
in the fit, and always take values that depend on the value of exponent
and this expression.