Fonctions sur les structures d'algèbre linéaire
Introduction
Notation des vecteurs, matrices et tenseurs
Dans le module Math, les structures multidimensionnelles ne servent pas uniquement aux calculs : elles constituent aussi un type de résultat possible pour les fonctions qui ne renvoient pas seulement une valeur scalaire. Les fonctions de chaînes de caractères qui recherchent certains motifs dans un texte en sont un exemple. Toutes les positions et longueurs des occurrences sont alors renvoyées dans une matrice.
En principe, les vecteurs, matrices et tenseurs peuvent être créés dans le module Math avec la syntaxe [ ... ]. Tous les types de données numériques sont possibles, mais pas <str>. Les éléments peuvent être des expressions, des constantes ou le contenu d'autres variables. Le type de données de la structure est toujours celui dans lequel tous les éléments peuvent être représentés au mieux.
Exemples :
num = 3.14159; // example for a variable as source
vec = [1, -2, false, num, 5]; // data type is <dbl> to represent num
mat = [ [ 1.1, num ] // 1st row
, [-num, 2.2 ] // 2nd row
, [ 3.1, 3.2 ] ]; // 3rd row
ten = [ [ [ 111, num, 113 ] // 1st matrix, first row
, [ 121, 122, 123 ] ] // second row
, [ [ 211, 212, 213 ] // 2nd matrix, first row
, [ 221, 222, num ] ] // second row
, [ [ 311, 312, 313 ] // 3rd matrix, first row
, [ 321, num, 323 ] ] // second row
, [ [ num, 412, 413 ] // 4th matrix, first row
, [ 421, 422, 423 ] ] ]; // second row
Lorsque les sous-éléments (lignes d'une matrice, matrices d'un tenseur) ont tous la même taille, la taille de la structure est déterminée uniquement par le nombre d'éléments et de sous-éléments. Dans l'exemple, vec comporte 5 éléments (selon l'utilisation, en lignes ou en colonnes), mat 3 lignes et 2 colonnes, et ten 4 tranches de matrice de 2 lignes et 3 colonnes chacune. Les différences de taille sont signalées comme erreur lors de la traduction ; aucun remplissage automatique (padding) n'a lieu.
Accès à des éléments individuels
Un élément d'un vecteur, d'une matrice ou d'un tenseur est également adressé avec la syntaxe [ ... ], les indices commençant toujours à 0, comme c'est l'usage dans les langages de programmation. Les indices peuvent aussi provenir de variables ou de calculs.
v_num = vec[3]; // liest das 4. Element des Vektors
m_num = mat[0, 1]; // liest in der 1. Zeile das 2. Element
t_422 = ten[3, 1, 1]; // liest aus der 4. Matrix, 2. Zeile, 2. Spalte
Opérations triviales sur les objets multidimensionnels
Les opérations suivantes sont implémentées directement dans la notation usuelle des formules :
-
La comparaison
==et!=est possible sur des objets multidimensionnels, à condition que les deux opérandes aient la même taille. -
L'addition et la soustraction d'objets multidimensionnels sont possibles, à condition que les deux opérandes aient la même taille.
M_Sum = M_1 + M_2;M_Dif = M_1 - M_2; -
Multiplication d'un objet multidimensionnel par un scalaire numérique. Le résultat est un objet de mêmes dimensions, dont chaque élément est mis à l'échelle en conséquence. La loi de commutativité est applicable.
M_Scaled_0 = M_Base * 2.56;M_Scaled_1 = 2.56 * M_Base;- Division d'un objet multidimensionnel par un scalaire numérique. Le résultat est un objet de mêmes dimensions, dont chaque élément est mis à l'échelle en conséquence. La division par une matrice ou un vecteur n'est pas autorisée.
M_Scaled_2 = M_Base / 2.56; -
La multiplication de deux objets multidimensionnels est possible si le nombre de colonnes du premier opérande correspond au nombre de lignes du second. Le résultat est un objet multidimensionnel ayant le nombre de lignes du premier et le nombre de colonnes du second opérande. Un vecteur ne distingue ici ni lignes ni colonnes : en tant que premier opérande, il est interprété comme vecteur ligne et, en tant que second opérande, comme vecteur colonne. Cela couvre sans doute 95 % des interprétations habituelles dans les applications techniques, sans avoir à recourir à une fonction de transposition.
M_mult = M_1 * M_2;V_row = V_1 * M; // V_1 interpreted as row-vectorV_col = M * V_2; // v_2 interpreted as column-vectorScalarProduct = V_1 * V_2; // by definitionCrossProduct = Cross(V_1, V_2); // := V_1 x V_2
Affectation d'un vecteur, d'une matrice ou d'un tenseur
En principe, une variable ne peut être écrite ou créée qu'à un seul endroit du jeu de formules. Cela s'applique également aux vecteurs, matrices et tenseurs.
Il est toutefois possible de renseigner indirectement des éléments individuels de la structure dans cette affectation. Dans ce cas, l'accès indexé à un élément doit figurer dans le texte de la formule après l'affectation proprement dite de la structure, afin que le compilateur puisse intégrer l'affectation de l'élément dans l'affectation de la structure entière.
Les références circulaires ne sont pas autorisées ici.
M_spare = Matrix(3, 3); // erzeugt zunächst eine 3x3 Matrix mit 0
M_spare[0,1] = 101; // ergänzt die erste Zuweisung für Element [0,1]
M_spare[1,2] = 202; // ergänzt die erste Zuweisung für Element [1,2]
M_spare[2,0] = 303; // ergänzt die erste Zuweisung für Element [2,0]
Chaque fois que la matrice M_spare est utilisée, elle a désormais le contenu suivant :
Cette écriture améliore la lisibilité du texte de la formule, en particulier pour les matrices ou vecteurs creux.
u_long = Vector(50, 3.14); // create a very long vector
u_long[ 3] = -3.14;
u_long[25] = -3.14;
u_long[44] = u_long[10] + u_long[11]; // not allowed !!!
Pour la mise à jour temporelle du vecteur, toutes les sources de données sont sur un pied d'égalité. La valeur du vecteur entier change donc dès qu'au moins un élément change. Il n'existe pas d'« état intermédiaire » dans lequel l'affectation des éléments n'aurait pas encore eu lieu ou n'aurait été effectuée que partiellement.
Export de parties d'un objet multidimensionnel
Pour extraire une partie donnée d'un objet multidimensionnel, les fonctions GetCol(), GetRow() ou GetSlice() peuvent être utilisées.
Il est ainsi possible d'exporter une ligne ou une colonne précise d'une matrice, ou une matrice unique à partir d'un tenseur comportant plusieurs tranches de matrice. GetSub() permet d'exporter librement une plage, définie dans chaque dimension par une plage d'indices de lignes, de colonnes ou de tranches.
Fonctions
Construction de vecteurs « Vector »
Les fonctions suivantes peuvent être utilisées pour construire un vecteur
u = Vector(size); // Mit 0 initialisierter Vektor der Dimension size x 1
u = Vector(size, v); // Mit v initialisierter Vektor der Dimension size x 1
L'orientation du vecteur, en ligne ou en colonne, n'est pas définie et est interprétée au mieux selon l'utilisation.
Vecteur unitaire « Normalize »
La fonction Normalize() détermine le vecteur unitaire du vecteur donné.
Si la norme du vecteur est nulle, la fonction renvoie soit un vecteur nul, soit la valeur de remplacement , afin de ne pas bloquer les étapes de calcul suivantes.
ev1 = Normalize(v);
ev2 = Normalize(v, v0);
Construction de matrices « Matrix »
Les fonctions suivantes peuvent être utilisées pour construire une matrice
A = Matrix(rows, columns); // Mit 0 initialisierte Matrix der Dimensionen rows x columns
B = Matrix(rows, columns, v); // Mit v initialisierte Matrix der Dimensionen rows x columns
Matrice identité « MIdent »
La fonction suivante renvoie une matrice identité de dimensions size x size
I = MIdent(size);
Matrice de rotation « MRot »
Il est possible de définir des matrices de rotation des types suivants
R_2 = MRot(alpha); // 2D-Rotationsmatrix um den Winkel alpha gegen den Uhrzeigersinn
R_3 = MRot(alpha, axis); // 3D-Rotationsmatrix um die mit axis bezeichnete Achse: x:0, y:1, z:2
M_3ypr = MRotYPR(y,p,r); // 3D-Rotationsmatrix, die eine durch Yaw, Pitch und Roll
// beschriebene Rotation beschreibt
M_3euler = MRotEuler(a,b,g); // 3D-Rotationsmatrix, die eine durch a, b, g beschriebene
// Euler-Rotation beschreibt
Avec
-
et
-
, on a
Voir aussi : Drehmatrix – Wikipedia
Avec
- , (Yaw),
- , (Pitch) et
- , (Roll), on a
Voir aussi : Eulersche – Winkel
Avec
- , (input Z-axis),
- , (node line, rotated X-axis) et
- , (output Z-axis), on a
Voir aussi : Eulersche – Winkel
Construction de tenseurs « Tensor »
Pour construire un tenseur de slices tranches de dimensions rows x columns, on utilise
T = Tensor(slices, rows, columns);
Propriétés des vecteurs, matrices et tenseurs
Vérification du type d'une variable « isScalar », « isVector », « isMatrix », « isTensor »
Les fonctions suivantes renvoient chacune true lorsque la variable possède la structure testée. Cela peut être utile lorsqu'une fonction, par exemple sFind(), renvoie soit un scalaire (-1, non trouvé), soit une matrice de résultats, et que la suite du traitement en dépend.
test1 = isScalar(var);
test2 = isVector(var);
test3 = isMatrix(var);
test4 = isTensor(var);
Interrogation des dimensions d'un objet « SizeOf »
L'interrogation des dimensions d'un objet renvoie un vecteur des dimensions, par exemple
VectorSize = SizeOf(v); // => [ 1, size ]
MatrixSize = SizeOf(M); // => [ 2, columns, rows]
TensorSize = SizeOf(T); // => [ 3, columns, rows, slices ]
La première composante indique le nombre de dimensions et les suivantes le nombre d'éléments dans chaque dimension.
Fonctions d'accès « GetCol », « GetRow », « GetSlice », « GetSub »
Ces fonctions servent à découper des parties d'un objet multidimensionnel, de sorte que le résultat est en général de nouveau un objet multidimensionnel. Pour accéder à un élément isolé, il est plus efficace d'utiliser la syntaxe d'indexation.
La coupe d'un objet multidimensionnel à un indice de colonne columnIndex donné peut être réalisée comme suit
v1 = GetCol(D, columnIndex);
v2 = GetCol(D, {...}); // Konfiguration verpflichtend!
// Konfiguration für alle Varianten
vx = GetCol(..., { col: <uint> // verpflichtend, falls kein columnIndex
, rBeg: <uint>
, rEnd: <uint>
, sBeg: <uint>
, sEnd: <uint>
});
Pour un vecteur, le résultat est un élément unique ; pour une matrice, un vecteur ; pour un tenseur, une matrice à l'indice de colonne indiqué. Pour les structures d'ordre supérieur, les plages copiées peuvent en outre être restreintes via l'objet de configuration.
| Propriété | Valeur | Description |
|---|---|---|
| col | <uint> | Indice de colonne pour le plan de coupe |
| rBeg | <uint> | Plage facultative pour les lignes |
| rEnd | <uint> | Plage facultative pour les lignes |
| sBeg | <uint> | Plage facultative pour les tranches |
| sEnd | <uint> | Plage facultative pour les tranches |
La coupe d'un objet multidimensionnel à un indice de ligne donné peut être réalisée comme suit
v1 = GetRow(D, rowIndex);
v2 = GetRow(D, {...}); // Konfiguration verpflichtend!
// Konfiguration für alle Varianten
vx = GetRow(..., { cBeg: <uint>
, cEnd: <uint>
, row: <uint> // verpflichtend, falls kein rowIndex
, sBeg: <uint>
, sEnd: <uint>
});
Pour un vecteur, le résultat est un élément unique ; pour une matrice, un vecteur ; pour un tenseur, une matrice à l'indice de ligne indiqué. Pour les structures d'ordre supérieur, les plages copiées peuvent en outre être restreintes via l'objet de configuration.
| Propriété | Valeur | Description |
|---|---|---|
| row | <uint> | Indice de ligne pour le plan de coupe |
| cBeg | <uint> | Plage facultative pour les colonnes |
| cEnd | <uint> | Plage facultative pour les colonnes |
| sBeg | <uint> | Plage facultative pour les tranches |
| sEnd | <uint> | Plage facultative pour les tranches |
La coupe d'un objet multidimensionnel à un indice de tranche donné peut être réalisée comme suit
v1 = GetSlice(D, sliceIndex);
v2 = GetSlice(D, {...}); // Konfiguration verpflichtend!
// Konfiguration für alle Varianten
vx = GetSlice(..., { cBeg: <uint>
, cEnd: <uint>
, rBeg: <uint>
, rEnd: <uint>
, slice:<uint> // verpflichtend, falls kein sliceIndex
});
Pour un vecteur, le résultat est un élément unique ; pour une matrice, un vecteur ; pour un tenseur, une matrice à l'indice de tranche indiqué. Pour les structures d'ordre supérieur, les plages copiées peuvent en outre être restreintes via l'objet de configuration.
| Propriété | Valeur | Description |
|---|---|---|
| slice | <uint> | Indice de tranche pour le plan de coupe |
| cBeg | <uint> | Plage facultative pour les colonnes |
| cEnd | <uint> | Plage facultative pour les colonnes |
| rBeg | <uint> | Plage facultative pour les lignes |
| rEnd | <uint> | Plage facultative pour les lignes |
L'extraction d'une sous-structure de données à partir d'une structure de données s'effectue comme suit
D1 = GetSub(D, { cBeg: <uint>
, cEnd: <uint>
, rBeg: <uint>
, rEnd: <uint>
, sBeg: <uint>
, sEnd: <uint>
});
| Propriété | Valeur | Description |
|---|---|---|
| cBeg | <uint> | Plage facultative pour les colonnes |
| cEnd | <uint> | Plage facultative pour les colonnes |
| rBeg | <uint> | Plage facultative pour les lignes |
| rEnd | <uint> | Plage facultative pour les lignes |
| sBeg | <uint> | Plage facultative pour les tranches |
| sEnd | <uint> | Plage facultative pour les tranches |
Fonctions de traitement
Transposition « Trans »
La transposition d'une matrice M x N renvoie une matrice N x M dans laquelle les lignes et les colonnes sont échangées ; elle se calcule comme suit
A_t = Trans(A);
Produit vectoriel « Cross »
Le produit vectoriel de deux vecteurs u et v de longueur 2 ou 3 renvoie un vecteur perpendiculaire à ceux-ci, dont la longueur correspond à l'aire sous-tendue par les deux vecteurs ; il se calcule comme suit
w = Cross(u, v);
Décomposition LU « LUDecomp »
La décomposition LU d'une matrice M renvoie une matrice triangulaire inférieure L et une matrice triangulaire supérieure U sous la forme d'un tenseur à deux tranches ; elle peut être réalisée comme suit
T = LUDecomp(M);
L = GetSlice(T, 0);
U = GetSlice(T, 1);
Déterminant « Det »
Le déterminant d d'une matrice carrée M peut être calculé comme suit
d = Det(M);
Longueur d'un vecteur « Length »
Calcul de la longueur d'un vecteur ; voir aussi abs(...)
len = Length(v);