Álgebra linear com Armadillo
Date: 2019-12-17Last modified: 2023-02-17

Algebra linear com a biblioteca armadillo.
$$
A_{m,n} =
\begin{pmatrix}
a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\
a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{m,1} & a_{m,2} & \cdots & a_{m,n}
\end{pmatrix}
$$
Armadillo é uma biblioteca de álgebra linear para C++ rápida e fácil de usar, com sintaxe parecida com a do Matlab.
Provê suporte para:
- vetores (tensores de primeira ordem)
- matrizes (tensores de segunda ordem)
- cubos (tensores de terceira ordem)
- matrizes densas e esparsas
- números inteiros, de ponto flutuante e complexos
- decomposição (via LAPACK)
- multi-thread (Intel MKL ou OpenBLAS)
- avaliador de expressão baseado em meta-programação
- paralelização (via OpenMP)
Principais usos:
- machine learning
- reconhecimento de padrões
- visão computacional
- processamento de sinais
- bioinformática
- estatística
- finanças
Instalação no Debian
apt install libarmadillo-dev
Instalação no MacOS
brew install armadillo
Exemplos de uso
#include <armadillo>
#include <iostream>
using namespace std;
using namespace arma;
int main()
{
// inicia o gerador de números aleatórios
arma_rng::set_seed_random();
// Cria uma matriz com dados aleatório com dimensão 2x3
auto A = randu( 2, 3 );
cout << A << endl;
// 0.7038 0.6819 0.9555
// 0.3804 0.9666 0.9270
// Transposta
cout << A.t() << endl;
// 0.7526 0.5681
// 0.5874 0.9469
// 0.3562 0.9346
// Multiplicação de matrizes
cout << A.t() * A << endl;
// 0.0536 0.2644 0.2534
// 0.4731 0.3874 0.9599
// 0.1739 0.3313 0.4768
mat B( 3, 3, fill::randu );
cout << B << endl;
// 0.9563 0.8955 0.0919
// 0.3291 0.3086 0.3452
// 0.1894 0.9898 0.8642
cout << "Determinante: " << det( B ) << endl;
// Determinante: -0.243228
auto C = randu( 3, 3 );
cout << C << endl;
// 0.5561 0.6219 0.2147
// 0.3105 0.2813 0.9172
// 0.3408 0.1925 0.4703
cout << "Determinante: " << det( C ) << endl;
// Determinante: -0.254525
mat D = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
cout << D << endl;
// 1.0000 2.0000 3.0000
// 4.0000 5.0000 6.0000
// 7.0000 8.0000 9.0000
cout << "Determinante: " << det( D ) << endl;
// Determinante: 6.66134e-16
D.row( 0 ) = D.row( 1 ) + D.row( 2 );
cout << D << endl;
// 11.0000 13.0000 15.0000
// 4.0000 5.0000 6.0000
// 7.0000 8.0000 9.0000
D.row( 1 ) = D.row( 1 ) * 5;
cout << D << endl;
// 11.0000 13.0000 15.0000
// 20.0000 25.0000 30.0000
// 7.0000 8.0000 9.0000
//
D.row( 2 ).zeros();
cout << D << endl;
// 11.0000 13.0000 15.0000
// 20.0000 25.0000 30.0000
// 0 0 0
D.col( 2 ) = D.col( 2 ) + 10;
cout << D << endl;
// 11.0000 13.0000 25.0000
// 20.0000 25.0000 40.0000
// 0 0 10.0000
D = diagmat( D );
cout << D << endl;
// 11.0000 0 0
// 0 25.0000 0
// 0 0 10.0000
D.save( "D.bin" );
D.save( "D.txt", arma_ascii );
// ARMA_MAT_TXT_FN008
// 3 3
// 1.10000000000000e+01 0.00000000000000e+00 0.00000000000000e+00
// 0.00000000000000e+00 2.50000000000000e+01 0.00000000000000e+00
// 0.00000000000000e+00 0.00000000000000e+00 1.00000000000000e+01
auto O = ones( 2, 2 );
cout << O << endl;
// 1.0000 1.0000
// 1.0000 1.0000
auto Z = zeros( 3, 5 );
cout << Z << endl;
// 0 0 0 0 0
// 0 0 0 0 0
// 0 0 0 0 0
mat F1, F2;
F1.load( "D.bin" );
F2.load( "D.txt" );
cout << F1 << endl;
// 11.0000 0 0
// 0 25.0000 0
// 0 0 10.000
cout << F1 - F2 << endl;
// 0 0 0
// 0 0 0
// 0 0 0
mat F( 2, 3 );
F.fill( 3.14 );
cout << F << endl;
// 3.1400 3.1400 3.1400
// 3.1400 3.1400 3.1400
F = F.ones();
F.col( 0 ) *= datum::pi;
F.col( 1 ) *= datum::inf;
F.col( 2 ) *= datum::nan;
cout << F << endl;
// 3.1416 inf nan
// 3.1416 inf nan
return 0;
}