Informatika1-2015/Gyakorlat9

A MathWikiből
A lap korábbi változatát látod, amilyen Gaebor (vitalap | szerkesztései) 2015. november 3., 10:41-kor történt szerkesztése után volt.

Előző gyakorlat - Fel - Következő gyakorlat

Tartalomjegyzék

Octave

Az Octave program alkalmas különböző matematikai számításokat numerikusan elvégzésére, a nagytestvérének a MatLab-nak az ingyenes (opensource) változata.

Kezdeti lépések

Hozzáférés a programhoz

Ha otthonról dolgozunk, akkor a következő lehetőségek legalább egyikével éljünk:

A géptermekből Linux-ról futtassuk az Octave-ot

Számológép

Az Octave egy fejlettebb számológépként is használható. Írjuk be az octave parancssorába az alábbiakat:

2+3

majd üssünk Enter-t. Ennek hatására:

> 2+3
ans =  5
> _

Próbáljuk ki ezeket is:

2-3
2*3
2/3
floor(2/3)
mod(2,3)
2^3
sqrt(2)
log(2)
log(3)
log(8)/log(2)
exp(1)
pi
cos(pi/2)
(180/pi)*acos(0.5)

Kilépni így lehet

exit

Adattípusok

Minden szám alapértelmezésben lebegőpontos, akkor is, ha véletlenül egész:

1000/9
ans = 111.11

Viszont megadhatjuk, hogy egészekként értelmezze a számokat:

int32(1000)/int32(9)
ans = 111

Octave-ban egy szám mindaddig valós, amíg komplexnek nem bizonyul:

sqrt(2)
sqrt(-2)

A számábrázolások

  • double: dupla lebegő pontos, 64 bit (8 byte)
    • valós: 8 byte
    • komplex: 16 byte
  • single: szimpla lebegő pontos, 32 bit (4 byte)
    • valós 4 byte
    • komplex: 8 byte
  • int32: 32 bites kettes komplemens egész (4 byte)
  • int8: 8 bites kettes komplemens egész: -128..127 (1 byte)
  • uint32: 32 bites előjel nélküli egész (4 byte)
  • uint8: 8 bites előjel nélküli egész: 0..255 (1 byte)

A méret nagyon is számít:

log(single(1.0001))
log(double(1.0001))
int32(100+100)
int8(100+100)

Mátrixok

Az octave-ban minden szám egy mátrix

  • számok: 1x1
  • vektorok:
    • sorvektor: 1xn
    • oszlopvektor: nx1
  • matrix: nxm

Ennek alapos oka van, amit majd később fogunk megérteni és ami a MatLab leglényegéhez vezet bennünket, ezt vette át az octave is. Bővebben itt.

Sorvektor:

[1, 2, 3, 4]
[1 2 3 4]

Oszlopvektor:

[1;2;3;4]

Ez nem oszlopvektor:

[[1], [2], [3], [4]]

Mátrix:

[1 2; 3 4]
[1, 2; 3, 4]

Speciális mátrixok:

  • zeros: csupa 0
  • ones: csupa 1
  • eye: diagonálisban 1, máshol 0
  • diag: négyzetes diagonális mátrix, megadott főátlóval
zeros(2,3)
eye(2,3)
ones(3,1)
diag([1,2,3,4])

Próbáljuk ki:

size(5)
size([1,2,3])
size([1;2;3])

Tartományok

A tartományok speciális sorvektorok, próbáljuk ki:

1:10

Ha nem egyesével akarunk ugrani:

1:0.1:2
1:2:10

Komplex számmal nem lehet, mert azok nem rendezhetőek!
Az eredmény mindig double lesz, de utána konvertálhatjuk:

int32(1:0.5:10)

Leszálló tartományok:

4:-1:1

Üres tartomány:

4:1:1

Diagonális mátrixot megadhatunk így is:

> diag(1:4)
ans =
  1 0 0 0
  0 2 0 0
  0 0 3 0
  0 0 0 4

typeinfo

