Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!


Учебная задача поставлена в статье — это обработка экспериментальных данных методами информационной теории измерений с минимизацией энтропийной погрешности при помощи фильтра Калмана.
Снижение погрешность измерений самая актуальная практическая задача.
import scipy.stats
from random import normalvariate
class Disp:
def __init__(self):
self.m=0
self.d=0
self.n=0
def add(self,x):
self.n=self.n+1
if self.n>1:
self.d=self.d*(self.n-2)/(self.n-1)+(x-self.m)**2/self.n
self.m=self.m+(x-self.m)/self.n
def getN(self):
return self.n # =n
def getM(self):
return self.m # =sum(x[i])/n
def getD(self):
return self.d # =sum((x[i]-m)^2)/(n-1)
def st(alpha,n):
return scipy.stats.t.ppf((1+alpha)/2, n-1)
disp=Disp()
xo=1
mu=0.5
print("Estimate xsi(xo=%.2f,mu=%.2f)\n"%(xo,mu))
alpha=0.95
print(" count xsi mean disp err(%.2f)"%alpha)
j=10
for i in range(100000):
y=normalvariate(xo,mu)
disp.add(y)
if i+1==j:
j=j*10
n,m,d=disp.getN(),disp.getM(),disp.getD()**0.5
print("%7d\t%7.4f\t%7.4f\t%7.4f\t%7.4f"%( n, y, m, d, d*st(alpha,n) ))
Estimate xsi(xo=1.00,mu=0.50)
count xsi mean disp err(0.95)
10 0.4935 0.9605 0.5443 1.2313
100 0.8873 1.0034 0.4685 0.9296
1000 1.3086 0.9905 0.4961 0.9734
10000 1.0788 1.0022 0.5023 0.9845
100000 0.8025 0.9999 0.5000 0.9800

from numpy import *
import matplotlib.pyplot as plt
from scipy.stats import norm
n_iter = 1000 # Число итераций.
sz = (n_iter,) # Размер массива
x =2 # Истинное значение измеряемой величины (фильтру неизвестно)
R1 = 0.1 # Ср. кв. ошибка измерения.
R = R1*R1 # Дисперсия
nr="нормальным распределением"
y=norm.rvs( x, R1, size=sz)
Q = 1e-5 # Дисперсия случайной величины в модели системы
xest1 = zeros(sz) # Априорная оценка состояния
xest2 = zeros(sz) # Апостериорная оценка состояния
P1 = zeros(sz) # Априорная оценка ошибки
P2 = zeros(sz) # Апостериорная оценка ошибки
G = zeros(sz) # Коэффициент усиления фильтра
err1=zeros(sz) # Ошибка оценки состояния
xest2[0] = 0.0
P2[0] = 1.0
for k in arange(1, n_iter,1): # Цикл по отсчётам времени.
xest1[k] = xest2[k-1] # Априорная оценка состояния.
P1[k] = P2[k-1] + Q # Априорная оценка ошибки.
# После получения нового значения измерения вычисляем апостериорные оценки:
G[k] = P1[k] / ( P1[k] + R )
xest2[k] = xest1[k] + G[k] * ( y[k] - xest1[k] )
P2[k] = (1 - G[k]) * P1[k]
err1[k]=abs(xest1[k]-x)
plt.title('Ошибки при подавлении шумов \n с %s'%nr, size=12)
i = arange(1, n_iter,1) # P1 на 0 м шаге не определено
plt.plot(i, P1[i])
plt.plot(i, err1[i],'--')
plt.xlabel('Номер итерации')
plt.ylabel('Априорная оценка ошибки')
plt.setp(plt.gca(), 'ylim', [0, 0.05] )
plt.show()
Фильтр Калмана для минимизации энтропийного значения случайной погрешности с не Гауссовым распределением