GeMM

Il metodo GeMM (General Matrix Multiply) implementa la moltiplicazione generale di due matrici. L'operazione è definita come C ← α A B + β C , dove le matrici A e B possono essere opzionalmente trasposte . Con una normale moltiplicazione delle matrici AB (MatMul), lo scalare alpha si presume sia pari a 1 e beta uguale a zero.

La differenza principale tra GeMM e MatMul in termini di efficienza è che MatMul crea sempre una nuova matrice/oggetto vettoriale, mentre GeMM lavora con un oggetto matrice esistente e non lo ricrea. Pertanto, quando si utilizza GeMM la memoria è pre-allocata per la matrice corrispondente, quindi, mentre si lavora con le stesse dimensioni della matrice, non ci saranno riallocazioni della memoria. Questo può essere un vantaggio importante di GeMM per il bulk computing, ad esempio, quando si eseguono ottimizzazioni in un tester di strategia o quando si allena una rete neurale.

Simile a MatMul, GeMM ha anche 4 sovraccarichi. Tuttavia, la semantica del quarto sovraccarico è stata modificata per consentire la moltiplicazione di un vettore verticale con uno orizzontale.

In un oggetto matrice/vettore esistente, non è necessario pre-allocare la memoria. La memoria verrà allocata e riempita di zeri alla prima chiamata GeMM.

Multiplying a matrix by a matrix:   matrix C[M][N] = α * ( matrix A[M][K] * matrix B[K][N]) + β * matrix C[M][N]

bool  matrix::GeMM(
  const matrix &A,    // prima matrice
  const matrix &B,    // seconda matrice
  double alpha,       // moltiplicatore alfa per prodotto AB
  double beta,        // moltiplicatore beta per matrice C
  uint   flags        // una combinazione di valori ENUM_GEMM (OR bitwise), che determina se le matrici A, B e C sono trasposte
   );

Multiplying a vector by a matrix: vector C[N] = α * ( vector A[K] * matrix B[K][N]) + β * vector C[N]

bool  vector::GeMM(
  const vector &A,    // vettore orizzontale
  const matrix &B,    // matrice
  double alpha,       // moltiplicatore alfa per prodotto AB
  double beta,        // moltiplicatore beta per vettore C
  uint   flags        // valore di enumerazione ENUM_GEMM che determina se la matrice A è trasposta
   );

Multiplying a matrix by a vector: vector C[M] = α * ( matrix A[M][K] * vector B[K] * ) + β * vector C[M]

bool  vector::GeMM(
  const matrix &A,    // matrice
  const vector &B,    // vettore verticale
  double alpha,       // moltiplicatore alfa per prodotto AB
  double beta,        // moltiplicatore beta per vettore C
  uint   flags        // Valore di enumerazione ENUM_GEMM che determina se la matrice B è trasposta
   );

Moltiplicare un vettore per un vettore: matrix C[M][N] = α * ( vector A[M] * vector B[N] * ) + β * matrix C[M][N]. Questo sovraccarico restituisce una matrice, a differenza di MatMul dove restituisce uno scalare.

bool  matrix::GeMM(
  const vector &A,    // primo vettore
  const vector &B,    // secondo vettore
  double alpha,       // moltiplicatore alfa per prodotto AB
  double beta,        // moltiplicatore beta per matrice C
  uint   flags        // Valore di enumerazione ENUM_GEMM che determina se la matrice C è trasposta
   );

Parametri

A

[in] Matrice o vettore.

B

[in] Matrice o vettore.

alpha

[in] Moltiplicatore alfa per il prodotto AB.

beta

[in] Moltiplicatore beta per la matrice C risultante.

flags

[in] Valore di enumerazione ENUM_GEMM che determina se le matrici A, B e C sono trasposte.

Valore Restituito

Restituisce true in caso di successo false altrimenti.

ENUM_GEMM

Enumerazione dei flag per il metodo GeMM.

ID

Descrizione

TRANSP_A

Usa la matrice trasposta A

TRANSP_B

Usa la matrice trasposta B

TRANSP_C

Usa la matrice trasposta C

Note

Matrici e vettori di tipo float, double e complex possono essere utilizzati come parametri A e B. Le varianti dei template del metodo GeMM sono le seguenti:

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);

Fondamentalmente la funzione generale di moltiplicazione della matrice è descritta come:

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

con le seguenti dimensioni: matrice A è M x K, matrice B è K x N e matrice C è M x N.

Pertanto, le matrici dovrebbero essere compatibili per la moltiplicazione, cioè il numero di colonne nella prima matrice dovrebbe essere uguale al numero di righe nella seconda matrice. La moltiplicazione di matrice non è commutativa: il risultato della moltiplicazione della prima matrice per la seconda non è uguale al risultato della moltiplicazione della seconda matrice per la prima nel caso generale.

 

Esempio:

void OnStart()
  {
   vector vector_a= {12345};
   vector vector_b= {4321};
   matrix matrix_c;
//-- calcola GeMM per due vettori
   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]]
   */
//-- creare matrici come vettori
   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]]
   */
//-- calcola GeMM per due matrici e ottieni lo stesso risultato
   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]]
   */
  }

 

Vedere anche

MatMul