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:
Coreimplementira vektore, matrice i polja te linearnu algebru i osnovne funkcije za rad s poljima (#include <Eigen/Core>)Eigenvaluesimplementira računanje karakterističnih vrijednosti i vektora te pripadne dekompozicije (#include <Eigen/Eigenvalues>)
Polja, matrice i vektori
Eigen::Matrixje tip kojim se zapisuju matriceEigen::Vectorje specijalizacije tipaEigen::Matrixkoja ima jedan stupacEigen::Arrayje 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 preciznosti- pomoćni nazivi tipova:
Eigen::Matrix3f3x3 matrica sfloatvrijednostima,Eigen::Matrix2d2x2 matrica sdoublevrijednostima
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
Bod 4 retka i 2 stupca pa izračunajte produkt te matrice i matriceA. Transponirajte matricuBpa izračunajte produkt matriceAi matrice dobivene transponiranjemB. - Dohvatite prvi stupac matrice
Bu vektor i izračunajte njegovu normu, a zatim dohvatite oba stupca matriceBu 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 > s1itd. (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.
Sparseimplementira 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 preciznosti-
spmat.insert(i, j) = vdodaje element vrijednostivna mjestui, jako element ne postoji, u protivnom:spmat.coeffRef(i, j) = vpostavlja element na mjestui, jna vrijednostvspmat.coeffRef(i, j) += vuvećava element na mjestui, jza vrijednostvspmat.coeffRef(i, j) -= vumanjuje element na mjestui, jza 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.
Author: Vedran Miletić