17.04.2014 Views

Matlab Hogyan - Hidrodinamikai Rendszerek Tanszék

Matlab Hogyan - Hidrodinamikai Rendszerek Tanszék

Matlab Hogyan - Hidrodinamikai Rendszerek Tanszék

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Matlab</strong> <strong>Hogyan</strong><br />

c○GPL<br />

csaklogo.eps<br />

BME <strong>Hidrodinamikai</strong> <strong>Rendszerek</strong> <strong>Tanszék</strong><br />

belső használatra<br />

2005. február 17.


Tartalomjegyzék<br />

1. Alapok 5<br />

1.1. Az alapbeállítás menürendszere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

1.2. Parancssor, scriptek, függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

1.3. Script fájlok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

1.4. Függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

1.5. Lokális és globális változók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

1.6. Függvény mutatók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

2. Műveletek mátrixokkal, vektorokkal 10<br />

2.1. Alapműveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />

2.2. Lineáris Algebra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />

3. Ciklusutasítások, elágazások 13<br />

3.1. for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

3.2. while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

3.3. if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

3.4. switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

4. Nemlineáris feladatok 16<br />

4.1. Polinomok zérushelyei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

4.2. Optimalizációs feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16<br />

4.3. Nemlineáris függvények zérushelyei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

5. I/0 22<br />

5.1. Formázott kivitel (output) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />

5.1.1. Mátrix kiírása fájlba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

5.2. Formázott beolvasás (intput) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

5.2.1. Adatfájlból beolvasás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

6. Grafika 26<br />

1


TARTALOMJEGYZÉK 2<br />

7. Interpoláció 28<br />

7.1. Egydimenziós interpoláció . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28<br />

7.2. Többdimenziós interpoláció . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28<br />

8. Görbeillesztés 29<br />

9. Közönséges differenciálegyenletek (ODE) megoldása 30<br />

9.1. Kezdeti érték feladatok (IVP) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30<br />

9.1.1. Szabadsugár sebességeloszlása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

9.1.2. Egy merev feladat: a Van der Pol egyenlet . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

9.1.3. Eseménykezelés: vízcsepp alakja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33<br />

9.2. Perem érték feladatok (BVP) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

9.2.1. Couette áramlás sebességgradienssel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36<br />

10.Fourier analízis 38<br />

11.Példaprogramok 40<br />

11.1. Karakterisztikák módszere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

11.2. Nyíltfelszínű csatornaáramlás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43<br />

11.3. Függőlegesből vízszintesbe vezető ívben mozgó anyagdugó . . . . . . . . . . . . . . . . . . . . 45


Tárgymutató<br />

Fourier analízis<br />

fft demo.m , 36<br />

függvény kilincsek<br />

handle pelda.m , 7<br />

függvények<br />

masodfok fv.m , 6<br />

for<br />

demo for.m , 12<br />

formázott i/o<br />

demo io 1.m , 21<br />

demo io 2.m , 22<br />

görbeillesztés<br />

polyfit pelda.m , 27<br />

grafika<br />

demo 2d grafika.m , 24<br />

demo 3d grafika.m , 25<br />

kezdeti érték feladatok<br />

csepp.m , 32<br />

szabadsugar.m , 30<br />

van der Pol.m , 31<br />

lokális és globális változók<br />

masodfok fv2.m , 6<br />

masodfok fv3.m , 6<br />

nemlineáris egyenleternedszerek<br />

ventillator.m , 18<br />

optimalizálás<br />

fminbnd demo.m , 16<br />

fminsearch demo.m , 17<br />

peremérték feladatok<br />

couette.m , 34<br />

nyiltfelszin.m , 38<br />

scriptek<br />

masodfok script.m , 5<br />

while<br />

stirling.m, 13<br />

3


TÁRGYMUTATÓ 4<br />

Előszó<br />

Ez a rövid összefoglaló a Budapesti Műszaki és Gazdaságtudományi Egyetem <strong>Hidrodinamikai</strong> <strong>Rendszerek</strong><br />

<strong>Tanszék</strong>én (volt Vízgépek <strong>Tanszék</strong>) készült a <strong>Matlab</strong> programcsomag oktatásának és használatának<br />

megkönnyítésére. Igyekeztem nagyon egyszerű példákkal kezdeni és onnan fokozatosan bemutatni a program<br />

által kínált lehetőségeket, ugyanakkor sokkal inkább ugródeszkát és ötleteket szeretnék adni, mintsem egy<br />

magyar nyelvű dokumentációt. Mivel nem vagyok profi felhasználó, esetleg egyes programozástechnikai megoldásaim<br />

nem elegánsak/szépek/gazdaságosak, ezért nagyon fontosnak tartom a beépített Help használatát,<br />

ami szerintem annyira alapos és érthető, hogy akár azon keresztül is gyorsan el lehet sajátítani a programnyelvet.<br />

A példaprogramokkal kapcsolatban szívesen fogadok minden észrevételt, javaslatot.<br />

Ezen írásos anyag és a hozzá tartozó kiegészítő és magyarázó példaprogramok letölthetők a<br />

www.vizgep.bme.hu<br />

oldalról nyíló link segítségével. Meg szeretném jegyezni, hogy a <strong>Matlab</strong> scriptek nagy része kompatibilis<br />

a Unix/Linux rendszerek alatt hozzáférhető és ingyenes Octave programcsomaggal, mely letölthető pl. a<br />

www.octave.org honlapról. A dokumentáció magyarosított L A TEX-ben készült, ehhez további információk<br />

találhatók pl. a következő weblapon:<br />

http://ebizlab.hit.bme.hu/ tisanyi/latex/<br />

Az anyaggal kapcsolatos minden észrevételt, hibát, stb. szívesen fogadok.<br />

Hős Csaba<br />

hoscsaba@vizgep.bme.hu<br />

2004. június 27.<br />

Szeretném megköszönni Kiss Atillának és Pandula Zolinak a hasznos észrevételeket! Igyekeztem tanácsaik<br />

alapján javítani a magyarázatokon ill. kijavítottam jópár hibát (de azért még hagytam benne....). Újdonságak<br />

számít a Pneumatikus anyagszállítás példaprogram, Dr. Váradi Sándor tárgyához segítség.<br />

2005. február 15.


1. fejezet<br />

Alapok<br />

A program neve a Matrix Laboratory rövidítése, ami nagyon találó, ugyanis az egész program mátrixstruktúrákban<br />

gonolkodik. Ez alatt nem csupán a numerikus mátrixokra gonolunk hanem pl. egy grafikus<br />

ábra beállításai is ilyen struktúrában kerülnek tárolásra. Ez első hallásra furcsának tűnhet, de (a) ha<br />

kellő gyakorlatra teszünk szert, nagyban megkönnyíti a munkát és (b) úgysem tudunk mást csinálni, ilyenre<br />

írták a programot és kész. A csomag maga egy matematikai eljárásgyűjteményként is felfogható, ahol a<br />

felhasználónak kell a konkrét kódot megírnia, de mikor pl. egy sajárértékfeladathoz ér, egyszerűen meghív<br />

egy eljárást. Ebből fakad az a tulajdonság is, hogy a <strong>Matlab</strong> fő erőssége a numerika, analitikus számítások<br />

elvégzésére nem kényelmes (arra pl. ott a Mathematica vagy a Maple rendszer). A program másik hatalmas<br />

előnye a fejlett grafikai rendszer, mellyel könnyen és gyorsan elkészíthetők a grafikonok, ábrák és ezek<br />

gyakorlatilag minden fontosabb formátumban (.ps, .eps, .jpg, .gif, stb.) menthetők.<br />

Elöljáróban még annyit érdemes tudni a <strong>Matlab</strong>-ról, hogy a technikai numerikus számításoknak pillanatnyilag<br />

ez a nemzetközileg legjobban elfogadott és elterjedt programnyelve.<br />

1.1. Az alapbeállítás menürendszere<br />

A <strong>Matlab</strong> indításakor megjelenő menürendszer a következő elemekből áll (alapbeállításban):<br />

• Command Window: itt adjuk ki a parancsokat, pl. egyszerűbb számítások, függvényhívások vagy<br />

programok futtatása.<br />

• Launch Pad: hozzáférhetünk az installált Toolbox-okhoz (amik általában külön megvásárolható ’extra’<br />

eljárásgyűjtemények.)<br />

• Workspace: nyomon követhetjük az aktuális változókat, azok nagyságát, esetleg törölhetjük őket.<br />

Ez komolyabb programok futtatása esetén lehet fontos, ha tudni akarjuk a <strong>Matlab</strong> által lefogalt<br />

memóriaterületet.<br />

• Command History: az eddig kiadott parancsok.<br />

• Current Directory: aktuális könyvtár. Ha esetleg más könyvtárban elhelyezett eljárást, adatfile-t<br />

szeretnénk használni, a File ⇒ Set Path... menüben hozzáadhatjuk a saját könyvtárainkat.<br />

Az ablakkiosztást megváltoztathatjuk a View ⇒ Desktop Layout paranccsal (vagy kézzel). A paranccsorba<br />

máris begépelhetjük:<br />

>> 2*2,<br />

mire a program boldogan válaszol:<br />

5


1. FEJEZET. ALAPOK 6<br />

ans =<br />

4<br />

1.2. Parancssor, scriptek, függvények<br />

A <strong>Matlab</strong>-bal végzett számítások során - a nagyon egyszerű, zsebszámológép szintű számításoktól eltekintve<br />

- programozói szemlélet szükséges, azaz az ember gyakorlatilag egy kódot ír. A bonyolultságtól függően<br />

(elméletileg) háromféle megközelítése lehet egy számítási feladatnak:<br />

• Parancssor (ld. előző példa)<br />

• Script: egymás után, lépésről lépésre végrehajtandó parancsok, külön fájlban tárolva.<br />

• Egymásba ágyazott függvények, eljárások, stb., hasonlóan más programnyelvekhez (pl. Pascal, C, C++,<br />

stb.).<br />

1.3. Script fájlok<br />

Ez egy lineárisan, lépésről lépésre végrehajtandó utasítássorozatot tartalmazó fájl. Példaként lépjünk be<br />

a <strong>Matlab</strong> saját szerkesztőjébe (File ⇒ New ⇒ M-file) és készítsünk programot a másodfokú egyenlet<br />

