Message Boards Message Boards

Fitting data to a square wave

I have a question about the attached MM notebook (just a few lines). I'm trying to fit a lineout through the digital image of a line pair gauge to a square wave. FindFit appears to fit the mean value (b) and at least takes a stab at fitting the amplitude (a); however, it seems to make no attempt to fit the offset on the x axis (x0). Why not? What am I missing?

Also, I would like to get more detail on the fit parameters, in particular, the uncertainties, but I haven't been able to figure out how to get MM to dump that information. How can I do that?

Thanks in advance for any help on this.

Attachments:
POSTED BY: James Hall
13 Replies

It could be natural to use Haar wavelets... But the fit is not very good.

Attachments:
POSTED BY: Claude Mante
Posted 15 hours ago

Given my previous comments, I wonder if your data was generated by a trapezoidal wave rather than a square wave.

data={{-6.25, 0.00219649}, {-5.75, 0.0291773}, {-5.25, 0.0428364}, {-4.75, 0.0418075}, 
  {-4.25, 0.0390189}, {-3.75, 0.0142977}, {-3.25, 0.000728449}, {-2.75, 0.000577218}, 
  {-2.25, 0.00314383}, {-1.75, 0.0275447}, {-1.25, 0.0428128}, {-0.75, 0.0433703}, 
  {-0.25, 0.0433703}, {0.25, 0.0403935}, {0.75, 0.0160277}, {1.25, 0.000686316}, 
  {1.75, 0.00036222}, {2.25, 0.00288114}, {2.75, 0.0256044}, {3.25, 0.0416728}, 
  {3.75, 0.0429419}, {4.25, 0.0396677}, {4.75, 0.0162309}};

nlm = NonlinearModelFit[data,
   (a/\[Pi])*(ArcSin[Sin[(\[Pi]/m) x + l]] + ArcCos[Cos[(\[Pi]/m) x + l]]) - a/2 + c,
   {{a, 0.04}, {m, 2}, {l, 3}, {c, 0.02}}, x];
Show[ListPlot[data], Plot[nlm[x], {x, Min[data[[All, 1]]], Max[data[[All, 1]]]}]]

Trapezoidal wave fit

The equation was lifted from Amrtanshu Raj 's answer at https://uk.mathworks.com/matlabcentral/answers/684163-generating-periodic-trapezoidal-waves-with-ramps. (Yes, a MATLAB site.)

POSTED BY: Drjbaldwin
Posted 2 hours ago

This looks very promising! Thanks much! I'll give it a try.

POSTED BY: Jamesa Hall
Posted 16 hours ago

I'm curious as to how you created the simulated data. I ask because if you sampled a square wave from $x=-6.3$ to $x=4.8$ with a constant error variance over a cycles of a square wave, it would seem near impossible to get any of those 6 points in the middle of the figure (i.e., those points between $y=0.01$ and $y=0.03$).

In other words, those 6 points could be considered outliers and maybe given very little weight.

POSTED BY: Drjbaldwin
Posted 3 hours ago

The data file is a scan through the simulated digital image of a rectangular line pair gauge. The detector has limited resolution, which is why the maxima show rolloff effects.

POSTED BY: Jamesa Hall
Posted 16 hours ago

Frankly I would find the phase separately by brute force, using reasonable candidate values (timesinbetween below). SqWave is just a pathologically nasty function to fit automatically. I would also, probably, rewrite SqWave in some other form (like SquareWave?), but here the method below doesn't really care about that:

POSTED BY: Jari Kirma
Posted 1 day ago

Hi James,

In the attached notebook, I first fit the data to a sine function, and then use the determined parameters as estimates for fitting to the square wave. I used NonlinearModelFit, which provides statistics on the fit.

Attachments:
POSTED BY: David Keith
Posted 23 hours ago

Thanks, David. Using a Sin fit looks like a good way to define x0 and estimate starting values for a & b. There are several other techniques you included that I can make use of. I'm puzzled that the amplitude (a) turns out to be negative (not sure what that means), and I'm a bit surprised/disappointed that the fit value doesn't match the approximate max & min values of the data better than it does, because I would like to use this technique to estimate the gauge modulation ((max-min)/(max+min)).

Again, thanks much for your help - I really appreciate it.

POSTED BY: Jamesa Hall
Posted 20 hours ago

Hi James, The parameter a being negative is only a phase inversion, which would be compensated in the fit by a different value of x0. It can be forced positive by including a condition in the model like this:

sinFit = 
 NonlinearModelFit[LPGdata, {sineWave[x, a, x0, b], a > 0}, {a, x0, b},
   x]

I am also disappointed that the peaks are modeled poorly in the square wave fit. It is likely due to the midlevel values in the data. Stripping these out before the fit could improve the result. But data manipulation carries its own risks.

POSTED BY: David Keith
Posted 17 hours ago

Quite so, David, and a subjective data analysis was precisely what I was hoping to avoid by doing this fit. Thanks again. - Jim

POSTED BY: Jamesa Hall
Posted 1 hour ago

Hi Jamesa, The attached notebook takes a perhaps too naïve approach. It does select data to be processed. It estimates the peaks using data with y values greater then 80% of the max, and the valleys using values less than 20% of the max.

enter image description here

Attachments:
POSTED BY: David Keith

NonlinearModelFit works better for this:

enter image description here

POSTED BY: Anton Antonov
Posted 23 hours ago

Thanks for your input, Anton. I appreciate your help. Did this actually use x0 as a fit parameter? It look like it just set the value to 1.000... with 0 uncertainty.

POSTED BY: Jamesa Hall
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract