data se snažíme modelovat funkcí

$$c\sin(a-a_0)+ b =c \sin(a)\cos(a_0)-c \cos(a)\sin(a_0) + b$$

tedy 3 parametrický model bude mít odpovídající vektor parametrů

$$p=[b, c \cos(a_0), c \sin(a_0)]$$

a amplitudu resp. nulový polarizační úhel budeme rekonstruovat jako

$c=\sqrt(p_2^2+p_3^2),\ a_0=\arctan(p3/p2)$

In [72]:
%matplotlib inline
from matplotlib import pyplot as pl
import numpy as np

#ve kterych bodech merime
xval=np.r_[0:10:50j]
#modelová matice
mat_M=np.array([np.ones(shape=len(xval)), np.cos(xval), np.sin(xval)]).T
hessian=mat_M.T.dot(mat_M)
print("hessian")
hessian
hessian
Out[72]:
array([[ 50.        ,  -2.57598072,   8.70814148],
       [ -2.57598072,  26.45480889,   0.94324109],
       [  8.70814148,   0.94324109,  23.54519111]])
In [73]:
#kovarianci matici ziskame jako inverzi
covar=np.linalg.inv(hessian)
covar
Out[73]:
array([[ 0.02152599,  0.00238331, -0.00805682],
       [ 0.00238331,  0.03811826, -0.00240851],
       [-0.00805682, -0.00240851,  0.0455478 ]])

teď nasimulujeme nějaká data: nejprve předpokládejme konstantní nejistotu měřených hodnot $\sigma$

In [74]:
a0,b,c=30*np.pi/180.,50,20
sigma=5
pars0=np.array([b,c*np.cos(a0),c*np.sin(a0)]) #hodnoty parametru prepocitane podle vzorce 2
yteor=mat_M.dot(pars0)
yval=yteor+np.random.normal(0,sigma,size=len(xval))
pl.plot(xval,yteor,label="teor. prubeh")
pl.plot(xval,yval,"v",label="mereni")
pl.xlabel("xval")
pl.ylabel("yval")
pl.legend(loc=0)
Out[74]:
<matplotlib.legend.Legend at 0x7f744e2f3810>
In [75]:
# jednoduchy vzorecek 
# p = H^(-1) M^T Y
pars1=covar.dot(mat_M.T.dot(yval))
pars1
Out[75]:
array([ 50.29593634,  16.11178384,  10.3227089 ])
In [76]:
ymodel=mat_M.dot(pars1)
pl.plot(xval,ymodel,'r',label="fitovany. prubeh")
pl.plot(xval,yval,"v",label="mereni")
pl.xlabel("xval")
pl.ylabel("yval")
pl.legend(loc=0)
Out[76]:
<matplotlib.legend.Legend at 0x7f744e28a890>
In [77]:
pl.plot(xval,ymodel-yteor)
pl.title("odchylka od praveho modelu")
Out[77]:
<matplotlib.text.Text at 0x7f744e217a10>
In [78]:
#suma rezidui
s0=sum((yval-ymodel)**2)
rs0=s0/(len(xval)-3) #3 urcovane parametry
print("reduk. chi^2: %.2f vs. skutecna sigma^2: %.2f"%(rs0,sigma**2))
reduk. chi^2: 25.63 vs. skutecna sigma^2: 25.00
In [79]:
errs=np.sqrt(covar.diagonal())
corel=covar/errs.reshape(1,3)/errs.reshape(3,1)
print("korelacni matice parametru")
corel
korelacni matice parametru
Out[79]:
array([[ 1.        ,  0.08320181, -0.25730511],
       [ 0.08320181,  1.        , -0.05780281],
       [-0.25730511, -0.05780281,  1.        ]])
In [80]:
errs*=np.sqrt(rs0)
print("nejistoty parametru:"+str(errs))
nejistoty parametru:[ 0.74280717  0.98846449  1.08050874]

na výpočet parametru $c$ aplikujeme šíření nejistot $\sigma_2, \sigma_3$ parametrů $p_2, p_3$

$$\frac{\partial c}{\partial p_2}=\frac{p_2}{\sqrt(p_2^2+p_3^2)}$$$$\frac{\partial c}{\partial p_3}=\frac{p_3}{\sqrt(p_2^2+p_3^2)}$$

V případě nekorelovaných parametrů $p_2, p_3$ by platilo (v rozvoji do prvního řádu)

$$\sigma_c^2 = \left( \frac{\partial c}{\partial p_2}\right)^2 \sigma_2^2 + \left( \frac{\partial c}{\partial p_3}\right)^2 \sigma_2^3$$

Zde ale máme nezanedbatelnou antikorelaci (-25%), tedy je nutno ještě přidat člen

$$\sigma_c^2 = \left( \frac{\partial c}{\partial p_2}\right)^2 \sigma_2^2 + \left( \frac{\partial c}{\partial p_3}\right)^2 \sigma_3^2 + \frac{\partial c}{\partial p_2} \sigma_2 \frac{\partial c}{\partial p_3} \sigma_3\ \rho_{23} $$
In [81]:
# konkretne
c=np.sqrt(pars1[1]**2+pars1[2]**2)
sigma2_c =(pars1[1]/c)**2 * errs[1]**2
sigma2_c+=(pars1[2]/c)**2 * errs[2]**2
sigma2_c+=pars1[1]*pars1[2]/c**2 * errs[1]*errs[2]*corel[1,2]
print("parametr c: %.4f +- %.4f"%(c,np.sqrt(sigma2_c)))
parametr c: 19.1350 +- 1.0022
In [82]:
sigma2x_c =(pars1[1]/c)**2 * errs[1]**2
sigma2x_c+=(pars1[2]/c)**2 * errs[2]**2
print("nejistota c bez zapocteni korelace : %.4f"%np.sqrt(sigma2x_c))
nejistota c bez zapocteni korelace : 1.0161

