/************************************ Extended Kalman Filter Matrix operations V. Smidl Rev. 30.8.2010 30.8.2010 Prvni verze *************************************/ #include "fixed.h" #include "stdio.h" /* Matrix multiply Full matrix by upper diagonal matrix; */ void mmultAU(int *m1, int *up, int *result, unsigned int rows, unsigned int columns) { unsigned int i, j, k; long tmp_sum=0L; int *m2pom; for (i=0; i>15; if (tmp_sum>32767) tmp_sum=32767; if (tmp_sum<-32768) tmp_sum=-32768; *result++=tmp_sum; tmp_sum=0; } m1+=(columns); } }; bool DBG=true; void show(const char name[10], int *I, int n) { if (!DBG) return; printf("%s: ",name); for (int i=0;i>15)*(Dold[i]); long s2=(((long)PSIU[i*rows+j]*PSIU[i*rows+j])>>15)*(Dold[j]); // printf("%d - %d\n",s1,s2); sigma += s2; } sigma += Q[i*rows+i]<<15; for (j=i+1;j>13)*Q[j*rows+j]; // sigma += (((long)G[i+j*rows]*G[i+j*rows])>>13)*Q[j+j*rows]; } *(D+i)=sigma>>15; if (D[i]==0) D[i]=1; //show("D",D,5); for (j=0;j>15)*Dold[k]; } for (k=0;k>13)*Q[k*rows+k]; } long z=sigma/D[i]; // shift by 15 if (z>32767) z=32767; if (z<-32768) z=-32768; U[j*rows+i] = (int)z; for (k=0;k>15; } for (k=0;k>15; } } //show("U",U,25); //show("G",G,25); if (i==0) return; } } void bierman_fast(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) { int alpha; int beta,lambda; int b[5]; // ok even for 4-dim state int *a; // in [0,1] -> q15 unsigned int iy,j,i; int *b_j,*b_i; int *a_j; int *D_j; int *U_ij; int *x_i; a = U; // iyth row of U for (iy=0; iy>15; alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b // R in q15, a in q15, b=q15 // gamma = (1<<15)/alpha; //(in q15) //min alpha = R[iy] = 164 //max gamma = 0.0061 => gamma_ref = q7 for (j=0,a_j=a,b_j=b,D_j=D; j>15; D[j] = ((((long)beta<<15)/alpha)*(*D_j))>>15; //gamma is long if (*D_j==0) *D_j=1; for (i=0,b_i=b,U_ij=U+j; i>15; *b_i += ((long)beta*(*b_j))>>15; } } int dzs = (((long)difz[iy])<<15)/alpha; // apply scaling to innovations // no shift due to gamma for (i=0,x_i=xp,b_i=b; i>15; // multiply by unscaled Kalman gain } //cout << "Ub: " << U << endl; //cout << "Db: " << D << endl <>15)*(*Dold_k); } sigma += *(Q+i+irows)<<15; for (j=i+1, G_ik=G+irows+i+1; j>13)**(Q+j+j*rows); } *D_i=sigma>>15; if (*D_i==0) *D_i=1; for (j=0;j>15)**Dold_k; } for (k=i,G_ik=G+irows+i,G_jk=G+jrows+i,Q_kk=Q+k*rows+k; k>13)**Q_kk; } long z=sigma/(*D_i); // shift by 15 if (z>32767) z=32767; if (z<-32768) z=-32768; U_ji=U+jrows+i; *U_ji = (int)z; for (k=0,PSIU_ik=PSIU+irows,PSIU_jk=PSIU+jrows; k>15; } for (k=0,G_jk=G+jrows,G_ik=G+irows; k>15; } } if (i==0) return; } } void bierman(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) { long alpha; long gamma,beta,lambda; int b[5]; // ok even for 4-dim state int *a; // in [0,1] -> q15 unsigned int iy,j,i; for (iy=0; iy>15; alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b // R in q15, a in q15, b=q15 // gamma = (1<<15)/alpha; //(in q15) //min alpha = R[iy] = 164 //max gamma = 0.0061 => gamma_ref = q7 for (j=0;j>15); D[j] = (((long)beta<<15)/alpha)*D[j]>>15; //gamma is long if (D[j]==0) D[j]=1; // cout << "a: " << alpha << "g: " << gamma << endl; for (i=0;i>15; b[i] += (beta*b[j])>>15; } } int dzs = (((long)difz[iy])<<15)/alpha; // apply scaling to innovations // no shift due to gamma for (i=0; i>15; // multiply by unscaled Kalman gain } //cout << "Ub: " << U << endl; //cout << "Db: " << D << endl <