megoldására.<br />

masodfok script.m<br />

a=1; b=2; c=1;<br />

D= b^2 - 4*a*c;<br />

if D>0<br />

uzenet=’valos gyokok:’;<br />

elseif D> masodfok_script<br />

komplex gyokok<br />

-1.0000e+000 +1.4142e+000i<br />

-1.0000e+000 -1.4142e+000i


1. FEJEZET. ALAPOK 7<br />

1.4. Függvények<br />

A függvényeket paraméterlistával hívjuk meg és visszatérési értékeik vannak. Az előző másodfokú példa<br />

függvényként:<br />

masodfok fv.m<br />

function gyokok = masodfok_fv(a,b,c)<br />

D=b^2-4*a*c;<br />

gyok1=(-b+sqrt(D))/2/a;<br />

gyok2=(-b-sqrt(D))/2/a;<br />

gyokok = [gyok1 gyok2];<br />

Magyarázat<br />

Ezt a fájlt már nem lehet akármilyen néven elmenteni, a fájlnévnek masodfok fv.m-nek kell lennie (azaz<br />

az eljárárs nevének). A függvény bemenete a, b és c, kimenete pedig a gyokok vektor. A függvény hívása<br />

parancssorból:<br />

>> mo=masodfok_fv(1,2,5);<br />

>> mo<br />

mo =<br />

-1.0000 + 2.0000i -1.0000 - 2.0000i<br />

A D diszkrimináns belső változó, a parancssorból nem érhető el:<br />

>> D<br />

??? Undefined function or variable ’D’.<br />

1.5. Lokális és globális változók<br />

Induljunk ki az előző esetből, ahol adott egy függvény és ezen belül definiáltunk változókat. Ha most azt<br />

szeretnénk, hogy valamilyen belső változóhoz másik függvény is hozzáférjen, két lehetőségünk van:<br />

• a függvények argumentumlistájában definiáljuk az értéket (ld. masodfok fv2.m)<br />

• globális változóként definiáljuk a változókat (ld. masodfok fv3.m)<br />

A következő program az argumentumlistában megkapott a, b és c változókat átadja a diszkr(a,b,c)<br />

eljárásnak, amely szintén az argumentumlistában veszi át az értékeket. A b2 és negyac véltozók csak a<br />

diszkr eljáráson belül hozzáférhetők.<br />

masodfok fv2.m<br />

function gyokok=masodfok_fv2(a,b,c)<br />

D=diszkr(a,b,c);<br />

gyok1=(-b+sqrt(D))/2/a;<br />

gyok2=(-b-sqrt(D))/2/a;


1. FEJEZET. ALAPOK 8<br />

gyokok = [gyok1 gyok2];<br />

function ertek=diszkr(a,b,c)<br />

b2=b^2;<br />

negyac=4*a*c<br />

ertek=b2-negyac;<br />

A masodfok fv3 eljárásnál az a, b és c változók globálisnak vannak deklarálva, így az összes olyan függvény<br />

hozzáfér ill. módosíthat rajtuk, amelyben szintén globálisként definiáltuk őket. (Tehát nem elég a ’főprogramban’<br />

globálisként definiálni, az összes olyan eljárásban meg kell tenni ugyanezt, ahol hozzá szeretnénk<br />

férni.)<br />

masodfok fv3.m<br />

function gyokok=masodfok_fv3<br />

global a b c<br />

a=1; b=2; c=3;<br />

D=diszkr;<br />

gyok1=(-b+sqrt(D))/2/a;<br />

gyok2=(-b-sqrt(D))/2/a;<br />

gyokok = [gyok1 gyok2];<br />

function ertek=diszkr<br />

global a b c<br />

b2=b^2;<br />

negyac=4*a*c;<br />

ertek=b2-negyac;<br />

1.6. Függvény mutatók<br />

A függvény mutatók segítségével függvényekre hivatkozhatunk. Tipikusan egy eljárás argumentumlistájában<br />

szerepelnek a változók mellett, pl. a beépített fzero(fun,x0) gyökkereső eljárás a fun változóban<br />

várja annak a függvénynek a nevét, melynek az x0-hoz közeli gyökét visszaadja. A mutatók használatának<br />

rejtelmeiről és előnyeiről a Help bő felvilágosítást ad. Tipikusan akkor érdemes használni, ha sokszor kell<br />

ugyanazt az eljárást lefuttatni különböző függvényeken és nem akarjuk mindig átírni a programot.<br />

Az alábbi egyszerű példa (handle pelda.m) szemlélteti a fentieket.<br />

handle pelda.m<br />

function handle_pelda<br />

a=2; b=3;<br />

fhandle=@osszead;<br />

c=feval(fhandle,a,b)<br />

fhandle=@szoroz;


1. FEJEZET. ALAPOK 9<br />

c=feval(fhandle,a,b)<br />

%------------------------<br />

function y=osszead(a,b)<br />

y=a+b;<br />

function y=szoroz(a,b)<br />

y=a*b;<br />

A program kimenete a parancssorban:<br />

>> handle_pelda<br />

c =<br />

5<br />

c =<br />

6


2. fejezet<br />

Műveletek mátrixokkal, vektorokkal<br />

2.1. Alapműveletek<br />

A <strong>Matlab</strong> használata során talán a mátrixműveletek megismerése és elsajátítása alapvető, hiszen az egész<br />

programnyelv erre épül (a név is innen ered: Matrix Laboratory). A mátrixok elemeit szögletes zárójel fogja<br />

közre, a sorok elemeit üres karakter választja el, az új sort pedig pontosvessző jelöli:<br />

>> A = [16 3 2 13; 5 10 11 8; 9 6 7 12; 4 15 14 1]<br />

A =<br />

16 3 2 13<br />

5 10 11 8<br />

9 6 7 12<br />

4 15 14 1<br />

A transzponálás felső vesszővel történik:<br />

>> A’<br />

ans =<br />

16 5 9 4<br />

3 10 6 15<br />

2 11 7 14<br />

13 8 12 1<br />

Egy mátrix elemeire pedig az alábbi módon hivatkozhatunk:<br />

>> A(2,3)<br />

ans =<br />

11<br />

Gyakran szükséges a mátrix egy sorát vagy oszlopát ’kivonni’, ez a kettőspont operátorral történik, a soroszlop<br />

konvenció figyelembevételével. Tehát a A(:,2) parancs a mátrix második oszlopát, a A(1,:) az első<br />

sorát adja eredményül. A kettőspont operátor jelentése lehet is, azaz:<br />

10


2. FEJEZET. MŰVELETEK MÁTRIXOKKAL, VEKTOROKKAL 11<br />

>> 0:pi/4:pi<br />

ans =<br />

0 0.7854 1.5708 2.3562 3.1416<br />

Fontos szerepet játszik még a pont operátor is, amely az elemenkénti műveleteket jelenti. Tehát ha A és B<br />

két mátrix, akkor A*B a hagyományos mátrixszorzatot adja, míg a A.*B az elemenkénti szorzatot.<br />

Mátrixokat beolvashatunk adatfájlból is a load parancs segítségével. Bármilyen szövegszerkesztőben (pl.<br />

Notepad) készítsük el az alábbi sorokat:<br />

1 4. -5.56<br />

344 -.454 33<br />

-0 1 1<br />

majd mentsük el ize.txt néven. A load parancs beolvassa az adatfile-t és a kiterjesztés levágásával kapott<br />

változóba teszi az adatokat:<br />

>> load ize.txt<br />

>> ize<br />

ize =<br />

1.0000 4.0000 -5.5600<br />

344.0000 -0.4540 33.0000<br />

0 1.0000 1.0000<br />

2.2. Lineáris Algebra<br />

A fontosabb parancsok rövid áttekintése:<br />

Például:<br />

Parancs Leírás<br />

zeros(n,m) n × m-es nullmátrixot hoz létre<br />

A+B<br />

Összeadás (elemenként)<br />

A*B<br />

Mátrixszorzás<br />

A’ Transzponált<br />

det(A)<br />

Determináns<br />

trace(A) Nyom (főátlóbeli elemek összege, spur)<br />

inv(A)<br />

Inverz<br />

eig(A)<br />

Sajátértékek, sajátvektorok<br />

poly(A) A karakterisztikus polinom együtthatói csökkenű kitevű szerint<br />

A.*B<br />

Elemenkénti mátrixszorzat<br />

A./B<br />

Elemenkénti osztás<br />

[L,U] = lu(A) A mátrix LU felbontása<br />

A\b Az Ax=b lineáris egyenletrendszer megoldása. Ugyanezt az<br />

eredményt adja az inv(A)*b parancs is. b-nek oszlopvektornak<br />

kell lennie!


2. FEJEZET. MŰVELETEK MÁTRIXOKKAL, VEKTOROKKAL 12<br />

>> [V,lambda]=eig(ize);<br />

>> ize*V(:,1)<br />

ans =<br />

-4.0124<br />

37.6942<br />

-0.9685<br />

>> lambda(1)*V(:,1)<br />

ans =<br />

-4.0124<br />

37.6942<br />

-0.9685<br />

Példaként számítsuk ki egy adott általános, térbeli feszültségi állapothoz tartozó főfeszültségeket és a főfeszültségi<br />

irányokat! A szilárdságtan tanítása szerint a T feszültségi tenzorhoz tartozó σ i főfeszültségek a<br />

feszültségi tenzor sajátértékei:<br />

T v i = σ i v i ,<br />

ahol v i jelöli a σ i -hez tartozó sajátvektort. A feszültségi mátrix diagonalizálható egy V transzformációs<br />

mátrixszal, melynek oszlopait a sajátvektorokból képezzük: V = [v 1 , v 2 , v 3 ] (az eig() parancs éppen ezt<br />

adja vissza):<br />

Valóban,<br />

⎛<br />

⎞<br />

σ 1 0 0<br />

V −1 T V = ⎝ 0 σ 2 0 ⎠ .<br />

0 0 σ 3<br />

>> inv(V)*ize*V<br />

ans =<br />

-37.9196 -0.0000 0.0000<br />

0.0000 37.1044 -0.0000<br />

-0.0000 -0.0000 2.3611


3. fejezet<br />

Ciklusutasítások, elágazások<br />

3.1. for<br />

Egy utasítás ismétlése megadott alkalommal.<br />

demo for.m<br />

n=4;<br />

