Comment effectuer un tirage aléatoire suivant une loi gaussienne multi-variante (également appelée loi multinormale) ? La réponse et un code C++ en prime.
Une possibilité est de considérer que chaque variable est indépendante des autres. On tire alors chaque variable dans une loi normale, en utilisant la méthode de Box-Muller :
En C++, tirer un chiffre y dans une loi normale de moyenne mean et d’écart-type std, ça donne quelque chose comme :
Malheureusement, se contenter de tirer toute les variables indépendamment ne permet pas de représenter une véritable loi multi-variante. Il manque en effet les co-variances.
Pour obtenir une loi normale prenant en compte les covariances, il faut déjà définir l’ensemble des variances et des covariances que l’on veut utiliser comme paramètres de la loi. Cela se fait sous la forme d’une matrice de variance-covariance, qui est carrée et symétrique, de la taille du nombre de variables et définie positive.
La première étape consiste à tirer un vecteur (du nombre de variables souhaité) en utilisant pour chaque élément un tirage dans une loi normale centrée réduite. Ensuite, on va factoriser la matrice de variance-covariance par une décomposition de Cholesky. Il suffit alors de pré-multiplier cette matrice par le vecteur aléatoire, et y ajouter un vecteur de moyenne.
En simplifiant, on aurait quelque chose comme ça :
Le code présenté dans l’archive ci-jointe est fait à la va-vite, non optimisé, l’interface est perclue de bogues (ne vous trompez pas dans l’appel de l’éxecutable), mais elle fait son boulot.
Exemple d’utilisation :
Voir aussi ces quelques passages sur Wikipédia :
Simulation d’une loi normale et multi-normale
factorisation de Cholesky
Le code présenté ici est à jour et maintenu sur le projet Open Metaheuristics, dans le fichier random.hpp.