Publicado em: 17/Dec/2019
Atualizado em: 04/Jan/2020
C++

Álgebra linear com 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

1apt install libarmadillo-dev

Instalação no MacOS

1brew install armadillo

Exemplos de uso

  1#include <armadillo>
  2#include <iostream>
  3
  4using namespace std;
  5using namespace arma;
  6
  7int main()
  8{
  9  // inicia o gerador de números aleatórios
 10  arma_rng::set_seed_random();
 11
 12  // Cria uma matriz com dados aleatório com dimensão 2x3
 13  auto A = randu( 2, 3 );
 14  cout << A << endl;
 15  //    0.7038   0.6819   0.9555
 16  //    0.3804   0.9666   0.9270
 17
 18  // Transposta
 19  cout << A.t() << endl;
 20  //    0.7526   0.5681
 21  //    0.5874   0.9469
 22  //    0.3562   0.9346
 23
 24  // Multiplicação de matrizes
 25  cout << A.t() * A << endl;
 26  //    0.0536   0.2644   0.2534
 27  //    0.4731   0.3874   0.9599
 28  //    0.1739   0.3313   0.4768
 29
 30  mat B( 3, 3, fill::randu );
 31  cout << B << endl;
 32  //    0.9563   0.8955   0.0919
 33  //    0.3291   0.3086   0.3452
 34  //    0.1894   0.9898   0.8642
 35
 36  cout << "Determinante: " << det( B ) << endl;
 37  // Determinante: -0.243228
 38
 39  auto C = randu( 3, 3 );
 40  cout << C << endl;
 41  //    0.5561   0.6219   0.2147
 42  //    0.3105   0.2813   0.9172
 43  //    0.3408   0.1925   0.4703
 44  cout << "Determinante: " << det( C ) << endl;
 45  // Determinante: -0.254525
 46
 47  mat D = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
 48  cout << D << endl;
 49  //    1.0000   2.0000   3.0000
 50  //    4.0000   5.0000   6.0000
 51  //    7.0000   8.0000   9.0000
 52  cout << "Determinante: " << det( D ) << endl;
 53  // Determinante: 6.66134e-16
 54
 55  D.row( 0 ) = D.row( 1 ) + D.row( 2 );
 56  cout << D << endl;
 57  // 11.0000   13.0000   15.0000
 58  //  4.0000    5.0000    6.0000
 59  //  7.0000    8.0000    9.0000
 60
 61  D.row( 1 ) = D.row( 1 ) * 5;
 62  cout << D << endl;
 63  // 11.0000   13.0000   15.0000
 64  // 20.0000   25.0000   30.0000
 65  //  7.0000    8.0000    9.0000
 66  //
 67
 68  D.row( 2 ).zeros();
 69  cout << D << endl;
 70  // 11.0000   13.0000   15.0000
 71  // 20.0000   25.0000   30.0000
 72  //       0         0         0
 73
 74  D.col( 2 ) = D.col( 2 ) + 10;
 75  cout << D << endl;
 76  // 11.0000   13.0000   25.0000
 77  // 20.0000   25.0000   40.0000
 78  //       0         0   10.0000
 79
 80  D = diagmat( D );
 81  cout << D << endl;
 82  // 11.0000         0         0
 83  //       0   25.0000         0
 84  //       0         0   10.0000
 85
 86  D.save( "D.bin" );
 87
 88  D.save( "D.txt", arma_ascii );
 89  // ARMA_MAT_TXT_FN008
 90  // 3 3
 91  //    1.10000000000000e+01   0.00000000000000e+00   0.00000000000000e+00
 92  //    0.00000000000000e+00   2.50000000000000e+01   0.00000000000000e+00
 93  //    0.00000000000000e+00   0.00000000000000e+00   1.00000000000000e+01
 94
 95  auto O = ones( 2, 2 );
 96  cout << O << endl;
 97  // 1.0000   1.0000
 98  // 1.0000   1.0000
 99
100  auto Z = zeros( 3, 5 );
101  cout << Z << endl;
102  // 0        0        0        0        0
103  // 0        0        0        0        0
104  // 0        0        0        0        0
105
106  mat F1, F2;
107  F1.load( "D.bin" );
108  F2.load( "D.txt" );
109  cout << F1 << endl;
110  // 11.0000         0         0
111  //       0   25.0000         0
112  //       0         0   10.000
113
114  cout << F1 - F2 << endl;
115  // 0        0        0
116  // 0        0        0
117  // 0        0        0
118
119  mat F( 2, 3 );
120  F.fill( 3.14 );
121  cout << F << endl;
122  // 3.1400   3.1400   3.1400
123  // 3.1400   3.1400   3.1400
124
125  F = F.ones();
126  F.col( 0 ) *= datum::pi;
127  F.col( 1 ) *= datum::inf;
128  F.col( 2 ) *= datum::nan;
129  cout << F << endl;
130  // 3.1416      inf      nan
131  // 3.1416      inf      nan
132
133  return 0;
134}

Referências

comments powered by Disqus