简体   繁体   English

如何在 Matlab 等矩阵迭代中使用 numpy

[英]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. reshaperavel可用于删除尺寸。 Also indexing A.dot(x)[:,0]还索引A.dot(x)[:,0]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM