Python中的矩阵矩阵 [英] Matrix of matrices in python

查看:68
本文介绍了Python中的矩阵矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hey so I'm working on this code for a material analysis. I have a matrix generated for each layer of the material and I want to save each of these matrices as their own element. The way I was doing this was by saving it to a dictionary. I then form one matrix by summing all the values of the dictionary. Now I do this for three different conditions which leaves me with 3 matrices: A, B, and D. I want to make a matrix of all of these so that it looks like:


    | A B |
    | B D |

但是我不能正确地打印它,因为它总是说矩阵:然后是诸如A之类的矩阵.它在第二行B上打印第二个矩阵B,A终止于该行,而不是紧邻A.我还需要在这个庞大的矩阵上执行将来的操作,所以我想知道实现此目标的最佳方法是什么.这是我的代码的一部分:

However I can't get it to print properly as it always says matrix: then one of the matrices such as A. It prints the second matrix, B, on the third line where A ended instead of being next to A. I also need to perform future operations on this massive matrix so I'm wondering what the best way to go about that would be. This is a part of my 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

我打算执行的下一个操作之一是将矩阵乘以一个如下所示的6x1数组:

One of the next operations I intend to perform would be to multiply the matrix by a 6x1 array that would look like such:

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

执行此操作的最佳方法是什么?

What would be the best way to go about doing this?

我做了这段较短的代码来重现我正在处理的内容,我想不出如何将其缩小.

I made this shorter code to reproduce what I'm dealing with, I couldn't think of how to make it even smaller.

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

推荐答案

正如其他人所指出的,

As others have noted, the matrix class is pretty much deprecated by now. They are more limited than ndarrays, with very little additional functionality. The main reason why people prefer to use numpy matrices is that linear algebra (in particular, matrix multiplication) works more naturally for matrices.

但是,据我所知,您使用的是np.dot而不是matrix类的重载算术运算符,因此使用np.array不会导致功能损失.此外,如果您要切换到python 3.5或更高版本,则可以使用@矩阵乘法运算符,该运算符可以让您编写诸如

However, as far as I can tell you're using np.dot rather than the overloaded arithmetic operators of the matrix class to begin with, so you would not see any loss of functionality from using np.array instead. Furthermore, if you would switch to python 3.5 or newer, you could use the @ matrix multiplication operator that would let you write things such as

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

出于上述原因,下面我将使用ndarray类而不是matrix类.

In the following I'll use the ndarray class instead of the matrix class for the above reasons.

因此,您的问题有两个主要部分:创建块矩阵并将结果与​​向量相乘.我建议使用最新的numpy版本,因为

So, your question has two main parts: creating your block matrix and multiplying the result with a vector. I suggest using an up-to-date numpy version, since there's numpy.block introduced in version 1.13. This conveniently does exactly what you want it to do:

>>> 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个长度的向量.

Similarly, you can concatenate your two 3-length vectors using np.concatenate or one of the stacking methods (these are available in older versions too).

现在,问题是您不能将形状为(6,1)的矩阵与形状为(6,6)的矩阵相乘,所以问题是您实际上要在这里做什么.如果您想将矩阵的每个元素与向量的相应行相乘,则可以乘以数组(属于np.ndarray!类)并利用数组广播:

Now, the problem is that you can't multiply a matrix of shape (6,1) with a matrix of shape (6,6), so the question is what you're really trying to do here. In case you want to multiply each element of your matrix with the corresponding row of your vector, you can just multiply your arrays (of class np.ndarray!) and make use of array broadcasting:

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

另一种选择是您要进行矩阵向量乘法,但是要么必须转置向量(以便将其与右边的矩阵相乘),要么交换矩阵和向量的顺序(将向量与左边的矩阵相乘).前者的示例:

The other option is that you want to do matrix-vector multiplication, but then either you have to transpose your vector (in order to multiply it with the matrix from the right) or swap the order of the matrix and the vector (multiplying the vector with the matrix from the left). Example for the former:

>>> 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数组(沿第三个轴的2d数组的集合),然后沿第三个维度求和,而不是将numpy数组放入字典中并以这种方式求和. numpy的一大好处是其高效的内存需求和性能,如果在整个代码中都使用numpy对象和方法,则这些方面将是最强的.混合本机python对象(例如dict,zip,循环)通常会影响性能.


Another benefit of arrays (rather than matrices) is that arrays can be multidimensional. Instead of putting numpy arrays inside a dict and summing them that way, you could define a 3d array (a collection of 2d arrays along a third axis), then you could sum along the third dimension. One huge benefit of numpy is its efficient memory need and performance, and these aspects are strongest if you use numpy objects and methods all through your code. Mixing native python objects (such as dicts, zips, loops) typically hinders performance.

这篇关于Python中的矩阵矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