11-29-2013 10:51 AM
Hi all.
I'm trying to play a sound as a sine wave down a pipe and detect the wave at the opposite end using a microphone, and then see how the two waves match up. I can get the frequency and amplitude using the 'tone measurement' vi's. The issue arises when trying to find a 'goodness of fit' between the generated and detected sine waves. I took inspiration from here:
http://forums.ni.com/t5/LabVIEW/Lev-Mar-non-linear-fit-problem/td-p/1187883
to generate the attached vi. The subvi simply generates a sin wave and its XY pairs are extracted. They then feed into the curve fit to theoretically give a perfect fit- but I get a 'wrong model' error. I've changed the model to incorperate a 2pi term too but to no avail. If anyone can suggest reasons why/ solutions it would be appreciated.
Thanks.
11-29-2013 01:29 PM
One of your parameters is called "c2" and does not appear in the formula. Rename it to "c"
The array of parameters has 4 elements, the last element being an emtpy string. (resize the container to see all, the size of the container does not determine the size of the array!) You need to remove that fourth array element.
(Besides, I don't think any of your flat sequence structures are necessary, they just clutter up the diagram).
11-29-2013 01:45 PM
You need to be extremely careful to follow the instructions for the fit VIs to make them work.
The Model description cluster has two simple errors which cause problems. When I expanded your string array for parameters I found two surprises: The third element has an extra character - c2 rather than c - and a fourth element exists. It is an empty string but the parser expects values to be there and it may assume that empty is a valid value for that parameter. However, no such parameter exists in the formula.
After changing the third element to c and deleting the fourth element, the code runs. But it does not fit well.
First, the Starting parameters are in different order in the fit VI (amplitude, frequency, phase) compared to the Generate VI (frequency, amplitude, phase). They are not wired together so this is not an error but if the user does not enter them in the correct order, the initialization is off.
Second, the Lev-Mar algorithm does not fit sine waves well. The reason: It uses derivatives of the model with respect to the parameters to be fitted to force the values closer to the desired points. But recall that the derivative of a sine is a cosine of the SAME FREQUENCY. d(sin(bx))/db = b*cos(bx). Thus, the process does not move the frequency in the correct direction. Even when the exact frequency is entered as initial parameter, it often does not work.
You do not need the sequence structures. The code will behave exactly the same without them. Dataflow.
Lynn
11-29-2013 02:22 PM
@johnsold wrote:
Second, the Lev-Mar algorithm does not fit sine waves well. The reason: It uses derivatives of the model with respect to the parameters to be fitted to force the values closer to the desired points. But recall that the derivative of a sine is a cosine of the SAME FREQUENCY. d(sin(bx))/db = b*cos(bx). Thus, the process does not move the frequency in the correct direction. Even when the exact frequency is entered as initial parameter, it often does not work.
Actually, it typically works just fine IF the initial parameters are reasonable. If they are not, you'll find an alias frequecy that has exactly thew same fit quality. There is an infinite number of solutions, but if the guess is close, the fit will work. If you estimate the parameters from the single tone measurement tool, you should be absolutely fine.
I also highly recommend to graph the function given the guess parameters. This will tell you if the guess is even reasonable.
I multiplied the x values by 2pi, but you would need to wrap that factor into the formula.
Here's a quick draft.
12-02-2013 09:47 AM
Hi both.
Thanks for the effot so far. It has helped clarify a few things. Can I ask, about the static reference as I've had no experience with these. II am generating a wave from a simple signal generator so know the expected frequncy and amplitude assuming the wave is not distorted, these values are set as the initial parameters. When these valus are used along with the equation within th model, the exat wave being input should be generated... is this correct so far?
Ideally, I'd then like o feed in a live sound wave (detected from a microphone), extract the X and Y values from the wave, and plo these against the input wave to see if any difference between the two waves exists. The X data is output as a time stamp, which I cnvert to a 1D array of double. The Y data is outpt as a 1D array of double. Feeding these arrays into the X an Y inputs of the Lev-Ma fit vi will give a comparrison of fit to the model and indicate any deviation. Th model is currently a*sin((b*x)+c) but as you say the 2pi valu should be input to give a*sin((2Pi*b*x)+c) . Does the static reference need to be changed to accomodate?
Hopefully ou can push me in the righ direction yet further. Thanks a lot!
12-02-2013 10:51 AM
If you are talking about the static VI reference I added, no, this does not need to change,. It is the model VI that understands the formula input. As long as you keep using the formula model, you can keep it. Of course it might be more efficient to use the VI model version. In this case you need to create your own model containing plain LabVIEW code and no longer need the formula string.
12-03-2013 04:06 AM
Hi.
When I alter the fomula string to contain a 2pi term, an error of Analysis: Bracket problem at the end. occurs at 'call by reference'. Can you laborate on how he modl string may be modified to add a 2pi term. Also, if you can explain the quesions I asked in the previous post it would be appreciated. If I can get a handl on what each part of the vi is doing, hopefully these issues won' arise again.
Regards.
12-03-2013 11:16 AM - edited 12-03-2013 11:18 AM
@Danbubbles wrote:
Bracket problem at the end. occurs at 'call by reference'. Can you laborate on how he modl string may be modified to add a 2pi term.
How did you modify it?
@Danbubbles wrote:
Also, if you can explain the quesions I asked in the previous post it would be appreciated. If I can get a handl on what each part of the vi is doing, hopefully these issues won' arise again.
You asked many questions and I thought I answered. Can you point out what part is still not clear to you?
12-04-2013 03:31 AM
Hi.
I modified he model string by adding in 2pi and 6.282 as a term befoe the b, as outlined above. Any form of modificaion seems to bring about the erorr. As i said, my main stumbling block is my lack of knowledge of how the model fits, and how it uses the static reference. Similarly, the call by reference icon is a new one. Is this just analogous to a subvi structure?
Regards.
12-04-2013 10:50 AM
Obviously, you introduced a syntax error when adding the 2pi. Unless you show us exactly what you entered, we cannot really tell what you are doing wrong.
Any obejct on the diagram has an associated help, even the call by reference node. Is there anything that's not explain clearly? Please let NI know. It is in many ways similar to a subVI call, except that the actual subVI can be determined at run time by dynamically creating a reference to a different VI on disk (that has the same connector pattern as strictly defined). A static VI reference statically points to a VI. Yes, in this particular case you could substitute the actual VI instead of the call by reference.
If you use the VI model of the nonlinear curve fit, you need to supply the model as a strictly typed VI reference to be used deep inside the fitting algorithm. Here you cannot use a plain subVI call, because you would need to edit the system VIs, which is probably not such a good idea. For this reason I typically also calculate the model with the paramter guesses using a call by reference node. If I need to change the model, I simply point the static VI reference elsewhere. If I would use a plain subVI call for the guess, I would need to change the VI reference and the instance where I calculate the model guess, leading to more work and more possibilities for errors (e.g. if I forget to change the subVI)