MATLAB: Sine Regression with NonLinearModel.fit

MATLABmodelnonlinear fitnonlinearmodel.fitregressionsine

I am trying to approximate an oscillating set of data from a sensor using the following model:
y ~ B0 + B1 * sin( B2 * X + B3 )
If I am not mistaken, B0 represents the vertical shift, B1 is the amplitude, B2 is the number of peaks being examined, and B3 is the phase shift. In my situation, finding accurate approximations for B1 and B3 is the priority. I tried doing this with the following section of code:
X = x_force;
Y = y_force;
s_l=size(peaks_f);
scatter(X,Y)
hold on
B0 = mean(Y);
B1 = p_p_force/2;
B2 = s_l(1);
B3 = 0;
myFit = NonLinearModel.fit(X,Y, 'y ~ b0 + b1*sin(b2*x1 + b3)', [B0, B1, B2, B3])
plot(X, myFit.Fitted)
In the code above, x_force and y_force denote data points for time and force, respectively. The variable p_p_force defines the difference between the average peak y-values and average trough y-values, and peaks_f is a list of force peak values. In this case, size(peaks_f) would be equal to [9,1].
When executing this code, I expected the fit values to match the original values more closely. However, this was not so. As you can see in the picture, the scatter plot of the original force values is not modeled correctly at all.
Am I using NonLinearModel.fit incorrectly in some way?
Thank you in advance for your advice.

Best Answer

You are making the mistake of providing poor starting values. You simply needed to provide a set of more intelligent starting values.
Just looking at your curve for some wild guesses...
B0 should be roughly 0
B1 should be roughly 10
B2 should be roughly 2*pi*10
B3 should be roughly 0.22
I'll predict that B2 was the only one that really mattered though. Regardless, all of those starting values are trivial to estimate programmatically.
Related Question