/************************************ Extended Kalman Filter Matrix operations V. Smidl Rev. 30.8.2010 30.8.2010 Prvni verze *************************************/ #include "fixed.h" #include "stdio.h" #include #include "matrix_vs.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; //in 15+qAU int *m2pom; int *m1pom=m1; int *respom=result; for (i=0; i>(15-qAU); m2pom+=columns; } // add the missing A(i,j) tmp_sum +=(long)(*m1pom)<>15; if (tmp_sum>32767) { //tmp_sum=32767; } if (tmp_sum<-32768) { //tmp_sum=-32768; } // printf("Au - saturated\n"); *respom++=tmp_sum; tmp_sum=0; } m1pom+=(columns); } }; /* Matrix multiply Full matrix by upper diagonal matrix; */ void mmultACh(int *m1, int *up, int *result, unsigned int rows, unsigned int columns) { unsigned int i, j, k; long tmp_sum=0L; int *m2pom; int *m1pom=m1; int *respom=result; for (i=0; i>15; if (tmp_sum>32767) { if (i!=3) tmp_sum=32767; } if (tmp_sum<-32768) { tmp_sum=-32768; } // printf("Au - saturated\n"); *respom++=tmp_sum; tmp_sum=0; } m1pom+=(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]))>>(2*qAU-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]; } // if (sigma>16384<<15) sigma = 16384<<15; *(D+i)=sigma>>15; if (D[i]==0) D[i]=1; //show("D",D,5); for (j=0;j>(2*qAU-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; //qAU*q15/q15=qAU } 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 <6554) { int xm05=x-16384; tmp = ((long)k1*xm05)>>15; tmp-=(((long(k2)*xm05)>>15)*xm05)>>15; tmp +=k1; } else { tmp = 4*x; tmp-=long(8*x)*x>>15; } return tmp; } void householder(int *Ch /*= int *PSICh*/, int *Q, unsigned int dimx) { int k,j,i; int sigma,alpha,beta; int B[25];//beware int w[5]; int v[5]; // copy Q to B for (i=0;i=0; k--) { sigma=0; for (j=0;j>15; } for (j=0;j<=k;j++) { sigma+=(long(Ch[k*dimx+j])*Ch[k*dimx+j])>>15; } /* double sigf=double(sigma)/(1<<15); double alpf = sqrt(sigf);*/ alpha=int_sqrt(sigma); // alpha = alpf*(1<<15); // sigma=0; for (j=0;j>15; } for (j=0; j<=k;j++) { if (j==k) { v[j]=Ch[k*dimx+j]-alpha; } else { v[j]=Ch[k*dimx+j]; } sigma+=(long(v[j])*v[j])>>15; } alpha=sigma>>1; for (i=0;i<=k;i++) { sigma=0; for (j=0;j>15; } for (j=0;j<=k;j++) { sigma+=(long(Ch[i*dimx+j])*v[j])>>15; } for (j=0;j>15; // double ab=(double)alpha*beta/32768./32768.; // double s_ab=sqrt(ab); gamma=int_sqrt(((long)alpha*beta)>>15); //gamma = round(s_ab*(1<<15)); eta=(long (beta)<<15) / gamma; //zeta=(long(sigma)<<15)/ gamma; w[j]=0; for (i=0;i<=j;i++) { tau=Ch[i*dimx+j]; Ch[i*dimx+j]=((long(eta)*Ch[i*dimx+j])>>15) -(long(sigma)*w[i])/gamma; w[i]+=(long(tau)*sigma)>>15; } } //epsilon=(long(difz)<<15) / (alpha); // q15*q13/q13 = q15 for (i=0;i