-
Hello dear lmfit community. I am having problems fitting natural logarithm function into my data - the model keeps getting NaNs and aborting. I think this might be happening due to the model yielding a negative expression within the ln() function. Of course there might be other reasons, but for now, I want to make sure the model never gets a negative expression and see if it work. I have discovered this page that talks about constraints, but it is not helpful for my case. Thus, I tried to infer from the said page how to impose a constraint on the entire expression within the ln() function. Here is what I came up with (remember, the expression within the ln() function must always be positive):
Having run the code, I get an error message: How do I make sure that p2 * coord - p3 always stays positive during the fitting procedure? Thank you in advance. UPDATE 1.
Then using my data I figured out 1) the largest possible value of coord I can have and 2) therefore, the shift parameter p3. Because my ln() function must be "facing" the left (not the right as it normally does), I could figure out the largest possible value of parameter p2. In other words, I just used min and max arguments in Irrespectively of all this, my original question still holds: how does one impose a constraint on an expression that has the independent variable in it? UPDATE 2. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
My main advice would be to prevent negative arguments to If But if For an inequality constraint (as shown in the example), you would have to define a parameter |
Beta Was this translation helpful? Give feedback.
-
Thank you @newville . I did almost exactly what you are suggesting and described that in the update to my post (may be not as articulated as you did). But that's a pretty convoluted way around and, most certainly, this is not a general solution to the problem. And I couldn't make it work anyway (see the second update to my post). To summarize: lmfit does not have an option of including independent variable into the expressions, is that correct? Lastly, you mentioned that I will have "to define a parameter |
Beta Was this translation helpful? Give feedback.
-
If you are not putting a check of the values sent to
Um, kind of "neither". Constraints use mathematical expressions within an asteval interpreter. Independent variables can be any python object, and could, in principle, be added to the asteval interpreter. But, you would have to do that, and then use that. That is a very convoluted appoach to preventing log() from getting a negative value, when you could just prevent log() from getting a negative value.
The example shows how to define
Um, no it doesn't... Maybe you are getting an error from your very weird usage of passing parameter values to
I don't know what this is supposed to do. But you did not post any error messages from that...
Just to move to a completely different problem domain (because I am not going to do your homework) you can do something like: import numpy as np
from lmfit import Model, Parameters
from lmfit.lineshapes import gaussian
def two_peaks(x, amp1, cen1, sig1, amp2, cen2, sig2):
return gaussian(x, amp1, cen1, sig1) + gaussian(x, amp2, cen2, sig2)
pars = Parameters()
pars.add('amp1', value=35.0)
pars.add('amp2', value=20.0)
pars.add('sig1', value=6.0, min=0)
pars.add('sig2', expr='2.0*sig1')
pars.add('cen1', value=50.0, min=0, max=100)
pars.add('peak_sep', value=5.0, min=0)
pars.add('cen2', expr='cen1 + peak_sep')
x = np.linspace(0, 100, 501)
y = gaussian(x, 30, 45, 3.5) + gaussian(x, 15, 57, 7.05)
y += np.random.normal(size=len(x), scale=0.1)
model = Model(two_peaks)
ret = model.fit(y, params=pars, x=x)
print(ret.fit_report()) Note that |
Beta Was this translation helpful? Give feedback.
My main advice would be to prevent negative arguments to
np.log()
- that would be independent of the values of yourcoord
and the parameter values. Like, you could just use an "abs()" or look for and negative values withnp.where((p2*coord + p3)<0)
in yourlnfit
function. That strengthens the function.If
coord
is all positive or all negative, and ifp3
is positive, setting an upper or lower limit onp2
shouldn't be too hard: justp2 > 0
orp2<0
would be sufficient.But if
coords
has both positive and negative values, it is much trickier, as the current value ofp3
would need to be known to set a bound onp2
. Andp3
not being known is sort of one of the points. Since you are asking the qu…