C'est ainsi que je l'ai compris après avoir un peu bricolé. Je suis heureux d'être corrigé et j'espère que cela vous aidera.
Disons que vous avez une matrice M de 2x3 éléments. Cela a deux dimensions, évidemment.
Je ne voyais pas de différence entre Matlab et Python lorsqu'on demandait de manipuler la matrice d'entrée selon les dimensions que la matrice possède déjà. Ainsi, les deux commandes
repmat(M,m,n) % matlab
np.tile(M,(m,n)) # python
sont réellement équivalentes pour une matrice de rang 2 (deux dimensions).
Les choses deviennent contre-intuitives lorsque vous demandez la répétition/le basculement sur plus de dimensions que la matrice d'entrée. Si l'on revient à la matrice M de rang deux et de forme 2x3, il suffit de regarder ce qui arrive à la taille/forme de la matrice de sortie. Disons que la séquence à manipuler est maintenant 1,1,2.
En Matlab
> size(repmat(M,1,1,2))
ans =
2 3 2
il a copié les deux premières dimensions (lignes et colonnes) de la matrice d'entrée et les a répétées une fois dans une nouvelle troisième dimension (copiée deux fois, donc). Fidèle à la dénomination repmat
pour la matrice de répétition.
En Python
>>> np.tile(M,(1,1,2)).shape
(1, 2, 6)
il a appliqué une procédure différente puisque, je présume, la séquence (1,1,2) est lue différemment que dans Matlab. Le nombre de copies dans le sens des colonnes, des lignes et de la dimension hors plan est lu de droite à gauche. L'objet résultant a une forme différente de celle de Matlab. On ne peut plus affirmer que repmat
y tile
sont des instructions équivalentes.
Afin d'obtenir tile
pour se comporter comme repmat
En Python, il faut s'assurer que la matrice d'entrée a autant de dimensions que d'éléments dans la séquence. Ceci est réalisé, par exemple, par un petit préconditionnement et la création d'un objet connexe N
N = M[:,:,np.newaxis]
Ensuite, du côté de l'entrée, on a N.shape = (2,3,1)
plutôt que M.shape = (2,3)
et du côté de la sortie
>>> np.tile(N,(1,1,2)).shape
(2, 3, 2)
qui était la réponse de size(repmat(M,1,1,2))
. Je suppose que c'est parce que nous avons demandé à Python d'ajouter la troisième dimension à la droite de (2,3) plutôt qu'à sa gauche, de sorte que Python calcule la séquence (1,1,2) comme cela était prévu dans la façon dont Matlab l'a lue.
L'élément dans [:,:,0]
dans la réponse Python pour N contiendra les mêmes valeurs que l'élément (:,:,1)
la réponse de Matlab pour M .
Enfin, je n'arrive pas à trouver un équivalent pour repmat
quand on utilise le produit de Kronecker à partir de
>>> np.kron(np.ones((1,1,2)),M).shape
(1, 2, 6)
sauf si I alors précondition M en N comme ci-dessus. Je dirais donc que la manière la plus générale d'avancer est d'utiliser les moyens de np.newaxis
.
Le jeu devient plus délicat lorsque l'on considère une matrice L de rang 3 (trois dimensions) et le cas simple où aucune nouvelle dimension n'est ajoutée dans la matrice de sortie. Ces deux instructions apparemment équivalentes ne produiront pas les mêmes résultats.
repmat(L,p,q,r) % matlab
np.tile(L,(p,q,r)) # python
car les directions de la ligne, de la colonne, hors du plan sont (p,q,r) dans Matlab et (q,r,p) dans Python, ce qui n'était pas visible avec les tableaux de rang 2. Là, il faut être prudent et obtenir les mêmes résultats avec les deux langages nécessiterait plus de préconditionnement.
Je suis conscient que ce raisonnement peut ne pas être général, mais je n'ai pu l'élaborer que jusqu'ici. J'espère que cela incitera d'autres personnes à le mettre à l'épreuve.