用numpy和matplotlib解决参数辨识问题

适用范围

本文对参数辨识以及相关优化问题进行总结,并给出实现代码和流程。这类问题特点如下:
(1)需要对目标函数进行多次计算,并且保存每次计算时所用的全部参数
(2)计算完后需要从存储的函数中选优,提取最优解以及对应参数
(3)需要批量绘图,得到迭代规律和每种参数的变化规律
例子:
(1)采用动态规划法求最小油耗:优化方法为动态规划法(论文中),目标函数为油耗,参数为划分的航段(或时段)、每个状态上的点的位置和个数
(2)船舶在风浪中航行的参数辨识,主要辨识出风浪对船舶的影响参数。
本文以例(2)为例讲解,优化方法以模拟退火算法为例。

存储数据

错误做法:先建立空list,再根据循环一个个append。坏处:极有可能出现浅拷贝,且list维度不够,必须建立多个list
正确做法:建立一个多维数组,比如三维数组np.zeros([2,3,100]),2表示退火的随机初始次数,3表示参数个数,100表示迭代次数,用来存储每次迭代的参数值(后面绘制迭代曲线图)。

批量绘制多图

subplot()格式如下:
subplot( numRows, numCols, plotNum)
整个Figure会被划分为numRows行,numCols列,并从左往右,从上往下编号为1,2…也就是说plotNum指定了子图所在的位置,此外,如果三个参数的都小于10,则可以简写在一起,例如:subplot(4, 3, 2)也可以写成 subplot(432)
根据以上信息,采用subplot()绘制多图的代码为:

import matplotlib.pyplot as plt
plt.figure(figsize=(5,4))#设置图像总大小,注意先设置大小再绘图
sub_plot=[231,232,233,234,235,236]
for i in range(len(sub_plot)):
	plt.subplot(sub_plot[i])
	plt.plot(x1[num],y1[num])#x1,y1是二维array,Num表示选取第num行
#如果多于10张图,则不能用类似(234)形式,需要用(2,3,4)
for i in range(10,13):
	plt.subplot(5,3,i)
	plt.plot(x1[num],yi[num])
plt.show()

绘制图像所示,第一张为目标函数迭代曲线,剩下的为各个参数迭代曲线。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
卡尔曼滤波是一种用于估计系统状态的算法,可以用于许多应用,例如机器人导航、无线通信和金融预测等。在这里,我将提供一个使用Python实现卡尔曼滤波参数辨识的案例。 首先,我们需要导入一些必要的库,包括numpymatplotlib和scipy: ```python import numpy as np import matplotlib.pyplot as plt from scipy import signal ``` 接下来,我们将生成一些随机信号并添加噪声,作为我们的测试数据。我们将使用一个正弦波作为我们的信号,并添加高斯白噪声: ```python # Generate test signal t = np.linspace(0, 10, 1000) x = np.sin(2 * np.pi * 1 * t) # Add noise noise = 0.5 * np.random.randn(len(t)) y = x + noise ``` 现在,我们将使用scipy库中的函数来估计信号的频率和阻尼。这些参数将成为我们卡尔曼滤波器的初始状态。为此,我们可以使用signal库中的find_peaks函数来找到信号的峰值,并计算它们之间的差异: ```python # Estimate frequency and damping using peak detection peaks, _ = signal.find_peaks(y, height=0) freq = len(peaks) / t[-1] damp = -np.log(np.abs(np.diff(y[peaks]))).mean() ``` 现在,我们可以构建我们的卡尔曼滤波器。我们将使用一个简单的一维模型来估计信号的振幅、频率和阻尼。我们的状态向量将包含这些参数,加上它们的一阶导数。我们将使用numpy的ndarray来表示状态向量和状态协方差矩阵。 ```python # Build Kalman filter dt = t[1] - t[0] A = np.array([[1, dt, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, dt, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, dt], [0, 0, 0, 0, 0, 1]]) B = np.array([[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [1, 0, 0], [0, 1, 0]]) C = np.array([[1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0]]) Q = np.eye(6) R = np.eye(3) * 0.1 x0 = np.array([1, 0, freq, 0, damp, 0]) P0 = np.eye(6) kf = KalmanFilter(A, B, C, Q, R, x0, P0) ``` 现在,我们可以使用我们的KalmanFilter类来辨识信号的频率、阻尼和振幅。我们使用kf.filter函数来更新卡尔曼滤波器的状态,并使用kf.state[0]估计信号的振幅、kf.state[2]估计频率和kf.state[4]估计阻尼: ```python # Run Kalman filter amplitude = [] frequency = [] damping = [] for i in range(len(y)): kf.filter(np.array([[y[i]], [0], [0]])) amplitude.append(kf.state[0]) frequency.append(kf.state[2]) damping.append(kf.state[4]) ``` 最后,我们可以使用matplotlib库绘制原始信号、过滤后的信号和估计的频率、阻尼和振幅: ```python # Plot results plt.plot(t, x, label='Original signal') plt.plot(t, y, label='Noisy signal') plt.plot(t, amplitude, label='Filtered signal') plt.legend() plt.show() plt.plot(t, frequency) plt.title('Frequency') plt.show() plt.plot(t, damping) plt.title('Damping') plt.show() plt.plot(t, amplitude) plt.title('Amplitude') plt.show() ``` 这样,我们就完成了卡尔曼滤波参数辨识的案例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值