问题:

对于一个未知参数的系统,往往需要用到系统辨识的方法,例如对于一个单输入单输出系统:

        Z(k)+a1*Z(k-1)+a2*Z(k-2)=b1*U(k-1)+b2*U(k-2)+V(k)

        其中:V(k)=c1*v(k)+c2*v(k-1)+c3*v(k-3)

输入信号采用四阶幅值为1的M序列,高斯噪声v(k)均值为0,方差为0.1。

假设真值为a1=1.6,a2=0.7,b1=1.0,b2=0.4,c1=1.0,c2=1.6,c3=0.7。需要对以上参数进行辨识。

方法:

一般最小二乘法是系统辨识中最简单的辨识方法之一,其MATLAB实现方法十分简单,我发现网上一大把,所以我决定“翻译”一个python版的一般最小二乘辨识方法供读者参考。

本文用到的库:

import numpy as np
import matplotlib.pyplot as plt
from operator import xor
from numpy.linalg import inv

M序列的产生:

在python中,M序列的产生方法与matlab类似,先产生随机数,然后采用四阶移位寄存器滤波变换,得到我们想要的M序列。

#M序列产生
L=16
#设置M序列周期
#定义初始值
y=np.zeros(L)
u=np.zeros(L)
y1=1
y2=1
y3=1
y4=0
for i in range(0,L):
x1=xor(y3,y4)
x2=y1
x3=y2
x4=y3
y[i]=y4
if y[i]>0.5:
u[i]=-1
else:
u[i]=1
y1=x1
y2=x2
y3=x3
y4=x4
plt.figure(num=2)
x=np.linspace(0,15,16)
plt.bar(x,u,width=0.1)
plt.title('输入信号M序列')

高斯分布噪声:

这里采用的是random库中的函数,可以看到,我们设置的均值为0,方差为0.1。

 #产生一组16个N(0,1)的高斯分布的随机噪声
mu=0
sigma=0.1
samplenum=16
n=np.random.normal(mu,sigma,samplenum)
plt.figure(num=1)
plt.plot(n)
plt.title("高斯分布随机噪声")

最小二乘辨识程序:

#最小二乘辨识过程
z=np.zeros(16) for k in range(2,15):
z[k]=-1.6*z[k-1]-0.7*z[k-2]+1.0*u[k-1]+0.4*u[k-2]+1.0*n[k]+1.6*n[k-1]+0.7*n[k-2] plt.figure(num=3)
plt.bar(x,z,width=0.1)
plt.title('输出观测值') H=np.array([[-z[1],-z[0],u[1],u[0]],[-z[2],-z[1],u[2],u[1]],[-z[3],-z[2],u[3],u[2]],[-z[4],-z[3],u[4],u[3]],[-z[5],-z[4],u[5],u[4]],[-z[6],-z[5],u[6],u[5]],[-z[7],-z[6],u[7],u[6]],[-z[8],-z[7],u[8],u[7]],[-z[9],-z[8],u[9],u[8]],[-z[10],-z[9],u[10],u[9]],[-z[11],-z[10],u[11],u[10]],[-z[12],-z[11],u[12],u[11]],[-z[13],-z[12],u[13],u[12]],[-z[14],-z[13],u[14],u[13]]])
Z=np.array([z[2],z[3],z[4],z[5],z[6],z[7],z[8],z[9],z[10],z[11],z[12],z[13],z[14],z[15]]) In_1=np.transpose(H)
In_2=np.dot(In_1,H)
In_3=inv(In_2)
In_4=np.dot(In_3,In_1)
c=np.dot(In_4,Z)

分离参数:

#分离参数并显示
a1=c[0]
a2=c[1]
b1=c[2]
b2=c[3]
print("a1的值是:",a1)
print("a2的值是:",a2)
print("b1的值是:",b1)
print("b2的值是:",b2)

注意:

由于在python中plt的库是不支持中文的,所以要加上这些代码,保证输出的图片标题的中文显示正常。

#显示中文字体
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

结果:

在网上找了半天python画针状图的资料,发现没有。。所以强行用瘦了的柱状图表示针状图了。

