LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Levenberg Marquardt curve fitting pt.2

My Pleasure!  In "function.vi" there is a for-loop where you are indexing three 2D arrays.  The row index is derived from the the first parameter (a[0]) and some of the constants, but is rounded-to-nearest just before the for-loop.  You might remove the round-to-nearest, and inside the for loop index a column from each 2D array, then interpolate within the column using the index value.  Attached is an implementation of this idea.  Also, try changing the curve-fitting algorithm (poly VI selector, Nonlinear Curve Fit TRDL Bound).  This algorithm seems to work a little better than Lev-Mar after implementing the linear interpolation inside function.vi.  You may get an error stating "no optimum found", but this just means that the parameters had not settled by the time the max-iterations was hit.  There atill seems to be something not quite smooth in your function, but it is much better than before.

Your application has demonstrated how difficult it can be to uncover this problem.  I am going to add a warning to the next LabVIEW release to cover this case (non-smooth function).  Hopefully that will make it easier for the next person. 😉

-Jim
0 Kudos
Message 21 of 32
(1,637 Views)


@DSPGuy wrote:
The smallest change in the first parameter that registers is about 2.6.  The finite difference VI within the Lev-Mar code was choosing a step-size of ~1E-4, yielding a partial derivative of zero at all X values.  .


-Jim





Is there any way to change the step-size to be greater than 1E-4? In my particular application, I would like it to be about 1e-2 if possible.
Thanks a bunch.
0 Kudos
Message 22 of 32
(1,530 Views)
"Is there any way to change the step-size to be greater than 1E-4? In my particular application, I would like it to be about 1e-2 if possible."
Unfortunately, not by simply specifying a value.  The model function VI has an output labeled f'(X,a).  You will have to compute your own derivatives and output them as f'(X,a) from the model function.  This is not so difficult if you use the code in the Lev-Mar algorithm as a starting point.  Attached is a simple forward difference version of the fitFunction.vi that you can use as a starting point.

-Jim


Message 23 of 32
(1,510 Views)

Excellent idea Jim,

In general, you would just relay the desired step size via the data variant input.

Sometimes you might even want different step sizes for different parameters, so you could even provide an array of step sizes and autoindex it at your FOR loop inside the function call. It is great that the 8.0+ fitting routines allow all this flexibility!

An alternative to keep the scales reasonable is reparametrization. Instead of fitting for A, we could fit for A' = 10000*A or A'=0.00001*A. Similarly, if paramter B is typically between 15.0000001 and 15.0000002, we could fit for B'=10000000*(B-15). 🙂

Message 24 of 32
(1,501 Views)
Thanks for the input.. I'd give it a shot but the function doesn't want to run in LV8.5

what version of LV was that code written in? ... I have some X-ed out boxes and messages about obsolete VIs. I can be more specific if that helps.
Thanks
0 Kudos
Message 25 of 32
(1,488 Views)


@altenbach wrote:

An alternative to keep the scales reasonable is reparametrization. Instead of fitting for A, we could fit for A' = 10000*A or A'=0.00001*A. Similarly, if paramter B is typically between 15.0000001 and 15.0000002, we could fit for B'=10000000*(B-15). 🙂






Brilliant! I wish I would have thought of it myself. I think that will end up helping a lot, although I still am considering trying the derivative approach.

Thanks.
0 Kudos
Message 26 of 32
(1,487 Views)
Nice idea Christian.

Unfortunately the code may not cooperate.  The stepsize computation is relative to the parameter size. 
It is computed as: delta_A=step_constant*max(abs(A),sqrt(machine_epsilon))
below is a snippet from the shipping code.




So if A' = 10000*A, then delta_A' would be step_constant*A', and when divided by 10000 in the model to convert from A' back to A would yield the same stepsize as just using A to begin with.  This became the behavior with LabVIEW 8.0, and was an done to make the numerical derivatives more robust w.r.t. the scaling of the parameters.

-Jim
0 Kudos
Message 27 of 32
(1,478 Views)
Darn! Lost the link to that screenshot.  Here it is:



0 Kudos
Message 28 of 32
(1,474 Views)
screenshot did not work
0 Kudos
Message 29 of 32
(1,468 Views)
Trying again.


0 Kudos
Message 30 of 32
(1,466 Views)