使用对角叠加构建Scipy矩阵

时间:2014-01-15 14:19:33

标签: arrays numpy scipy

我想在偏移位置覆盖几个相等4x4大小的数组,从而创建一个重叠元素加在一起的大数组。

[a] 0 0 0
 0 [a+b] 0 0
 0 0 [b+c] 0
 0 0 0 [c+...

这用于创建用于连续光束分析的刚度矩阵。这很容易用循环创建,但使用Scipy稀疏矩阵例程是否有更好的方法? block_diag已关闭,但未提供叠加方法。

Members = [[100.0, 1000.0],[100.0, 2000.0],[200.0, 2000.0]]

SSM = np.zeros((2*M+2,2*M+2), dtype = float)
i=0
for mem in Members:
    a = SMX(mem)
    print a
    print "*"*40

    SSM[i:i+4,i:i+4] = SSM[i:i+4,i:i+4] + a
    print SSM
    i +=2

def SMX(member):
    """ Prismatic beam member stiffness function
    Purpose: Create a member stiffness matrix for a given set of member parameters.
    Input:  Modulus of elasticity - E
            Moment of inertia with respect to the z axis - Iz
            Length of the span - L

    Returns: 4 x 4 matrix representing the member stiffness with respect to end conditions    
"""

    L = member[0]
    Iz = member[1]

    pbms = np.zeros((4,4), dtype = float)

    pbms[0,0] = (12.0 * E * Iz)/L**2
    pbms[0,1] = (6.0 * E * Iz)/L**2
    pbms[0,2] = -pbms[0,0]
    pbms[0,3] = pbms[0,1]

    pbms[1,0] = pbms[0,1]
    pbms[1,1] = (4.0 * E * Iz)/L
    pbms[1,2] = -pbms[0,1]
    pbms[1,3] = (2.0 * E * Iz)/L

    pbms[2,0] = pbms[0,2]
    pbms[2,1] = -pbms[0,1]
    pbms[2,2] = pbms[0,0]
    pbms[2,3] = -pbms[0,1]

    pbms[3,0] = pbms[0,1]
    pbms[3,1] = pbms[1,3]
    pbms[3,2] = -pbms[0,1]
    pbms[3,3] = pbms[1,1]

    return pbms

结果输出:

[[  12000.    6000.  -12000.    6000.]
 [   6000.  400000.   -6000.  200000.]
 [ -12000.   -6000.   12000.   -6000.]
 [   6000.  200000.   -6000.  400000.]]
****************************************
[[  12000.    6000.  -12000.    6000.       0.       0.       0.       0.]
 [   6000.  400000.   -6000.  200000.       0.       0.       0.       0.]
 [ -12000.   -6000.   12000.   -6000.       0.       0.       0.       0.]
 [   6000.  200000.   -6000.  400000.       0.       0.       0.       0.]
 [      0.       0.       0.       0.       0.       0.       0.       0.]
 [      0.       0.       0.       0.       0.       0.       0.       0.]
 [      0.       0.       0.       0.       0.       0.       0.       0.]
 [      0.       0.       0.       0.       0.       0.       0.       0.]]
[[  24000.   12000.  -24000.   12000.]
 [  12000.  800000.  -12000.  400000.]
 [ -24000.  -12000.   24000.  -12000.]
 [  12000.  400000.  -12000.  800000.]]
****************************************
[[   12000.     6000.   -12000.     6000.        0.        0.        0.
         0.]
 [    6000.   400000.    -6000.   200000.        0.        0.        0.
         0.]
 [  -12000.    -6000.    36000.     6000.   -24000.    12000.        0.
         0.]
 [    6000.   200000.     6000.  1200000.   -12000.   400000.        0.
         0.]
 [       0.        0.   -24000.   -12000.    24000.   -12000.        0.
         0.]
 [       0.        0.    12000.   400000.   -12000.   800000.        0.
         0.]
 [       0.        0.        0.        0.        0.        0.        0.
         0.]
 [       0.        0.        0.        0.        0.        0.        0.
         0.]]
[[   6000.    3000.   -6000.    3000.]
 [   3000.  400000.   -3000.  200000.]
 [  -6000.   -3000.    6000.   -3000.]
 [   3000.  200000.   -3000.  400000.]]
****************************************
[[   12000.     6000.   -12000.     6000.        0.        0.        0.
         0.]
 [    6000.   400000.    -6000.   200000.        0.        0.        0.
         0.]
 [  -12000.    -6000.    36000.     6000.   -24000.    12000.        0.
         0.]
 [    6000.   200000.     6000.  1200000.   -12000.   400000.        0.
         0.]
 [       0.        0.   -24000.   -12000.    30000.    -9000.    -6000.
      3000.]
 [       0.        0.    12000.   400000.    -9000.  1200000.    -3000.
    200000.]
 [       0.        0.        0.        0.    -6000.    -3000.     6000.
     -3000.]
 [       0.        0.        0.        0.     3000.   200000.    -3000.
    400000.]]

注意到我遗漏了上面的M = 3.

2 个答案:

答案 0 :(得分:1)

我没有看到scipy.sparse.block_diag的问题,但我可能并不完全明白“叠加​​”的含义。例如,您在问题中说明的输出可以形成如下:

In [41]: from scipy import sparse

In [42]: a = np.array([[1, 2], [3, 4]])

In [43]: b = np.array([[5, 6], [7, 8]])

In [44]: c = np.array([[9, 10], [11, 12]])

In [45]: m = sparse.block_diag([a, a+b, b+c])

In [46]: m.A
Out[46]: 
array([[ 1,  2,  0,  0,  0,  0],
       [ 3,  4,  0,  0,  0,  0],
       [ 0,  0,  6,  8,  0,  0],
       [ 0,  0, 10, 12,  0,  0],
       [ 0,  0,  0,  0, 14, 16],
       [ 0,  0,  0,  0, 18, 20]])

编辑:在浏览了一些关于光束分析的资料后,我想我更了解你想要如何叠加矩阵。

例如,假设有四个2x2阵列a,b,c和d。 “叠加”的示例如下:

a[0,0]     a[0,1]            0              0            0
a[1,0]  a[1,1]+b[0,0]     b[0,1]            0            0
  0        b[1,0]      b[1,1]+c[0,0]     c[0,1]          0
  0           0           c[1,0]      c[1,1]+d[0,0]  d[0,1]
  0           0              0           d[1,0]      d[1,1]

此处演示了使用block_diag形成此方法的一种方法。它涉及一个带有每个2x2数组的术语的表达式,它可以被重写为循环,所以它并没有真正回答你的问题。

In [92]: a,b,c,d
Out[92]: 
(array([[1, 2],
       [3, 4]]),
 array([[5, 6],
       [7, 8]]),
 array([[ 9, 10],
       [11, 12]]),
 array([[13, 14],
       [15, 16]]))

In [93]: bd = sparse.block_diag  # A convenient alias

In [94]: m = bd([a,0,0,0])+bd([0,b,0,0])+bd([0,0,c,0])+bd([0,0,0,d])

In [95]: m.A
Out[95]: 
array([[ 1,  2,  0,  0,  0],
       [ 3,  9,  6,  0,  0],
       [ 0,  7, 17, 10,  0],
       [ 0,  0, 11, 25, 14],
       [ 0,  0,  0, 15, 16]])

答案 1 :(得分:0)

您可以使用coo_matrix。您需要提供三个数组:数据,行索引和列索引,如链接中的第二个示例所示。关键点是:

  

默认情况下,转换为CSR或CSC格式时,重复(i,j)条目将汇总在一起。这有利于提高效率   有限元矩阵的构造等。 (见例)