总结:

可以看出Python写的系统辨识误差还是有一些的,不过也是受到一般最小二乘参数辨识方法的限制,如果采用递推最小二乘,增广最小二乘等方法可能会进一步提高准确性。笔者尝试过递推最小二乘,但是与MATLAB相比,其代码量大大增加,因此在系统辨识方法上,不建议都用Python来写,MATLAB是个不错的选择。当然,喜欢写python的话,这都不是问题。

代码全文:

 # -*- coding: utf-8 -*-
"""
Created on Wed Sep 20 16:11:27 2017
@author: Hangingter
"""
#一般最小二乘辨识 #导入相应科学计算的包
import numpy as np
import matplotlib.pyplot as plt
from operator import xor
from numpy.linalg import inv #显示中文字体
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
#产生一组16个N(0,1)的高斯分布的随机噪声
mu=0
sigma=0.1
samplenum=16
n=np.random.normal(mu,sigma,samplenum)
plt.figure(num=1)
plt.plot(n)
plt.title("高斯分布随机噪声")
#M序列产生
L=16
#设置M序列周期
#定义初始值
y=np.zeros(L)
u=np.zeros(L)
y1=1
y2=1
y3=1
y4=0
for i in range(0,L):
x1=xor(y3,y4)
x2=y1
x3=y2
x4=y3
y[i]=y4
if y[i]>0.5:
u[i]=-1
else:
u[i]=1
y1=x1
y2=x2
y3=x3
y4=x4
plt.figure(num=2)
x=np.linspace(0,15,16)
plt.bar(x,u,width=0.1)
plt.title('输入信号M序列')
#最小二乘辨识过程
z=np.zeros(16) for k in range(2,15):
z[k]=-1.6*z[k-1]-0.7*z[k-2]+1.0*u[k-1]+0.4*u[k-2]+1.0*n[k]+1.6*n[k-1]+0.7*n[k-2] plt.figure(num=3)
plt.bar(x,z,width=0.1)
plt.title('输出观测值') H=np.array([[-z[1],-z[0],u[1],u[0]],[-z[2],-z[1],u[2],u[1]],[-z[3],-z[2],u[3],u[2]],[-z[4],-z[3],u[4],u[3]],[-z[5],-z[4],u[5],u[4]],[-z[6],-z[5],u[6],u[5]],[-z[7],-z[6],u[7],u[6]],[-z[8],-z[7],u[8],u[7]],[-z[9],-z[8],u[9],u[8]],[-z[10],-z[9],u[10],u[9]],[-z[11],-z[10],u[11],u[10]],[-z[12],-z[11],u[12],u[11]],[-z[13],-z[12],u[13],u[12]],[-z[14],-z[13],u[14],u[13]]])
Z=np.array([z[2],z[3],z[4],z[5],z[6],z[7],z[8],z[9],z[10],z[11],z[12],z[13],z[14],z[15]]) In_1=np.transpose(H)
In_2=np.dot(In_1,H)
In_3=inv(In_2)
In_4=np.dot(In_3,In_1)
c=np.dot(In_4,Z) #分离参数并显示
a1=c[0]
a2=c[1]
b1=c[2]
b2=c[3]
print("a1的值是:",a1)
print("a2的值是:",a2)
print("b1的值是:",b1)
print("b2的值是:",b2)

参考:

MATLAB版的系统辨识一般最小二乘方法:

http://blog.csdn.net/sinat_20265495/article/details/51426537

