% Illustration of the bias/variance dilemma
% use a polynomial of degree m and n training points
% to approximate a function f

% bounds of the range of the input x
lx = -5;
ux = +5;
px = lx:0.01:ux;

n = input('number of training examples ? -> ');  
while n > 0
    m = input('degree of the polynomial approximation ? -> ');
    noiseLevel = 0.2;

    % data
    x = linspace(lx, ux, n);

    % define the target function
    f = inline('x + sin(x)', 'x');

    % row vector of target values
    y = f(x) + noiseLevel * (rand(size(x)) - 0.5);

    % compute and visualize polynomial
    while m >= 0
        %      |  1    ...    1   |
        %      | x1^1  ...   xn^1 |
        %  y = |        :         |
        %      | x1^m  ...   xn^m |
        %   
        A = powerCol(x, m);
		        
        % w is the column vector of the coefficients of the approximating 
        % polynomial
        w = pinv(A')*y';
        
        % plot
        plot(px, f(px), '-b');
        hold on
        plot(x, y, '+r');
        py = px;
        for i = 1:length(py)
            py(i) = polynom(px(i), w);
        end
        plot(px, py, '-k');
        title(['target blue, polynomial black, degree -> ' int2str(m)])
        hold off
        
        m = input('degree of the polynomial approximation ? -> ');		
    end
    n = input('number of training examples ? -> ');      
end