a = zeros(n,n);<br />

for i = 1:n<br />

for j = 1:n<br />

a(i,j) = 1/(i+j -1);<br />

end;<br />

end;<br />

disp(a);<br />

A script futásának eredménye :<br />

>> demo_for<br />

1.0000 0.5000 0.3333 0.2500<br />

0.5000 0.3333 0.2500 0.2000<br />

0.3333 0.2500 0.2000 0.1667<br />

0.2500 0.2000 0.1667 0.1429<br />

3.2. while<br />

Egy utasítás ismétlése bizonytalan számú alkalommal, valamilyen feltétel teljesüléséig. Példaként számítsuk<br />

ki π értékét eps relatív pontossággal a Stirling-formula segítségével:<br />

π =<br />

lim<br />

n→∞<br />

( )<br />

1 n! e<br />

n 2<br />

2n n n .<br />

Fontos azonban, hogy n!, n n és e n értékét ne közvetlenül számítsuk ki a túlcsordulás veszélye miatt, hanem<br />

az alábbi alakban:<br />

n! e n<br />

n n<br />

= e n × 2e<br />

n × 3e (n − 1)e<br />

× · · · × × e.<br />

n n<br />

13


3. FEJEZET. CIKLUSUTASÍTÁSOK, ELÁGAZÁSOK 14<br />

Az eljárást függvényként definiáljuk kimenet nélkül, max rel hiba bemenettel stirling.m :<br />

stirling.m<br />

function stirling(max_rel_hiba)<br />

fprintf(’\n pi szamitasa Stirling-fromulaval \n’);<br />

eps=1.e5;<br />

n=1;<br />

while eps>max_rel_hiba<br />

a=1;<br />

for i=1:n<br />

a=a*i/n*exp(1);<br />

end;<br />

pii=a^2/2/n;<br />

eps=abs(pi-pii)/pi;<br />

n=n+1;<br />

end;<br />

fprintf(’\n n = %d \n kozelito ertek: %10.8f \n ...<br />

hiba: %10.8e \n \n’,n,pii,eps);<br />

A futtatás eredménye:<br />

>> stirling(1e-4)<br />

pi szamitasa Stirling-fromulaval<br />

n = 1668<br />

kozelito ertek: 3.14190677<br />

hiba: 9.99850013e-005<br />

Az eredmények:<br />

eps 10 −1 10 −2 10 −3 10 −4<br />

n 3 18 168 1668<br />

3.3. if<br />

A parancsok feltételes elvégzése. Szintaxis:<br />

if kifejezés1<br />

parancs1;<br />

parancs2;<br />

elseif kifejezés2<br />

parancsok<br />

else<br />

parancsok<br />

end<br />

Természetesen az elseif rész kihagyható, az else sem kötelező egyszintes if esetén. A feltételvizsgálatnál<br />

több kifejezés is összekapcsolható a logikai és &, vagy | ill. a nem ~ operátorokkal. Majd ha lesz valami jó,<br />

nemtriviális ötletem példaprogramra, írok egyet.


3. FEJEZET. CIKLUSUTASÍTÁSOK, ELÁGAZÁSOK 15<br />

3.4. switch<br />

Kapcsolás egy kifejezés több, előre megadott értéke esetén (ez általában megoldható if-el is, de akkor az<br />

eseményvizsgálat lassítja a programot). Tegyük fel pl., hogy adva van egy nap nevű string változónk:<br />

switch nap<br />

case {’hetfo’,’szerda’}<br />

program=’mozi’<br />

case ’kedd’<br />

program=’szinhaz’<br />

case ’pentek’, program=’koncert’<br />

otherwise, program=’Meg nem tudom...’<br />

end<br />

C/C++ programozók figyelmébe: a <strong>Matlab</strong>-ban nem kell break parancs minden case után, csak az aktuális<br />

parancsok kerülnek hívásra.


4. fejezet<br />

Nemlineáris feladatok<br />

4.1. Polinomok zérushelyei<br />

Legyen adva az alábbi m-edrendű polinom:<br />

p(x) =<br />

m∑<br />

a i x i = a 0 + a 1 x + a 2 x 2 + a 3 x 3 + · · · + a m x m .<br />

i=0<br />

Ekkor a fenti polinomnak pontosan m darab zérushelye van (multiplicitásokkal számolva), valósak és esetleg<br />

komplexek. A gyököket a roots(a) paranccsal kereshetjük meg, ahol a egy vektor, mely az együtthatókat<br />

tartalmazza x hatványai szerint csökkenő sorrendben, azaz a = [a m , a m−1 , . . . a 1 , a 0 ]. A függvény kimenete<br />

szintén egy vektor, mely a gyököket tartalmazza. Példaként számítsuk ki a<br />

polinom zérushelyeit (ahol i a képzetes egységgyök):<br />

p(x) = −4 + (3 + 5i)x − 2ix 2 + x 3<br />

>> a=[ 1 -2i 3+5i -4]; roots(a)<br />

ans =<br />

-1.2403 + 3.4313i<br />

1.1345 - 0.5762i<br />

0.1058 - 0.8551i<br />

4.2. Optimalizációs feladatok<br />

Logikailag ez a feladat megelőzi a nemlineáris egyenletrendszerek zérushelyeinek kérdését, ugyanis azokat is<br />

erre fogjuk visszavezetni.<br />

Nézzük előre az egy ismeretlen szerinti optimalizációt! Keressük azt az x 0 értéket, melyre<br />

f(x 0 ) = Min! és x 1 ≤ x 0 ≤ x 2 .<br />

(Egy maximumfeladatot analóg módon, −f(x 0 ) minimumfeladataként lehet megfogalmazni.) A alkalmazandó<br />

16


4. FEJEZET. NEMLINEÁRIS FELADATOK 17<br />

fminbnd.eps<br />

4.1. ábra. Az f(x) = (x − 1) 2 sin(10x) függvény és a két megtalált minimumhely.<br />

<strong>Matlab</strong> függvény a fminbnd(fun,x1,x2), mely a fun függvény x1 és x2 közötti egyik, lokális minimumhelyét<br />

próbálja megkeresni. Példaként keressük meg a<br />

f(x) = (x − 1) 2 sin(10x)<br />

függvény minimumát az 0 ≤ x ≤ 2 intervallumon! A kapcsolódó példaprogram (fminbnd demo.m) két<br />

iterációt indít, egyet a 0 ≤ x ≤ 2 intervallumon, másikat a 1 ≤ x ≤ 2-en. Mint az a 4.1 ábrán látszik,<br />

két különböző minimumhelyet talált meg az eljárás, ami erősen óvatósságra int a könnyelmű használattal<br />

kapcsolatban. A függvényhívás bal oldalán elegendő egy érték is (tehát pl. x1 az [x1,y1] helyett), ekkor<br />

csak minimumhely koordinátáját adja meg az eljárás. Az optimset paranccsal különböző opciókat állíthatunk<br />

be, itt az összes iterációs lépésről lekérdeztük az információt. Hasonlóan beállítható a tolerancia (TolX), a<br />

maximális iterációk száma (MaxIter) és a függvény kiértékeléseinek maximális száma (MaxFunEvals). A<br />

grafikával kapcsolatban a részleteket a 6. fejezet tartalmazza.<br />

function fmin1D_demo<br />

fmin1D demo.m<br />

[x1,y1] = fminbnd(@fv,0,2);<br />

[x2,y2] = fminbnd(@fv,1,2,optimset(’Display’,’iter’));<br />

fplot(@fv,[0,2]), hold on<br />

plot(x1,y1,’rx’,’Markersize’,15), hold on<br />

plot(x2,y2,’r+’,’Markersize’,15), hold off<br />

xlabel(’x’), ylabel(’y’), grid on<br />

function y=fv(x)<br />

y=(x-1)^2*sin(10*x);<br />

A program kimenete:<br />

>> fmin1D_demo


4. FEJEZET. NEMLINEÁRIS FELADATOK 18<br />

Func-count x f(x) Procedure<br />

1 1.38197 0.138606 initial<br />

2 1.61803 -0.173796 golden<br />

3 1.76393 -0.546067 golden<br />

4 1.8541 -0.22152 golden<br />

5 1.73995 -0.543538 parabolic<br />

6 1.75356 -0.549226 parabolic<br />

7 1.75369 -0.549227 parabolic<br />

8 1.75381 -0.549228 parabolic<br />

9 1.75384 -0.549228 parabolic<br />

10 1.75377 -0.549228 parabolic<br />

Ha egy többváltozós függvény minimum- vagy maximumhelyeit szeretnénk megkeresni, az fminsearch<br />

eljárást kell használnunk. Az fminserach demo program az ún. Rosenbrock-féle banánfüggvény minimumát<br />

keresi:<br />

f(x, y) = 100(y − x 2 ) 2 + (1 − x) 2 ,<br />

mely a minimumkereső eljárások egyik tesztfeladata. A minimumhely koordinátái (x, y) = (1, 1), az eljárást<br />

az (x 0 , y 0 ) = (−1.2, 1) pontból indítjuk, így annak át kell kelnie a két pont közti ”<br />

csúcson” (ld. 4.2 ábra).<br />

function fmin2D_demo<br />

fmin2D demo.m<br />

x0=-1.2; y0=1; z0=banan([x0 y0]);<br />

[x,z] = fminsearch(@banan,[x0,y0])<br />

ezsurf(’100*(y-x^2)^2+(1-x)^2’,[-1.3,1.3,0.5,1.5]), hold on<br />

plot3(x0,y0,z0,’r*’,’Markersize’,30), hold on<br />

plot3(x(1),x(2),z,’y*’,’Markersize’,30), hold off<br />

xlabel(’x’), ylabel(’y’), zlabel(’z’), grid on<br />

function y=banan(x)<br />

y=100*(x(2)-x(1)^2)^2+(1-x(1))^2;<br />

4.3. Nemlineáris függvények zérushelyei<br />

Itt megint azzal az egyszerű esettel kezdjük, amikor egyváltozós nemlineáris függvény zérushelyét kell megtalálnunk.<br />

A rendelkezésünkre álló beépített <strong>Matlab</strong> függvény az fzero(fun,x0), mely a fun függvény<br />

zérushelyét keresi x0 közelében. Használata teljesen analóg az fminbnd használatával. Amennyiben x0 egy<br />

