/*
Particle Filter
一般系:
x_t = F_t x_{t-1} + G_t v_t
y_t = H_t x_t + w_t
ここでは:
x_t = x_{t-1} + v_t
y_t = x_t + w_t
where v_t, w_t は N(0,1).
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926
#define NN 1100 /*粒子の最大数*/
#define MM 100 /*時刻ステップの最大数*/
#define LL 30 /*平滑化の区間*/
/*for random number*/
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
double gauss(double mu, double sigma2);
double pdf(double x, double mu, double sigma);
void showData(double d[], int num );
void showParticle(double f[], double v[], double w[], double p[], double y[], double alpha[], int num) ;
double ran2();
unsigned long int idum =1024;
main()
{
int l,n,n1,nmax,nend;/*step*/
int j,j1,jmax;/*粒子数*/
double v[NN],mu,sigma2,w[NN],mu2,sigma3;/*v,wの平均、分散*/
double v1,w1,x[MM],y1[MM];/*観測値のノイズ、観測値の状態と観測値の配列*/
double p[MM][NN],y[MM][NN];/*状態pj、観測値yj*/
double alfa[NN],a1,a2; /*尤度*/
double A,A1,a[NN],ran;/*alfaの合計,尤度のメモリの配列*/
double f[MM][NN],fh[MM][NN];/*リサンプリングした配列*/
int k,K[MM][NN];/*平滑化の時に使う配列と引数*/
double fwa,fa,bun,hensa,sa,Y,pbun,yhensa;
nmax=100;/*ステップ数*/
/*ノイズの特定化*/
mu=0.0;
mu2=0.0;
sigma2=1.0;
sigma3=1.0;
jmax=1000; /*粒子数*/
/*尤度の計算で使用*/
a1=1.0/(sqrt(2.0*M_PI))/sigma3;
a2=1.0;/*Gの偏微分の絶対値*/
n=0;
x[0]=0.0;
/*データ作成*/
for(n=1;n<nmax;++n) {
v1=gauss(mu,sigma2);/*vの生成*/
w1=gauss(mu2,sigma3);/*wの生成*/
/*システムモデル*/
x[n]=x[n-1]+v1;
/*観測値モデル*/
y1[n]=x[n]+w1;
/*printf("%d %lf %lf\n",n,x[n],y1[n]);*/
}
/* +-30で一様分布にとる */
for (j=0;j<jmax;++j) {
f[0][j]=(60.0/jmax)*j-30.0;
}
for (n=1;n<nmax;++n) {
A=0.0;
for (j=0;j<jmax;++j) {
v[j]=gauss(mu,sigma2);
w[j]=gauss(mu2,sigma3);
p[n][j]=f[n-1][j]+v[j];
y[n][j]=p[n][j]+w[j];
alfa[j]=pdf((y1[n]-p[n][j]),mu2,sigma3)*a2;
A+=alfa[j];
}
A1=1.0/A;
a[0]=0;
for(j=0;j<jmax;++j){
a[j+1]=a[j]+alfa[j]*A1;
}
for(n1=0;n1<n;++n1){
for(j=0;j<jmax;++j){
fh[n1][j]=f[n1][j];
}
}
/*リサンプリング*/
for(j=0;j<jmax;++j){
ran=ran2(&idum);
for(l=0;l<jmax;++l){
if(ran<a[l+1] && a[l]<ran){
k=l;
}
}
f[n][j]=p[n][k];
/*固定区間平滑化*/
nend=n-1-LL;
if(nend<0)nend=0;
for(n1=n-1;n1>nend;--n1){
f[n1][j]=fh[n1][k];
}
}
}
/*平均と標準偏差*/
for(n=1;n<nmax;++n){
fwa=0.0;bun=0.0;
for(j=0;j<jmax;++j){
fwa+=f[n][j];
}
fa=fwa/jmax;
for(j=0;j<jmax;++j){
bun+=pow(f[n][j]-fa,2.0);
}
hensa=sqrt(bun/jmax);
/*printf("%d %lf %lf %lf\n",n,fa,hensa,fa-x[n]);*/
}
for(n=1;n<nmax;++n){
Y=0.0;pbun=0.0;sa=0.0;
for(j=0;j<jmax;++j){
Y+=p[n][j];
}
for(j=0;j<jmax;++j){
pbun+=pow(p[n][j]-(Y/jmax),2.0);
}
sa=(Y/jmax)-y1[n]; /*予測観測値の平均と理論値の差*/
printf("%d %lf %lf %lf\n",n,Y/jmax,sqrt(pbun/jmax),sa);
}
}
/*表示関数*/
void showData(double d[], int num)
{
int i;
for (i=0; i<num;++i ) {
printf("%lf ", d[i]);
}
printf("\n");
}
/*結果確認*/
void showParticle(double f[], double v[], double w[], double p[], double y[], double alpha[], int num)
{
printf("f\n");
showData(f,num);
printf("v\n");
showData(v,num);
printf("w\n");
showData(w,num);
printf("p\n");
showData(p,num);
printf("y\n");
showData(y,num);
printf("alpha\n");
showData(alpha,num);
}
/*確率密度関数 (ここでは正規分布)*/
double pdf(double x, double mu, double sigma) {
return exp(-pow((x-mu),2.0)/(2.0*sigma*sigma))/(sqrt(2.0*M_PI)*sigma);
}
/*ノイズが従う分布 (ここでは正規分布)*/
double gauss(double mu, double sigma2)
{
double t,u,r1,r2;
double sigma=sqrt(sigma2);
t=sqrt(-2.0*log(1.0-ran2(&idum)));
u=2.0*PI*ran2(&idum);
r1=t*cos(u);
return r1*sigma+mu;
}
/*Random Number*/
double ran2(long *idum)
{
int j;
long k;
static long idum2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if(*idum <= 0){
if(-(*idum) < 1) *idum=1;
else *idum = -(*idum);
idum2=(*idum);
for(j=NTAB+7; j>=0; j--){
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if(*idum < 0) *idum += IM1;
if(j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if(*idum < 0) *idum += IM1;
k=idum2/IQ2;
idum2=IA2*(idum2-k*IQ2)-k*IR2;
if(idum2 < 0) idum2 += IM2;
j=iy/NDIV;
iy=iv[j]-idum2;
iv[j]=*idum;
if(iy<1) iy += IMM1;
if((temp = AM*iy) > RNMX) return RNMX;
else return temp;
}
[出力結果]
step 予測観測の平均 偏差 理論値との差 1 0.017988 17.373540 -0.003108 2 0.025417 1.344455 0.393198 3 -0.248597 1.277703 1.247872 4 -1.053549 1.277196 -0.769730 5 -0.569006 1.282229 4.513963 6 -3.242339 1.148304 -0.432243 7 -3.042069 1.250402 -1.913078 8 -1.807175 1.242435 -0.877669 9 -1.222287 1.256939 -2.122946 10 0.037819 1.335024 -2.122451 11 1.319921 1.294579 -3.332589 12 3.444641 1.298284 0.778013 13 2.956242 1.274834 0.990396 14 2.351089 1.269184 -0.372974 15 2.585562 1.240364 -0.437311 16 2.857707 1.244902 -1.110906 17 3.567647 1.281882 0.771209 18 3.043078 1.257063 -0.242051 19 3.243303 1.276396 1.616374 20 2.276833 1.252842 -0.956716 21 2.893434 1.283294 2.082407 22 1.600277 1.272351 -1.630626 23 2.534451 1.237347 -1.503776 24 3.430353 1.233525 1.257182 25 2.676560 1.236485 0.110273 26 2.620786 1.294432 -0.924263 27 3.189752 1.316879 -1.207734 28 3.977979 1.263428 -1.980239 29 5.139980 1.326943 0.754355 30 4.619487 1.337006 0.105379 31 4.564191 1.343342 0.644016 32 4.108552 1.262138 2.052912 33 2.848548 1.251307 1.922607 34 1.762655 1.290456 -3.690113 35 4.087774 1.286305 0.247373 36 3.987683 1.279503 0.588147 37 3.671689 1.289687 2.361987 38 2.154840 1.323967 2.082500 39 0.908723 1.272497 -0.206598 40 1.095729 1.257794 -0.306813 41 1.253017 1.253046 0.582154 42 0.808314 1.274043 0.322751 43 0.508966 1.298451 -2.901013 44 2.409413 1.284859 -0.735228 45 2.893339 1.287879 0.295820 46 2.758199 1.330833 -1.357038 47 3.592417 1.278142 0.404373 48 3.304833 1.281612 2.531589 49 1.758497 1.280394 0.392202 50 1.545999 1.310920 -1.056786 51 2.190174 1.267770 2.639912 52 0.595522 1.208428 5.103554 53 -2.521735 1.267895 -2.039339 54 -1.292546 1.302815 -0.032658 55 -1.255533 1.336068 1.814952 56 -2.424788 1.301066 1.313037 57 -3.217728 1.262489 0.166638 58 -3.330066 1.305039 0.247324 59 -3.503007 1.285833 -1.418116 60 -2.645417 1.267560 1.547358 61 -3.613956 1.302293 1.123600 62 -4.385690 1.308220 -0.800382 63 -3.898306 1.265432 -3.359117 64 -1.749634 1.248332 0.552694 65 -2.072527 1.306821 1.165875 66 -2.863412 1.296486 1.304900 67 -3.669239 1.243378 2.034793 68 -4.971230 1.249551 -2.323981 69 -3.538345 1.287443 0.811753 70 -4.081381 1.310238 -2.725708 71 -2.268759 1.274856 2.796109 72 -4.088349 1.280111 4.171715 73 -6.730337 1.338879 1.973857 74 -7.985089 1.234455 1.822011 75 -9.086156 1.242905 -0.820753 76 -8.618827 1.267814 0.335695 77 -8.830110 1.245011 -1.241534 78 -8.089841 1.268387 1.303797 79 -8.894709 1.270887 -0.716428 80 -8.467357 1.322398 1.281794 81 -9.332648 1.244045 1.207775 82 -10.065665 1.271964 -3.455282 83 -7.883522 1.268311 -1.029089 84 -7.283919 1.333828 1.598512 85 -8.281383 1.240839 -3.585497 86 -6.093962 1.314501 1.553135 87 -7.096817 1.262598 1.197301 88 -7.803457 1.284039 0.281371 89 -8.013835 1.254791 -1.133229 90 -7.334920 1.312391 0.464980 91 -7.626792 1.269901 0.302128 92 -7.890816 1.264972 -0.205159 93 -7.744679 1.316248 -0.247753 94 -7.545355 1.248156 2.743462 95 -9.283384 1.264485 -0.345352 96 -9.095572 1.299782 -3.329767 97 -7.045077 1.297091 2.719507 98 -8.649321 1.221566 -3.299159 99 -6.662245 1.226565 -0.206662
Back to C Language



