/************************************ Extended Kalman Filter Matrix operations V. Smidl, Z. Peroutka Rev. 28.10.2010 (ZP) 26.10.2010 Prvni verze (VS) 26.10.2010 Upravena chyba v Thorton_fast - spatne shiftovani o vypoctu SIGMA. 27.10.2010 Pokus o odstraneni problemu v Thorton_fast - potize dela omezovani (orezavani) varianci. 28.10.2010 Drobne upravy v kodu. *************************************/ #include "matrix_vs.h" /* Matrix multiply Full matrix by upper diagonal matrix; */ void mmultAU(int16 *m1, int16 *up, int16 *result, unsigned int16 rows, unsigned int16 columns) { unsigned int16 i, j, k; int32 tmp_sum=0L; //in 15+qAU int16 *m2pom; int16 *m1pom=m1; int16 *respom=result; for (i=0; i>(15-qAU); m2pom+=columns; } // add the missing A(i,j) tmp_sum +=(int32)(*m1pom)<>15; tmp_sum=0; } m1pom+=(columns); } }; void bierman_fast(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ) { int16 alpha; int16 beta,lambda; int16 b[5]; // ok even for 4-dim state int16 *a; // in [0,1] -> q15 unsigned int16 iy,j,i; int16 *b_j,*b_i; int16 *a_j; int16 *D_j; int16 *U_ij; int16 *x_i; int32 z_pom; int16 z_pom_int16; a = U; // iyth row of U for (iy=0; iy>15; alpha = 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] = ((int32)beta**D_j)/alpha;*/ /*xx*/ lambda=alpha; alpha += ((int32)(*a_j)*(*b_j))>>15; D[j] = ((int32)lambda**D_j)/alpha; z_pom_int16 = -((int32)(*a_j)<<15)/lambda; /*xx*/ if (*D_j==0) *D_j=1; for (i=0,b_i=b,U_ij=U+j; i>15; // puvodni reseni *U_ij -= ((int32)(*a_j)*(*b_i))/lambda; // pozadovane optimalni reseni // *U_ij -= ((int32)((int16)((int32)(*a_j)<<15)/lambda)**b_i)>>15; // tohle funguje - problem je s tim pretypovanim na (int16) // *U_ij -= (int16)((int32)(*a_j)*(*b_i))/lambda; // z_pom = (((int32)(*a_j)*(*b_i))/lambda); /* z_pom = (int32)(*U_ij)-(int16)((int32)(*a_j)*(*b_i))/lambda; if (z_pom > 32767) z_pom = 32767; if (z_pom < - 32768) z_pom = -32768; *U_ij = z_pom; /**/ // *U_ij += ((int32)z_pom_int16*(*b_i))>>15; // puvodni reseni - jen jina konstanta *b_i += ((int32)beta*(*b_j))>>15; } } // no shift due to gamma for (i=0,x_i=xp,b_i=b; i>(qAU))*(*Dold_k); } sigma += (int32)(*(Q+i+irows))<>16)**(Q+j+j*rows); } if (sigma>((int32)1<<(qAU+15))) { *D_i = 32767; // *(Dold+i)-=*(Q+i+irows); } else { *D_i=sigma>>qAU; } if (*D_i==0) *D_i=1; for (j=0;j>qAU)**Dold_k); } for (k=i,G_ik=G+irows+i,G_jk=G+jrows+i,Q_kk=Q+k*rows+k; k>16)**Q_kk; } z=(sigma/(*D_i))<<(15-qAU); // shift to q15 if (z>32767) z=32767; if (z<-32768) z=-32768; U_ji=U+jrows+i; *U_ji = (int16)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; } } /* square root of 06554) { 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 alpha,beta; long sigma; 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;j16384) sigma=16384; // alpha=int_sqrt(sigma); alpha = (int)(sqrt((double)sigma)+0.5); // predelat pro DSP // alpha = alpf*(1<<15); // sigma=0; for (j=0;j>16; if (alpha==0) alpha =1; for (i=0;i<=k;i++) { sigma=0; for (j=0;j> 15; // navrat do Q15 for (j=0;j>15; // double ab=(double)alpha*beta/32768./32768.; // double s_ab=sqrt(ab); gamma=(int)(sqrt((double)((long)alpha*beta))+0.5); // predelat v DSP //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)beta*Ch[i*dimx+j] -(long)sigma*w[i])/gamma; w[i]+=((long)tau*sigma)>>15; } } //epsilon=(long(difz)<<15) / (alpha); // q15*q13/q13 = q15 for (i=0;i=0; i--){ for (j=0; j>15); if (rho==0) break; s=(long(A[i*dimx+j])<<15)/rho; c=(long(Ch[i*dimx+i])<<15)/rho; for (k=0;k<=i; k++){ tau=(long(c)*A[k*dimx+j]-long(s)*Ch[k*dimx+i])>>15; Ch[k*dimx +i]=(long(s)*A[k*dimx+j]+long(c)*Ch[k*dimx+i])>>15; A[k*dimx +j]=tau; } } } for (j=0; j>15); if (rho==0) break; s=(long(Ch[i*dimx+j])<<15)/rho; c=(long(Ch[i*dimx+i])<<15)/rho; for (k=0; k<=i; k++){ tau=(long(c)*Ch[k*dimx+j]-long(s)*Ch[k*dimx+i])>>15; Ch[k*dimx+i]=(long(s)*Ch[k*dimx+j]+long(c)*Ch[k*dimx+i])>>15; Ch[k*dimx+j]=tau; } } }