vektor, pl. [x1 x2], az eljárás feltételezi, hogy fun(x1) és fun(x2) előjele különböző (ellenkező esetben<br />

hibaüzenettel tér vissza) és az adott intervallumon azt a pontot keresi meg, ahol fun előjelet vált.<br />

Meglepő módon, nincsen 1 az fminsearch-el analóg eljárárás, azaz olyan függvény, mely nemlineáris egyenletrendszerek<br />

zérushelyeit keresi meg. Egy egyszerű trükkel azonban könnyen felhasználhatjuk az fminsearch<br />

1 azaz én nem találtam meg...


4. FEJEZET. NEMLINEÁRIS FELADATOK 19<br />

banan.eps<br />

4.2. ábra. A banánfüggvény, az iteráció kiindulópontja (piros csillag) és a megtalált minimumhely (sárga<br />

csillag).<br />

eljárást ilyen célra. Legyen adva ugyanis az alábbi nemlineáris egyenletrendszer:<br />

F 1 (x 1 , x 2 , . . . , x n ) = 0,<br />

F 2 (x 1 , x 2 , . . . , x n ) = 0,<br />

.<br />

F n (x 1 , x 2 , . . . , x n ) = 0.<br />

Ha most valamilyen (x 0 1, x 0 2, . . . , x 0 n) értékeket behelyettesítünk a fenti egyenletbe, nyilván nem fog teljesülni,<br />

hanem valamilyen nemnulla hiba lesz az eredmény: F i (x 0 1 , x0 2 , . . . , x0 n ) = r i. Ezek után a fenti egyenlet zérushelyének<br />

koordinátáira igaz lesz, hogy<br />

R(x 1 , x 2 , . . . , x n ) =<br />

n∑<br />

ri 2<br />

i=1<br />

= Min! = 0.<br />

Példaként tekintsük az alábbi differenciálegyenlet rendszert (DER), mely egy sorbakapcsolt ventillátor, cső,<br />

tartály és fojtás dinamikus viselkedését írja le:<br />

d<br />

dt Q<br />

d<br />

dt ∆p<br />

= f(Q) − ∆p = F 1(Q, ∆p)<br />

= Q − a√ ∆p = F 2 (Q, ∆p),<br />

ahol a ventillátor jelleggörbéjét a<br />

f(Q) = 0.27 + 0.18<br />

(1 + 3 2 (4Q − 1) − 1 )<br />

2 (4Q − 1)3<br />

(4.1)<br />

függvény írja le. Ki szeretnénk számolni a DER egyensúlyi helyzeteit, melyekben a rendszer nyugalomban van,<br />

azaz minden változó idő szerinti deriváltja zérus. Tehát meg kell keresnünk az F 1 (Q, ∆p) = 0, F 2 (Q, ∆p) = 0<br />

nemlineáris egyenletrendszer megoldásait. Grafikailag a megoldást a ventillátor jelleggörbe ∆p v = f(Q)<br />

és a fojtás jelleggörbe ∆p f = 1<br />

a<br />

Q 2 metszéspontja adja. A kapcsolódó <strong>Matlab</strong> program ventillator.m<br />

2<br />

közvetlenül a nemlineáris egyenletrendszert oldja meg az előzőekben leírt séma szerint.


4. FEJEZET. NEMLINEÁRIS FELADATOK 20<br />

ventillator.eps<br />

4.3. ábra. Ventillátor- és fojtásjelleggörbe ill. a kiszámolt metszéspont.<br />

1 function ventillator<br />

ventillator.m<br />

2<br />

3 a=0.6;<br />

4<br />

5 q0=0.5; dp0=0.6;<br />

6 [x,z] = fminsearch(@hiba,[q0,dp0],[],a);<br />

7<br />

8 xx=0:0.01:0.9;<br />

9 yv=jelleggorbe(xx);<br />

10 yf=1/a^2*xx.^2;<br />

11 plot(xx,yv,xx,yf,x(1),x(2),’ro’)<br />

12 axis([0 0.9 0 0.8]), grid on<br />

13 xlabel(’Q’), ylabel(’\Delta p’)<br />

14<br />

15 function R=hiba(x,a)<br />

16<br />

17 Q =x(1); dp=x(2);<br />

18 r1 = jelleggorbe(Q)-x(2);<br />

19 r2 = Q-a*sqrt(dp);<br />

20 R=r1^2+r2^2;<br />

21<br />

22 function dp=jelleggorbe(q)<br />

23<br />

24 dp=0.27+0.18*(1+1.5*(4*q-1)-0.5*(4*q-1).^3);<br />

Külön magyarázatot igényel a 6. sorban az üres szögletes zárójel. Az a változó szeretnénk a főprogram 3.<br />

sorában beállítani és aztán átadni az összes többi eljárásnak is. Ezt megtehetjük az fminsearch argumentumlistájában,<br />

de ott a kezdeti értékek után az options változónak kell állnia és csak azután kerülhetnek<br />

be az egyéb extra argumentumok. Ezért, bár semmilyen opciót nem kívánunk igénybe venni, ki kell tennünk<br />

a szögletes zárójelet és csak azután kerülhet be az a változó.<br />

Ártatlannak tűnhet még a 24. sor végén kitett pont a ∧3 előtt, azonban ez nagyon is fontos. Ugyanis ha a<br />

jellegörbe eljárást csak skalár értékkel hívnánk meg, ez a pont nem kellene, de a 9. sorban az xx vektor


4. FEJEZET. NEMLINEÁRIS FELADATOK 21<br />

szerepel az argumentumban és így az eljárásnak egy vektort kell a harmadik hatványra emelnie a 24. sorban.<br />

Természetesen ezt elemenként szertnénk elvégezni, ezért ki kell tenni a pontot. A grafikával kapcsolatban a<br />

részleteket a 6. fejezet tartalmazza.


5. fejezet<br />

I/0<br />

Legegyszerűbben a sorvégi pontosvessző elhagyásával vagy a disp() paranccsal jeleníthetjük meg a parancsablakban<br />

egy változó, string, stb. értékét. Formázott adatkivitelt a C nyelvhez hasonló operátorokkal<br />

valósíthatunk meg.<br />

A formázás szintaktikája a következő:<br />

io.eps<br />

Fontosabb értékek:<br />

zászló + A szám előjelét mindig kiírja.<br />

- Balra igazítja a számot a mezőben.<br />

0 A lefoglalt mezőben a kihasználatlan karaktereket 0-val tölti fel<br />

(és nem az alapértelmezett szóközzel).<br />

mezőszélesség<br />

Az eredménynek lefoglalt karakterek száma.<br />

pontosság<br />

A tizedesvesszőtől jobbra megjelenítendő jegyek száma.<br />

formázás módja %d Decimális megjelenítés (egész típus számára).<br />

%e Exponenciális (tudományos) formátum.<br />

%f Lebegőpontos megjelenítés.<br />

%g Legjobb formátum az adott szám számára.<br />

%s String megjelenítése.<br />

Pozicionálás mezők között:<br />

\n új sor<br />

\t tabulátor<br />

5.1. Formázott kivitel (output)<br />

A formázott adatkivitel legfontosabb parancsa az fprintf(), amellyel mind képernyőre, mind fájlba írhatunk:<br />

22


5. FEJEZET. I/0 23<br />

képernyőre:<br />

fprintf(formátum,a,b,c)<br />

Itt a formátum egy sztring, pl.<br />

’a=%g \t b=%+10.7e vegul egy egesz: c=%d es jon a sorleptetes:\n’<br />

fájlba:<br />

azonosító = fopen(filenév,jogok)<br />

fprintf(azonosító,formátum,a,b,c)<br />

fclose(azonosító)<br />

Az fopen() parancs megnyitja a filenév állományt a megadott jogokkal (amit el lehet hagyni, ekkor csak<br />

olvasásra). Megnyitás után az fprintf() a már leírt szintaktikával működik, de az argumentumlista elején<br />

a kimenet azonosítóját meg kell adni. Végül pedig lezárjuk a fájlt az fclose() paranccsal.<br />

A jogok lehetnek:<br />

r olvasás (read), ez az alapbeállítás.<br />

w file megnyitása/létrehozása írásra (write), már létezű file esetén a<br />

tartalom elvész.<br />

a létező file megnyitása/létrehozása hozzáírásra (append).<br />

r+ file megnyitása írásra és olvasásra.<br />

w+ file megnyitása/létrehozása írásra és olvasásra, már létezű file<br />

esetén a tartalom elvész.<br />

a+ file megnyitása/létrehozása írásra és olvasásra, már létezű file<br />

esetén a tartalom nem vész el, az új adatokat a végéhez fűzi.<br />

5.1.1. Mátrix kiírása fájlba<br />

A kovetkezo program formazva, elemrol elemre menti el M mátrix tartalmat (demo io 1.m).<br />

demo io 1.m<br />

% Az adatok:<br />

M= [ 1.2345 2.56 3.009 -4.01<br />

-5.45e4 6245 76543 -453458<br />

9 8 1.23e-5 0];<br />

% Fajlnyitas<br />

adatfajl = fopen(’demo_io_1.dat’,’w’);<br />

% Iras tabulatorral tagolva, legalkalmasabb formatumban<br />

for i=1:length(M(:,1))<br />

for j=1:length(M(1,:))<br />

fprintf(adatfajl,’%g \t’,M(i,j));<br />

end;<br />

fprintf(adatfajl,’\n’);<br />

end;<br />

% Kihagyunk ket sort....<br />

fprintf(adatfajl,’\n\n’);<br />

% Iras fix szelesen, tabulatorral, tudomanyos formatumban


5. FEJEZET. I/0 24<br />

for i=1:length(M(:,1))<br />

for j=1:length(M(1,:))<br />

fprintf(adatfajl,’%+10.5e \t’,M(i,j));<br />

end;<br />

fprintf(adatfajl,’\n’);<br />

end;<br />

% Fajl lezarasa<br />

fclose(adatfajl);<br />

5.2. Formázott beolvasás (intput)<br />

A legegyszerűbb eset az, ha a beolvasandó fájlban struktúráltan, mátrixszerűen, csak numerikus értékek<br />

vannak, ekkor megúszhatjuk egy load() paranccsal. Bonyolultabb esetben (pl. mérési eredmények) azonban<br />

a fájlnak fejléce van, nem egy mátrixot akarunk kiolvasni hanem több számot, stb...<br />

