GeMM

La méthode GeMM (General Matrix Multiply) implémente la multiplication générale de deux matrices. L'opération est définie comme C ← α A B + β C , où les matrices A et B peuvent être éventuellement transposées. Avec une multiplication normale des matrices AB (MatMul), le scalaire alpha est supposé égal à 1 et bêta égal à zéro.

La principale différence entre GeMM et MatMul en termes d'efficacité est que MatMul crée toujours un nouvel objet matrice/vecteur, tandis que GeMM fonctionne avec un objet matrice existant et ne le recrée pas. Par conséquent, lorsque vous utilisez GeMM et pré-allouez de la mémoire pour la matrice correspondante, alors, tout en travaillant avec les mêmes tailles de matrice, il n'y aura pas de réallocation de mémoire. Cela peut être un avantage important de GeMM pour le calcul en masse, par exemple, lors de l'exécution d'optimisations dans un testeur de stratégie ou lors de la formation d'un réseau de neurones.

De la même façon que MatMul, GeMM a également 4 surcharges. Cependant, la sémantique de la quatrième surcharge a été modifiée afin de permettre la multiplication d'un vecteur vertical par un vecteur horizontal.

Dans un objet matrice/vecteur existant, il n'est pas nécessaire de pré-allouer de la mémoire. La mémoire sera allouée et remplie de 0 au premier appel GeMM.

Multiplication d'une matrice par une matrice :   matrix C[M][N] = α * ( matrix A[M][K] * matrix B[K][N]) + β * matrix C[M][N]

bool  matrix::GeMM(
  const matrix &A,    // première matrice
  const matrix &B,    // deuxième matrice
  double alpha,       // multiplicateur alpha pour le produit AB
  double beta,        // multiplicateur beta pour la matrice C
  uint    flags        // une combinaison de valeurs ENUM_GEMM (OR au niveau du bit ), qui détermine si les matrices A, B et C sont transposées
   );

Multiplication d'un vecteur par une matrice : vector C[N] = α * ( vector A[K] * matrix B[K][N]) + β * vector C[N]

bool  vector::GeMM(
  const vector &A,    // vecteur horizontal
  const matrix &B,    // matrice
  double alpha,       // multiplicateur alpha pour le produit AB
  double beta,        // multiplicateur beta pour le vecteur C
  uint   flags        // ENUM_GEMM valeur d'énumération qui détermine si la matrice A est transposée
   );

Multiplication d'une matrice par un vecteur : vector C[M] = α * ( matrix A[M][K] * vector B[K] * ) + β * vector C[M]

bool  vector::GeMM(
  const matrix &A,    // matrice
  const vector &B,    // vecteur vertical
  double alpha,       // multiplicateur alpha pour le produit AB
  double beta,        // multiplicateur beta pour le vecteur C
  uint   flags        // ENUM_GEMM valeur d'énumération qui détermine si la matrice B est transposée
   );

Multiplication d'un vecteur par un vecteur : matrix C[M][N] = α * ( vector A[M] * vector B[N] * ) + β * matrix C[M][N]. Cette surcharge renvoie une matrice, contrairement à MatMul où elle renvoie un scalaire.

bool  matrix::GeMM(
  const vector &A,    // premier vecteur
  const vector &B,    // deuxième vecteur
  double alpha,       // multiplicateur alpha pour le produit AB
  double beta,        // beta pour la matrice C
  uint   flags        // ENUM_GEMM valeur d'énumération qui détermine si la matrice C est transposée
   );

Paramètres

A

[in]  Matrice ou vecteur.

B

[in]  Matrice ou vecteur.

alpha

[in]  Multiplicateur alpha pour le produit AB.

beta

[in]  Multiplicateur beta pour la matrice C résultante.

flags

[in]  La valeur d'énumération ENUM_GEMM qui détermine si les matrices A, B et C sont transposées.

Valeur de Retour

Renvoie true en cas de succès ou false sinon.

ENUM_GEMM

Valeurs de l'énumération pour la méthode GeMM.

ID

Description

TRANSP_A

Utilise la matrice transposée A

TRANSP_B

Utilise la matrice B transposée

TRANSP_C

Utilise la matrice transposée C

Note

Les matrices et les vecteurs de types float, double et complex peuvent être utilisés comme paramètres A et B. Les variantes de modèle de la méthode GeMM sont les suivantes :

bool matrix<T>::GeMM(const matrix<T> &A,const matrix<T> &B,T alpha,T beta,ulong flags);
bool matrix<T>::GeMM(const vector<T> &A,const vector<T> &B,T alpha,T beta,ulong flags);
 
bool vector<T>::GeMM(const vector<T> &A,const matrix<T> &B,T alpha,T beta,ulong flags);
bool vector<T>::GeMM(const matrix<T> &A,const vector<T> &B,T alpha,T beta,ulong flags);

Fondamentalement, la fonction générale de multiplication matricielle est décrite comme suit :

C[m,n] = α *Sum(A[m,k]*B[k,n]) + β*C[m,n]

avec les tailles suivantes : la matrice A est M x K, la matrice B est K x N et la matrice C est M x N.

Les matrices doivent donc être compatibles pour la multiplication, c'est-à-dire que le nombre de colonnes dans la première matrice doit être égal au nombre de lignes dans la deuxième matrice. La multiplication matricielle est non commutative : le résultat de la multiplication de la première matrice par la seconde n'est pas égal au résultat de la multiplication de la seconde matrice par la première dans le cas général.

 

Exemple :

void OnStart()
  {
   vector vector_a= {12345};
   vector vector_b= {4321};
   matrix matrix_c;
//--- calcule GeMM pour deux vecteurs
   matrix_c.GeMM(vector_avector_b10);
   Print("matrix_c:\n "matrix_c"\n");
   /*
   matrix_c:
    [[4,3,2,1]
    [8,6,4,2]
    [12,9,6,3]
    [16,12,8,4]
    [20,15,10,5]]
   */
//--- crée des matrices sous forme de vecteurs
   matrix matrix_a(51);
   matrix matrix_b(14);
   matrix_a.Col(vector_a0);
   matrix_b.Row(vector_b0);
   Print("matrix_a:\n "matrix_a);
   Print("matrix_b:\n "matrix_b);
   /*
   matrix_a:
   [[1]
   [2]
   [3]
   [4]
   [5]]
   matrix_b:
   [[4,3,2,1]]
   */
//-- calcule GeMM pour deux matrices et obtient le même résultat
   matrix_c.GeMM(matrix_amatrix_b10);
   Print("matrix_c:\n "matrix_c);
   /*
   matrix_c:
    [[4,3,2,1]
    [8,6,4,2]
    [12,9,6,3]
    [16,12,8,4]
    [20,15,10,5]]
   */
  }

 

Voir aussi

MatMul