Une introduction à Armadillo

Installation

Je recommande d’installer Armadillo avec le gestionnaire de paquets de macOS Homebrew. C’est l’un des gestionnaires les plus utilisés pour le système d’exploitation de Apple du fait de sa facilité d’utilisation et de son interface integrée dans le terminal. Si Homebrew n’est pas encore installé dans votre système, copiez cette commande dans votre terminal:

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew install armadillo --c++11

Compilation

Pour utiliser Armadillo dans un fichier C++ il faut d’abord importer la librairie:

#include <armadillo>
$ g++ main.cc -o main.o -O2 -larmadillo
-l/usr/local/opt/armadillo/include

Premiers pas

Armadillo permet la manipulation de tableaux de 1, 2 ou 3 dimensions et définit de nombreux opérateurs classiques ce qui permet d’écrire un code compact et lisible. Nous nous limitons ici aux tableaux de 1 ou 2 dimensions.

  • matrices (MxN);
  • vecteurs; qui peuventêtre définis comme ligne (Nx1) ou colonne(1xN) et sont des sous-classes de matrices;
arma::Mat<double> A = arma::Mat<double>(); 
arma::mat B = arma::mat(); // both are equivalent
using namespace arma;
arma::mat A = arma::mat(); // matrix of doubles
arma::vec A = arma::vec(); vector of doubles
arma::umat A = arma::mat(); // matrix of unsigned int
arma::uvec A = arma::vec(); vector of unsigned int
arma::mat M1 = arma::mat(5,10,arma::fill::zero);
arma::mat M2 = arma::mat(size(M1),arma::fill::randu);
arma::mat M3 = arma::mat(size(M1),arma::fill::ones);
std::cout << M1.n_rows << "\n"; // returns '5'
std::cout << M1.n_cols << "\n"; // returns '10'
std::cout << M1.n_nonzero << "\n"; // returns '0'
std::cout << M3.n_nonzero << "\n"; // returns '50'
  • arma::fill::zero: initialise tous les éléments à 0;
  • arma::fill::ones: initialise tous les éléments à 1;
  • arma::fill::eye: initialise les éléments de la diagonale à 1 et les autres éléments à 0;
  • arma::fill::randu: initialise les éléments comme réalisations indépendantes de la loi uniforme sur l’intervalle [0,1];
  • arma::fill::randn: initialise les éléments comme réalisations indépendantes de la loi normale centrée réduite;
  • arma::fill::none: ne modifie aucun élément;
arma::mat fromString arma::mat("1 9;-1 3");
arma::datum::pi; // pi
arma::datum::inf; // infinite
arma::datum::nan; // not a number
fromString(0,0); // extrait '1'
fromString(30,30); // erreur !
fromString[1,0]; // extrait '9'
fromString[10,0]; // ??
vec x = vec();
colvec y = colvec();
x = fromString.row(0); // x = [1,9]
y = fromString.col(0); // x = [1;-1]
int firstR(2),lastR(3),firstC(3),lastC(4);// -- 1 --
arma::mat X = arma::mat(10,10,arma::fill::ones);
arma::mat Y = X.submat(firstR,lastR,firstC,lastC);std::cout << Y.n_rows << "\n";
std::cout << Y.n_cols << "\n";
// -- 2 --
X.submat(firstR,lastR,firstC,lastC) = mat(size(Y),arma::fill::zeros)
  • in_range() vérifie qu’un indice est valide, c’est-à-dire que si on essaye d’y accéder avec l’opérateur () une exception ne sera pas lancée.
arma::mat X = arma::mat(4,4,arma::fill:randu);std::cout << X.in_range(2,3) << "\n"; // returns True
std::cout << X.in_range(1,4) << "\n"; // returns False
std::cout << X.in_range(5,0) << "\n"; // returns False
std::cout << X.in_range(10,100) << "\n"; // returns False
  • is_empty() vérifie qu’une matrice est “vide”. Cette function membre renvoie la valeur True pour les matrices pour lesquelles la méthode .reset() a été appliquée ou pour les éléments initialisés avec le constructeur par défaut.
arma::mat X = arma::mat();
std::cout << X.is_empty() << "\n"; returns True;
X(0,0) = double(0.5);
std::cout << X.is_empty() << "\n"; returns False;
X.reset();
std::cout << X.is_empty() << "\n"; returns True;
  • is_finite() vérifie que tous les éléments d’une matrice sont finis (i.e. différent de inf ou de nan)
arma::mat X = arma::mat(3,10,arma::fill::ones);
std::cout << X.is_finite() << "\n"; returns True;
X(1,1) = arma::datum::inf;
std::cout << X.is_finite() << "\n"; returns False;
X(1,1) = double(0.0);
X(1,1) = arma::datum::inf;
std::cout << X.is_finite() << "\n"; returns False;
  • is_square() vérifie que la matrice est carrée (nombre de lignes égal au nombre de colonnes):
arma::mat X = arma::mat(3,10,arma::fill::ones);
std::cout << X.is_square() << "\n"; returns False;
arma::mat Y = arma::mat(3,3,arma::fill::eye);
std::cout << Y.is_square() << "\n"; returns True;
  • is_vec() vérifie si l’un des composants de la taille de la matrice est égal à 1 (i.e. s’il s’agit d’un vecteur ligne ou colone);
arma::mat a = arma::mat(3,10,arma::fill::ones);
std::cout << a.is_vec() << "\n"; returns False;
arma::mat b = arma::mat(1,3,arma::fill::zeros);
std::cout << b.is_vec() << "\n"; returns True;
arma::mat c = arma::mat(3,1,arma::fill::randu);
std::cout << c.is_vec() << "\n"; returns True;
arma::vec d = arma::vec(4,arma::fill::randu);
std::cout << d.is_vec() << "\n"; returns True;
arma::colvec e = arma::colvec(3,arma::fill::randu);
std::cout << e.is_vec() << "\n"; returns True;
  • has_inf() vérifie que les éléments de la matrice sont tous finis (i.e. différents de inf):
arma::vec r = arma::vec(100,arma::fill::zero);
std::cout << r.has_inf() << "\n"; returns False;
r(99) = arma::datum::nan;
std::cout << r.has_inf() << "\n"; returns False;
r(99) = arma::datum::inf;
std::cout << r.has_inf() << "\n"; returns True;
  • has_nan() vérifie que les éléments de la matrice sont tous des nombres(i.e. différents de nan):
arma::vec r = arma::vec(100,arma::fill::zero);
std::cout << r.has_nan() << "\n"; returns False;
r(99) = arma::datum::inf;
std::cout << r.has_nan() << "\n"; returns False;
r(99) = arma::datum::nan;
std::cout << r.has_nan() << "\n"; returns True;
  • q * A ou A * q : multiplication des éléments d’une matrice A par un scalaire q;
  • A + B : addition élément par éléments d’une matrice (elles doivent avoir la même taille);
  • A * B : multiplication classique de matrices (les tailles doivent être compatibles);
  • A / B : division élément par élément de la matrice A par la matrice B (elles doivent être de même taille et B doit être une matrice dont tous les éléments sonts différents de zéro);
  • A == B : revoie la valeur True si et seulement si les matrices sont de même taille et les éléments à la même position ont la même valeur;
  • A != B : revoie la valeur True si et seulement siA == B renvoie la valeur False;
  • A % B : multiplicatio élément par élément de la matrice A par la matrice B (elles doivent être de même taille);

--

--

Head of Data Engineering. I write about data science, mlops, python and sometimes C++

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
René-Jean Corneille

René-Jean Corneille

Head of Data Engineering. I write about data science, mlops, python and sometimes C++