5.2.1. Adatfájlból beolvasás<br />

Tegyük fel pl., hogy az adatfájlunk így néz ki (adatok.dat):<br />

adatok.dat<br />

Meres helye: BME Vizgepek labor<br />

Meres ideje: 2002.12.25<br />

Merest vegezte: Hos Csaba<br />

Mintaveteli frekvencia: 10200 Hz<br />

adatfile felepitese: t,p1,p2<br />

0.1 1.1 2.1<br />

0.2 1.3 2.01<br />

0.3 1.6 1.9<br />

0.4 1.8 1.4<br />

Ekkor az alabbi script segitsegevel kiolvashatunk mindent (demo io 2.m):<br />

fp=fopen(’adatok.dat’,’r’);<br />

demo io 2.m<br />

% A 13. karaktertol a sorvegig olvassuk a nevet:<br />

temp=fseek(fp,13,’bof’); % bof >> beginning of file<br />

hely=fgetl(fp);<br />

% az aktualis poziciotol sorvegig<br />

disp(hely);<br />

temp=fseek(fp,13,’cof’); % cof >> current position in the file<br />

datum=fscanf(fp,’%4f.%2f.%2f\n’);<br />

% a datum 3 elemu vektorban van az ev, honap, nap<br />

disp(datum’);<br />

temp=fseek(fp,16,’cof’); % cof >> current position in the file<br />

nev=fgetl(fp);<br />

disp(nev);


5. FEJEZET. I/0 25<br />

temp=fseek(fp,24,’cof’); % cof >> current position in the file<br />

frek=fscanf(fp,’ %g Hz’);<br />

disp(frek);<br />

% 2 sort ugrunk<br />

for i=1:2<br />

temp=fgetl(fp);<br />

end;<br />

% 3 oszlopu matrixot olvasunk, ameddig csak lehet (>> inf)<br />

A=fscanf(fp,’%g %g %g’,[3 inf]);<br />

A=A’; % igy lesz jo...<br />

disp(A);<br />

% lezarjuk az adatfajlt, ahogy azt illik<br />

fclose(fp);


6. fejezet<br />

Grafika<br />

A grafikák készítését is áthatja a vektor-alapú szemlélet: pl. a plot(x,y) parancs az x és y vektorok által<br />

megadott pontokat rajzolja ki. Parancssorból (scriptből) az ábra formázása elkészíthető és a már elkészült<br />

ábra is tovább alakítható, de a grafikus ablakon beállított formázások újrarajzoláskor elvesznek. A rajzok<br />

elmenthetőek xxx.fig formátumban, ami a <strong>Matlab</strong>-bal bármikor megnyitható és tovább alakítható. Exportálni<br />

is lehet számos grafikai típusban (.bmp, .gif, .jpg, .eps, .ps), de ezek utólag már nem alakíthatóak (<strong>Matlab</strong>bal).<br />

Tehát az ábrákat érdemes először xxx.fig formátumban teljesen elkészíteni és csak utána exportálni.<br />

Íme egy kis példa 2D grafikára (demo 2d grafika.m) :<br />

sin.eps<br />

6.1. ábra. A demo 2d grafika.m script kimenete.<br />

demo 2d grafika.m<br />

% x és y vektorok elkeszitese:<br />

x = -pi:.1:pi;<br />

y = sin(x).*cos(x);<br />

% Rajzolas:<br />

26


6. FEJEZET. GRAFIKA 27<br />

plot(x,y,’r-.’);<br />

%Beallitasok:<br />

grid; xlabel(’-\pi \leq \phi \leq \pi’); ylabel(’sin(\phi) cos(\phi)’);<br />

title(’Az y(\phi)=sin(\phi)cos(\phi) fuggveny grafikonja’)<br />

% x tengelyen a jelolo atallitasa:<br />

set(gca,’XTick’,-pi:pi/2:pi);<br />

set(gca,’XTickLabel’,{’-pi’,’-pi/2’,’0’,’pi/2’,’pi’});<br />

Egy másik példa 3D grafikára (demo 3d grafika.m) :<br />

demo 3d grafika.m<br />

[X,Y] = meshgrid([-2:0.1:2]);<br />

Z = sin(X.*Y);<br />

% Elso abra rajzolasa (vonalasan)<br />

figure(1);<br />

plot3(X,Y,Z);<br />

% Masodik abra rajzolasa (feluletkent)<br />

figure(2);<br />

ezmeshc(’sin(x*y)’,[-2,2,-2,2]);<br />

xlabel(’x’); ylabel(’y’); zlabel(’z’);<br />

title(’A sin(xy) fuggveny.’);<br />

sinxy.eps<br />

6.2. ábra. A demo 3d grafika.m script második ablaka.


7. fejezet<br />

Interpoláció<br />

7.1. Egydimenziós interpoláció<br />

Egydimenziós interpoláció esetén az yi = interp1(X,Y,xi,módszer) eljárást használjuk, ahol X és Y tartalmazza<br />

az adatokat és az xi pontokban szeretnénk az interpolált értékeket megkapni. A beépített módszerek:<br />

’nearest’<br />

’linear’<br />

’spline’<br />

’pchip’<br />

’v5cubic’<br />

Legközelebbi szomszéd” interpoláció.<br />

”<br />

Lineáris interpoláció (alapbeállítás).<br />

Harmadfokú spline interpoláció.<br />

Harmadfokú szakaszos Hermite interpoláció.<br />

Harmadfokú interpoláció az <strong>Matlab</strong> 5-bűl.<br />

A ’nearest’, ’linear’, és ’v5cubic’ módszerek esetén interp1(X,Y,xi,módszer) NaN (Not-a-Number) üzenettel<br />

tér vissza xi azon elemeire, melyek az x értékei által meghatározott szakaszon kívül esnek. A többi módszer<br />

ez esetben extrapolál.<br />

7.2. Többdimenziós interpoláció<br />

Kétdimenziós interpoláció esetén az<br />

zi = interp2(x,Y,z,xi,yi,módszer)<br />

eljárást használhatjuk, teljesen analóg módon az előzőekkel. Mindezek egyszerű általánosítása a<br />

vi = interp3(x,Y,z,v,xi,yi,zi,módszer)<br />

háromdimenziós és a<br />

yi = interp3(x1,x2,x3,y,x1i,x2i,x3i,módszer)<br />

sokdimenziós interpoláció.<br />

28


8. fejezet<br />

Görbeillesztés<br />

Az alap <strong>Matlab</strong> csomagban csak a polinomiális görbeillesztés található meg előre kész eljárás formájában. A<br />

p = polyfit(x,y,n)<br />

parancs eredménye p vektor, mely az n-edfokú polinom együtthatóit tartalmazza csökkenű kitevő szerint.<br />

Ha egyszer ezeket az együtthatókat kiszámítottuk, tetszőleges xi pontokban<br />

yi = polyval(p,xi)<br />

paranccsal számíthatjuk ki a függvény értékét.<br />

A polyfit pelda.m program az f(x) = x 2 sin(5x) függvényhez illeszt poinomot a (0, π/2) intervallumon,<br />

majd kiszámítja a kapott polinom eltérését az osztáspontokban a norm parancs segítségével.<br />

polyfit pelda.m<br />

function polyfit_pelda<br />

X=0:0.01:pi/2; Y=sin(5*X).*X.^2;<br />

for i=1:1:10<br />

p=polyfit(X,Y,i);<br />

yy=polyval(p,X);<br />

hiba=norm(Y-yy,2);<br />

fprintf(’\nfokszam: %2d, hiba=%5.3e’,i,hiba);<br />

end<br />

>> polyfit_pelda<br />

fokszam: 1, hiba=9.571e+00<br />

fokszam: 2, hiba=6.386e+00<br />

fokszam: 3, hiba=2.374e+00<br />

fokszam: 4, hiba=2.341e+00<br />

fokszam: 5, hiba=8.731e-01<br />

fokszam: 6, hiba=2.577e-01<br />

fokszam: 7, hiba=1.375e-01<br />

fokszam: 8, hiba=1.321e-02<br />

fokszam: 9, hiba=1.030e-02<br />

fokszam: 10, hiba=4.593e-04<br />

29


9. fejezet<br />

Közönséges differenciálegyenletek<br />

(ODE) megoldása<br />

Amennyiben közönséges differenciálegyenleteket szeretnénk numerikusan megoldani, az első lépés mindenképpen<br />

az, hogy elsőrendű alakra kell átírni az ún. Cauchy-átírással. Ez általánosan úgy történik, hogy ha adva van<br />

a<br />

d (n) z<br />

(<br />

)<br />

dx n = G x; z (n−1) , z (n−2) , . . . , z<br />

függvény, akkor új változókat vezetünk be: y 1 = z, y 2 = z ′ = z (1) , y 3 = z ′′ = z (2) ,...,, y n−1 = z (n−1) . Így<br />

megoldandó a<br />

⎛ ⎞ ⎛<br />

⎞<br />

y 1 F 1 (x; y 1 , y 2 , . . . , y n )<br />

d<br />

y 2<br />

⎜ ⎟<br />

dx ⎝ . ⎠ = F 2 (x; y 1 , y 2 , . . . , y n )<br />

⎜<br />

⎟<br />

⎝ . ⎠<br />

y n F n (x; y 1 , y 2 , . . . , y n )<br />

közönséges differenciálegyenlet rendszer (a Cauchy-átírás a példákon keresztül könyebben megérthető). Kezdeti<br />

érték feladatról beszélünk, ha az y(x 0 ) = ( y 0 1 , y0 2 , . . . , y0 n)<br />

kezdeti értékből kiindulva kíváncsiak vagyunk<br />

y(x 1 ) értékére. Peremérték feladatról beszélünk, ha y(x 0 ) mellett elő van írva y(x 1 ) is, ekkor azonban a megoldás<br />

létezéséhez általában meg kell adni a DE-ben egy szabad paramétert is. A DE jobb oldalához tartozó<br />

Jacobi mátrix elemeit következőképpen számíthatjuk:<br />

J ij = ∂F i(x; y 1 , y 2 , . . . , y n )<br />

∂y j<br />

ahol i, j = 1 . . . n.<br />

9.1. Kezdeti érték feladatok (IVP)<br />

A megoldó szintaktikája a következő:<br />

[t,y] = megoldó(odefun,tspan,y0,options)<br />

