V zimním semestru jsme se naučili používat funkci LINREGRESE (resp. LINEST v anglické verzi Excelu), která pomocí metody nejmenších čtverců vypočítala koeficienty přímky (y = m1x1 + m2x2 + ... + b), která nejlépe odpovídala zadaným datům (y, x1, x2...). Kromě vypočtených koeficientů funkce uměla vracet i další regresní statistiky. V MATLABu lze samozřejmě data aproximovat také. V případě, že chceme zadaná (naměřená) data aproximovat polynomem n-tého stupně, můžeme to jednoduše provést pomocí funkce polyfit
, která používá metodu nejmenších čtverců:
p=polyfit(x,y,n)
, kde
x
je vektor hodnot nezávisle proměnné,
y
je vektor hodnot závisle proměnné,
n
je stupeň polynomu, jímž chceme aproximovat body [xi,yi] a
p
je vektor koeficientů výsledného polynomu P(x), přičemž P(x)=p(1)
xn + p(2)
xn-1 + ... + p(n)x
+ p(n+1)
Poznámky:
polyfit
hlásí "Warning"
polyfit
upravit (a uložit pod jiným názvem) nebo použít metodu nejmenších čtverců, která vede k řešení soustavy lineárních rovnic. Uvedené postupy lze samozřejmě použít pouze pro modely, které jsou lineární v parametrech!
Protože nás kromě koeficientů aproximačního polynomu většinou zajímají také hodnoty polynomu P(x) ve všech prvcích vektoru x
(např. kvůli grafickému znázornění), existuje také funkce polyval
:
y_aprox=polyval(p,x)
, kde
p
je vektor koeficientů aproximačního polynomu,
x
je vektor hodnot nezávisle proměnné a
y_aprox
je vektor hodnot aproximačního polynomu.
Součet čtverců odchylek pak vypočteme snadno - buď pomocí cyklu for
(přes všechny prvky y_aprox
a y
), anebo jednoduše s využitím toho, že nás zajímá součet prvků vektoru, který vznikl umocněním každého prvku vektoru rozdílů mezi y_aprox
a y
:
S=sum((y_aprox-y).^2)
Příklad - chceme aproximovat 8 naměřených hodnot u
a v
polynomem 2. stupně:
>> u=[1 1.5 2.1 2.5 3 3.1 3.2 3.5]; % namerena data, nezav. prom. >> v=[7.8 8.15 8.3 8.25 8.1 8.3 8.35 8.2]; % namerena data, zav. prom. >> p=polyfit(u,v,2) % koeficienty polynomu 2. stupne pro 'u' a 'v' p = -0.1684 0.8977 7.1150 >> v_aprox=polyval(p,u); % hodnoty polynomu v 'u' >> S=sum((v_aprox-v).^2) % soucet ctvercu odchylek S = 0.0345 >> plot(u,v,'r+') % graf, puvodni data jako cervene krizky >> hold on % prikreslime dalsi >> plot(u,v_aprox,'k.-') % graf polynomu jako cerne body spojene carou >> axis([0.8 3.7 7.7 8.4]) % uprava os >> title('Data a jejich aproximace parabolou')% nazev grafu >> legend('data','aproximacni polynom',4) % zobrazime legendu (4 = vpravo dole)A výsledek:
Samozřejmě by bylo lepší napsat tyto příkazy jako skript nebo ještě lépe jako funkci (aby se stupeň aproximačního polynomu dal snadno měnit).
Návrh na vylepšení:
namísto příkazu >> plot(u,v_aprox,'k.-')
by se graf polynomu mohl vykreslit s menším krokem (bude vypadat lépe), například:
>> plot(min(u):0.05:max(u),polyval(p,min(u):0.05:max(u)),'k',u,v_aprox,'k.')
A výsledek:
Pokud chceme data aproximovat jinou funkcí než polynomem (např. f(x)=C1.sin(x)+C2.1/x), řešíme danou úlohu pomocí metody nejmenších čtverců (pouze pro modely, které jsou lineární v parametrech!), kdy pro neznámé koeficienty (C1, C2) získáme soustavu lineárních rovnic.