function [Q,alpha,L]=approxUniform(f,alter)

% APPROXUNIFORM - Funkcija vrsi ravnomernu aproksimaciju funkcije f pod
% pretpostavkom da su poznate tacke Cebisevljeve alternanse
% ULAZ :
%    f - anonimna funkcija koja se aproksimira
%    alter - vektor tacaka Cebisevljeve alternanse
% IZLAZ :
%    Q - niz koeficijenata aproksimacionog polinoma
%    alfa - +1 ili -1 u zavisnosti da li je u prvoj tacki alternanse
% f(x1)-Q(x1) jednako L ili -L
%    L - ||f-Q||

%Provera korektnosti argumenata
if nargin<2
    error('Ocekivana bar dva argumenta : funkcija koju aproksimiramo i niz tacaka Cebisevljeve alternanse');
end

[m,n]=size(alter);

if n<2
    error('Potrebno je da postoje bar dve tacke alternanse');
end

if (m~=1 || ~isnumeric(alter) || ~all(isfinite(alter)) || any(imag(alter)))
    error('Drugi argument mora da bude vektor konacnih realnih brojeva (tacke Cebisevljeve alternanse)')
end

% Koeficijente aproksimacionog polinoma nalazimo primenom Cebisevljeve
% teoreme tj, resavanjem sistema :
%               f(xk)-Q(xk)=(-1)^k*alpha*L  k=1..n
%
% Neka je polinom Q=q0+q1x+...+qn-2x^(n-2), tada sistem postaje :
%   -1     x1^n-2   ...   x1   1        alphaL      f(x1)
%    1     x2^n-2   ...   x2   1   *    qn-2     =  f(x2) 
%               ...
%   (-1)^n xn^n-2   ...   xn   1         q0         f(xn)

%prealokacija (obratimo paznju da koristimo cinjenicu da su na pocetku svi
%elementi 1
A=ones(n); 

%ako se ne radi o trivijalnom slucaju n=2
if n>2
    % Pretposlednju kolonu postavimo na alter
    A(:,n-1)=alter; 

    % Svaku novu kolonu dobijamo tako sto prethodnu pomnozimo sa alter
    for i=n-2:-1:2
        A(:,i)=alter.*A(:,i+1);
    end
end

% Svaki drugi elemenat prve kolone stavimo na -1
A(1:2:n,1)=-1;

% Vektor slobodnih clanova
b=f(alter);

% Resavamo sistem i dobijamo vektor [alpha*L qn-2 ... q0]
Q=A\b';

% alpha odredjujemo tako da je L>0
if (Q(1)>=0)
    alpha=1;
    L=Q(1);
else
    alpha=-1;
    L=-Q(1);
end

%Koeficijenti polinoma (transponovano da bi bio vektor vrsta)
Q=Q(2:end)';