Numerická lineární algebra 1 – cvičení 3
Práce s řídkou maticí
Při práci s plnou maticí se její prvky ukládají po sloupcích. Každý prvek má 8 B, celá matice s rozměry m × n je uložena v souvislém poli o délce 8mn B.
Řídká matice o rozměrech m × n je oproti tomu v Matlabu uložena ve třech polích v tzv. CSC formátu (viz přednáška). Potřebná paměť je 8*nnz+8*(nnz+n+1) B (na 64-bitových architekturách).
Např. matice
A = [ 1 0 2 0 0 0 1 0 0 1 2 0 0 2 0 3 1 2 0 0 ];
je interně reprezentována poli:
H = [ 1; 2; 3; 1; 1; 2; 2; 2; 1 ]; % hodnoty nenulových prvků
S = [ 1; 4; 6; 8; 9; 9 ]; % indexy počátků sloupců v H a R R = [ 1; 3; 4; 2; 4; 1; 4; 3; 2 ]; % indexy řádků
Řídkou nulovou matici vytvoříme příkazem sparse:
S = sparse( 5, 4 ); % řídká nulová matice o rozměrech 5 × 4
Řídkou jednotkovou matici vytvoříme příkazem speye:
S = speye( 5, 4 ); % řídká jednotková matice o rozměrech 5 × 4
Podobně, pomocí příkazu sprand vytvoříme náhodnou matici s daným rozměrem a hustotou zaplnění:
S = sprand( 5, 4, 0.1 ); % řídká matice s nenulovými prvky z rovnoměrného náhodného rozdělení a hustotou zaplnění 0,1
S = sprandn( 5, 4, 0.1 ); % řídká matice s nenulovými prvky z normálního náhodného rozdělení a s hustotou zaplnění 0,1 S = sprandsym( 5, 0.1 ); % symetrická řídká matice s nenulovými prvky
z normálního náhodného rozdělení
Následujícími příkazy vytvoříme náhodné matice stejných rozměrů jako
S a s náhodnýminenulovými prvky na pozicích nenulových prvků S.
S=sprand(5,4,0.1);
sprand(S); sprandn(S); sprandsym(S);
Chceme-li nalézt nenulové prvky (tedy souřadnice řádků a sloupců a hodnoty) v řídké matici, použijeme funkci find:
S = sprand( 5, 4, 0.1 );
[ I, J, V ] = find( S ); % vrátí indexy nenulových prvků a hodnoty (v souřadnicovém COO formátu, ne v interním CSC formátu!)
Řídkou matici můžeme konvertovat na plnou a naopak:
A = full( S ); % konvertuje řídkou matici na plnou
S = sparse( A ); % konvertuje plnou matici na řídkou
Řídkou matici můžem přímo sestavit pomocí souřadnicového formátu. Např. matici
A = [ 1 0 4 0 0 0 3 0 0 6 2 0 0 5 0 ];
uložíme v řídkém formátu pomocí příkazů
I = [ 1 3 2 1 3 2 ]; J = [ 1 1 2 3 4 5 ]; V = [ 1 2 3 4 5 6 ];
m = 3, n = 5;
S = sparse( I, J, V, m, n );
Všimněte si, že se jedná o souřadnicový (COO) formát, ne interní CSC formát.
Řídkou diagonální matici můžeme vytvořit příkazem spdiag. První parametr je matice, jejíž sloupce mají být umístěny na diagonály vytvářené matice, následuje vektor určující, na kterou diagonálu se daný sloupec umístí; poslední dva parametry jsou rozměry vytvářené matice. Např.
n = 5; e = ones( n, 1 ); D = [ -e, 2*e, -e ]; Didx = [ -1, 0, 1 ];
S = spdiag( D, Didx, n, n );
vytvoří diagonální matici řádu 5 s 2 na hlavní diagonále a -1 na subdiagonále a superdiagonále.
Uveďme další užitečné příkazy pro práci s maticemi:
issparse( S ); % Urci, zda vstupni argument je ridka matice nnz( S ); % Pocet nenulovych prvku matice
nonzeros( S ); % Nenulove prvky matice
nzmax( S ); % Mnozstvi pameti alokovane pro nenulove prvky spalloc( m, n, nzmax ); % Alokace pameti pro ulozeni ridke matice spfun( @sin, S ); % Aplikuje zadanou funkci na nenulove prvky
matice
spones( S ); % Nahradi nenulove prvky matice S jedničkami
Nenulové prvky matice můžeme graficky znázornit pomocí příkazu
spy( S ). Příkaz imagesc( S ) matici zobrazí jako obrázek – každý prvek je obdélníkový element a jehohodnota určuje barvu elementu.
Příklad 1.
a) Vyskládejte efektivně následující řídkou matici (pomocí COO formátu):
A=[ 1 0 2 0 0 0 1 0 0 1 2 0 0 2 0 3 1 2 0 0 ];
b) Vyskládejte efektivně řídkou matici B tvořenou 6
×8 bloky A (využijte funkci repmat).
c) Napište funkci spndiag( x, d, m ), kde x a d jsou vektory délky n, která sestaví řídkou n diagonální matici D rozměru m
× m s prvky x(i) umístěnými na diagonále d(i).Např.
Grafika v Matlabu
Základní příkazy
• figure
o vytvoří prázdné okno grafu
• hold on/hold off
o zapne/vypne možnost kreslení více funkcí do jednoho okna
• ezplot
o slouží k jednoduchému vykreslení funkcí, použití např.
§ ezplot('x^2 ');
§ ezplot('sin(x)', [-3*pi, 6*pi]);
§ ezplot('x^2+y^2=1');
• fplot
o slouží k jednoduchému vykreslení funkcí, použití např.
§ f = @(x) sin(x);
fplot(f);
§ fplot(@(x) cos(x), [-pi, pi]);
o umožňuje definovat parametry křivek, např.
§ fplot(@(x) x.^3, 'LineWidth', 2);
§ fp = fplot(@(x) x.^2); fp.Color = 'r';
§ pro další parametry viz fci plot níže
• ezplot3
o kreslí 3D parametrické křivky, použití např.
§ ezplot3('sin(t)','cos(t)','t',[0,6*pi]);
• fplot3
o kreslí 3D parametrické křivky, použití např.
o xt = @(t) sin(t); yt = @(t) cos(t); zt = @(t) t;
fplot3(xt,yt,zt);
Příkaz plot
• Vstupem jsou vektory X a Y
• plot(X, Y)
o Vykreslí line-plot (spojnicový, čárový graf) dat Y versus X
• plot(X, Y, LineSpec)
o Umožňuje specifikovat vlastnosti grafu (viz dále)
• plot(X1, Y1, X2, Y2, …); plot(X1, Y1, LineSpec1, X2, Y2, LineSpec2, …)
o V rámci jednoho grafu vykreslí více páru X, Y
• plot(Y)
o Vykreslí hodnoty v Y oproti jejich indexům
• Příklady použití (příkaz linspace(a, b, n) generuje vektor n hodnot rovnoměrně rozložených mezi čísla a, b)
o plot([0.0, 0.5, 1.0], [1.5, pi, 1.0]);
o x = linspace(0, 2*pi, 100);
y1 = sin(x); % aplikuje funkci sinus na každý prvek vektoru x a vrati vektor vysledku odpovídající delky
plot(x, y1);
o x = linspace(-pi, pi, 100);
y1 = sin(x)
y2 = sin(2*x);
plot(x, y1, x, y2);
o plot([1 2 3 1], [2 0 4 2]);
% vykreslí trojúhelník z bodů (1,2), (2,0), (3,4)
• Specifikace stylu čáry
o Není třeba zadávat všechny specifikátory, lze použít samostatně, např. 'c', 'ro', 'y--', ':'
o Příklad použití
§ plot(0:0.01:pi, sin(0:0.01:pi), 'm');
§ plot(0:0.1:0.5, 0:-0.1:-0.5, 'p');
% vykreslí pouze datové body (bez čáry)
§ x=0:0.25:1;
y = [1.0, 0.1, -0.5, 0.2, 0.0];
plot(x, y, 'go--');
% čárkovaná zelená čára, ukazatel je kruh
§ x1=-0.5:0.25:0.5;
x2=0.0:0.1:0.3;
y1=x1.^2 + 1;
y2=[1.05,1.05, 1.1, 1.2];
plot(x1, y1, 'c+-.', x2, y2, 'r*:');
% dvě čáry pro dvě různé datové řady, jedna čerchovaná modrozelená se ukazatelem +, druhá tečkovaná červená s ukazatelem *
o LineWidth
§ Šířka čáry
o MarkerSize, MarkerEdgeColor, MarkerFaceColor
§ Velikost barva okraje a barva plochy ukazatele
§ Příklad použití
• x = -pi:pi/10:pi;
y = sin(x.^2);
plot(x, y, '--gs', 'LineWidth', 2,
'MarkerSize', 10, 'MarkerEdgeColor', 'b', 'MarkerFaceColor', [0.5, 0.5, 0.5]);
• Název grafu, popisky os, legenda
o title, ylabel, xlabel, legend o Příklad použití
§ x = linspace(-2*pi, 2*pi, 100);
y1 = sin(x);
y2 = cos(x);
figure
plot(x, y1, x, y2);
title('Graf funkci sinus a cosinus mezi -2\pi a 2\pi');
xlabel('-2\pi < x < 2\pi') ylabel('Hodnoty sinu a cosinu') legend('sin(x)', 'cos(x)')
% k zapsani pi lze pouzit TeX prikaz \pi
• Kombinace více grafů
o Pomocí příkazu hold on o Např.
§ x = linspace(0, 10, 50);
y1 = sin(x);
figure
plot(x, y1);
title('Combine Plots');
xlabel('0 < x < 10');
hold on
y2 = sin(x/2);
plot(x, y2);
y3 = 2*sin(x);
plot(x, y3, 'yo');
o Příkaz subplot() vytvoří v rámci okna mřížku podgrafů (viz dokumentace)
• Specifikace rozsahu os
o Pomocí příkazů xlim, ylim o Např.
§ x = linspace(-10, 10, 200);
y = sin(4*x)./exp(x);
plot(x, y) xlim([0 10]) ylim([-0.4 0.8])
grid on % prida mrizku do grafu
• Dvě osy y v grafu
o Pomocí příkazu yyaxis
o Příkaz yyaxis left vytvoří graf se dvěmi osami a přepne na levou. Další příkazy pro vykreslení a zadání vlastností os se budou týkat levé osy. Na pravou osu se přepneme pomocí yyaxis right. Např.
§ x = linspace(0,25);
y = sin(x./2);
yyaxis left plot(x, y) y2 = x.^2/2;
yyaxis right plot(x, y2)
o Pokud nefunguje příkaz yyaxis (v některých verzích Matlabu) použijte plotyy
Příkaz plot3
• Čárový graf ve 3D. Funguje obdobně jako funkce plot ve 2D, např. k vykreslení trojúhelníku z bodů (0,0,0), (1,1,1), (1,1,-1) lze použít:
o plot3([0 1 1 0], [0 1 1 0], [0 1 -1 0]);
Příkaz surf
• Slouží ke kreslení grafů z R2 do R.
• surf(X, Y, Z), kde X a Y jsou matice, reprezentující síť bodů (v X jsou první souřadnice, v Y druhé). Z je matice obsahující hodnoty funkce v příslušných bodech mřížky.
• Mřížku lze vytvořit pomocí příkazu [X, Y] = meshgrid(x, y), kde x je vektor souřadnic x, y je vektor souřadnic y mřížky. X je matice obsahující ve sloupcích kopie x, Y obsahuje v řádcích kopie y. Počet řádků obou matic je length(y), počet sloupců je length(x).
Stejný rozměr musí mít matice Z. Např.
o x = 0:0.1:0.3;
y = 0.1:0.1:0.3;
[X, Y] = meshgrid(x, y)
% vrátí
Z = sin(X.*Y); % vyčíslí hodnotu funkce v bodech mřížky (X(1,1), Y(1,1)), (X(1, 2), Y(1,2)), (X(1,3), Y(1,3)), atd. Nezapomeňte na tečku! (Proč?)
surf(X, Y, Z) % vykreslíme
Figure 1:Body mřížky, nad kterými je funkce vyčíslována (vlevo). Vyčíslená a vykreslená funkce (vpravo)
o [X,Y] = meshgrid(1:0.5:10,1:20);
Z = sin(X) + cos(Y);
surf(X,Y,Z)
• Podobně funguje např. příkaz mesh nebo contour (vrstevnicový graf). Vyzkoušejte (stačí nahradit surf v předchozím příkladu).
Další typy grafů s ukázkovým zdrojovým kódem najdete na
https://www.mathworks.com/products/matlab/plot-gallery.html
Příklady
Replikujte následující grafy:
1. x=linspace(2*pi, 4*pi);
y=sin(x).*cos(x);
...
s 2. Funkce sin na interval (0, 2*pi), cos na intervalu (pi, 3*pi).
3.