LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Nonlinear curve fit reinitialization problem

Hello all,
 
I am using the Levenberg-Marquardt Nonlinear Curve Fit vi within a large data acquisition/analysis application. Once the data is taken, the program makes repeated calls to this function through a while loop to fit curves in a time series. The problem I am running into is that after the initial call, subsequent calls to the same function give erroneous results. The function is behaving like it is not properly reinitializing. The first data set is fit correctly. However, when I analyze another dataset, the returned fit is not correct. This VI is running within a subpanel VI, and when I kill the subpanel and restart it and look at the exact same dataset that just gave me incorrect results, it is now fit correctly. I have verified that all parameters being supplied to the nonlinear curve fit vi are not being changed. Basically, with the exact same input, I am getting correct results only when it is the first call to the function, and incorrect results thereafter.
 
Any suggestions would be greatly appreciated. 
Message 1 of 10
(4,836 Views)
This VI should not require any form or initialization and the VI should not retain any information from previous iterations of the while loop.   How were you able to determine that all of your parameters were not being changed?  Also how were you able to kill the sub-vi in mid-execution and capture the input data / paramters?  Could you reproduce the same behavior by putting the VI in a smaller application and giving it controlled inputs?
0 Kudos
Message 2 of 10
(4,813 Views)
Hello. Thanks for the response. Yes, I did isolate the code in a vi that is independent of the main program. I was able to reproduce similar behavior. I monitored both the inputs to the function and the outputs with probes and stepped through the execution of the program. The data is very well behaved in that it is a textbook gaussian. Given two input spreadsheet files, when I input the first dataset, the result is correct, but entering the second dataset, the Gaussian fit is noticably incorrect. It consistently overfits the data in that the FWHM is found to be too large. If I terminate the calling VI and restart, this time first inputting the second dataset, it is now fit correctly, and when I put in the first dataset, it now is fit incorrectly. The function seems to be correctly fitting the first dataset input to it, but fails on subsequent input. In all cases, the probes monitoring the inputs are unchanged, so the Lev-Mar subVI is receiving the same input. I have not examined the inner workings of this function. I implemented a separate levmar algorithm written in C that I am accessing through a library function call. Substituting this where the Lev-Mar subVI does not show the same problem, so the problem, whatever it is, is with the Lev-Mar subVI supplied with LabView. Now, I realize this subVI is not new, and a problem this obvious should have been noticed by now. So, I believe there is something wrong with how I wrote the calling VI, and I am curious if anyone has any ideas.

I am at home now, but if anyone wants me to upload the test VI that I wrote around this problem, I can do that when I'm at work.
Brian.
0 Kudos
Message 3 of 10
(4,807 Views)
Since these routines received a major facelift in LabVIEW 8.0, it would be important to know your LabVIEW version.
 
Since there is no exact match for "Levenberg-Marquardt Nonlinear Curve Fit vi", which function are you actually using?
  1. Nonlinear Curve Fit (polymorphic), LabVIEW 8.0
  2. Levenberg Marquardt (Formula model, pre LabVIEW 8.0)
  3. Nonlinear Lev-Mar Fit (subVI model, pre LabVIEW 8.0)

Would you mind attaching your code?

0 Kudos
Message 4 of 10
(4,805 Views)

Yes, I was a little loose with the VI name. It is the Nonlinear Curve Fit.vi from LV8. I am including the debug VI that I used including its dependencies in the compressed attachment. It contains debug_lm.vi which needs to call two user defined subVI's which I included as well. There are two datafiles that I used to test this. The output is set to just output coefficients from the fit, and I probed all the inputs to make sure they were not being changed. I ran the VI and opened time0_aug followed by time165_aug, then stopped the VI and restarted, opening time165_aug followed by time0_aug. The coefficients I am getting (index 0,1) are respectively: time0_aug=(-1.9233,321.469); time165_aug=(-0.0906148,337.272) followed by time165_aug=(-0.0885339,319.335); time0_aug=(-1.9195,320.941) when I start the VI over. I can repeat this several times. Of course they should be the same regardless of which order I read them in. I'd be very interested if this does/does not reproduce itself on someone else's computer. I verified that all the inputs to the Nonlinear Curve Fit function stay the same, the output is the only thing that is different. I should also note that if I replace that function with a library call to an external DLL containing another implentation of the Levenberg-Marquardt algorithm, I do not encounter this problem.

Brian.

0 Kudos
Message 5 of 10
(4,783 Views)
Here's my superficial interpretation:
 
OK, it seems the problem is deep in a system VI: LM Formula string function.vi. It caches the parsed formula on first run in an uninitilized shift register, but since you are rewriting the formula between runs, it misses the change. As a workaround, one could probably replace the "first run" node and replace it with a not equal, comparing the "function parameters" value with the previous value from a shift register.
 
If you simply remove that case structure, leaving only the TRUE case, everything behaves correctly, with a performance penalty of course.
 
I think it is a bug.
0 Kudos
Message 6 of 10
(4,774 Views)
Excellent. That makes a lot of sense considering it was behaving as if it had some memory of what was sent to the function before. I will apply the workaround you suggested and play with it. Thanks a lot for your help,

Brian.
0 Kudos
Message 7 of 10
(4,762 Views)
Yeah, Christian found it.  I missed that when I wrote this VI.  Attached is a fix for the problem (LabVIEW 8.01).  Currently LM formula string function.vi will parse the formula string once, when the "first call" is true.  I have added a check for a changed formula string.  So now, if first call is true, or if the formula string is changed from the previous call, the formula string is parsed.  Otherwise the cached parse result is used (better performance than reparsing the same formula string every call).  Please post any problems you have with this fix.  I will add this to the next LabVIEW release.

Thanks Christian!

-Jim


0 Kudos
Message 8 of 10
(4,759 Views)
Cool!
 
I would think we can get rid of the "first call" entirely, and keep only the "not equal". This way it will execute when the shift register does not yet contain data or whenever the formula changes. The "first call" would also execute the true case during different runs of the same editing session, even if the formula is still cached. This is not needed.
 
Now we need to find a solution to the problem that these libraries are passworded, making it impossible for the enduser to make corrections and e.g. save the vi under a new name elsewhere (even if I don't try to overwrite any vi.lib stuff). Is there a way?
0 Kudos
Message 9 of 10
(4,754 Views)
 

This was reported to R&D (# 3XHB2IQO) and was fixed in LabVIEW 8.2. Here is a link to the current evaluation software download for LabVIEW.

Thanks!

Travis H.
LabVIEW R&D
National Instruments
Message 10 of 10
(4,519 Views)