ahol megoldó a numerikus módszert jelöli, odefun a DE jobb oldalát meghatározó függvényt, tspan vektor<br />

a megoldás intervallumát ([x_eleje x_vége]), y0 a kezdeti feltételek vektora és options a nem kötelező,<br />

esetleges további beállításokat tartalmazza.<br />

A numerikus megoldók az alábbiak lehetnek:<br />

30


9. FEJEZET. KÖZÖNSÉGES DIFFERENCIÁLEGYENLETEK (ODE) MEGOLDÁSA 31<br />

NEM Merev feladatok:<br />

ode45<br />

ode23<br />

ode113<br />

Explicit, egylépéses, negyedrendű Runge-Kutta képlet. Általában<br />

ez lehet az első próbálkozás.<br />

Szintén egylépéses Runge-Kutta típusú módszer. Enyhén<br />

merev feladatoknál gazdaságosabb lehet, mint az ode45.<br />

Változó rendű, többlépéses Adams-Bashforth-Moulton PE-<br />

CE megoldó. Ha nagyon pontos megoldásra van szükség<br />

vagy a DE nagyméretű (a jobb oldal kiszámítása drága),<br />

gazdaságosabb lehet, mint az ode45.<br />

Merev (stiff) feladatok:<br />

ode15s<br />

ode23s<br />

ode23t<br />

ode23tb<br />

Változó rendű többlépéses módszer. Ha az ode45 nem<br />

működik és gyanús, hogy ez a DE merevsége miatt van,<br />

ez lehet az elsű nekifutás.<br />

Ezek is mind merev megoldók, a pontos dokumentáció a<br />

Help-ben megtalálható.<br />

Az options változó fontosabb lehetőségei:<br />

Hiba (pontosság) beállítása<br />

RelTol<br />

AbsTol<br />

NormControl<br />

Relatív hiba.<br />

Abszolút hiba.<br />

A relatív hibát hibrid módon, a megoldás normájával<br />

számítja.<br />

Megoldó kimenet<br />

OutputFcn<br />

OutputSel<br />

Refine<br />

Stats<br />

A felhasználó által beállítható kimeneti függvény (ilyen lehet<br />

pl. az odeplot függvény).<br />

A megoldásmátrix mely indexeit adja át a kimeneti fv.-nek.<br />

Ha a megoldó túl nagyokat lép és nem vagyunk megelégedve<br />

a megoldás felbontásával, ezzel átállíthatjuk az elmentett<br />

lépések sűrűségét, így a program maga nem lassul.<br />

Statisztika<br />

Jacobi mátrix<br />

Jacobian A Jacobi mátrixot explicit módon, függvény alakjában a<br />

felhasználó definiálja.<br />

JPattern A Jacobi mátrix nemnulla elemei helyére 1-et, máshova 0-t<br />

kell írni. így a megoldó a nulla elemeknek megfelelű deriváltakat<br />

meg sem próbálja kiszámítani, ami gyorsítja a<br />

programot.<br />

Vectorized Vektorizálás. (Én nem igazán értem, miért jó. Ha valaki<br />

elmesélné, hálás lennék.)<br />

Lépésköz


9. FEJEZET. KÖZÖNSÉGES DIFFERENCIÁLEGYENLETEK (ODE) MEGOLDÁSA 32<br />

Esemény figyelés<br />

InitialStep Javasolt kezdőlépés.<br />

MaxStep Maximális lépésköz. Ha a kiszámított megoldást túl<br />

durvának tartjuk és sűríteni szeretnénk a pontokat, a refine<br />

parancsot használjuk!<br />

Events<br />

Ha valamilyen esemény bekövetkezését szeretnénk nyomon<br />

követni (pl. ütközés, valamilyen határérték elérése, stb.) ezt<br />

kapcsoljuk be. Ilyenkor az integrálás megállítható.<br />

9.1.1. Szabadsugár sebességeloszlása<br />

Egy kétdimenziós szabadsugár sebességeloszlásának számítása az alábbi kezdeti érték feladatra vezet:<br />

F ˙ F = ¨F 2 , ahol F (0) = 1 és ˙ F (0) = 0.<br />

Bevezetve az y 1 = F és az y 2 = ˙ F új koordinátákat kapjuk az elsőrendű DE rendszert:<br />

) ( )<br />

(ẏ1 y2<br />

=<br />

ẏ 2 − √ y 1 y 2<br />

(A negatív előjelű gyök kell ẏ 2 egyenletében, különben a megoldások a végtelenhez tartanak.) Az alábbi kis<br />

program megoldja a feladatot (szabadsugar.m) .<br />

szabadsugar.eps<br />

9.1. ábra. A szabadsugár feladat megoldása.<br />

szadadsugar.m<br />

function szabadsugar<br />

[t,y] = ode45(@f,[0 2.5],[0; 1]);<br />

plot(t,y(:,2));<br />

xlabel(’\xi’); ylabel(’F’);<br />

title(’Szabadsugar’);


9. FEJEZET. KÖZÖNSÉGES DIFFERENCIÁLEGYENLETEK (ODE) MEGOLDÁSA 33<br />

function dydt = f(t,y,mu)<br />

dydt = [ y(2)<br />

-sqrt(y(1)*y(2))];<br />

9.1.2. Egy merev feladat: a Van der Pol egyenlet<br />

Balthazar van der Pool 1927-ben egy vákuumcsövet tartalmazó egyszerű áramkör vizsgálata közben időnként<br />

zajokat figyelt meg. Az áramkört modellező egyenlet<br />

ẍ + µ ( x 2 − 1 ) ẋ + x = 0<br />

valóban öngerjesztett rezgéseket mutat bizonyos µ paramétertartományokban (ami meglepő volt, hiszen<br />

explicit időfüggés nincs az egyenletekben, azaz senki sem ’rázza’ a rendszert). Hogy a numerikus megoldót<br />

használni tudjuk, először Cauchy átírással elsőrendű rendszerré alakítjuk az y 1 = x és y 2 = ẋ új változók<br />

segítségével, amivel az egyenlet az<br />

) (<br />

)<br />

(ẏ1<br />

y<br />

=<br />

2<br />

ẏ 2 µ ( )<br />

1 − y1<br />

2 y2 − y 1<br />

alakot ölti. A (van der Pol.m) példaprogramban átállítjuk a relatív hibát 10 −4 -re és az ode15s megoldót<br />

használjuk, mert a feladat merev (gyors-lassú mozgást végez a rendszer).<br />

van der Pol.m<br />

function van_der_Pol(mu)<br />

options = odeset(’RelTol’,1e-4);<br />

[t,y] = ode15s(@vdp,[0 3000],[2; 0],options,mu);<br />

plot(t,y(:,1));<br />

xlabel(’t’); ylabel(’y_1’);<br />

title([’van der Pol egyenlet, \mu=’,num2str(mu)]);<br />

function dydt = vdp(t,y,mu)<br />

dydt = [ y(2)<br />

mu*(1-y(1)^2)*y(2)-y(1)];<br />

9.1.3. Eseménykezelés: vízcsepp alakja<br />

A csapból lassan kifolyó vízcsepp y(x) alakját a<br />

y ′′<br />

(1 + y ′2 ) + y ′<br />

3/2 x (1 + y ′2 ) = 1/2 2y′′ (0) − ρg<br />

σ y<br />

egyenlet írja le, ahol σ a felületi feszültség, ρ a folyadék sűrűsége. Az egyenletet numerikus célokra átírva<br />

kapjuk a


9. FEJEZET. KÖZÖNSÉGES DIFFERENCIÁLEGYENLETEK (ODE) MEGOLDÁSA 34<br />

van_der_Pol.eps<br />

9.2. ábra. A van der Pol egyenlet megoldása.<br />

) (<br />

)<br />

