- Timestamp:
- 10/29/10 19:10:03 (14 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
applications/pmsm/simulator_zdenek/ekf_example/matrix_vs.cpp
r1239 r1240 3 3 Matrix operations 4 4 5 V. Smidl 6 7 Rev. 30.8.2010 8 9 30.8.2010 Prvni verze 5 V. Smidl, Z. Peroutka 6 7 Rev. 28.10.2010 (ZP) 8 9 26.10.2010 Prvni verze (VS) 10 11 26.10.2010 Upravena chyba v Thorton_fast - spatne shiftovani o vypoctu SIGMA. 12 27.10.2010 Pokus o odstraneni problemu v Thorton_fast - potize dela omezovani (orezavani) varianci. 13 28.10.2010 Drobne upravy v kodu. 10 14 11 15 *************************************/ 12 #include "fixed.h"13 #include "stdio.h"14 #include <math.h>15 16 16 17 #include "matrix_vs.h" 17 18 18 19 /* Matrix multiply Full matrix by upper diagonal matrix; */ 19 void mmultAU(int *m1, int *up, int *result, unsigned int rows, unsigned intcolumns) {20 unsigned int i, j, k;21 longtmp_sum=0L; //in 15+qAU22 int *m2pom;23 int *m1pom=m1;24 int *respom=result;20 void mmultAU(int16 *m1, int16 *up, int16 *result, unsigned int16 rows, unsigned int16 columns) { 21 unsigned int16 i, j, k; 22 int32 tmp_sum=0L; //in 15+qAU 23 int16 *m2pom; 24 int16 *m1pom=m1; 25 int16 *respom=result; 25 26 26 27 for (i=0; i<rows; i++) //rows of result 27 28 { 28 29 for (j=0; j<columns; j++) //columns of result 29 30 { 30 31 m2pom=up+j;//?? 31 32 32 33 for (k=0; k<j; k++) //inner loop up to "j" - U(j,j)==1; 33 34 { 34 tmp_sum+=(( long)(*(m1pom++))**m2pom)>>(15-qAU);35 tmp_sum+=((int32)(*(m1pom++))**m2pom)>>(15-qAU); 35 36 m2pom+=columns; 36 37 } 37 38 // add the missing A(i,j) 38 tmp_sum +=( long)(*m1pom)<<qAU; // no need to shift39 tmp_sum +=(int32)(*m1pom)<<qAU; // no need to shift 39 40 m1pom-=(j); // shift back to first element 40 41 41 // saturation effect42 /* tmp_sum=tmp_sum>>15;43 if (tmp_sum>32767) {44 printf("Au - saturated\n");45 }46 if (tmp_sum<-32768) {47 printf("Au - saturated\n");48 }*/49 // printf("Au - saturated\n");50 51 42 *respom++=tmp_sum>>15; 52 43 … … 57 48 }; 58 49 59 /* Matrix multiply Full matrix by upper diagonal matrix; */ 60 void mmultACh(int *m1, int *up, int *result, unsigned int rows, unsigned int columns) { 61 unsigned int i, j, k; 62 long tmp_sum=0L; 63 int *m2pom; 64 int *m1pom=m1; 65 int *respom=result; 66 67 for (i=0; i<rows; i++) //rows of result 68 { 69 for (j=0; j<columns; j++) //columns of result 70 { 71 m2pom=up+j;//?? 72 73 for (k=0; k<=j; k++) //inner loop up to "j" - U(j,j)==1; 74 { 75 tmp_sum+=(long)(*(m1pom++))**m2pom; 76 m2pom+=columns; 77 } 78 m1pom-=(j+1); // shift back to first element 79 80 // saturation effect 81 tmp_sum=tmp_sum>>15; 82 if (tmp_sum>32767) { 83 if (i!=3) tmp_sum=32767; 84 } 85 if (tmp_sum<-32768) { 86 tmp_sum=-32768; 87 } 88 // printf("Au - saturated\n"); 89 90 *respom++=tmp_sum; 91 92 tmp_sum=0; 93 } 94 m1pom+=(columns); 95 } 96 }; 97 98 bool DBG=true; 99 100 void show(const char name[10], int *I, int n) { 101 if (!DBG) return; 102 103 printf("%s: ",name); 104 for (int i=0;i<n;i++) { 105 printf("%d ",*(I+i)); 106 } 107 printf("\n"); 108 } 109 110 // Thorton procedure - Kalman predictive variance in UD 111 void thorton(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned int rows) { 112 unsigned int i,j,k; 113 // copy D to Dold 114 int *Dold_pom=Dold; 115 for (i=0;i<rows;i++) { 116 *Dold_pom++=*D++; 117 } 118 D-=rows; // back to first D 119 120 // initialize G = eye() 121 int *G_pom = G; 122 *G_pom++=1<<14; 123 for (i=0;i<rows-1;i++) { 124 // clean elem before diag 125 for (j=0; j<rows; j++) { 126 *G_pom++=0.0; 127 } 128 *G_pom++=1<<14; 129 } 130 // eye created 131 132 long sigma; // in q30!!!!!! 133 for (i=rows-1; true;i--) { // check i==0 at the END! 134 sigma = 0; 135 136 for (j=0;j<rows; j++) { 137 //long s1=(((long)PSIU[i+j*rows]*PSIU[i+j*rows])>>15)*(Dold[i]); 138 long s2=((((long)PSIU[i*rows+j]*Dold[j]))>>(2*qAU-15))*PSIU[i*rows+j]; 139 // printf("%d - %d\n",s1,s2); 140 sigma += s2; 141 } 142 sigma += Q[i*rows+i]<<15; // Q is in q15 143 for (j=i+1;j<rows; j++) { 144 sigma += (((long)G[i*rows+j]*G[i*rows+j])>>13)*Q[j*rows+j]; 145 // sigma += (((long)G[i+j*rows]*G[i+j*rows])>>13)*Q[j+j*rows]; 146 } 147 148 if (sigma>16384<<15) sigma = 16384<<15; 149 *(D+i)=sigma>>15; 150 if (D[i]==0) D[i]=1; 151 //show("D",D,5); 152 153 for (j=0;j<i;j++) { 154 // printf("\n%d,%d\n",i,j); 155 sigma =0; 156 for (k=0;k<rows;k++) { 157 int tmp= (((long(PSIU[i*rows+k])*Dold[k]))>>(2*qAU-15)); 158 if (tmp>32767) printf("!"); 159 sigma += (((long(PSIU[i*rows+k])*Dold[k]))>>(2*qAU-15))*PSIU[j*rows+k]; 160 } 161 for (k=0;k<rows;k++) { 162 sigma += ((((long)G[i*rows+k])*G[j*rows+k])>>13)*Q[k*rows+k]; 163 } 164 long z=sigma/D[i]; // shift by 15 165 if (z>32767) z=32767; 166 if (z<-32768) z=-32768; 167 168 U[j*rows+i] = (int)z; 169 170 171 for (k=0;k<rows;k++) { 172 PSIU[j*rows+k] -= ((long)U[j*rows+i]*PSIU[i*rows+k])>>15; //qAU*q15/q15=qAU 173 } 174 175 for (k=0;k<rows;k++) { 176 G[j*rows+k] -= ((long)U[j*rows+i]*G[i*rows+k])>>15; 177 } 178 179 } 180 //show("U",U,25); 181 //show("G",G,25); 182 if (i==0) return; 183 } 184 } 185 186 void bierman_fast(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) { 187 int alpha; 188 int beta,lambda; 189 int b[5]; // ok even for 4-dim state 190 int *a; // in [0,1] -> q15 191 unsigned int iy,j,i; 192 193 int *b_j,*b_i; 194 int *a_j; 195 int *D_j; 196 int *U_ij; 197 int *x_i; 198 int dzs; 50 51 void bierman_fast(int16 *difz, int16 *xp, int16 *U, int16 *D, int16 *R, unsigned int16 dimy, unsigned int16 dimx ) 52 { 53 int16 alpha; 54 int16 beta,lambda; 55 int16 b[5]; // ok even for 4-dim state 56 int16 *a; // in [0,1] -> q15 57 unsigned int16 iy,j,i; 58 59 int16 *b_j,*b_i; 60 int16 *a_j; 61 int16 *D_j; 62 int16 *U_ij; 63 int16 *x_i; 64 65 int32 z_pom; 66 int16 z_pom_int16; 199 67 200 68 a = U; // iyth row of U … … 202 70 // a is a row 203 71 for (j=0,a_j=a,b_j=b,D_j=D; j<dimx; j++,b_j++,D_j++,a_j++) 204 *b_j=(( long)(*D_j)*(*a_j))>>15;205 206 alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b72 *b_j=((int32)(*D_j)*(*a_j))>>15; 73 74 alpha = R[iy]; //\alpha = R+vDv = R+a*b 207 75 // R in q15, a in q15, b=q15 208 76 // gamma = (1<<15)/alpha; //(in q15) … … 210 78 //max gamma = 0.0061 => gamma_ref = q7 211 79 for (j=0,a_j=a,b_j=b,D_j=D; j<dimx; j++,a_j++,b_j++,D_j++) { 212 beta = alpha; 213 lambda = -((long)(*a_j)<<15)/beta; 214 alpha += ((long)(*a_j)*(*b_j))>>15; 215 D[j] = ((((long)beta<<15)/alpha)*(*D_j))>>15; //gamma is long 80 /* beta=alpha; 81 lambda = -((int32)(*a_j)<<15)/beta; 82 alpha += ((int32)(*a_j)*(*b_j))>>15; 83 D[j] = ((int32)beta**D_j)/alpha;*/ 84 /*xx*/ 85 lambda=alpha; 86 alpha += ((int32)(*a_j)*(*b_j))>>15; 87 D[j] = ((int32)lambda**D_j)/alpha; 88 z_pom_int16 = -((int32)(*a_j)<<15)/lambda; 89 /*xx*/ 90 216 91 if (*D_j==0) *D_j=1; 217 92 218 93 for (i=0,b_i=b,U_ij=U+j; i<j; i++, b_i++,U_ij+=dimx) { 219 94 beta = *U_ij; 220 *U_ij += ((long)lambda*(*b_i))>>15; 221 *b_i += ((long)beta*(*b_j))>>15; 222 } 223 } 224 dzs = (((long)difz[iy])<<15)/alpha; // apply scaling to innovations 95 // *U_ij += ((int32)lambda*(*b_i))>>15; // puvodni reseni 96 *U_ij -= ((int32)(*a_j)*(*b_i))/lambda; // pozadovane optimalni reseni 97 // *U_ij -= ((int32)((int16)((int32)(*a_j)<<15)/lambda)**b_i)>>15; // tohle funguje - problem je s tim pretypovanim na (int16) 98 // *U_ij -= (int16)((int32)(*a_j)*(*b_i))/lambda; 99 // z_pom = (((int32)(*a_j)*(*b_i))/lambda); 100 /* z_pom = (int32)(*U_ij)-(int16)((int32)(*a_j)*(*b_i))/lambda; 101 if (z_pom > 32767) z_pom = 32767; 102 if (z_pom < - 32768) z_pom = -32768; 103 *U_ij = z_pom; /**/ 104 // *U_ij += ((int32)z_pom_int16*(*b_i))>>15; // puvodni reseni - jen jina konstanta 105 *b_i += ((int32)beta*(*b_j))>>15; 106 } 107 } 225 108 // no shift due to gamma 226 109 for (i=0,x_i=xp,b_i=b; i<dimx; i++,x_i++,b_i++) { 227 *x_i += ((long)dzs*(*b_i))>>15; // multiply by unscaled Kalman gain 228 } 229 230 //cout << "Ub: " << U << endl; 231 //cout << "Db: " << D << endl <<endl; 232 233 } 234 235 } 110 *x_i += ((int32)difz[iy]*(*b_i))/alpha; // multiply by unscaled Kalman gain 111 } 112 } 113 } 114 236 115 237 116 // Thorton procedure - Kalman predictive variance in UD 238 void thorton_fast(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned introws) {239 unsigned int i,j,k;117 void thorton_fast(int16 *U, int16 *D, int16 *PSIU, int16 *Q, int16 *G, int16 *Dold, unsigned int16 rows) { 118 unsigned int16 i,j,k; 240 119 // copy D to Dold 241 int *Dold_i,*Dold_k;242 int *D_i;243 int *PSIU_ij,*PSIU_ik,*PSIU_jk;244 int *Q_jj,*Q_ii,*Q_kk;245 int *U_ji;246 int *G_ik,*G_jk;247 int irows,jrows;248 longsigma; // in qAU+15!!249 longz;120 int16 *Dold_i,*Dold_k; 121 int16 *D_i; 122 int16 *PSIU_ij,*PSIU_ik,*PSIU_jk; 123 int16 *Q_jj,*Q_ii,*Q_kk; 124 int16 *U_ji; 125 int16 *G_ik,*G_jk; 126 int16 irows,jrows; 127 int32 sigma; // in qAU+15!! 128 int32 z; 250 129 251 130 for (i=0,Dold_i=Dold,D_i=D;i<rows;i++,Dold_i++,D_i++) { … … 271 150 for (k=0, PSIU_ik=PSIU+irows,Dold_k=Dold; 272 151 k<rows; k++, PSIU_ik++,Dold_k++) { 273 sigma += ((( long)(*PSIU_ik)**PSIU_ik)>>(qAU))*(*Dold_k);274 } 275 sigma += *(Q+i+irows)<<qAU;152 sigma += (((int32)(*PSIU_ik)**PSIU_ik)>>(qAU))*(*Dold_k); 153 } 154 sigma += (int32)(*(Q+i+irows))<<qAU; 276 155 for (j=i+1, G_ik=G+irows+i+1; j<rows; j++,G_ik++) { 277 sigma += (((long)(*G_ik)**G_ik)>>16)**(Q+j+j*rows); 278 279 } 280 281 if (sigma>((long)1<<(qAU+15))) { 156 sigma += (((int32)(*G_ik)**G_ik)>>16)**(Q+j+j*rows); 157 } 158 159 if (sigma>((int32)1<<(qAU+15))) { 282 160 *D_i = 32767; 283 161 // *(Dold+i)-=*(Q+i+irows); … … 294 172 k<rows; k++, PSIU_ik++, PSIU_jk++, Dold_k++) { 295 173 296 sigma += (((( long)(*PSIU_ik)**PSIU_jk)>>qAU)**Dold_k);174 sigma += ((((int32)(*PSIU_ik)**PSIU_jk)>>qAU)**Dold_k); 297 175 } 298 176 299 177 for (k=i,G_ik=G+irows+i,G_jk=G+jrows+i,Q_kk=Q+k*rows+k; 300 178 k<rows;k++,G_ik++,G_jk++,Q_kk+=rows+1) { 301 sigma += (((( long)*G_ik)**G_jk)>>16)**Q_kk;179 sigma += ((((int32)*G_ik)**G_jk)>>16)**Q_kk; 302 180 } 303 181 … … 307 185 308 186 U_ji=U+jrows+i; 309 *U_ji = (int )z;187 *U_ji = (int16)z; 310 188 311 189 312 190 for (k=0,PSIU_ik=PSIU+irows,PSIU_jk=PSIU+jrows; 313 191 k<rows;k++,PSIU_ik++,PSIU_jk++) { 314 *PSIU_jk -= (( long)*U_ji**PSIU_ik)>>15;192 *PSIU_jk -= ((int32)*U_ji**PSIU_ik)>>15; 315 193 } 316 194 317 195 for (k=0,G_jk=G+jrows,G_ik=G+irows; 318 196 k<rows;k++, G_jk++, G_ik++) { 319 *G_jk -= (( long)*U_ji**G_ik)>>15;197 *G_jk -= ((int32)*U_ji**G_ik)>>15; 320 198 } 321 199 … … 323 201 if (i==0) return; 324 202 } 325 }326 327 void bierman(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) {328 long alpha;329 long gamma,beta,lambda;330 int b[5]; // ok even for 4-dim state331 int *a; // in [0,1] -> q15332 unsigned int iy,j,i;333 334 for (iy=0; iy<dimy; iy++) {335 // a is a row336 a = U+iy*dimx; // iyth row of U337 for (j=0;j<dimx;j++) {338 (j<iy)? b[j]=0: (j==iy)? b[j]=D[j] : b[j]=((long)D[j]*a[j])>>15;339 }340 341 alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b342 // R in q15, a in q15, b=q15343 // gamma = (1<<15)/alpha; //(in q15)344 //min alpha = R[iy] = 164345 //max gamma = 0.0061 => gamma_ref = q7346 for (j=0;j<dimx;j++) {347 beta = alpha;348 lambda = -(long(a[j])<<15)/beta;349 alpha += ((long(a[j])*b[j])>>15);350 D[j] = (((long(beta)<<15)/alpha)*D[j])>>15; //gamma is long351 if (D[j]==0) D[j]=1;352 353 // cout << "a: " << alpha << "g: " << gamma << endl;354 for (i=0;i<j;i++) {355 beta = U[i*dimx+j];356 U[i*dimx+j] += (lambda*b[i])>>15;357 b[i] += (beta*b[j])>>15;358 }359 }360 int dzs = (long(difz[iy])<<15)/alpha; // apply scaling to innovations361 // no shift due to gamma362 for (i=0; i<dimx; i++) {363 xp[i] += (long(dzs*b[i]))>>15; // multiply by unscaled Kalman gain364 }365 366 //cout << "Ub: " << U << endl;367 //cout << "Db: " << D << endl <<endl;368 369 }370 371 203 } 372 204