teď s nekonstantními nejistotami

$y$ budou data s Poissonovským rozdělením s rozptylem $\sigma^2_y=y_{teor}$

Poněvadž ale $y_{teor}$ při analýze neznáme, budeme dosazovat experimentální hodnoty $y_{val}$

In [83]:
yval2=np.random.poisson(yteor)
mat_W=np.linalg.inv(yval2*np.eye(len(xval))) #vahova matice jako inverze kovarianci merenych hodnot 
hessian2=mat_M.T.dot(mat_W.dot(mat_M))
covar2=np.linalg.inv(hessian2)

pars2=covar2.dot(mat_M.T.dot(mat_W.dot(yval2)))
ymodel2=mat_M.dot(pars2)
pl.plot(xval,ymodel2,'r',label="fitovany. prubeh")
pl.plot(xval,yval2,"v",label="mereni")
pl.xlabel("xval")
pl.ylabel("yval")
pl.legend(loc=0)
pars2
Out[83]:
array([ 48.96602833,  19.23028487,   7.29359425])
In [84]:
s02=sum((yval2-ymodel2)**2)
rs02=s02/(len(xval)-3) #3 urcovane parametry
print("reduk. chi^2: %.2f vs. \"prumerna\" sigma^2: %.2f (%.2f)"%(rs02,yval2.mean(),(np.sqrt(yval2).mean())**2))
reduk. chi^2: 46.83 vs. "prumerna" sigma^2: 50.08 (48.67)

minimalizovaná hodnota je ale ve skutečnosti $(Y-Y_m)^T W (Y-Y_m)$, po vydělení počtem stupňů volnosti (očekávaná hodnota $\chi^2$) máme dostat hodnotu blízkou 1

In [85]:
s02m=(yval2-ymodel2).T.dot(mat_W.dot(yval2-ymodel2))
rs02m=s02m/(len(xval)-3)
rs02m
Out[85]:
0.88769735772079039
In [86]:
errs2=np.sqrt(covar2.diagonal())
corel2=covar2/errs2.reshape(1,3)/errs2.reshape(3,1)
print("nejistoty parametru:"+str(errs2))
print("korelacni matice parametru")
corel2
nejistoty parametru:[ 1.02126232  1.35908702  1.42981015]
korelacni matice parametru
Out[86]:
array([[ 1.        ,  0.36197321, -0.14852489],
       [ 0.36197321,  1.        , -0.06690906],
       [-0.14852489, -0.06690906,  1.        ]])
In [87]:
c2=np.sqrt(pars2[1]**2+pars2[2]**2)
sigma2_c2 =(pars2[1]/c2)**2 * errs2[1]**2
sigma2_c2+=(pars2[2]/c2)**2 * errs2[2]**2
sigma2_c2+=pars1[1]*pars1[2]/c**2 * errs2[1]*errs2[2]*corel2[1,2]
print("parametr c: %.4f +- %.4f"%(c2,np.sqrt(sigma2_c2)))
parametr c: 20.5670 +- 1.3464

rozdělení reziduí

pokusíme se o analýzu pomocí momentů: šikmosti (skew) a špičatosti (curtosis)

In [88]:
#mame relativne malo bodu pro histogram
xbins=np.r_[-15:15:2]
ok1=pl.hist(yval-ymodel,xbins,alpha=0.5,label="konst.sigma")
ok2=pl.hist(yval2-ymodel2,xbins,alpha=0.5,label="poisson")
pl.legend(loc=0)
Out[88]:
<matplotlib.legend.Legend at 0x7f744e020310>
In [89]:
def moments(meas):
    cmeas=meas-meas.mean()
    return (cmeas**2).mean(),(cmeas**3).mean(),(cmeas**4).mean()
moms1=moments(yval-ymodel)
skew1,curt1=moms1[1]/moms1[0]**1.5,moms1[2]/moms1[0]**2-3
skew1,curt1
Out[89]:
(-0.69929532170288267, 0.6615122622535381)
In [90]:
moms2=moments(yval2-ymodel2)
skew2,curt2=moms1[1]/moms2[0]**1.5,moms2[2]/moms2[0]**2-3
skew2,curt2
Out[90]:
(-0.29002121055135538, 0.93438502580620453)
In [91]:
print("nejistoty skew %.2f a curt. %.2f "%(np.sqrt(6./len(xval)),np.sqrt(24./len(xval))))
nejistoty skew 0.35 a curt. 0.69 

ani v jednom případě (pokud šikmosti a špičatosti přisoudíme v nulové hypotéze normální rozdělení) není odchylka o 0 větší jako 2 $\sigma$, tedy hypotézu, že původní měřená data mají normální rozdělené, nemůžeme zamítnout (ne s rizikem menším jako $2\sigma$ kvantil (4.5%).

In [96]:
from scipy import stats
stats.norm().sf(2)*2
Out[96]:
0.045500263896358389