2017-10-20 40 views
1

Hé donc je travaille sur ce code pour une analyse matérielle. J'ai une matrice générée pour chaque couche du matériau et je veux sauvegarder chacune de ces matrices comme leur propre élément. La façon dont je faisais ceci était de le sauvegarder dans un dictionnaire. Je forme alors une matrice en additionnant toutes les valeurs du dictionnaire. Maintenant, je fais cela pour trois conditions différentes qui me laisse avec 3 matrices: A, B et D. Je veux faire une matrice de tous ces éléments de sorte qu'il ressemble à:Matrice de matrices en python

 
    | A B | 
    | B D |

Cependant je ne peux pas l'obtenir pour imprimer correctement comme il dit toujours matrice: alors une des matrices telles que A. Il imprime la deuxième matrice, B, sur la troisième ligne où A a fini au lieu d'être à côté de A. Je dois également effectuer des opérations futures sur cette matrice massive donc je me demande quelle serait la meilleure façon de procéder. Ceci est une partie de mon code:

Qbars = {} 
    for i in plies: 

    Qbar11 = Q11 * math.cos(float(thetas[j]))**4 + Q22  *math.sin(float(thetas[j]))**4 + \ 
     2 * (Q12 + 2 * Q66) * math.sin(float(thetas[j]))**2 * math.cos(float(thetas[j]))**2 
     Qbar22 = Q11 * math.sin(float(thetas[j]))**4 + Q22 *math.cos(float(thetas[j]))**4 + \ 
     2 * (Q12 + 2 * Q66) * math.sin(float(thetas[j]))**2 * math.cos(float(thetas[j]))**2 
     Qbar12 = (Q11 + Q22 - 4 * Q66) * math.sin(float(thetas[j]))**2 * \ 
     math.cos(float(thetas[j]))**2 + Q12 * (math.cos(float(thetas[j]))**4 + \ 
     math.sin(float(thetas[j]))**4) 
     Qbar66 = (Q11 + Q22 - 2 * Q12 - 2 * Q66) * math.sin(float(thetas[j]))**2 * \ 
     math.cos(float(thetas[j])) **2 + Q66 * (math.sin(float(thetas[j]))**4 + \ 
     math.cos(float(thetas[j]))**4) 
     Qbar16 = (Q11 - Q12 - 2 * Q66) * math.cos(float(thetas[j]))**3 * \ 
     math.sin(float(thetas[j])) - (Q22 - Q12 - 2 * Q66) * math.cos(float(thetas[j])) * \ 
     math.sin(float(thetas[j]))**3 
     Qbar26 = (Q11 - Q12 - 2 * Q66) * math.cos(float(thetas[j])) * \ 
     math.sin(float(thetas[j]))**3 - (Q22 - Q12 - 2 * Q66) * \ 
     math.cos(float(thetas[j]))**3 * math.sin(float(thetas[j])) 

     Qbar = np.matrix ([[Qbar11, Qbar12, Qbar16], [Qbar12, Qbar22, Qbar26], \ 
     [Qbar16, Qbar26, Qbar66]]) 

     Qbars[i] = Qbar 

     if len(thetas) == 1: 
      j = 0 
     else: 
      j = j + 1 

    k=0 
    Alist = {} 
    for i in plies: 
     Alist[i] = Qbars[i].dot(h[k]) 
     if len(h) == 1: 
      k = 0 
     else: 
      k = k + 1 
    A = sum(Alist.values()) 

    ABD = ([A, B],[B, D]) 
    print ABD

L'une des opérations suivantes que je compte effectuer serait de multiplier la matrice par un réseau de 6x1 qui ressemblerait comme:

 | Nx |  | A A A B B B | 
    | Ny |  | A A A B B B | 
    | Nxy|  | A A A B B B | 
    ------ * ---------------- 
    | Mx |  | B B B D D D | 
    | My |  | B B B D D D | 
    | Mxy|  | B B B D D D |

Quelle serait la meilleure façon de faire cela?

EDIT: J'ai fait ce code plus court pour reproduire ce que j'ai affaire, je ne pouvais pas penser à la façon de le rendre encore plus petit.

import os 
import numpy as np 
import math 
os.system('cls') 
ang = raw_input("ENTER 0 (SPACE) 45 ") 
thetas = [int(i) for i in ang.split()] 
x = 40 
h = [3, 5] 
y = [1,2] 
j = 0 
Qbars = {} 
for i in y: 
    theta = [thetas[j] * math.pi/180] 
    Q = math.sin(float(thetas[j])) 
    Qbar = np.matrix ([[Q, Q, Q], [Q, Q, Q], [Q, Q, Q]]) 

    Qbars[i] = Qbar 

    if len(thetas) == 1: 
     j = 0 
    else: 
     j = j + 1 

print Qbars 
k=0 
Alist = {} 
for i in y: 
    Alist[i] = Qbars[i].dot(h[k]) 
    if len(h) == 1: 
     k = 0 
    else: 
     k = k + 1 
A = sum(Alist.values()) 