python实现一般最小二乘系统辨识方法的更多相关文章

  1. Python知识(7)--最小二乘求解

    这里展示利用python实现的最小二乘的直接求解方法.其求解原理,请参考:最小二乘法拟合非线性函数及其Matlab/Excel 实现 1.一般曲线拟合 代码如下: # -*- coding:utf-8 ...

  2. 用 Python 排序数据的多种方法

    用 Python 排序数据的多种方法 目录 [Python HOWTOs系列]排序 Python 列表有内置就地排序的方法 list.sort(),此外还有一个内置的 sorted() 函数将一个可迭 ...

  3. sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO

    sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO 今天在弄一个 sqlalchemy 的数据库基类的时候,遇到了跟多继承相关的一个小问题,因此顺便看了一 ...

  4. python子类调用父类的方法

    python子类调用父类的方法 python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法.如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问, ...

  5. paip.编程语言方法重载实现的原理及python,php,js中实现方法重载

    paip.编程语言方法重载实现的原理及python,php,js中实现方法重载 有些语言,在方法的重载上,形式上不支持函数重载,但可以通过模拟实现.. 主要原理:根据参数个数进行重载,或者使用默认值 ...

  6. python常用数据类型内置方法介绍

    熟练掌握python常用数据类型内置方法是每个初学者必须具备的内功. 下面介绍了python常用的集中数据类型及其方法,点开源代码,其中对主要方法都进行了中文注释. 一.整型 a = 100 a.xx ...

  7. Python使用MySQL数据库的方法以及一个实例

    使用环境:Windows+python3.4+MySQL5.5+Navicat 一.创建连接 1.准备工作,想要使用Python操作MySQL,首先需要安装MySQL-Python的包,在Python ...

  8. python中List的sort方法的用法

    python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. 关键字: python列表排序 python字典排序 sorted List的元素可以是各种东 ...

  9. python字符串内容替换的方法(转载)

    python字符串内容替换的方法 时间:2016-03-10 06:30:46来源:网络 导读:python字符串内容替换的方法,包括单个字符替换,使用re正则匹配进行字符串模式查找与替换的方法.   ...

随机推荐

  1. Spring context:property-placeholder 一些坑

    今天在配置多配置文件的时候偶然发现如果我使用   <context:property-placeholder location="classpath:filePath.properti ...

  2. win10外接键盘失灵

    故障描述:笔记本外接的键盘突然之间就失灵,键盘的灯不亮,无法输入 处理方程: 1. 我的电脑右击--> 管理 --> 设备管理器(开始失灵时,键盘下的HID Keyboard Device ...

  3. Egret学习笔记 (Egret打飞机-9.子弹对敌机和主角的碰撞)

    运行起来,虽然主角飞机和敌机都在互相发射子弹,但是子弹打中了就和没打中效果是一样的.. 这一章我们就来处理子弹和飞机的碰撞问题. 我们所有的操作都是基于Main这个容器来做的.所以我就把这个处理放到M ...

  4. hdu2089 不要62--经典数位DP

    一道十分经典的数位DP的题目. dp[i][j]表示最高位是数字i,连同最高位在内共有j位.注意边界的初始化. 接下来就是区间划分,特殊情况处理.....对了,如果不知道自己的方法是否正确,可以写一个 ...

  5. yum源配置的三种方法

    (一)yum源概述 yum需要一个yum库,也就是yum源.默认情况下,CentOS就有一个yum源.在/etc/yum.repos.d/目录下有一些默认的配置文件(可以将这些文件移到/opt下,或者 ...

  6. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.coder520.mamabike.user.dao.UserMapper.selectByPrimaryKey

    这个异常是IDEA中漏加载mapper.xml文件,在classes中没找到,所以要在配置文件中加入: !--如果不添加此节点mybatis的mapper.xml文件都会被漏掉.--> < ...

  7. Hive导入HDFS/本地数据

    #创建表人信息表  person(String name,int age) hive> create table person(name STRING,age INT)ROW FORMAT DE ...

  8. DirectDraw读书笔记

    DirectDraw对象 DirectDraw对象是DirectDraw应用程序的核心.它是你在建立DirectDraw应用程序时所要创建的第一个对象,再用它来创建所有其它相关的对象.通过调用Dire ...

  9. vxWorks/BootROM Imageq启动顺序详解

    vxWorks/BootROM Imageq启动顺序详解 VxWorks image     分为在ROM中运行和在RAM中运行两种,两者启动顺序的区别在于sysInit()函数的调用,该函数在RAM ...

  10. .Net4.0 任务(Task)

    任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks 命名空间下任务相关类一览: 类 ...