Matlab Hogyan - Hidrodinamikai Rendszerek Tanszék
Matlab Hogyan - Hidrodinamikai Rendszerek Tanszék
Matlab Hogyan - Hidrodinamikai Rendszerek Tanszék
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.