嘿所以我正在研究这个代码进行材料分析。我为每个材质层生成了一个矩阵,我希望将每个矩阵保存为自己的元素。我这样做的方法是将它保存到字典中。然后,我通过对字典的所有值进行求和来形成一个矩阵。现在我在三个不同的条件下执行此操作,这使我得到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")
答案 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)通常会影响性能。