我是python / numpy的新手。 我需要做以下计算: 对于一系列离散时间t,计算$ e ^ {At} $ $ 2 \次2 $矩阵$ A $
我做了什么:
def calculate(t_,x_0,v_0,omega_0,c):
# define A
a_11,a_12, a_21, a_22=0,1,-omega_0^2,-c
A =np.matrix([[a_11,a_12], [a_21, a_22]])
print A
# use vectorization
temps = np.array(t_)
A_ = np.array([A for k in range (1,n+1,1)])
temps*A_
x_=scipy.linalg.expm(temps*A)
v_=A*scipy.linalg.expm(temps*A)
return x_,v_
n=10
omega_0=1
c=1
x_0=1
v_0=1
t_ = [float(5*k*np.pi/n) for k in range (1,n+1,1)]
x_, v_ = calculate(t_,x_0,v_0,omega_0,c)
但是,在将A_(包含n次A的数组)与temps(包含我想要计算exp(At)的时间相乘时,我得到此错误:
ValueError:操作数无法与形状(10,)(10,2,2)
一起广播据我了解矢量化,A_中的每个元素都会乘以与temps相同的索引处的元素;但我想我做对了。 任何帮助/评论非常感谢
答案 0 :(得分:2)
t_
的纯In [254]: t = 5*np.arange(1,n+1)*np.pi/n
In [255]: t
Out[255]:
array([ 1.57079633, 3.14159265, 4.71238898, 6.28318531, 7.85398163,
9.42477796, 10.99557429, 12.56637061, 14.13716694, 15.70796327])
In [256]: a_11,a_12, a_21, a_22=0,1,-omega_0^2,-c
In [257]: a_11
Out[257]: 0
In [258]: A = np.array([[a_11,a_12], [a_21, a_22]])
In [259]: A
Out[259]:
array([[ 0, 1],
[-3, -1]])
In [260]: t.shape
Out[260]: (10,)
In [261]: A.shape
Out[261]: (2, 2)
In [262]: A_ = np.array([A for k in range (1,n+1,1)])
In [263]: A_.shape
Out[263]: (10, 2, 2)
计算是(创建数组而不是列表):
A_
np.ndarray
是A
。我也np.ndarray
np.matrix
了;你的A_
是np.ndarray
,但np.matrix
仍为A_
。 t * A
只能是2d,而(10,) (10,2,2)
是3d。
所以In [264]: result = t[:,None,None]*A[None,:,:]
In [265]: result.shape
Out[265]: (10, 2, 2)
将是数组元素乘法,因此广播错误为einsum
。
要进行元素乘法,你需要像
这样的东西In [266]: result1 = np.einsum('i,ijk', t, A_)
In [267]: result1
Out[267]:
array([[ 0. , 86.39379797],
[-259.18139392, -86.39379797]])
但是如果你想要(10,)与(10,2,2)的矩阵乘法,那么np.dot
很容易做到:
tensordot
einsum
不能这样做,因为它的规则是'倒数第二个'。 einsum
可以,但我对In [268]: (t[:,None,None]*A[None,:,:]).sum(axis=0)
Out[268]:
array([[ 0. , 86.39379797],
[-259.18139392, -86.39379797]])
感到满意。
但是(t[:,None,None]*A[None,:,:]).cumsum(axis=0)
表达式(对我来说)显而易见的是,我可以通过在第一轴上求和来从元素*得到相同的东西:
DECLARE @TAB TABLE(ID INT,NAME VARCHAR(20),DTE DATETIME)
INSERT INTO @TAB
SELECT 1,'RAJIV',GETDATE()
UNION ALL
SELECT 2,'RAJIV',GETDATE()
UNION ALL
SELECT 3,'RAVI',GETDATE()
UNION ALL
SELECT 4,'RAVI',GETDATE()
UNION ALL
SELECT 5,'AJAY',GETDATE()
或SELECT
A.ID
,CASE WHEN A.R = 1 THEN A.NAME ELSE '' END AS NAME
,A.DTE
FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY ID) AS R,*
FROM @TAB) A
ORDER BY A.ID
每次获得2x2。
答案 1 :(得分:0)
这就是我要做的。
import numpy as np
from scipy.linalg import expm
A = np.array([[1, 2], [3, 4]])
for t in np.linspace(0, 5*np.pi, 20):
print(expm(t*A))
此处不尝试矢量化。 expm
函数一次应用于一个矩阵,它肯定需要大量的计算时间。无需担心将A乘以标量的成本。