Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Sine curve fitting

Subject: Sine curve fitting

From: Rafael Herrejon

Date: 17 Apr, 2008 04:49:02

Message: 1 of 3

Hello

I'm having some trouble to fit a curve to a set of points.

Having a sinusoidal wave given by
y=A*abs(sin((B*pi*time)+C)

some values are "taken" every 0.0145 secs.

xdata=0.0:0.0145:1.4065;
ydata=1.16*abs(sin((xdata*pi*17.5439)+2.7 ));

Having the values of xdata and ydata only, how can i
calculate the coefficients A,B and C?

i tried using

x0 = [0; 0.5411; 2.7] % Starting guess
[x,resnorm] = lsqcurvefit(@fun,x0,xdata,ydata)

where

function F = fun(x,xdata)
F =x(1)*abs(sin((x(2)*pi*xdata)+x(3)));

y is periodic and sinusoidal, but the coefficients obtained
are not correct. I really dont understand what might be
wrong. Could you give me an idea?

Thank you
Rafael

%%Code
xdata=0.0:0.0145:1.4065;
ydata=1.16*abs(sin((xdata*pi*17.5439)+2.7 ));
x0 = [0; 0.5411; 2.7] % Starting guess
[x,resnorm] = lsqcurvefit(@example7f,x0,xdata,ydata)
time=0.0:0.001:1.4065;
y=1.16*abs(sin((time*pi*17.5439)+2.7 ));
curvecalc =x(1)*abs(sin((time*pi*x(2))+ x(3) ));
figure
plot(time,y,'b',xdata,ydata,'g*',time,curvecalc,'r'),
legend('original curve','sampled points','calculated
curve');
%%

Subject: Sine curve fitting

From: helper

Date: 17 Apr, 2008 07:33:02

Message: 2 of 3

"Rafael Herrejon" <rafael.erasethis@ic.is.tohoku.ac.jp>
wrote in message <fu6kru$3tm$1@fred.mathworks.com>...
> Hello
>
> I'm having some trouble to fit a curve to a set of points.
>
> Having a sinusoidal wave given by
> y=A*abs(sin((B*pi*time)+C)
>
> some values are "taken" every 0.0145 secs.
>
> xdata=0.0:0.0145:1.4065;
> ydata=1.16*abs(sin((xdata*pi*17.5439)+2.7 ));
>
> Having the values of xdata and ydata only, how can i
> calculate the coefficients A,B and C?
>
> i tried using
>
> x0 = [0; 0.5411; 2.7] % Starting guess
> [x,resnorm] = lsqcurvefit(@fun,x0,xdata,ydata)
>
> where
>
> function F = fun(x,xdata)
> F =x(1)*abs(sin((x(2)*pi*xdata)+x(3)));
>
> y is periodic and sinusoidal, but the coefficients
obtained
> are not correct. I really dont understand what might be
> wrong. Could you give me an idea?
>
> Thank you
> Rafael
>
> %%Code
> xdata=0.0:0.0145:1.4065;
> ydata=1.16*abs(sin((xdata*pi*17.5439)+2.7 ));
> x0 = [0; 0.5411; 2.7] % Starting guess
> [x,resnorm] = lsqcurvefit(@example7f,x0,xdata,ydata)
> time=0.0:0.001:1.4065;
> y=1.16*abs(sin((time*pi*17.5439)+2.7 ));
> curvecalc =x(1)*abs(sin((time*pi*x(2))+ x(3) ));
> figure
> plot(time,y,'b',xdata,ydata,'g*',time,curvecalc,'r'),
> legend('original curve','sampled points','calculated
> curve');
> %%
>
>


The answer you are receiving is not "wrong" as far as
LSQCURVEFIT knows. It just converges to the local minimum
closest to your initial guess. You have given the solver
an initial guess relatively far from the global minimum.

You simply need to give the solver an initial guess closer
to the global minimum. If you have no reason to expect
your signal to have a period and amplitude within any
specific range, you can perform an initial analysis on the
data to obtain better guesses. For example, you can get a
good guess at your amplitude simply using:

x0(1) = max(ydata)

I am sure there are better methods for guessing at the
period (for example using FFT), but I simply used:

d = diff(ydata);
i = find(d(1:end-1)>0 & d(2:end)<0);
x0(2) = 1./mean(diff(xdata(i)))

I then used an initial guess of 0 for the phase and
obtained a very accurate result from LSQCURVEFIT.

Before using any of the optimization tools, you need to
have a good idea of what your objective function looks
like. In this case, your objective function will have many
local minimums. Therefore, you should expect to have to
determine an initial guess very close to the global minimum
in order to find it.

Subject: Sine curve fitting

From: Miroslav Balda

Date: 17 Apr, 2008 18:10:19

Message: 3 of 3

"Rafael Herrejon" <rafael.erasethis@ic.is.tohoku.ac.jp>
wrote in message <fu6kru$3tm$1@fred.mathworks.com>...
> Hello
>
> I'm having some trouble to fit a curve to a set of points.
>
> Having a sinusoidal wave given by
> y=A*abs(sin((B*pi*time)+C)
>
> some values are "taken" every 0.0145 secs.
>
> xdata=0.0:0.0145:1.4065;
> ydata=1.16*abs(sin((xdata*pi*17.5439)+2.7 ));
>
> Having the values of xdata and ydata only, how can i
> calculate the coefficients A,B and C?
>
> i tried using
>
> x0 = [0; 0.5411; 2.7] % Starting guess
> [x,resnorm] = lsqcurvefit(@fun,x0,xdata,ydata)
>
:
SNIP
:
Hi
The initial estimat x0 is very important for convergence of
iterations. It is easy to find at least some good estimates
for your function:
x0(1)=max(ydata); % as an amplitude,
x0(2)= number of extrems/time interval/2; as frequency,
x0(3)= more difficult to find - choose some value.
The code could be:

xdata=(0.0:0.0145:1.4065)';
ydata=1.16*abs(sin((xdata*pi*17.5439)+2.7 ));
fun = @(x) x(1)*abs(sin((x(2)*pi*xdata)+x(3)))-ydata;
L = extr(ydata); % FEX Id 10272
f = sum(L{1}+L{2})/xdata(end)/2
[x,ssq,cnt]=LMFnlsq(fun,[max(ydata),f,5]) % FEX Id 17534
% with the solution:
x =
    1.1600
   17.5439
    5.8416
ssq =
  3.2954e-027
cnt =
     7
I used my function LMFnlsq for least squares solution of
overdetermined system of nonlinear equations, because I
don't have Optimization Toolbox at disposal. The function
extr finds all local extremes of the vector. Both functions
may be found in the File Exchange collection of functions
under given identification number.

The solution is in order, when ssq is very small, what says
that the iteration process converged .
Hope it heps.

Mira

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us