试图为结构/土木工程应用提供一种执行载荷组合和瞬态载荷模式的方法。
没有模式就很简单:
list of load results = [[d],[t1],...,[ti]], where [ti] = transient load result as a numpy array = A
list of combos = [[1,0,....,0],[0,1,....,1], [dfi, tf1,.....,tfi]] , where tfi = code load factor for transient load = B
在python中,其作用为numpy.dot(A,B)
所以我的问题出现在哪里:
`list of load results = [[d],[t1],.....[ti]]`, where [t1] = [[t11]......[t1i]] for i pattern possibilities and [t1i] = numpy array
所以我在另一个数组中有一个嵌套数组,并想乘以负载组合矩阵。有没有一种方法可以在一个矩阵运算中实现这一点,我可以想出一种方法:先将模式的可能性循环,然后将点乘积与负载组合组合起来,但这在计算上是昂贵的。有什么想法吗?
谢谢
有关不考虑图案化的示例,请参见:https://github.com/buddyd16/Structural-Engineering/blob/master/Analysis/load_combo_test.py
基本,我需要一种给出类似结果的方法,假设loads = np.array([[D],[Ex],[Ey],[F],[H],[L],[Lr],[R],[S],[Wx],[Wy]])
-> [L],[Lr],[R],[S]
实际上是嵌套数组,即如果D = 1x500数组/矢量,则L,Lr,R或S可以= 100x500阵列。
我的简单解决方案是:
combined_pattern = []
for pattern in load_patterns:
loads = np.array([[D],[Ex],[Ey],[F],[H],[L[pattern]],[Lr[pattern]],[R[pattern]],[S[pattern]],[Wx],[Wy]])
combined_pattern.append(np.dot(basic_factors, loads))
简单示例:
import numpy as np
#Simple
A = np.array([1,0,0])
B = np.array([0,1,0])
C = np.array([0,0,1])
Loads = np.array([A,B,C])
Factors = np.array([[1,1,1],[0.5,0.5,0.5],[0.25,0.25,0.25]])
result = np.dot(Factors, Loads)
# Looking for a faster way to accomplish the below operation
# this works but will be slow for large data sets
# bi can be up to 1x5000 in size and i can be up to 500
A = np.array([1,0,0])
b1 = np.array([1,0,0])
b2 = np.array([0,1,0])
b3 = np.array([0,0,1])
B = np.array([b1,b2,b3])
C = np.array([0,0,1])
result_list = []
for load in B:
Loads = np.array([A,load,C])
Factors = np.array([[1,1,1],[0.5,0.5,0.5],[0.25,0.25,0.25]])
result = np.dot(Factors, Loads)
result_list.append(result)
edit:在np.dot()中具有相反的因子和负载。
答案 0 :(得分:1)
在您的简单示例中,数组形状为:
In [2]: A.shape
Out[2]: (3,)
In [3]: Loads.shape
Out[3]: (3, 3)
In [4]: Factors.shape
Out[4]: (3, 3)
In [5]: result.shape
Out[5]: (3, 3)
dot
中的规则是Loads
的最后一个维度与Factors
的第二个到最后一个配对
result = np.dot(Loads,Factors)
(3,3) dot (3,3) => (3,3) # 3's in common
(m,n) dot (n,l) => (m,l) # n's in common
在迭代中,A
,load
和C
都是(3,),而Loads
是(3,3)。
result_list
是3(3,3)个数组的列表,而np.array(result_list)
将是(3,3,3)。
让我们对所有Loads
进行3d排列:
In [16]: Bloads = np.array([np.array([A,load,C]) for load in B])
In [17]: Bloads.shape
Out[17]: (3, 3, 3)
In [18]: Bloads
Out[18]:
array([[[1, 0, 0],
[1, 0, 0],
[0, 0, 1]],
[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]],
[[1, 0, 0],
[0, 0, 1],
[0, 0, 1]]])
我可以轻松地用dot
来完成Bloads
和Factors
中的einsum
:
In [19]: np.einsum('lkm,mn->lkn', Bloads, Factors)
Out[19]:
array([[[1. , 1. , 1. ],
[1. , 1. , 1. ],
[0.25, 0.25, 0.25]],
[[1. , 1. , 1. ],
[0.5 , 0.5 , 0.5 ],
[0.25, 0.25, 0.25]],
[[1. , 1. , 1. ],
[0.25, 0.25, 0.25],
[0.25, 0.25, 0.25]]])
einsum
不是唯一的方法,但是(对我来说)这是跟踪尺寸的最简单方法。
如果尺寸不同,则保持直线更容易。它们都是3,因此很难将它们分开。但是,如果B
为(5,4)和Factors
(4,2),则Bloads
为(5,3,4),而einsum
的结果为( 5,3,2)(尺寸4在dot
中消失)。
无循环地构造Bloads
有点棘手,因为B
的行与A
和C
交错。
In [38]: np.stack((A[None,:].repeat(3,0),B,C[None,:].repeat(3,0)),1)
Out[38]:
array([[[1, 0, 0],
[1, 0, 0],
[0, 0, 1]],
[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]],
[[1, 0, 0],
[0, 0, 1],
[0, 0, 1]]])
要了解此测试的子表达式,例如A[None,:]
,repeat
等。
等效地:
np.array((A[None,:].repeat(3,0),B,C[None,:].repeat(3,0))).transpose(1,0,2)