Egy érték típusáról meggyőződhetünk a typeinfo paranccsal.

typeinfo(1)
typeinfo(int32(1))
typeinfo(i)
typeinfo(single(i))
typeinfo([1 2 3 4])
typeinfo([1 i -1 -i])
typeinfo(1:4)
typeinfo([1:4])

Műveletek mátrixokkal

Mivel minden szám egyben egy 1x1-es mátrix, így ezek mindig használhatóak.

Transzponált

Transzponált egyszerűen vesszővel ('):

> [1 2; 3 4]'
ans =
 1 3
 2 4
> _

Vagy

> (1:4)'
ans =
  1
  2
  3
  4

Komplex mátrixokra a vessző adjungálást jelent:

> [1,2i;3i,4]'
ans =
  1 - 0i   0 - 3i
  0 - 2i   4 - 0i

Konjugálást így csinálhatunk: i'

Összeadás

1+(1:4)
eye(2,2)+ones(2,2)
[1;2;3;4]-[4;3;2;1]

Szorzás

Minden szorzás mátrixszorzás:

> [1 2; 3 4]*[1 2; 3 4]
ans =
   7   10
  15   22

Hatványozás szintén, így az invertálás is:

[1 2; 3 4]^2
[1 2; 3 4]^-1

A szorzásnál a méreteknek kompatibiliseknek kell lenniük:

ones(2,3)*ones(3,5)

Sorvektor szorozva oszlopvektorral a skalárszorzás, fordítva diádszorzatnak hívjuk:

[1,2,3]*[1;2;3]
[1;2;3]*[1,2,3]

Tagonként vagy mátrixként

Ha a hatványozást ismételt mátrixszorzásként értelmezi, akkor ez mi?

[1 2; 3 4]^0.5

És ez mi?

sqrt([1 2; 3 4])

Bizonyos műveletek tagonként hatnak ha egy mátrixra alkalmazzuk, míg mások mátrix-műveletként. De tudunk váltani köztük.

> (1:4)^2
error: for A^b, A must be a square matrix

Hibát ad, mert két 1x4-es mátrixnak nem értelmes a szorzata. De:

> (1:4).^2
ans =
  1  4  9 16

Minden műveleti jel olyan, hogy ha elé pontot rakunk, akkor elemenként hat. Például az összeadásnál a mátrix összeadás és az elemenkénti összeadás ugyan az.

> [1 2; 3 4]+[1 2; 3 4]
ans =
  2   4
  6   8
> [1 2; 3 4].+[1 2; 3 4]
ans =
  2   4
  6   8

De a szorzásnál már nem:

> [1 2; 3 4]*[1 2; 3 4]
ans =
   7   10
  15   22
> [1 2; 3 4].*[1 2; 3 4]
ans =
   1    4
   9   16

Hatványozás hasonlóan:

> [1 2; 3 4]^-1
ans =
 -2.00000   1.00000
  1.50000  -0.50000
> [1 2; 3 4].^-1
ans =
  1.00000   0.50000
  0.33333   0.25000

A nevesített függvények általában elemenként hatnak:

sin(0:0.1:2*pi)
exp([0,-1;1,0])

A műveleti jelek pedig mátrix műveletként (*, ^, /, \)

Változók

Ahhoz hogy ne csak egy soros dolgokat tudjunk számolni, az adatokat változókban tároljuk.

a=2
b=3
a+b

Mindig van egy ans nevű változónak, amiben az utoljára kiszámolt érték található.
Ha nincsen érték adva egy változónak, akkor nem tudunk hivatkozni rá:

> a/q
error: `q' undefined

A kettősponttal (;) csendes számolást végezhetünk, ekkor a parancs eredménye nem kerül kiírásra:

a=2;
b=3;
a+b

A whos paranccsal megnézhetjük az aktuálisan tárolt változóinkat.

> whos
Variables in the current scope:
  Attr Name        Size                     Bytes  Class
  ==== ====        ====                     =====  =====
       a           1x1                          8  double
       ans         1x1                          8  double
       b           1x1                          8  double
Total is 3 elements using 24 bytes
> _

Egy változó értékét bármikor felülírhatjuk:

> a=2;
> a=[1,2;3,4];
> whos
Variables in the current scope:
  Attr Name        Size                     Bytes  Class
  ==== ====        ====                     =====  =====
       a           2x2                         32  double

Indexelés

Legyen M egy 3x3-as mátrix. Ennek az i-edik sorának j-edik eleme a következő.

M = rand(3,3);
i = 1;
j = 3;
M(i,j)

Mátrixok összefűzése:

[M M]
[M; M]

Részsorozat kiválasztása a tartományok használatával:

l=0:0.1:1;
l(:)
l(1:11)
l(1:5)
l(5:end)
l(1:2:11)

Sőt:

l(1:2:11)=0

Részmátrix hasonlóan, csak két indexszel.

A=[1,2,3;4,5,6;7,8,9];
A(1:3,1:2)
A(1:2,1:3)

Egy sor kihagyása:

A([1,3],:)

Vagy részmátrix kiválasztása:

S=ones(8,8);
S(3:6,3:6)=-1

Vagy adott indexekre:

S=ones(8,8);
S([1,2,8],[2,4,6])=-1

Mátrix kilapítása:

A=eye(3,3);
A(:)

Vektorizáció

Az Octave-ban (MatLab-ban) általában egyszerre sok dolgot számolunk, nem csak egy értéken értékelünk ki egy függvényt. Például az X mátrix minden sorának számoljuk ki a normáját (X lehet nx3-as, ahol n nagyon sok):

X = rand(10,3);
sqrt(sum(X.^2,2))
ans =
  0.99105
  0.86977
  1.29362
  0.91697
  1.26149
  0.84024
  1.45410
  1.19791
  1.01153
  1.07420

Belülről kifelé haladva elemezzük a függvényeket:

  • X.^2: kiszámolja az elemenkénti négyzetet
  • sum(●, 2): összegzi a mátrix sorait egy oszlopvektorba
  • sqrt: elemenként gyököt von

Számoljuk ki a 2x^2-3x+1 függvényértékeket, ahol x egy hosszú sorvektor:

x=0:0.1:1;
fx=2.*x.^2 - 3.*x + 1

A vektorizáció lényege, hogy ahol lehet mátrix és vektor műveletekre vezessük vissza a számításainkat, mert 1000 darab számpár összeszorzása lassabb, mint két darab 1000 hosszú vektor szorzása!

Feladatok

Mi ez?

Figyeljük meg a következőket.

A=[1,2,3;4,5,6;7,8,9];
B=[9,8,7;6,5,4;3,2,1];
trace(A*B')
A(:)'*B(:)

Mi a trace(A*B')?

LER

Számoljuk ki a következő lineáris egyenletrendszer megoldását:

 x + 2y = 3
4x + 5y = 6

Megoldás: legyen

A=[1,2;4,5]
b=[3;6]

és ekkor egyszerűen:

x=A^-1*b

Erre van egy speciális szintaxis:

(A^-1)*b = A\b

És inverzzel jobbról szorozva:

B*(A^-1) = B/A

Segíts magadon

A help segítségével próbáljuk kiszámolni a következőket.

  • A determinánsa
  • A saját értékei, saját vektorai

Numerikus deriválás

Deriváljuk az f(x)=2x^2-3x+1 függvényt numerikusan! Adott egy x sorvektor, ami az abszcissza értékeket tartalmazza, fx pedig a hozzájuk tartozó függvényértékeket.

x=0:0.1:1
fx=2.*x.^2 - 3.*x + 1

Ekkor a függvény numerikus deriváltja:

df = (fx(2:end) - fx(1:end-1))./0.1

Nem egyenletes lépésközzel pedig:

df = (fx(2:end) - fx(1:end-1))./(x(2:end)-x(1:end-1))

Előző gyakorlat - Fel - Következő gyakorlat

Személyes eszközök