root/applications/pmsm/simulator_zdenek/ekf_example/matrix_vs.cpp @ 1195

Revision 1195, 8.5 kB (checked in by smidl, 14 years ago)

fixes

Line 
1/************************************
2        Extended Kalman Filter
3        Matrix operations
4
5        V. Smidl
6
7Rev. 30.8.2010
8
930.8.2010      Prvni verze
10
11*************************************/
12#include "fixed.h"
13#include "stdio.h"
14/* Matrix multiply Full matrix by upper diagonal matrix; */
15void mmultAU(int *m1, int *up, int *result, unsigned int rows, unsigned int columns) {
16    unsigned int i, j, k;
17    long tmp_sum=0L;
18    int *m2pom;
19
20    for (i=0; i<rows; i++) //rows of result
21    {
22        for (j=0; j<columns; j++) //columns of result
23        {
24            m2pom=up+j;//??
25
26            for (k=0; k<j; k++) //inner loop up to "j" - U(j,j)==1;
27            {
28                tmp_sum+=(long)(*m1++)**m2pom;
29                m2pom+=columns;
30            }
31            // add the missing A(i,j)
32            tmp_sum +=(long)(*m1)<<15; // no need to shift
33            m1-=(j); // shift back to first element
34
35            // saturation effect
36            tmp_sum=tmp_sum>>15;
37            if (tmp_sum>32767) tmp_sum=32767;
38            if (tmp_sum<-32768) tmp_sum=-32768;
39
40            *result++=tmp_sum;
41
42            tmp_sum=0;
43        }
44        m1+=(columns);
45    }
46};
47
48bool DBG=true;
49
50void show(const char name[10], int *I, int n) {
51        if (!DBG) return;
52       
53        printf("%s: ",name);
54    for (int i=0;i<n;i++) {
55                printf("%d ",*(I+i));
56        }
57    printf("\n");
58}
59
60// Thorton procedure - Kalman predictive variance in UD
61void thorton(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned int rows) {
62    unsigned int i,j,k;
63    // copy D to Dold
64    int *Dold_pom=Dold;
65    for (i=0;i<rows;i++) {
66        *Dold_pom++=*D++;
67    }
68    D-=rows; // back to first D
69
70    // initialize G = eye()
71    int *G_pom = G;
72    *G_pom++=1<<14;
73    for (i=0;i<rows-1;i++) {
74        // clean elem before diag
75        for (j=0; j<rows; j++) {
76            *G_pom++=0.0;
77        }
78        *G_pom++=1<<14;
79    }
80    // eye created
81
82    long sigma; // in q30!!!!!!
83    for (i=rows-1; true;i--) { // check i==0 at the END!
84        sigma = 0;
85               
86        for (j=0;j<rows; j++) {
87                        //long s1=(((long)PSIU[i+j*rows]*PSIU[i+j*rows])>>15)*(Dold[i]);
88                        long s2=(((long)PSIU[i*rows+j]*PSIU[i*rows+j])>>15)*(Dold[j]);
89//                      printf("%d - %d\n",s1,s2);
90                        sigma += s2;
91                }
92                sigma += Q[i*rows+i]<<15;
93        for (j=i+1;j<rows; j++) {
94            sigma += (((long)G[i*rows+j]*G[i*rows+j])>>13)*Q[j*rows+j];
95//                      sigma += (((long)G[i+j*rows]*G[i+j*rows])>>13)*Q[j+j*rows];
96                }
97               
98        *(D+i)=sigma>>15;
99        if (D[i]==0) D[i]=1;
100//show("D",D,5);
101
102        for (j=0;j<i;j++) {
103//                      printf("\n%d,%d\n",i,j);
104            sigma =0;
105            for (k=0;k<rows;k++) {
106                sigma += ((((long)PSIU[i*rows+k])*PSIU[j*rows+k])>>15)*Dold[k];
107                   }
108                        for (k=0;k<rows;k++) {
109                sigma += ((((long)G[i*rows+k])*G[j*rows+k])>>13)*Q[k*rows+k];
110            }
111                        long z=sigma/D[i]; // shift by 15
112            if (z>32767) z=32767;
113            if (z<-32768) z=-32768;
114
115            U[j*rows+i] = (int)z;
116
117
118            for (k=0;k<rows;k++) {
119                PSIU[j*rows+k] -= ((long)U[j*rows+i]*PSIU[i*rows+k])>>15;
120            }
121                       
122            for (k=0;k<rows;k++) {
123                G[j*rows+k] -=  ((long)U[j*rows+i]*G[i*rows+k])>>15;
124            }
125                       
126        }
127        //show("U",U,25);
128                //show("G",G,25);
129                if (i==0) return;
130    }
131}
132
133void bierman_fast(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) {
134    int alpha;
135    int beta,lambda;
136    int b[5]; // ok even for 4-dim state
137    int *a; // in [0,1] -> q15
138    unsigned int iy,j,i;
139
140    int *b_j,*b_i;
141    int *a_j;
142    int *D_j;
143    int *U_ij;
144    int *x_i;
145    a = U; // iyth row of U
146    for (iy=0; iy<dimy; iy++, a+=dimx) {
147        // a is a row
148        for (j=0,a_j=a,b_j=b,D_j=D; j<dimx; j++,b_j++,D_j++,a_j++)
149            *b_j=((long)(*D_j)*(*a_j))>>15;
150
151        alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b
152        // R in q15, a in q15, b=q15
153//              gamma = (1<<15)/alpha; //(in q15)
154        //min alpha = R[iy] = 164
155        //max gamma = 0.0061 => gamma_ref = q7
156        for (j=0,a_j=a,b_j=b,D_j=D; j<dimx; j++,a_j++,b_j++,D_j++) {
157            beta   = alpha;
158            lambda = -((long)(*a_j)<<15)/beta;
159            alpha  += ((long)(*a_j)*(*b_j))>>15;
160            D[j] = ((((long)beta<<15)/alpha)*(*D_j))>>15; //gamma is long
161            if (*D_j==0) *D_j=1;
162
163            for (i=0,b_i=b,U_ij=U+j; i<j; i++, b_i++,U_ij+=dimx) {
164                beta   = *U_ij;
165                *U_ij +=  ((long)lambda*(*b_i))>>15;
166                *b_i  +=  ((long)beta*(*b_j))>>15;
167            }
168        }
169        int dzs = (((long)difz[iy])<<15)/alpha;  // apply scaling to innovations
170        // no shift due to gamma
171        for (i=0,x_i=xp,b_i=b; i<dimx; i++,x_i++,b_i++) {
172            *x_i  += ((long)dzs*(*b_i))>>15; // multiply by unscaled Kalman gain
173        }
174
175        //cout << "Ub: " << U << endl;
176        //cout << "Db: " << D << endl <<endl;
177
178    }
179
180}
181
182// Thorton procedure - Kalman predictive variance in UD
183void thorton_fast(int *U, int *D, int *PSIU, int *Q, int *G, int *Dold, unsigned int rows) {
184    unsigned int i,j,k;
185    // copy D to Dold
186    int *Dold_i,*Dold_k;
187    int *D_i;
188    int *PSIU_ij,*PSIU_ik,*PSIU_jk;
189    int *Q_jj,*Q_ii,*Q_kk;
190    int *U_ji;
191    int *G_ik,*G_jk;
192    int irows,jrows;
193    long sigma; // in q15
194
195    for (i=0,Dold_i=Dold,D_i=D;i<rows;i++,Dold_i++,D_i++) {
196        *Dold_i=*D_i;
197    }
198
199    // initialize G = eye()
200    G_ik= G;
201    *G_ik++=1<<14;
202    for (i=0;i<rows-1;i++) {
203        // clean elem before diag
204        for (k=0; k<rows; k++) {
205            *G_ik++=0;
206        }
207        *G_ik++=1<<14;
208    }
209    // eye created
210
211    for (i=rows-1, Dold_i=Dold+i, D_i=D+i;
212            true; i--, Dold_i--,D_i--) { // stop if i==0 at the END!
213        irows=i*rows;
214        sigma = 0;
215        for (k=0, PSIU_ik=PSIU+irows;
216           k<rows; k++, PSIU_ik++) {//Dold_i=
217            sigma += (((long)(*PSIU_ik)**PSIU_ik)>>15)*(*Dold_i);
218                }
219                sigma += *(Q+i+irows)<<15;
220        for (j=i+1, G_ik=G+irows+i+1; j<rows; j++,G_ik++) {
221            sigma += (((long)(*G_ik)**G_ik)>>13)**(Q+j+j*rows);
222                       
223        }
224               
225        *D_i=sigma>>15;
226        if (*D_i==0) *D_i=1;
227
228
229        for (j=0;j<i;j++) {
230            jrows = j*rows;
231
232            sigma =0;
233            for (k=0, PSIU_ik=PSIU+irows, PSIU_jk=PSIU+jrows, Dold_k=Dold;
234                    k<rows; k++, PSIU_ik++, PSIU_jk++, Dold_k++) {
235                               
236                sigma += ((((long)*PSIU_ik)**PSIU_jk)>>15)**Dold_k;
237            }
238                       
239            for (k=i,G_ik=G+irows+i,G_jk=G+jrows+i,Q_kk=Q+k*rows+k;
240            k<rows;k++,G_ik++,G_jk++,Q_kk+=rows+1) {
241                sigma += ((((long)*G_ik)**G_jk)>>13)**Q_kk;
242            }
243                       
244                        long z=sigma/(*D_i); // shift by 15
245            if (z>32767) z=32767;
246            if (z<-32768) z=-32768;
247
248            U_ji=U+jrows+i;
249            *U_ji = (int)z;
250
251
252            for (k=0,PSIU_ik=PSIU+irows,PSIU_jk=PSIU+jrows;
253                    k<rows;k++,PSIU_ik++,PSIU_jk++) {
254                *PSIU_jk -= ((long)*U_ji**PSIU_ik)>>15;
255            }
256                       
257            for (k=0,G_jk=G+jrows,G_ik=G+irows;
258            k<rows;k++, G_jk++, G_ik++) {
259                *G_jk -=  ((long)*U_ji**G_ik)>>15;
260            }
261                       
262        }
263        if (i==0) return;
264    }
265}
266
267void bierman(int *difz, int *xp, int *U, int *D, int *R, unsigned int dimy, unsigned int dimx ) {
268    long alpha;
269    long gamma,beta,lambda;
270    int b[5]; // ok even for 4-dim state
271    int *a; // in [0,1] -> q15
272    unsigned int iy,j,i;
273
274    for (iy=0; iy<dimy; iy++) {
275        // a is a row
276        a = U+iy*dimx; // iyth row of U
277        for (j=0;j<dimx;j++)
278            b[j]=((long)D[j]*a[j])>>15;
279
280        alpha = (long)R[iy]; //\alpha = R+vDv = R+a*b
281        // R in q15, a in q15, b=q15
282//              gamma = (1<<15)/alpha; //(in q15)
283        //min alpha = R[iy] = 164
284        //max gamma = 0.0061 => gamma_ref = q7
285        for (j=0;j<dimx;j++) {
286            beta   = alpha;
287            lambda = -((long)a[j]<<15)/beta;
288            alpha  += ((long)(a[j])*b[j]>>15);
289            D[j] = (((long)beta<<15)/alpha)*D[j]>>15; //gamma is long
290            if (D[j]==0) D[j]=1;
291
292            //                  cout << "a: " << alpha << "g: " << gamma << endl;
293            for (i=0;i<j;i++) {
294                beta   = U[i*dimx+j];
295                U[i*dimx+j] +=  (lambda*b[i])>>15;
296                b[i]   +=  (beta*b[j])>>15;
297            }
298        }
299        int dzs = (((long)difz[iy])<<15)/alpha;  // apply scaling to innovations
300        // no shift due to gamma
301        for (i=0; i<dimx; i++) {
302            xp[i]  += ((long)dzs*b[i])>>15; // multiply by unscaled Kalman gain
303        }
304
305        //cout << "Ub: " << U << endl;
306        //cout << "Db: " << D << endl <<endl;
307
308    }
309
310}
Note: See TracBrowser for help on using the browser.