Curve Not Fitting

81 views
Skip to first unread message

Priscilla Kelly

unread,
Nov 15, 2017, 12:07:06 AM11/15/17
to lmfit-py
Hello,

I am very grateful for the fitting code and have been using it for all my ellipsometry fittings.
However, recently I have implemented a B-Spline fitting to the system and have run into problems. I have a 45 knot b-spline function model that I use to predict ellipsometry data: Psi and Delta.

I call my residual like so:
    def residual(params):
        model = ellipsFunc(params)  #< -- params is the knots that I sent for ellipsometry data
        diff = (model[0] - data[0])**2
        diff += (model[1] - data[1])**2
        diff = diff/(2*len(w_data)-45)

I am trying to fit a section of data that I haven't been able to before with other models, so I hoped the b-spline would offer flexibility. 
No matter how many times I run the code, the residual value isn't improving. 

This is the call I make:
minimizer_results = minimize(residual,params, gtol=1e-5, xtol=1e-5, ftol = 1.e-5)

I reduced the tolerance values since that came up in a warning message.

Could there be an issue with using b-splines? Or perhaps there is another setting I could consider?

This section of data is very complex, so I did anticipate some difficulty, but to not see any improvement what so ever is worrisome. 

Thank you,
Priscilla

Matt Newville

unread,
Nov 15, 2017, 8:50:38 AM11/15/17
to lmfit-py
Hi Priscila,

On Tue, Nov 14, 2017 at 11:07 PM, Priscilla Kelly <priscill...@gmail.com> wrote:
Hello,

I am very grateful for the fitting code and have been using it for all my ellipsometry fittings.
However, recently I have implemented a B-Spline fitting to the system and have run into problems. I have a 45 knot b-spline function model that I use to predict ellipsometry data: Psi and Delta.

I call my residual like so:
    def residual(params):
        model = ellipsFunc(params)  #< -- params is the knots that I sent for ellipsometry data
        diff = (model[0] - data[0])**2
        diff += (model[1] - data[1])**2
        diff = diff/(2*len(w_data)-45)


It should definitely be possible to fit B-spline coefficients -- I have production code that does something very similar (currently using cubic splines with UnivariateSpline, but I used B-splines in the past).   I don't have a simple, small example, but that would be a good example to have....

But when I look at your code snippet, I see  

     diff = (model[0] - data[0])**2
     diff += (model[1] - data[1])**2

and wonder if you're doing more harm than good.  The objective function should return `(model - data)*weights`, **NOT** the square of that or sum-of-squares, just the residual which has a meaningful sign.


I am trying to fit a section of data that I haven't been able to before with other models, so I hoped the b-spline would offer flexibility. 
No matter how many times I run the code, the residual value isn't improving. 

Could that be because the best fit was actually found?  Do you mean the residual isn't improving *during* the fit, or between subsequent fits?
 

This is the call I make:
minimizer_results = minimize(residual,params, gtol=1e-5, xtol=1e-5, ftol = 1.e-5)

I reduced the tolerance values since that came up in a warning message.

What is that message? 

Generally speaking, the tolerance changes the stopping condition, but very often it does not actually improve the quality or "precision" of the fit.   Those are typically set by the data and/or ability of the model to match the model.
 

Could there be an issue with using b-splines? Or perhaps there is another setting I could consider?

I think B-splines should work fine.
 

This section of data is very complex, so I did anticipate some difficulty, but to not see any improvement what so ever is worrisome. 


It is always helpful to try to come up with a small test example that either shows the problem or helps diagnose the trouble.

Hope that helps. 
Cheers,

--Matt 

Priscilla Kelly

unread,
Nov 16, 2017, 4:11:26 PM11/16/17
to lmfit-py
Thank you, that hint in the residual helped a lot. 

I made two simple examples and they both worked well. I think the problem lies with my bigger code, so I need to do some more digging to see the problem there. 

The error I get in the big code is this:
Termination Status: Tolerance seems to be too small... Could not estimate error-bars
which is why I added
minimizer_results = minimize(residual,params, gtol=1e-5, xtol=1e-5, ftol = 1.e-5)
since I saw it in another thread.

I'll let you know if I find another issue! 
Thank you,
Priscilla
Reply all
Reply to author
Forward
0 new messages