AAAA = ([A, A], [A, A]) 
print AAAA 
test = raw_input("Press ENTER to close")
+1

Je pense que vous devez sortir un extrait de code qui peut être exécuté, qui montre le problème auquel vous faites face. Il se lit comme la majorité de ce code ne concerne pas la question –

+0

Pour développer le commentaire d'Andy, veuillez lire [Comment créer un exemple minimal, complet et vérifiable] (https://stackoverflow.com/help/mcve) Si vous avez besoin de pointeurs sur la façon de le faire. – Taelsin

+0

Post EDITED avec un programme plus court qui peut être exécuté pour reproduire mon problème! – Azyru

Répondre

1

Comme d'autres l'ont noté, la classe de matrice est à présent pratiquement obsolète. Ils sont plus limités que ndarray s, avec très peu de fonctionnalités supplémentaires. La raison principale pour laquelle les gens préfèrent utiliser des matrices numpy est que l'algèbre linéaire (en particulier, la multiplication matricielle) fonctionne plus naturellement pour les matrices.

Cependant, pour autant que je peux dire que vous utilisez np.dot plutôt que les opérateurs arithmétiques surchargées de la classe matrix pour commencer, de sorte que vous ne verrez aucune perte de fonctionnalité de l'utilisation np.array à la place. De plus, si vous passer en python 3.5 ou plus récent, vous pouvez utiliser l'opérateur de multiplication de la matrice @ qui vous permettre d'écrire des choses telles que

Alist[i] = Qbars[i] @ h[k] 

Dans ce qui suit, je vais utiliser la classe ndarray au lieu de la classe matrix pour les raisons ci-dessus. Ainsi, votre question comporte deux parties principales: créer votre matrice de blocs et multiplier le résultat par un vecteur. Je suggère d'utiliser une version numpy mise à jour, depuis there's numpy.block introduit dans la version 1.13. Cela ne pratique exactement ce que vous voulez faire:

>>> import numpy as np 
>>> A,B,C = (np.full((3,3),k) for k in range(3)) 
>>> A 
array([[0, 0, 0], 
     [0, 0, 0], 
     [0, 0, 0]]) 
>>> B 
array([[1, 1, 1], 
     [1, 1, 1], 
     [1, 1, 1]]) 
>>> C 
array([[2, 2, 2], 
     [2, 2, 2], 
     [2, 2, 2]]) 
>>> np.block([[A,B],[B,C]]) 
array([[0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 1, 1, 1], 
     [0, 0, 0, 1, 1, 1], 
     [1, 1, 1, 2, 2, 2], 
     [1, 1, 1, 2, 2, 2], 
     [1, 1, 1, 2, 2, 2]]) 

De même, vous pouvez concaténer vos deux vecteurs 3-longueur à l'aide np.concatenate ou l'une des méthodes d'empilage (celles-ci sont disponibles dans des versions plus anciennes aussi).

Maintenant, le problème est que vous ne pouvez pas multiplier une matrice de forme (6,1) avec une matrice de forme (6,6), alors la question est ce que vous essayez vraiment de faire ici. Dans le cas où vous voulez multiplier chaque élément de votre matrice avec la ligne correspondante de votre vecteur, vous pouvez simplement multiplier vos tableaux (de la classe np.ndarray!) Et utiliser la diffusion de tableau:

>>> Q = np.block([[A,B],[B,C]]) # (6,6)-shape array 
>>> v = np.arange(6).reshape(-1,1) # (6,1)-shape array 
>>> v * Q 
array([[ 0, 0, 0, 0, 0, 0], 
     [ 0, 0, 0, 1, 1, 1], 
     [ 0, 0, 0, 2, 2, 2], 
     [ 3, 3, 3, 6, 6, 6], 
     [ 4, 4, 4, 8, 8, 8], 
     [ 5, 5, 5, 10, 10, 10]]) 

L'autre option est que vous voulez faire la multiplication matrice-vecteur, mais soit vous devez transposer votre vecteur (afin de multiplier avec la matrice de la droite) ou permuter l'ordre de la matrice et du vecteur (en multipliant le vecteur par la matrice à partir de la gauche). Exemple pour l'ex-:

>>> v.T @ Q # python 3.5 and up 
array([[12, 12, 12, 27, 27, 27]]) 

>>> v.T.dot(Q) 
array([[12, 12, 12, 27, 27, 27]]) 

Un autre avantage de tableaux (plutôt que des matrices) est que les tableaux peuvent être multidimensionnelle. Au lieu de placer des tableaux chiffrés à l'intérieur d'une dict et de les additionner de cette façon, vous pouvez définir un tableau 3d (une collection de tableaux 2d le long d'un troisième axe), puis vous pouvez additionner le long de la troisième dimension. Un avantage énorme de numpy est son besoin de mémoire efficace et ses performances, et ces aspects sont les plus forts si vous utilisez des objets et des méthodes numpy tout au long de votre code. Le mélange d'objets python natifs (tels que les dicts, les zips, les boucles) entrave généralement les performances.