Python中的矩阵矩阵

时间:2017-10-20 19:58:57

标签: python python-2.7 numpy matrix

嘿所以我正在研究这个代码进行材料分析。我为每个材质层生成了一个矩阵,我希望将每个矩阵保存为自己的元素。我这样做的方法是将它保存到字典中。然后,我通过对字典的所有值进行求和来形成一个矩阵。现在我在三个不同的条件下执行此操作,这使我得到3个矩阵:A,B和D.我想制作所有这些矩阵,使其看起来像:

    | A B |
    | B D |

然而我无法正确打印,因为它总是说矩阵:然后是A之类的矩阵之一。它在第三行打印第二个矩阵B,其中A结束而不是A的下一个。我还需要在这个庞大的矩阵上执行未来的操作,所以我想知道最好的方法是什么。这是我的代码的一部分:

    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

我打算执行的下一个操作之一是将矩阵乘以一个看起来像这样的6x1数组:

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

这样做的最佳方法是什么?

编辑:我制作了这个较短的代码来重现我正在处理的内容,我想不出如何让它变得更小。

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 个答案:

答案 0 :(得分:1)

正如其他人所说,矩阵类现在已经被弃用了。它们比ndarray更受限制,只有很少的附加功能。人们更喜欢使用numpy矩阵的主要原因是线性代数(特别是矩阵乘法)对矩阵更自然地起作用。

但是,据我所知,使用np.dot而不是matrix类的重载算术运算符开头,所以你不会看到任何功能丢失使用np.array代替。此外,如果您要切换到python 3.5或更新版本,您可以使用@矩阵乘法运算符来编写诸如

之类的内容。
Alist[i] = Qbars[i] @ h[k]

在下文中,出于上述原因,我将使用ndarray类而不是matrix类。

因此,您的问题有两个主要部分:创建块矩阵并将结果与​​向量相乘。我建议使用最新的numpy版本,因为版本1.13中引入了there's numpy.block。这很方便地完成你想要它做的事情:

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

同样,您可以使用np.concatenate或其中一种堆叠方法连接两个3长度向量(这些也可用于旧版本)。

现在,问题在于你不能将形状矩阵(6,1)与形状(6,6)的矩阵相乘,所以问题就是你真正想要做的事情这里。如果你想将矩阵的每个元素与向量的相应行相乘,你可以将数组(类np.ndarray!)乘以并使用数组广播:

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

另一种选择是你想要进行矩阵向量乘法,但是你必须转置你的向量(为了将它与右边的矩阵相乘)或者交换矩阵和向量的顺序(将向量与左边的矩阵相乘)。前者的例子:

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

数组(而不是矩阵)的另一个好处是数组可以是多维的。您可以定义一个3d数组(沿第三个轴的二维数组的集合),而不是将numpy数组放在一个dict中并将它们相加,然后你可以沿第三个维度求和。 numpy的一个巨大好处是它有效的内存需求和性能,如果你在代码中使用numpy对象和方法,这些方面是最强的。混合本机python对象(例如dicts,zips,loops)通常会影响性能。