KTE / PPEL Počítačová podpora v elektrotechnice Ing. Lenka Šroubová, Ph.D. email: lsroubov@kte.zcu.cz http://home.zcu.cz/~lsroubov Polynomy opakování a pokračování 31. 10. 2012 Příklad: Funkce, která vykreslí zadaný polynom p v zadaném rozsahu a najde a označí v grafu maximum a minimum v daném rozsahu function kreslipolynom(p,odkudx,kamx,prvkux) x = linspace(odkudx,kamx,prvkux); hodnotypolynomu = polyval(p,x); plot(x,hodnotypolynomu,'.') title('prubeh polynomu') xlabel('x') ylabel('y') hold on [Max,indexMax]=max(hodnotyPolynomu) plot(x(indexmax),max,'or') [Min,indexMin]=min(hodnotyPolynomu) plot(x(indexmin),min,'ok') hold off show endfunction Volání funkce s příslušnými vstupními daty: kreslipolynom(p,-0.4,0.8,1000)
A výsledek: Max = 11 maximum z vektoru hodnotypolynomu indexmax = 334 poloha (index) maxima ve vektoru Min = 9.3020 minimum z vektoru hodnotypolynomu indexmin = 930 poloha (index) minima ve vektoru Grafy grid mřížka v grafu hold on přidrží aktuální graf v grafickém okně, lze nakreslit více grafů do jednoho grafického okna postupně hold off vypnutí, konec možnosti kreslit více grafů do jednoho grafického okna legend('krivka 1',krivka 2','krivka 3') zobrazení legendy v grafu, nutno dodržet pořadí jednotlivých křivek, jak byly kresleny, např. příkazem plot
Další příkazy pro práci s polynomy conv(p, q) součin polynomů p a q, tj. p(x)*q(x) = (4x 5 + 3.1x 3 7x 2 + 11)*( x 4 + x 3 x) ans = Columns 1 through 7: -4.00000 4.00000-3.10000 6.10000-7.00000-14.10000 18.00000 Columns 8 through 10: 0.00000-11.00000 0.00000 Tedy p(x)*q(x) = 4x 9 +4x 8 3.1x 7 + 6.1x 6 7x 5 14.1x 4 + 18x 3 11x roots(p) výpočet kořenů polynomu p (všechna x pro která je hodnota polynomu 0), tj. řešení rovnice 4x 5 + 3.1x 3 7x 2 + 11 = 0 ans = 0.97274 + 0.57470i 0.97274-0.57470i -0.51238 + 1.44129i -0.51238-1.44129i -0.92071 + 0.00000i Pozn. Stupněm polynomu p(x) rozumíme nejvyšší exponent proměnné x s nenulovým koeficientem. Stupeň polynomu p(x) je 5 => položíme-li ho rovný 0, má pak 5 kořenů) poly(x) zjištění koeficientů polynomu z kořenů (má-li vektor x n prvků, vypíše se vektor s n+1 prvky koeficienty polynomu n-tého stupně), funkce je opakem roots, první koeficient polynomu, tj. koeficient u nejvyššího exponentu proměnné x je vždy roven 1. Řešení kvadratické rovnice Kvadratická rovnice polynom, který je položen rovný nule Stupeň kvadratického polynomu (např k(x) = x 2 + 5x + 6) je tedy 2. Kvadratická rovnice má 2 kořeny. x 2 + 5x + 6 = 0 1x 2 + 5x + 6 = 0 k = [1, 5, 6]; x=roots(k)
x = -3.0000 tj x 1, -2.0000 tj x 2, tato kvadratická rovnice má reálné kořeny. Zkouška: (-3) 2 + 5*(-3) + 6 = 0 a (-2) 2 + 5*(-2) + 6 = 0, tj. polyval(k,x(1)) ans = 1.3323e-15 polyval(k,x(2)) ans = 2.2204e-16 Zjištění koeficientů polynomu z kořenů poly(x) ans = 1 5 6 Spočítáme průběh polynomu a vykreslíme graf i s kořeny xx = linspace(-4,1,1000); hp = polyval(k,xx); plot(xx,hp) hold on plot(x(1), polyval(k,x(1)),'*m') plot(x(2), polyval(k,x(2)),'*g') hold off
2x 2 + 4x + 6 = 0 k2 = [2,4,6]; x2 = roots(k2) x2 = -1.0000 + 1.4142i tj. x 1, -1.0000-1.4142i tj. x 2, tato kvadratická rovnice má komplexní kořeny. poly(x2) ans = 1.0000 2.0000 3.0000 Obě strany kvadratické rovnice můžeme vydělit dvěma: 2x 2 + 4x + 6 = 0 : 2 1x 2 + 2x + 3 = 0, tj. toto jsou koeficienty získané pomocí poly(x2) roots([1,2,3]) ans = -1.0000 + 1.4142i tj. x 1, -1.0000-1.4142i tj. x 2, => kvadratická rovnice 1x 2 + 2x + 3 = 0 má totožné řešení jako kvadratická rovnice 2x 2 + 4x + 6 = 0.
2x 2 + 6 = 0 2x 2 +0x + 6 = 0 k3 = [2,0,6]; x3 =roots(k3) x3 = 0 + 1.7321i tj. x 1, 0-1.7321i tj. x 2, tato kvadratická rovnice má komplexní kořeny bez reálné části poly(x2).*2 ans = 2.00000 0.00000 6.00000 x 2 2x + 1 = 0 1x 2 +( 2)x + 1 = 0 x4 = roots([1,-2,1]) x4 = 1 tj. x 1 1 tj. x 2, platí x 1 = x 2 tato kvadratická rovnice má dvojnásobný reálný kořen poly(x4) ans = 1-2 1 Řešení rovnic s polynomem vyššího stupně x 6 14 x 4 + 49x 2 = 36 1 x 6 + 0 x 5 14 x 4 + 0 x 3 + 49x 2 + 0x 36 x 0 = 0 r=[1,0,-14,0,49,0,-36] length(r) ans = 7 počet prvků ve vektoru je vždy o 1 větší než stupeň polynomu roots(r)
ans = -3.00000 3.00000-2.00000-1.00000 2.00000 1.00000 řešením je 6 kořenů počet kořenů stejný jako stupeň polynomu 7 x 8 = 7x 7 x 8 + 0 x 7 + 0 x 6 + 0 x 5 + 0 x 4 + 0 x 3 + 0 x 2 7x + 0 x 0 = 0 r2=[7,0,0,0,0,0,0,-7,0]; length(r2) ans = 9 počet prvků ve vektoru je vždy o 1 větší než stupeň polynomu roots(r2) ans = -0.90097 + 0.43388i -0.90097-0.43388i -0.22252 + 0.97493i -0.22252-0.97493i 1.00000 + 0.00000i 0.62349 + 0.78183i 0.62349-0.78183i 0.00000 + 0.00000i řešením je 8 kořenů počet kořenů stejný jako stupeň polynomu Polynomiální regrese polyfit(x, y, st) proloží množinu bodů o souřadnicích obsažených ve vektorech x a y polynomem stupně st. Výstupem jsou koeficienty polynomu zvoleného stupně st. Např.: Při měření byla získána data uvedená v tabulce.
t[s] 1 2 3 4 5 u[v] 5.5 43.1 100.2 190.7 218.4 t = [1:5]; u = [5.5, 43.1, 100.2, 190.7, 218.4] plot(t,u,'o') xlabel('t[s]') ylabel('u[v]') title('data z mereni') show Body na příslušných souřadnicích zobrazeny jako kolečka. Proložíme naměřené hodnoty polynomem 3. řádu a vykreslíme jeho průběh společně s naměřenými hodnotami do grafu. Nejprve vypočteme regresní polynom: regr = polyfit(t,u,3) regr = -6.8583 62.6964-110.3452 61.5800 tj.: regr(x) = 6.8583 x 3 + 62.6964 x 2-110.3452 x 1 + 61.5800 x 0 = 6.8583 x 3 + 62.6964 x 2-110.3452 x + 61.5800
Regresní křivku (zjištěný polynom) přidáme do grafu t t = 1 2 3 4 5 Pro zobrazení polynomu musíme zjemnit x-ovou osu (na ní zobrazeno t), vytvoříme vektor rt: rt = [0:0.05:6]; Vektor rt je z intervalu od 0 do 6 => dali jsme kousek i okolo. Pak vypočteme hodnoty polynomu pro všechna rt: hp = polyval(regr,rt); plot(t,u,'o',rt, hp, 'r') show Prokládané body i křivka (polynom) jsou v jednom grafu, polynom zobrazen červeně, aby byl dobře vidět ;-) Křivka není úplně v pořádku, zvláště na krajích intervalu. Zkusíme proložit naměřené hodnoty polynomem 4. řádu a vykreslíme jeho průběh společně s naměřenými hodnotami do grafu. regr_moc = polyfit(t,u,4) regr_moc = -4.5875 48.1917-164.7125 263.2083-136.6000
hp_moc = polyval(regr_moc,rt); plot(rt, hp_moc, 'g') show Prokládané body i křivky (polynomy) jsou v jednom grafu, polynom 3. st. zobrazen červeně, polynom 4. st. zobrazen zeleně. Dostali jsme nevhodnou regresní křivku, nesmyslnou. Ani ta červená není úplně v pořádku Zkusíme tedy ještě polynom ještě vyššího stupně. regr_jeste_vic = polyfit(t,u,6); hp_jeste_vic = polyval(regr_jeste_vic,rt); plot(t,u,'o',rt, hp, 'r',rt, hp_moc, 'g',... rt, hp_jeste_vic, 'k') show
Polynom 6. st. zobrazen černě, je to ještě horší, proto zkusíme proložit naměřené hodnoty polynomem 2. stupně: regr_mene = polyfit(t,u,2) regr_mene = 0.9714 51.5114-53.6400 hp_mene = polyval(regr_mene,rt); plot(t, u,'o',... rt, hp, 'r',... rt, hp_moc, 'g',... rt, hp_jeste_vic, 'k',... rt, hp_mene, 'm') show
Nejlépe by zde vyhověl polynom 2. stupně. Zkusíme ještě přímku (polynom 1. stupně): regr_min = polyfit(t,u,1) regr_min = 57.340-60.440 hp_min = polyval(regr_min,rt); regr_min = polyfit(t,u,1) hp_min = polyval(regr_min,rt); plot(t,u,'o', rt,hp_mene,'m', rt,hp_min,'c') legend('body','polynom 2.st.','polynom 1.st.','Location','SouthEast') show Polynom 1. stupně y(x) = 57.34 x 60.44 (rovnice přímky) Polynom 2. stupně y(x) = 0.9714 x 2 + 51.5114 x 53.6400 (rovnice paraboly) Polynom 1. stupně a polynom 2. stupně na intervalu od 0 do 6 mají velmi podobný průběh a jsou vhodné pro proložení těchto naměřených dat z tabulky.
Příklady viz http://edison.fel.zcu.cz publikované sešity Lze použít i další typy regresních křivek, nejen výše uvedené polynomy Např.: spline Použitelné funkce: interp1 1Dimenzionální interpolace interp2 2D interpolace interp3 3D interpolace interpn ndimenzionální interpolace interpft interpolace s využitím FFT Např. 1D interpolace pomocí spline fukcí spl_int = interp1(t,u,rt,'spline'); plot(t,u,'o',rt,spl_int, 'g')
Příklad: vlastní funkce pro polynomiální interpolaci Vstupní data: x-ové a y-ové souřadnice bodů (2 vektory), stupeň polynomu, kterým budou body proloženy. Nejprve provedeme jemnější dělení osy x pro zobrazení křivky (od minima z vektoru x do maxima z vektoru x s krokem vypočteným jako (max(x)-min(x))/100), poté získáme koeficienty polynomu n- tého stupně pro polynomiální interpolaci příkazem polyfit a vyčíslíme hodnoty polynomu pro všechny body z jemnějšího dělení osy x příkazem polyval. Nakonec vykreslíme graf. function prolozeni_bodu(x,y,n) xp=[min(x):((max(x)-min(x))/100):max(x)]; yn=polyval(polyfit(x,y,n),xp); plot(x,y,'*',xp,yn,'m') show endfunction Volání funkce: prolozeni_bodu([1:7],[1,2,2,4,3,4,5],3)
Vlastní uživatelské funkce opakování a pokračování Příklad výpočet obsahu a obvodu kruhu function [S,o]=obsah_obvod(r) S=pi.*(r.^2); o=2.*pi.*r; endfunction Volání funkce [obs,obv]=obsah_obvod(10) obs = 314.16 obv = 62.832 Některé z uvedených funkcí v MATLABu m-file File > New > M-file (editor) function [S,o]=obsah_obvod(r) S=pi.*(r.^2); o=2.*pi.*r; Soubor je nutné uložit. Save as: obsah_obvod.m
Volání funkce v příkazovém okně Command Window [obs,obv]=obsah_obvod(10) obs = 314.16 obv = 62.832 whos Name Size Bytes Class Attributes obs 1x1 8 double obv 1x1 8 double r lokální proměnná (s ukončením funkce zaniká), výstupní proměnné zůstanou zachovány Funkce bez výstupu function obsah_obvod2(r) S=pi.*(r.^2); o=2.*pi.*r; disp('obsah') disp(s) disp('obvod') disp(o) Volání funkce obsah_obvod2(5) Obsah 78.5398 Obvod 31.4159 r, S, o lokální proměnné (s ukončením funkce zanikají), výstupní proměnná není
whos => po příkazu whos se nevypíše nic Relační operátory == porovnání na rovnost (je rovno) ~= porovnání na nerovnost (není rovno) <, > je menší, je větší <=, >= je menší nebo rovno, je větší nebo rovno ~ negace (not) Příklady viz http://edison.fel.zcu.cz publikované sešity Logické operátory & a zároveň (and) nebo (or) xor exkluzivní nebo ~ negace (not) (3<5)&(4<6) ans = 1 (3<5)&(4>6) ans = 0 (3>5)&(4>6) ans = 0 Lze psát i takto: and((3>5),(4<6)) ans = 0 pravda a zároveň pravda pravda a zároveň nepravda nepravda a zároveň nepravda nepravda a zároveň pravda (3<5) (4<6) pravda nebo pravda ans = 1 (3<5) (4>6) pravda nebo nepravda ans = 1
(3>5) (4>6) nepravda nebo nepravda ans = 0 Lze psát i takto: or((3>5),(4<6)) nepravda nebo pravda ans = 1 xor((3<5),(4<6)) ans = 0 xor((3>5),(4<6)) ans = 1 xor((3>5),(4>6)) ans = 0 pravda nebo pravda exkluzivně pravda nebo pravda exkluzivně pravda nebo pravda exkluzivně ~0 negace 0 (nepravdy) je 1 (pravda) ans =1 ~1 negace 1 (pravdy) je 0 (nepravda) ans =0 ~5 negace 5 (pravdy) je 0 (nepravda) ans =0 ~(3<5) negace pravdy je nepravda ans =0 not(3<5) lze psát i takto, nepravda ans =0 Tedy pak: (~(3<5))&(4<6) nepravda a zároveň pravda ans = 0 Příklady viz http://home.zcu.cz/~lsroubov/ppel nebo http://portal.zcu.cz