(ẏ1<br />

y 2<br />

=<br />

ẏ 2 (A − By 1 ) ( 1 + y2) 2 3/2<br />

−<br />

y 2<br />

( )<br />

t<br />

1 + y<br />

2<br />

2<br />

A (csepp.m) programban a numerikus megoldás során figyeljük y 2 értékét (ami a felületet leíró görbe meredeksége)<br />

és ha már majdnem függőleges (itt y 2 > 10 4 ), abbahagyjuk az integrálást. Ezt valósítja meg az<br />

events(t,x) eljárás.<br />

function csepp<br />

global A B<br />

A=1;<br />

B=0.1343;<br />

csepp.m<br />

options = odeset(’Events’,@events);<br />

[t,x] = ode45(@f_csepp,[1e-5 10],[0; 0],options);<br />

plot(t,x(:,1),’k’,-t,x(:,1),’k’);<br />

title([’Vizcsepp alak, A=’,num2str(A)]);<br />

xlabel(’x’);<br />

ylabel(’y’);<br />

%-----------------------------------------------------<br />

function dxdt = f_csepp(t,x)<br />

global A B<br />

dxdt = [x(2);<br />

(A-B*x(1))*(1+x(2)^2)^(3/2)-x(2)/t*(1+x(2)^2)];<br />

%------------------------------------------------------<br />

function [value,isterminal,direction] = events(t,x)<br />

value = abs(x(2))-10^4;<br />

isterminal = 1; % megall az integralas<br />

direction = 0; % mindket iranyban


9. FEJEZET. KÖZÖNSÉGES DIFFERENCIÁLEGYENLETEK (ODE) MEGOLDÁSA 35<br />

csepp.eps<br />

9.3. ábra. A vízcsepp alakja.<br />

9.2. Perem érték feladatok (BVP)<br />

A peremérték feladatok esetén egyrészről ugyanúgy definiálni kell a DE jobb oldalát, mint a kezdeti érték<br />

feladatoknál, de két további eljárásra is szükség van: a peremfeltételeket definiáló függvényre és a megoldót<br />

inicializáló eljárásra. Nagyon fontos, hogy ’jó’ kiindulófüggvényt válasszunk az iterációhoz, mert ez jelentősen<br />

megkönnyíti a megoldást.<br />

BVP megoldó szintaktika:<br />

sol = bvp4c(odefun,bcfun,solinit),<br />

ahol<br />

odefun tartalmazza a DE jobb oldalát. Formája a szokásos dydx = odefun(x,y), ahol x skalár, y és dydx<br />

pedig oszlopvektor.<br />

bcfun definiálja a peremfeltételeket nullára rendezve. Formája res = bcfun(ya,yb), ahol ya és yb oszlopvektorok,<br />

melyek a megoldást reprezentálják a tartomány elején és végén. res egy oszlopvektor, mely<br />

a rezíduumokat tartalmazza.<br />

solinit inicializálja a megoldást x által kifeszített hálón y értékekkel. A peremfeltételeket a=solinit.x(1)<br />

és b=solinit.x(end) helyeken értelmezzük. Ez az eljárás opcionális, az inicializáló vektorok feltöltése<br />

másként is lehetséges (pl. adatfájlból).<br />

sol az eredményeket tartalmazó struktúra. Mivel a felhasznált numerikus megoldó mozgóhálós kollokációs<br />

módszer, az x-ben definiált kezdeti hálót a megoldó felülírta.<br />

Érdemes még a bvpinit és a deval eljárásokat használnunk; az első az inicializálást könnyíti meg, a második<br />

pedig a kapott eredmények kiértékelését. Fontos még tudnunk, hogy a peremfeltételek száma:<br />

N peremfeltételek = N ODE + N paraméterek ,<br />

ui. egyes esetekben szabad paramétereket kell hagyni a DE rendszerben a megoldás létezésének biztosítására.<br />

A következő példákban extra paraméterek keresésével nem foglalkozunk (ld. Help: Matthieu egyenlet sajátértéke),


9. FEJEZET. KÖZÖNSÉGES DIFFERENCIÁLEGYENLETEK (ODE) MEGOLDÁSA 36<br />

de pl. ilyenre vezet periodikus megoldások keresése is, de ekkor a peremfeltétel egy ismeretlen x = T helyen<br />

van. Ilyenkor a T ismeretlen periódussal átskálázzuk az x változót és így már jól definiált a feladat:<br />

y ′ (x) = T F (x, y) ahol y(0) = y(1),<br />

és még egy peremfeltételt elő kell írni T szabad paraméter miatt, ami általában a fázisra vonatkozik.<br />

9.2.1. Couette áramlás sebességgradienssel<br />

Két síklap közötti lamináris, stacioner áramlást leírja az<br />

∂p<br />

∂x = µ ∂2 v<br />

∂y 2 ,<br />

egyenlet, ahol a x a hosszirányú, y a keresztirányú koordináta. Ha a ∂p<br />

∂x<br />

nyomásgradiens konstans, a fenti<br />

egyenlet zárt alakban megoldható. Két speciális eset a Poiseuille-áramlás (mindkét lap áll és a nyomásgradiens<br />

nemzérus, ekkor a sebességeloszlás parabolikus) és a Couette-áramlás (ekkor az egyik lap mozog, nincs<br />

nyomásgradiens, a sebességprofil pedig lineáris). Ha van nyomásgradiens és a felső lap is mozog, akkor is<br />

megoldható a feladat zárt alakban, a sebességprofil egy ’ferde tengelyű’ parabola. Ha a két lap távolsága<br />

h = 1m, az mozgó fal sebessége v 0 = 2m/s és az áramló közeg víz, akkor mivel Re = vh/ν ≈ 10 3 , az áramlás<br />

még a lamináris tartományban van. A probléma peremértékfeladatként megfogalmazva:<br />

y ′ 1 = y 2<br />

y ′ 2 = 1<br />

ρ ν<br />

a tapadás törvénye miatt a peremfeltételek pedig az y(0) = 0 és y(1) = v 0 alakot öltik. A <strong>Matlab</strong> program<br />

így néz ki :<br />

∂p<br />

∂x ,<br />

function couette<br />

couette.m<br />

global P v0 nu<br />

P = -0.01; v0 = 2; nu = 0.001;<br />

% Megoldas inicializalasa:<br />

solinit=bvpinit(linspace(0,1,10),@mat4init);<br />

% Megoldo hivasa:<br />

sol=bvp4c(@mat4ode,@mat4bc,solinit);<br />

% Eredmenyek interpolalasa:<br />

xint = linspace(0,1,100);<br />

Sxint = deval(sol,xint);<br />

% Szinezes csusztatofeszultseg szerint:<br />

tau_max=max(Sxint(2,:));<br />

tau_min=min(Sxint(2,:));<br />

for i=1:length(Sxint(1,:))<br />

szin=(Sxint(2,i)-tau_min)/(tau_max-tau_min);<br />

plot(Sxint(1,i),xint(i),’+’,’MarkerEdgeColor’,[szin 0.5*szin 0.75-0.5*szin]);


9. FEJEZET. KÖZÖNSÉGES DIFFERENCIÁLEGYENLETEK (ODE) MEGOLDÁSA 37<br />

hold on;<br />

end;<br />

hold off;<br />

title([’Adatok: dp/dx=’,num2str(P),’ \nu=’,num2str(nu)],’FontSize’,14);<br />

xlabel(’aramlasi sebesseg, v’,’FontSize’,14);<br />

ylabel(’keresztemtszet, x’,’FontSize’,14);<br />

%---------------------------------------------<br />

function dydx=mat4ode(x,y)<br />

global P nu<br />

dydx=[ y(2); P/nu];<br />

%----------------------------------------------<br />

function res=mat4bc(ya,yb)<br />

global v0<br />

res=[ ya(1); yb(1)-v0];<br />

%---------------------------------------------<br />

function yinit=mat4init(x)<br />

global v0<br />

yinit = [ v0*x^2; 2*v0*x ];<br />

couette.eps<br />

9.4. ábra. Sebességeloszlás Couette áramlás esetén nyomásgradienssel, τ csúsztatófeszültség szerint színezve.


10. fejezet<br />

Fourier analízis<br />

Fourier analízist és frekvenciaspektrumot az fft(y,N) paranccsal végezhetünk, ahol N 2 egész számú hatványa<br />

(mivel a <strong>Matlab</strong> gyors Fourier transzformációt alkalmaz). Inverz transzormáció az ifft paranccsal<br />

számítható.<br />

Például vegyünk egy 1000Hz-el mintavételezett jelet, mely egy 50 és egy 120 Hz-es komponenset tartalmaz,<br />

de el van rontva egy véletlenszerű, zérusátlagú zajjal. Végezzük el a Fourier-transzformációt és számítsuk ki<br />

a komplex amplitúdó abszolúrtékét (fft demo.m ).<br />

t = 0:0.001:0.6;<br />

x = sin(2*pi*50*t)+sin(2*pi*120*t);<br />

y = x + 2*randn(size(t));<br />

n=8;<br />

Y = fft(y,2^n);<br />

Pyy = Y.* conj(Y) / 2^n;<br />

f = 1000*(0:2^(n-1))/2^n;<br />

hossz=min(length(Pyy),length(f));<br />

subplot(2,1,1)<br />

plot(t,x), xlabel(’t’), ylabel(’x(t)’)<br />

grid on, axis([0 0.6 -2.5 2.5])<br />

subplot(2,1,2)<br />

plot(f(1:hossz),Pyy(1:hossz))<br />

xlabel(’f [Hz]’), ylabel(’amplitudo’)<br />

grid on<br />

fft demo.m<br />

38


10. FEJEZET. FOURIER ANALÍZIS 39<br />

fft.eps<br />

10.1. ábra. Eredeti időjel és a spektrum.


11. fejezet<br />

Példaprogramok<br />

11.1. Karakterisztikák módszere<br />

Hidraulikus tranziensek számítása esetén a csövekben az áramlást az 1D mozgásegyenlet és a kontinuitási<br />

egyenlet<br />

∂v<br />

∂t + 1 ∂p<br />

ρ ∂x = S és ∂ρ<br />

∂t + ∂ρv<br />

∂x = 0.<br />

Tegyük fel, hogy a sűrűség csak a nyomás függvénye, azaz ρ = ρ(p), így ∂ρ/∂t = dρ/dp × ∂p/∂t. Vezessük<br />

be a hangsebességet: dρ/dp = a −2 . Adjuk hozzá a mozgásegyenlethez a kontinitási egyenlet λ szorosát:<br />

∂v<br />

∂t + λ (<br />

∂p ∂v<br />

a 2 ∂t + λρ ∂x + 1 )<br />

∂p<br />

λρ 2 = S.<br />

∂x<br />

Amennyiben az ismeretlen λ szorzót ± a dx<br />

ρ<br />

-nak választjuk, az (x, t) síkon két speciális irányban<br />

dt = ± egy -<br />

egy közönséges differenciálegyenletet kapunk:<br />

d<br />

dz<br />

(p ± ρav) = ∓ρag<br />

dt dx ∓ ρaS.<br />

A numerikus módszer ezek után egyszerű. A fenti differenciálegyenletet egy egyenközű rácson oldjuk meg,<br />

ahol az aktuális i-edik pontban a jellemzőket az i − 1 ből indított a meredekségű és az i + 1-edik pontból<br />

indított −a meredekségű karakterisztika segítségével határozzuk meg.<br />

Két programot készítettünk: egy önálló megoldót kar.m és egy vezérlő programot: kar driver.m. A megoldó<br />

bemenete a cső egyes paraméterei, a ’régi’ p és v nyomáseloszlás, ill. a peremfeltételek típusa és értéke (2<br />

db). Ezek alapján kiszámítja és visszaadja a ∆t-vel későbbi csőállapotot. A vezérlőprogram ezt az eljárást<br />

ismétli, ill. előkészíti a számítást és megjeleníti az eredményeket.<br />

40


11. FEJEZET. PÉLDAPROGRAMOK 41<br />

kar.m<br />

function [puj,vuj]=kar(adatok,p,v,PF0_tipus,PF0_ertek,PFN_tipus,PFN_ertek)<br />

D = adatok{1}(1); % csoatmero<br />

L = adatok{1}(2); % csohossz<br />

N = adatok{1}(3); % csodarabok szama (csomopontok szama: N+1)<br />

a = adatok{1}(4); % hangsebesseg<br />

ro = adatok{1}(5); % suruseg<br />

g = 9.81;<br />

dx = L/N;<br />

dt = dx/a;<br />

roa = ro*a;<br />

dzdx = adatok{2};<br />

nu = 1e-6;<br />

lambda=0.02;<br />

for i=2:N<br />

ar = p(i-1)+ro*a*v(i-1);<br />

br = p(i+1)-ro*a*v(i+1);<br />

vuj(i) = (-2*dt*roa*g*dzdx(i)+ar-br)/roa/(2+dt*lambda/2/D*(abs(v(i+1))+abs(v(i-1))));<br />

puj(i) = ( -dt*roa*g*dzdx(i)+ar)-roa*(1+dt*lambda/2/D* abs(v(i-1)))*vuj(i);<br />

end<br />

% Peremfeltetelek beallitasa.<br />

perem_1 = p(2)-ro*a*v(2) + dt*roa*g*dzdx(1);<br />

perem_N = p(N)+ro*a*v(N) - dt*roa*g*dzdx(N+1);<br />

szorzo1 = roa*(1+dt*lambda/2/D*abs(v(2)));<br />

szorzoN = roa*(1+dt*lambda/2/D*abs(v(N)));<br />

switch PF0_tipus<br />

case ’p’<br />

puj(1) = PF0_ertek;<br />

vuj(1) = (puj(1)-perem_1)/szorzo1;<br />

case ’v’<br />

vuj(1) = PF0_ertek;<br />

puj(1) = perem_1 + ro*a*vuj(1);<br />

otherwise<br />

error(’Ismeretlen peremfeltétel!’);<br />

end<br />

switch PFN_tipus<br />

case ’p’<br />

puj(N+1) = PFN_ertek;<br />

vuj(N+1) = -(puj(N+1)-perem_N)/ro/a;<br />

case ’v’<br />

vuj(N+1) = PFN_ertek;<br />

puj(N+1) = perem_N-szorzoN*vuj(N+1);<br />

otherwise<br />

error(’Ismeretlen peremfeltétel!’);<br />

end


11. FEJEZET. PÉLDAPROGRAMOK 42<br />

function kar_driver<br />

kar driver.m<br />

% adatok<br />

D=0.05; A=D^2*pi/4; L=10; N=10; a=1000;<br />

ro=1000; lambda=0.02; tmax=0.1;<br />

% inicializalas<br />

t=0; dt=L/N/a; x=0:L/N:L; dzdx=zeros(1:N);<br />

% cell{} tip. vektorral több adattipust be lehet csomagolni<br />

adatok{1}=[D L N a ro]; adatok{2}=dzdx;<br />

% Inicializálás (t=0-hoz tartozó állapot)<br />

p=2e5*ones(1,N+1); v=zeros(1,N+1); i=1;<br />

% indulamandula<br />

while t


11. FEJEZET. PÉLDAPROGRAMOK 43<br />

11.2. Nyíltfelszínű csatornaáramlás<br />

Nyíltfelszínű stacioner csatornaáramlás esetén<br />

y + z + v2<br />

2g + h′ = állandó,<br />

ahol y(x) a folyadékfelszín alakja, z a csatorna fenekének magassága, v az áramlási sebesség, h ′ pedig a<br />

veszteségmagasság. Ez utóbbi számítása a Chézy képlettel történik:<br />

dh ′<br />

dx =<br />

v2<br />

C 2 , ahol R h = A R h K<br />

R1/6<br />

h<br />

és C =<br />

n .<br />

Itt A(y) a nedvesített felület, K(y) a nedvesített kerület, n pedig az cső érdességétől függő tényező. Figyelembe<br />

véve a kontinuitást, azaz hogy Q = Av = állandó, a fenti képlet kicsit megdolgozva a<br />

Q2<br />

A 2 C 2 R h<br />

dy<br />

dx = i −<br />

1 − Q2 B<br />

alakot ölti, ahol i a csatorna lejtése, B a folyadéktükör szélessége és g a gravitációs gyorsulás.<br />

A feladatot kezedti érték feladatként fogalmazzuk meg, azaz előírunk egy kezdeti folyadékszintet és térfogatáramot.<br />

Ismert, hogy ha a térfogatáram kisebb, mint az egyenes felszínhez tartozó normál térfogatáram, a folyadékszint<br />

duzzad, ha pedig nagyobb, akkor gyorsul a mozgás és kialakulhat a rohanás jelensége. Ezt kezelendő<br />

eseményfigyelést alkalmazunk, azaz a program automatikusan abbahagyja az integrálást, ha bekövetkezik<br />

az y = 0 esemény (rohanas(x,y)).<br />

Az alábbi program (nyiltfelszin.m) az egyszerűség kedvéért b szélességű, téglalap keresztmetszetű csatornát<br />

feltételez . Futtassuk le a programot Q = 0.2, 0.25, 0.298, 0.299, 0.3[m 3 /s] térfogatáramokkal!<br />

A 3 g<br />

nyiltfelszin.eps<br />

11.2. ábra. A nyiltfelszin.m program grafikus kimenete.


11. FEJEZET. PÉLDAPROGRAMOK 44<br />

function nyiltfelszin<br />

global B n g Q ii<br />

nyiltfelszin.m<br />

Q = 0.298; % eloirt terfogataram<br />

y0= 0.6; % szint a csatorna elején<br />

ii = 0.001; % hidraulikai lejtes<br />

n = 0.01; % csoerdesseg<br />

B = 0.5; % csatorna szelesseg<br />

g = 9.81; % gravitacio<br />

L = 1000; % csohossz<br />

Rh = y0*B/(2*y0+B);<br />

C = Rh^(1/6)/n;<br />

Qn = y0*B*C*sqrt(ii*Rh);<br />

fprintf(’\n Nyiltfelszinu csatornaaramlas\n’);<br />

fprintf(’\n %g m-es cs}oeleji felszinhez tartozó térfogatáram: %g m^3/s’,y0,Qn);<br />

