-2

:) I'm trying to code a Least Squares algorithm and I've come up with this:

function [y] = ex1_Least_Squares(xValues,yValues,x) % a + b*x + c*x^2 = y

points = size(xValues,1); 
A = ones(points,3);  
b = zeros(points,1); 

for i=1:points
    A(i,1) = 1; 
    A(i,2) = xValues(i); 
    A(i,3) = xValues(i)^2; 

    b(i) = yValues(i);
end

constants = (A'*A)\(A'*b);

y = constants(1) + constants(2)*x + constants(3)*x^2;

When I use this matlab script for linear functions, it works fine I think. However, when I'm passing 12 points of the sin(x) function I get really bad results.

These are the points I pass to the function:

xValues = [ -180; -144; -108; -72; -36; 0; 36; 72; 108; 144; 160; 180];

yValues = [sind(-180); sind(-144); sind(-108); sind(-72); sind(-36); sind(0); sind(36); sind(72); sind(108); sind(144); sind(160); sind(180) ];

And the result is sin(165°) = 0.559935259380508, when it should be sin(165°) = 0.258819

syfantid
  • 366
  • 5
  • 20
  • Let's say I have 4 points: (-1,1), (0,0), (1,0) and (2,-2). I want to find a parabola that actually minimizes the squares of the distances or something. I followed the instructions I was given from my professor. I used the parabola y=a+b*t+c*t^2. I replaced the points in the equations and got 4 equations that I put inside matrices, in order to solve the linear system (A'*A)*constants=(A'*b) and when I find constants I was supposed to find a, b and c of the final equation. At least that's what the example from my notes says (they're in Greek, otherwise I'd post them here). – syfantid Jan 23 '14 at 17:23
  • 1
    You should plot the points and curves to get better insight. –  Jan 23 '14 at 17:29

2 Answers2

1

There is no reason why fitting a parabola to a full period of a sinusoid should give good results. These two curves are unrelated.

  • Our professor told us to use the Least Square Method to fit the sine function. Linear fitting obviously isn't a good choice and neither is a parabola... which curve should I choose then? I would really appreciate your help! – syfantid Jan 23 '14 at 17:17
  • Experiment with polynomials of increasing degree and see. Plot the curves ! The sine function is oscillating, having roots, extrema and inflection points. Think for yourself how many roots, extrema and inflection points a polynomial of given degree can have. –  Jan 23 '14 at 17:22
  • Also think about the range of values for which you want a good fit. Can you make a connection with Taylor/Maclaurin expansion ? –  Jan 23 '14 at 17:23
0

MATLAB already contains a least square polynomial fitting function, polyfit and a complementary function, polyval. Although you are probably supposed to write your own, trying out something like the following will be educational:

xValues = [ -180; -144; -108; -72; -36; 0; 36; 72; 108; 144; 160; 180];
% you may want to experiment with different ranges of xValues
yValues = sind(xValues);

% try this with different values of n, say 2, 3, and 4
p = polyfit(xValues,yValues,n);
x = -180:36:180;
y = polyval(p,x);

plot(xValues,yValues);
hold on
plot(x,y,'r');

Also, more generically, you should avoid using loops as you have in your code. This should be equivalent:

points = size(xValues,1); 
A = ones(points,3);      
A(:,2) = xValues; 
A(:,3) = xValues.^2; % .^ and ^ are different

The part of the loop involving b is equivalent to doing b = yValues; either name the incoming variable b or just use the variable yValues, there's no need to make a copy of it.

nkjt
  • 7,825
  • 9
  • 22
  • 28