[英]How to use numpy in matrices iterations like Matlab
I am used to make my discrete time control systems simulations in Matlab and now I'm trying python and numpy.我习惯在 Matlab 中进行离散时间控制系统模拟,现在我正在尝试 python 和 numpy。
So, my code bellow is working, but I would like to iterate over the numpy vector instead appending values into a list.因此,下面的代码正在运行,但我想遍历 numpy 向量,而不是将值附加到列表中。 Is it possible?可能吗?
In other words, instead of using换句话说,而不是使用
xl.append(xt)
ul.append(uc)
I would like to use some Matlab equivalent like x[:, k+1] = np.dot(Ad, x[:, k]) + Bd*uc, but it's not working on my code.我想使用一些 Matlab 等价物,例如 x[:, k+1] = np.dot(Ad, x[:, k]) + Bd*uc,但它不适用于我的代码。 If I do that, instead of obtaining a two line column vector that is the expected, I got a 2x2 matrix and an error.如果我这样做,而不是获得预期的两行列向量,我得到一个 2x2 矩阵和一个错误。
Another question: Why it's neccessary to use plt.plot(tk, u[:, 0], label='u') instead plt.plot(tk, u, label='u')?另一个问题:为什么需要使用 plt.plot(tk, u[:, 0], label='u') 而不是 plt.plot(tk, u, label='u')?
from control.matlab import *
import math
import numpy as np
import matplotlib.pyplot as plt
Ts = 0.1
N = 50
#x = np.zeros((2, N+1))
tk = np.zeros(N)
u = np.zeros(N)
v = np.random.randn(N)/86.6 #% measurement noise
wn = 1.12
wn2 = pow(wn, 2)
A = [[0, 1], [-1.5, -1.4]]
B = [[0], [1.5]]
C = [[1, 0]]
D = 0
# Control gains
K = np.array([2.64, 3.41071429])
# Now build a feedback with control law u = -K*x
Ad = np.eye(2) + np.multiply(A, Ts)
Bd = np.multiply(B, Ts)
Cd = C
xt = [[1.0], [0.12]] # initial states
xl = []
ul = []
for k in range(0, N):
tk[k] = k*Ts
uc = -K.dot(xt)
xt = np.dot(Ad, xt) + Bd*uc
xt[1, 0] += v[k]
xl.append(xt)
ul.append(uc)
x = np.array(xl)
u = np.array(ul)
#x = np.delete(x, N, 1) # delete the last position of x
#s = TransferFunction.s
#Gs = wn2/(s**2 + 0*s + wn2) # This is the KF solution
#yout, T = step(Gs)
plt.rcParams["figure.figsize"] = (10, 7)
plt.figure()
#plt.plot(T, yout, label='Open loop')
plt.plot(tk, x[:, 0], label='x_0')
plt.plot(tk, x[:, 1], label='x_1')
plt.plot(tk, u[:, 0], label='u')
plt.legend()
plt.title('Pendulum ex. 7.14 Franklin book')
plt.xlabel('Time')
plt.ylabel('amp.')
plt.show()
what I want is the code like this:我想要的是这样的代码:
from control.matlab import *
import math
import numpy as np
import matplotlib.pyplot as plt
Ts = 0.1
N = 50
x = np.zeros((2, N+1))
tk = np.zeros(N)
u = np.zeros(N)
v = np.random.randn(N)/86.6 #% measurement noise
wn = 1.12
wn2 = pow(wn, 2)
A = [[0, 1], [-1.5, -1.4]]
B = [[0], [1.5]]
C = [[1, 0]]
D = 0
# Control gains
K = np.array([2.64, 3.41071429])
# Now build a feedback with control law u = -K*x
Ad = np.eye(2) + np.multiply(A, Ts)
Bd = np.multiply(B, Ts)
Cd = C
for k in range(0, N):
tk[k] = k*Ts
u[k] = -K.dot(x[:, k])
x[1, k] += v[k]
x[:, k+1] = np.dot(Ad, x[:, k]) + Bd*u[k]
x = np.delete(x, N, 1) # delete the last position of x
#s = TransferFunction.s
#Gs = wn2/(s**2 + 0*s + wn2) # This is the KF solution
#yout, T = step(Gs)
plt.rcParams["figure.figsize"] = (10, 7)
plt.figure()
#plt.plot(T, yout, label='Open loop')
plt.plot(tk, x[:, 0], label='x_0')
plt.plot(tk, x[:, 1], label='x_1')
plt.plot(tk, u[:, 0], label='u')
plt.legend()
plt.title('Pendulum ex. 7.14 Franklin book')
plt.xlabel('Time')
plt.ylabel('amp.')
plt.show()
But it results in a following error:但这会导致以下错误:
Traceback (most recent call last):
File "C:\Users\ ... \np_matrices_v1.py", line 46, in <module>
x[:, k+1] = np.dot(Ad, x[:, k]) + Bd*u[k]
ValueError: could not broadcast input array from shape (2,2) into shape (2,)
I don't know why, but if you try:我不知道为什么,但如果你尝试:
A = np.array([[1, 2], [2, 3]])
x = np.array([[0.5], [2.0]])
y = A.dot(x)
print(y)
xa = np.zeros((2, 10))
xa[:, 2] = A.dot(x)
You'll got:你会得到:
Traceback (most recent call last):回溯(最近一次通话最后):
File "C:\Users\eletr.spyder-py3\temp.py", line 19, in xa[:, 2] = A.dot(x)文件“C:\Users\eletr.spyder-py3\temp.py”,第 19 行,在 xa[:, 2] = A.dot(x)
ValueError: could not broadcast input array from shape (2,1) into shape (2,) ValueError:无法将输入数组从形状 (2,1) 广播到形状 (2,)
But if you do:但如果你这样做:
import numpy as np
A = np.array([[1, 2], [2, 3]])
x = np.array([[0.5], [2.0]])
y = A.dot(x)
print(y)
xa = np.zeros((2, 10))
#xa[:, 2] = A.dot(x)
xa[:, [2]] = A.dot(x)
print(xa)
You'll got the correct answer:你会得到正确答案:
[[4.5]
[7. ]]
[[0. 0. 4.5 0. 0. 0. 0. 0. 0. 0. ]
[0. 0. 7. 0. 0. 0. 0. 0. 0. 0. ]]
Can anyone explain it...?谁能解释一下...?
In [248]: A = np.array([[1, 2], [2, 3]])
...: x = np.array([[0.5], [2.0]])
In [249]: A.shape, x.shape
Out[249]: ((2, 2), (2, 1))
In [250]: y = A.dot(x)
In [251]: y.shape
Out[251]: (2, 1)
Note the shapes.注意形状。 x
is (2,1), and as a result y
is too. x
是 (2,1),因此y
也是。 y
can be assigned to a (2,1) slot, but not a (2,) shape. y
可以分配给 (2,1) 槽,但不能分配给 (2,) 形状。
In [252]: xa = np.zeros((2,5),int)
In [253]: xa
Out[253]:
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
In [254]: xa[:,2]
Out[254]: array([0, 0]) # (2,) shape
In [255]: xa[:,[2]]
Out[255]:
array([[0], # (2,1) shape
[0]])
In contrast to MATLAB numpy
arrays can be 1d, eg (2,).与 MATLAB numpy
相比,arrays 可以是 1d,例如 (2,)。 Also leading dimensions are the outermost, as opposed to trailing.与尾随相反,前导尺寸也是最外层的。 MATLAB readily reduces a (2,3,1) shape to (2,3), but a (2,1,1) only becomes (2,1). MATLAB 很容易将 (2,3,1) 形状简化为 (2,3),但 (2,1,1) 仅变为 (2,1)。
broadcasting
the way numpy
uses arrays that can differ in shape. broadcasting
方式numpy
使用形状不同的 arrays。 The two basic rules are that两个基本规则是
- leading size 1 dimensions can added automatically to match
- size 1 dimensions can be adjusted to match
Thus a (2,) can become a (1,2).因此 (2,) 可以变成 (1,2)。
If you remove the inner [] from x
, you get a 1d array:如果从x
中删除内部 [] ,则会得到一个一维数组:
In [256]: x = np.array([0.5, 2.0])
In [257]: x.shape
Out[257]: (2,)
In [258]: A.dot(x)
Out[258]: array([4.5, 7. ]) # (2,) shape
This can then be assigned to a row of xa
: xa[:,2] = A.dot(x)
然后可以将其分配给xa
行: xa[:,2] = A.dot(x)
reshape
and ravel
can be used to remove dimensions. reshape
和ravel
可用于删除尺寸。 Also indexing A.dot(x)[:,0]
还索引A.dot(x)[:,0]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.