/*
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

Google




BLOG


REF:


時系列解析入門 北川 源四郎