root/applications/pmsm/simulator_zdenek/ekf_example/MATRIX_vs_bierman_new.CPP @ 1438

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