% Megoldo hivasa:<br />

options=odeset(’events’,@rohanas);<br />

[x,y]=ode45(@nyiltfelszin_de,[0 L],y0,options);<br />

% A csatorna alja és az ahhoz képesti folydékszint (rajzoláshoz):<br />

for i=1:length(x)<br />

yy(i)=ii*(1-x(i)/L)*L;<br />

yf(i)=yy(i)+y(i); v(i) =Q/y(i)/B;<br />

end<br />

figure(1)<br />

subplot(2,1,1), plot(x,yy,x,yf);<br />

title([’Nyiltfelszin}u csatornaáramlás: i=’,num2str(ii),’<br />

ylabel(’folyadekfelszin, y [m]’,’FontSize’,12)<br />

legend(’csatorna feneke’,’folyadék felszíne’)<br />

axis([0 L 0 yf(1)*1.2])<br />

Q=’,num2str(Q)],’FontSize’,12);<br />

subplot(2,1,2), plot(x,v);<br />

xlabel(’csohossz, x [m]’,’FontSize’,12);<br />

ylabel(’aramlasi sebesseg, v [m/s]’,’FontSize’,12);<br />

%---------------------------------------------<br />

function dydx=nyiltfelszin_de(x,y)<br />

global B n g Q ii<br />

A=y(1)*B; Rh=y(1)*B/(2*y(1)+B); C=Rh^(1/6)/n;<br />

dydx=[ (ii-Q^2/A^2/C^2/Rh)/(1-Q^2*B/A^3/g)];<br />

%---------------------------------------------<br />

function [val,ter,dir]=rohanas(x,y)<br />

val=y(1); % Az esemény definiciója<br />

ter=1; % Állítsuk meg az integrálást.<br />

dir=0; % Mindkét irányban (1: + -> -, 2: - -> +)


11. FEJEZET. PÉLDAPROGRAMOK 45<br />

11.3. Függőlegesből vízszintesbe vezető ívben mozgó anyagdugó<br />

Pneumatikus anyagszállítás témakörében felmerülő probléma, hogy egy függőlegesből vízszintesbe vezető<br />

90 o -os ívben hogyan mozog az anyagdugó. Tegyük fel, hogy az anyagdugó hossza nagyobb, mint az ív, azaz<br />

L > R π/2. Ekkor a mozgás 3 szakaszra osztható:<br />

• az anyagdugó tölti az ívet,<br />

• az anyagdugó az ívben mozog és<br />

• az anyagdugó ürül az ívből.<br />

A független változók az anyagdugó elejének (ill. végének) α szögelfordulása és az anyagdugó sebessége v a ,.<br />

helyzete z és gyorsulása a a . A mozgásegyenletek az egyes szakaszokban:<br />

1. szakasz (telítődés): 0 ≤ α ≤ π 2<br />

{ α ′ =<br />

√<br />

z<br />

z ′ k<br />

= F 1 (α, z) = C 31 + Π 0 Π 2 d hs<br />

ρ g2 p 2 (v g2 − Rz) 2 + p 2 2 − µ 2<br />

(cos α − α) −<br />

sin α−α<br />

2<br />

− αµRz 2<br />

2. szakasz (mozgás az ívben): z + R π 2 ≤ L: ⎧<br />

⎨ v a ′ = a a<br />

a ′ a = F 2 (a a , v a )<br />

⎩<br />

z a ′ = v a<br />

3. szakasz (ürülés): 0 ≤ α ≤ π 2<br />

{<br />

α ′ = z<br />

z ′ = F 3 (α, z)<br />

Nincs értelme itt pontosan definiálni az egyes változókat és fizikai konstansokat, ezt az előadásjegyzete alapján<br />

mindenki megteheti. (Egyébként F 1 a legegyszerűbb mozgásegyenlet, ezért ezt írtam ki.) Azt viszont vegyük<br />

észre, hogy az egyenleteket egymás után szakaszosan kell megoldani éspedig úgy, hogy eseménykezeléssel<br />

meg kell állítani az integrálást és a végállapotból indítani a következő szakasz megoldását. Ez az 1. és a 3.<br />

szakaszban viszonylag egyszerű, mert α értékét kell figyelni, ami az egyik független változó. Ellenben a 2.<br />

szakaszban az elmozdulást kell figyelni, amire (eredetileg) nincs egyenlet (csak v a -ra és a a -ra), ezért csatolunk<br />

egy harmadik diff. egyenletet, mely az egyszerűen a z = ∫ v a kapcsolatból nyerhető. Így már tudjuk követni<br />

az anyagdugó helyzetét is. A példaprogram megtalálható az interneten www.hds.bme.hu. A kimenet a 11.3<br />

ábrán látható, az egyes szakaszok különböző szinekkel vannak feltüntetve.


11. FEJEZET. PÉLDAPROGRAMOK 46<br />

pneu_iv.eps<br />

11.3. ábra. A pneu iv.m program grafikus kimenete.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!