Section author: Vedran Miletić
C++ biblioteka predložaka za linearnu algebru Eigen¶
Eigen je popularna C++ biblioteka predložaka koja implementira:
podatkovne strukture za linearnu algebru kao što su matrice i vektori te
s njima povezane algoritme kao što su rješavanje linearnih jednažbi, računanje karakterističnih vrijednosti i drugi
Funkcionalnost:
vektori i matrice svih veličina, od malih matrica fiksnih veličina do velikih matrica dinamički promjenjive veličine
svi standardni numerički tipovi podataka za elemente matrice, uključujući
std::complex
(dokumentacija na cppreference.com)gusti i rijetki vektori i matrice, dekompozicija matrica, računanje linearnih najmanjih kvadrata i geometrijske transformacije
u nepodržanim modulima: tenzori, nelinearna optimizacija, rješavanje polinomskih jednadžbi i brojne druge
Performanse:
omogućuje primjenu “lijenog izračuna” (engl. lazy evaluation) gdje god to ima smisla
provodi eksplicitnu vektorizaciju za SSE2/SSE3/SSE4, AVX/AVX2/AVX512, FMA i srodne ekstenzije na drugim arhitekturama
izbjegava se dinamička alokacija memorije kod matrica fiksne veličine
odpetljavaju se petlje kad to ima smisla
Osim toga, Eigen je dizajniran da bude jednostavan za korištenje programerima naviklim na C++.
Guste matrice i polja¶
Kratki pregled načina korištenja.
Moduli:
Core
implementira vektore, matrice i polja te linearnu algebru i osnovne funkcije za rad s poljima (#include <Eigen/Core>
)Eigenvalues
implementira računanje karakterističnih vrijednosti i vektora te pripadne dekompozicije (#include <Eigen/Eigenvalues>
)
Polja, matrice i vektori¶
Eigen::Matrix
je tip kojim se zapisuju matriceEigen::Vector
je specijalizacije tipaEigen::Matrix
koja ima jedan stupacEigen::Array
je polje (produkt dva polja računa se element po element, a ne kao produkt matrica)
Inicijalizacija:
Eigen::Matrix<float, 4, 3>
matrica od 4 retka i 3 stupca čiji su elementi brojevi s pomičnim zarezom jednostruke preciznostiEigen::Matrix<double, Dynamic, Dynamic>
matrica dinamički promjenjivog broja redaka i stupaca čiji su elementi brojevi s pomičnim zarezom dvostruke preciznostipomoćni nazivi tipova:
Eigen::Matrix3f
3x3 matrica sfloat
vrijednostima,Eigen::Matrix2d
2x2 matrica sdouble
vrijednostima
Aritmetički operatori (neka su mat1
, mat2
i mat3
matrice, vec1
i vec2
bilo kakvi vektori iste vrste, row1
retčani vektor, col1
stupčani vektor te s1
skalar):
zbrajanje:
mat1 + mat2
množenje sklalarom:
s1 * mat1
,mat1 * s1
,mat1 / s1
množenje matrice i vektora:
mat1 * col1
,row1 * mat1
množenje matrica:
mat1 * mat2
transponiranje:
mat2.transpose()
skalarni (unutarnji) produkt:
vec1.dot(vec2)
vektorski produkt:
vec1.cross(vec2)
vanjski produkt:
col1 * row1
norma:
vec1.norm()
Primjer korištenja:
#include <Eigen/Core>
#include <iostream>
int main() {
Eigen::Matrix2d A;
A << 2., 0., -0.5, 1.;
std::cout << A << std::endl;
std::cout << "trag: " << A.trace() << std::endl;
std::cout << "norma: " << A.norma() << std::endl;
std::cout << "minimalni koeficijent: " << A.minCoeff() << std::endl;
std::cout << "maksimalni koeficijent: " << A.maxCoeff() << std::endl;
return 0;
}
Zadatak
Dopunite primjer tako da inicijalizirate još jednu matricu
B
od 4 retka i 2 stupca pa izračunajte produkt te matrice i matriceA
. Transponirajte matricuB
pa izračunajte produkt matriceA
i matrice dobivene transponiranjemB
.Dohvatite prvi stupac matrice
B
u vektor i izračunajte njegovu normu, a zatim dohvatite oba stupca matriceB
u dva vektora i izračunajte njihov skalarni produkt.
Operatori na poljima (neka su array1
i array2
polja istog oblika, a s1
skalar):
aritmetički operatori element po element:
array1 + array2
,array1 - array2
,array1 * array2
,array1 / array2
usporedbe:
array1 < array2
,array1 => array2
,array2 > s1
itd. (rezultat usporedbe je polje elemenata tipabool
)funkcije:
array1.abs()
,array1.log()
,array1.pow(array2)
,array1.pow(s1)
itd.
Zadatak
Inicijalizirajte dva polja i dvije matrice s elementima iste vrijednosti pa usporedite rezultate korištenja aritmetičkih operatora +
i *
.
Rijetke matrice¶
Kratki pregled načina korištenja.
Sparse
implementira rijetke matrice i pripadnu linearnu algebru (#include <Eigen/Sparse>
)
Inicijalizacija:
SparseMatrix<double> spmat(1000, 100)
rijetka matrica od 1000 stupaca i 100 redaka čiji su elementi brojevi s pomičnim zarezom dvostruke preciznostispmat.insert(i, j) = v
dodaje element vrijednostiv
na mjestui, j
ako element ne postoji, u protivnom:spmat.coeffRef(i, j) = v
postavlja element na mjestui, j
na vrijednostv
spmat.coeffRef(i, j) += v
uvećava element na mjestui, j
za vrijednostv
spmat.coeffRef(i, j) -= v
umanjuje element na mjestui, j
za vrijednostv
Dohvaćanje svojstava:
spmat.nonZeros()
broj elemenata različitih od nulespmat.norm()
euklidska norma matricespmat.isCompressed()
provjera je li matrica zapisana u komprimiranom obliku
Aritmetički operatori (spmat1
i spmat2
rijetke matrice, s1
skalar, dm1
gusta matrica, dv1
gusti vektor):
zbrajanje:
spmat1 + spmat2
, oduzimanje:spmat1 - spmat2
množenje skalarom:
spmat1 * s1
,spmat1 / s1
množenje rijetkih matrica:
spmat1 * spmat2
množenje rijetkih matrica gustim matricama i vektorima:
spmat1 * dm1
,spmat1 * dv1
transponiranje:
spmat1.transpose()
Zadatak
Napravite program koji inicijalizira gustu matricu s 2000 redaka i 2000 stupaca i elementima tipa
double
. Za vrijeme dok se program izvodi izmjerite zauzeće memorije, korištenjemtop
-a (stupac RES) ilips
-a (stupac RSS).Napravite program koji inicijalizira rijetku matricu s 2000 redaka i 2000 stupaca i elementima tipa
double
. Postavite vrijednosti svih elemenata na dijagonali. Za vrijeme dok se program izvodi izmjerite zauzeće memorije, a zatim usporedite s prethodnim slučajem.