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 bytů, celá matice s rozměry m × n je uložena v souvislém poli o délce 8mn bytů.
Ří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). 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ými nenulový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 jeho hodnota 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-ti diagonální matici D rozměru m × m s prvky x(i) umístěnými na diagonále d(i). Např.