easykf-2.04
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Macros Pages
ukf_sr_state_ndim.h
Go to the documentation of this file.
1 /* ukf_sr_state_ndim.h
2  *
3  * Copyright (C) 2011-2014 Jeremy Fix
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #define DEBUGMODE true
21 
22 #ifndef UKF_SR_STATE_NDIM_H
23 #define UKF_SR_STATE_NDIM_H
24 
25 #include <gsl/gsl_linalg.h> // For the Cholesky decomposition
26 #include <gsl/gsl_math.h>
27 #include <gsl/gsl_blas.h>
28 
29 #include "ukf_types.h"
30 #include "ukf_math.h"
31 
32 void print_mat(const gsl_matrix * A)
33 {
34  for(unsigned int i = 0 ; i < A->size1 ; ++i)
35  {
36  for(unsigned int j = 0 ; j < A ->size2 ; ++j)
37  printf("%e ", gsl_matrix_get(A,i,j));
38 
39  printf("\n");
40  }
41 }
42 
43 void print_vec(const gsl_vector * A)
44 {
45  for(unsigned int i = 0 ; i < A->size ; ++i)
46  {
47  printf("%e ", gsl_vector_get(A,i));
48  }
49  printf("\n");
50 }
51 
52 namespace ukf
53 {
54 
59  namespace srstate
60  {
65  inline void ukf_init(ukf_param &p, ukf_state &s)
66  {
67  // Parameters for the sigma points of the process equation
68  p.nbSamples = 2 * p.n + 1;
69  p.lambda = p.alpha * p.alpha * (p.n + p.kpa) - p.n;
70  p.gamma = sqrt(p.n + p.lambda);
71 
72  // Parameters for the sigma points of the observation equation
73  p.nbSamplesMeasure = 4 * p.n + 1;
74  p.lambda_aug = p.alpha * p.alpha * (2*p.n + p.kpa) - 2*p.n;
75  p.gamma_aug = sqrt(2*p.n + p.lambda_aug);
76 
77  // Init the matrices used to iterate
78  s.xi = gsl_vector_alloc(p.n);
79  gsl_vector_set_zero(s.xi);
80 
81  // Images of the sigma points
82  s.xi_prediction = gsl_matrix_alloc(p.n, p.nbSamples);
83  gsl_matrix_set_zero(s.xi_prediction);
84 
85  s.xi_mean = gsl_vector_alloc(p.n);
86  gsl_vector_set_zero(s.xi_mean);
87 
88  // Cholesky factor of the variance/covariance matrix Pxxi
89  s.Sxi = gsl_matrix_alloc(p.n,p.n);
90  gsl_matrix_set_identity(s.Sxi);
91  gsl_matrix_scale(s.Sxi, sqrt(p.prior_x));
92 
93  // Cholesky factor of the variance/covariance matrix of the process noise
94  s.Svi = gsl_matrix_alloc(p.n,p.n);
95  gsl_matrix_set_identity(s.Svi);
96  gsl_matrix_scale(s.Svi, sqrt(p.process_noise));
97 
98  s.yi_prediction = gsl_matrix_alloc(p.no, p.nbSamplesMeasure);
99  gsl_matrix_set_zero(s.yi_prediction);
100 
101  s.yi_mean = gsl_vector_alloc(p.no);
102  gsl_vector_set_zero(s.yi_mean);
103 
104  s.ino_yi = gsl_vector_alloc(p.no);
105  gsl_vector_set_zero(s.ino_yi);
106 
107  // Cholesky factor of the variance/covariance matrix Pyyi
108  s.Syi = gsl_matrix_alloc(p.no, p.no);
109  gsl_matrix_set_zero(s.Syi);
110 
111  s.Sni = gsl_matrix_alloc(p.no,p.no);
112  gsl_matrix_set_identity(s.Sni);
113  gsl_matrix_scale(s.Sni, sqrt(p.measurement_noise));
114 
115  s.Pxyi = gsl_matrix_alloc(p.n, p.no);
116  gsl_matrix_set_zero(s.Pxyi);
117 
118  s.sigmaPoint = gsl_vector_alloc(p.n);
119  gsl_vector_set_zero(s.sigmaPoint);
120 
121  s.sigmaPoints = gsl_matrix_alloc(p.n, p.nbSamples);
122  gsl_matrix_set_zero(s.sigmaPoints);
123 
124  s.sigmaPointMeasure = gsl_vector_alloc(p.n);
125  gsl_vector_set_zero(s.sigmaPoint);
126 
127  s.sigmaPointsMeasure = gsl_matrix_alloc(p.n, p.nbSamplesMeasure);
128  gsl_matrix_set_zero(s.sigmaPointsMeasure);
129 
130  s.U = gsl_matrix_alloc(p.n, p.no);
131  gsl_matrix_set_zero(s.U);
132 
133  // Weights used to update the statistics
134  s.wm_j = gsl_vector_alloc(p.nbSamples); // Weights used to compute the mean of the sigma points images
135  s.wc_j = gsl_vector_alloc(p.nbSamples); // Weights used to update the covariance matrices
136 
137  // Set the weights
138  gsl_vector_set(s.wm_j, 0, p.lambda / (p.n + p.lambda));
139  gsl_vector_set(s.wc_j, 0, p.lambda / (p.n + p.lambda) + (1.0 - p.alpha*p.alpha + p.beta));
140  for(int j = 1 ; j < p.nbSamples; j ++)
141  {
142  gsl_vector_set(s.wm_j, j, 1.0 / (2.0 * (p.n + p.lambda)));
143  gsl_vector_set(s.wc_j, j, 1.0 / (2.0 * (p.n + p.lambda)));
144  }
145 
146  // Set the weights
147  s.wm_aug_j = gsl_vector_alloc(p.nbSamplesMeasure); // Weights used to compute the mean of the sigma points images
148  s.wc_aug_j = gsl_vector_alloc(p.nbSamplesMeasure); // Weights used to update the covariance matrices
149  gsl_vector_set(s.wm_aug_j, 0, p.lambda_aug / (2*p.n + p.lambda_aug));
150  gsl_vector_set(s.wc_aug_j, 0, p.lambda_aug / (2*p.n + p.lambda_aug) + (1.0 - p.alpha*p.alpha + p.beta));
151  for(int j = 1 ; j < p.nbSamplesMeasure; j ++)
152  {
153  gsl_vector_set(s.wm_aug_j, j, 1.0 / (2.0 * (2*p.n + p.lambda_aug)));
154  gsl_vector_set(s.wc_aug_j, j, 1.0 / (2.0 * (2*p.n + p.lambda_aug)));
155  }
156 
157  s.Ki = gsl_matrix_alloc(p.n, p.no);
158  s.Ki_T = gsl_matrix_alloc(p.no, p.n);
159 
160  // Allocate temporary matrices
161  s.temp_n = gsl_vector_alloc(p.n);
162  s.temp_no = gsl_vector_alloc(p.no);
163 
164  s.temp_n_1 = gsl_matrix_alloc(p.n,1);
165  s.temp_1_n = gsl_matrix_alloc(1,p.n);
166  s.temp_n_n = gsl_matrix_alloc(p.n, p.n);
167  s.temp_n_no = gsl_matrix_alloc(p.n, p.no);
168  s.temp_no_1 = gsl_matrix_alloc(p.no,1);
169  s.temp_1_no = gsl_matrix_alloc(1,p.no);
170  s.temp_no_no = gsl_matrix_alloc(p.no, p.no);
171 
172  s.temp_3n_n = gsl_matrix_alloc(3*p.n, p.n);
173  s.temp_2nno_no = gsl_matrix_alloc(2*p.n + p.no, p.no);
174  }
175 
180  inline void ukf_free(ukf_param &p, ukf_state &s)
181  {
182  gsl_vector_free(s.xi);
183  gsl_matrix_free(s.xi_prediction);
184  gsl_vector_free(s.xi_mean);
185  gsl_matrix_free(s.Sxi);
186  gsl_matrix_free(s.Svi);
187 
188  gsl_matrix_free(s.yi_prediction);
189  gsl_vector_free(s.yi_mean);
190  gsl_vector_free(s.ino_yi);
191  gsl_matrix_free(s.Syi);
192  gsl_matrix_free(s.Sni);
193 
194  gsl_matrix_free(s.Pxyi);
195 
196  gsl_vector_free(s.sigmaPoint);
197  gsl_matrix_free(s.sigmaPoints);
198 
199  gsl_vector_free(s.sigmaPointMeasure);
200  gsl_matrix_free(s.sigmaPointsMeasure);
201 
202  gsl_matrix_free(s.U);
203 
204  gsl_vector_free(s.wm_j);
205  gsl_vector_free(s.wc_j);
206 
207  gsl_vector_free(s.wm_aug_j);
208  gsl_vector_free(s.wc_aug_j);
209 
210  gsl_matrix_free(s.Ki);
211  gsl_matrix_free(s.Ki_T);
212 
213  gsl_vector_free(s.temp_n);
214  gsl_vector_free(s.temp_no);
215 
216  gsl_matrix_free(s.temp_n_1);
217  gsl_matrix_free(s.temp_1_n);
218  gsl_matrix_free(s.temp_n_n);
219 
220  gsl_matrix_free(s.temp_n_no);
221  gsl_matrix_free(s.temp_no_1);
222  gsl_matrix_free(s.temp_1_no);
223  gsl_matrix_free(s.temp_no_no);
224 
225  gsl_matrix_free(s.temp_3n_n);
226  gsl_matrix_free(s.temp_2nno_no);
227  }
228 
233  template <typename FunctProcess, typename FunctObservation>
234  inline void ukf_iterate(ukf_param &p, ukf_state &s, FunctProcess f, FunctObservation h, gsl_vector* yi)
235  {
236  int i,j;
237  gsl_matrix_view mat_view;
238  gsl_vector_view vec_view;
239  // ************************************************** //
240  // ************ Compute the sigma points ************ //
241  // ************************************************** //
242 
243  // 1- Compute the sigma points,
244  // Equation (3.209)
245  // sigmapoint_j = x_(i-1)
246  // sigmapoint_j = x_(i-1) + gamma * Sxi_j for 1 <= j <= n
247  // sigmapoint_j = x_(i-1) - gamma * Sxi_(j-(n+1)) for n+1 <= j <= 2n
248  gsl_matrix_set_col(s.sigmaPoints, 0, s.xi);
249  for(j = 1 ; j < p.n + 1 ; ++j)
250  for(i = 0 ; i < p.n ; ++i)
251  {
252  gsl_matrix_set(s.sigmaPoints,i,j, s.xi->data[i] + p.gamma * gsl_matrix_get(s.Sxi, i, j-1));
253  gsl_matrix_set(s.sigmaPoints,i,j+p.n, s.xi->data[i] - p.gamma * gsl_matrix_get(s.Sxi, i, j-1));
254  }
255 
256  /**********************************/
257  /***** Time update equations *****/
258  /**********************************/
259 
260  // Time update equations
261  // 0 - Compute the image of the sigma points and the mean of these images
262  gsl_vector_set_zero(s.xi_mean);
263  for(j = 0 ; j < p.nbSamples ; ++j)
264  {
265  gsl_matrix_get_col(s.sigmaPoint, s.sigmaPoints, j);
266  // Compute the image of the sigma points
267  // Eq 3.210
268  vec_view = gsl_matrix_column(s.xi_prediction,j);
269  f(s.params, s.sigmaPoint, &vec_view.vector);
270 
271  // Update the mean, Eq (3.211)
272  for(i = 0 ; i < p.n ; ++i)
273  s.xi_mean->data[i] += s.wm_j->data[j] * gsl_matrix_get(s.xi_prediction,i,j);
274  }
275 
276  // 1- Compute the QR decomposition and keeps only the upper triangular part of R
277  // Eq. 3.212
278  // We first fill the matrix Sxk^-
279  // with the transpose of what is in the brackets of qr { ... }
280  for(j = 1 ; j < p.nbSamples; ++j)
281  {
282  for(i = 0 ; i < p.n ; ++i)
283  {
284  gsl_matrix_set(s.temp_3n_n, j-1, i, sqrt(s.wc_j->data[1]) * (gsl_matrix_get(s.xi_prediction,i,j) - s.xi_mean->data[i]));
285  }
286  }
287  // The last rows are filled with the cholesky factor of the process noise covariance
288  for(j = 0 ; j < p.n ; ++j)
289  {
290  mat_view = gsl_matrix_submatrix(s.temp_3n_n, p.nbSamples-1, 0, p.n, p.n);
291  gsl_matrix_memcpy(&mat_view.matrix, s.Svi);
292  }
293  // We now perform the QR decomposition of s.temp_3n_n;
294  gsl_linalg_QR_decomp(s.temp_3n_n, s.temp_n);
295  // From this QR decomposition, we keep only the upper triangular part of R and copy it in s.Sxi
296  for( j = 0 ; j < p.n ; ++j)
297  {
298  for(i = 0 ; i < j+1 ; ++i)
299  gsl_matrix_set(s.Sxi, i, j, gsl_matrix_get(s.temp_3n_n, i, j));
300 
301  for(i = j+1 ; i < p.n ; ++i)
302  gsl_matrix_set(s.Sxi, i, j, 0.0);
303  }
304  //gsl_matrix_transpose(s.Sxi);
305  if(DEBUGMODE) print_mat(s.Sxi);
306  if(DEBUGMODE) printf("\n");
307 
308  // 2- Perform the cholupdate, which is a rank one update
309  // Eq. 3.213
310  for(i = 0 ; i < p.n ; ++i)
311  s.temp_n->data[i] = gsl_matrix_get(s.xi_prediction,i,0) - s.xi_mean->data[i];
312 
313  if(DEBUGMODE) printf("Before cholupdate 1 \n");
314  gsl_matrix_transpose(s.Sxi);
315  ukf::math::choleskyUpdate(s.Sxi, ukf::math::signof(s.wc_j->data[0]) * sqrt(fabs(s.wc_j->data[0])), s.temp_n);
316  // Warning : Here, we keep Sxi as a triangular inferior matrix
317 
318  //gsl_matrix_transpose(s.Sxi);
319  if(DEBUGMODE) printf("ok\n");
320  if(DEBUGMODE) printf("Sxi after cholupdate : \n");
321  if(DEBUGMODE) print_mat(s.Sxi);
322  // ** Augment the sigma points ** //
323  // Eq 3.124
324 
325  // 1 - Copy the images of the original sigma points
326  mat_view = gsl_matrix_submatrix(s.sigmaPointsMeasure,0,0, p.n, p.nbSamples);
327  gsl_matrix_memcpy(&mat_view.matrix, s.xi_prediction);
328 
329  // 2 - Compute the additional sigma points
330  for(j = 0 ; j < p.n ; ++j)
331  {
332  for(i = 0 ; i < p.n ; ++i)
333  {
334  gsl_matrix_set(s.sigmaPointsMeasure, i ,j + p.nbSamples , gsl_matrix_get(s.xi_prediction, i, 0) + p.gamma_aug * gsl_matrix_get(s.Svi, i,j));
335  gsl_matrix_set(s.sigmaPointsMeasure, i ,j + p.nbSamples + p.n , gsl_matrix_get(s.xi_prediction, i, 0) - p.gamma_aug * gsl_matrix_get(s.Svi, i,j));
336  }
337  }
338 
339  // Compute the image of the sigma points, i.e. the associated predicted observations
340  // and their mean
341  gsl_vector_set_zero(s.yi_mean);
342  for(j = 0 ; j < p.nbSamplesMeasure ; ++j)
343  {
344  gsl_matrix_get_col(s.sigmaPointMeasure, s.sigmaPointsMeasure, j);
345  vec_view = gsl_matrix_column(s.yi_prediction,j);
346  h(s.sigmaPointMeasure, &vec_view.vector);
347 
348  // Update the mean , eq (3.176)
349  for(i = 0 ; i < p.no ; ++i)
350  s.yi_mean->data[i] += s.wm_aug_j->data[j] * gsl_matrix_get(s.yi_prediction,i,j);
351  }
352 
353  /*****************************************/
354  /***** Measurement update equations *****/
355  /*****************************************/
356 
357  // Compute the Cholesky factor of the variance-covariance matrix of the observations
358  // Eq. 3.217
359  // First put in s.temp_2nno_no the transpose of what is in the brackets of qr{...} ,
360  for(j = 0 ; j < 2*p.n ; ++j)
361  for(i = 0 ; i < p.no ; ++i)
362  gsl_matrix_set(s.temp_2nno_no, j, i, sqrt(s.wc_aug_j->data[1])*(gsl_matrix_get(s.yi_prediction, i, j+1) - s.yi_mean->data[i]) );
363 
364  // Copy the Cholesky factor of the covariance of the observation noise
365  mat_view = gsl_matrix_submatrix(s.temp_2nno_no,2*p.n, 0, p.no, p.no);
366  gsl_matrix_memcpy(&mat_view.matrix, s.Sni);
367 
368  // We now perform the QR decomposition of s.temp_2nno_no;
369  gsl_linalg_QR_decomp(s.temp_2nno_no, s.temp_no);
370  // From this QR decomposition, we keep only the upper triangular part of R and copy it in s.Syi
371  for( j = 0 ; j < p.no ; ++j)
372  {
373  for(i = 0 ; i < j+1 ; ++i)
374  gsl_matrix_set(s.Syi, i, j, gsl_matrix_get(s.temp_2nno_no, i, j));
375 
376  for(i = j+1 ; i < p.no ; ++i)
377  gsl_matrix_set(s.Syi, i, j, 0.0);
378  }
379  if(DEBUGMODE) printf("Syi : \n");
380  if(DEBUGMODE) print_mat(s.Syi);
381  if(DEBUGMODE) printf("\n");
382  //gsl_matrix_transpose(s.Syi);
383 
384  // 2- Perform the cholupdate, which is a rank one update
385  // Eq. 3.218
386  // Syi is triangular superior
387  for(i = 0 ; i < p.no ; ++i)
388  s.temp_no->data[i] = gsl_matrix_get(s.yi_prediction,i,0) - s.yi_mean->data[i];
389  if(DEBUGMODE) print_vec(s.temp_no);
390  if(DEBUGMODE) printf("Before cholupdate 2 \n");
391  gsl_matrix_transpose(s.Syi);
392  ukf::math::choleskyUpdate(s.Syi, ukf::math::signof(s.wc_aug_j->data[0])*sqrt(fabs(s.wc_aug_j->data[0])), s.temp_no);
393  if(DEBUGMODE) printf("ok \n");
394  // Now, Syi is the lower triangular cholesky factor
395  //gsl_matrix_transpose(s.Syi);
396  if(DEBUGMODE) printf("Syi after cholupdate : \n");
397  if(DEBUGMODE) print_mat(s.Syi);
398 
399 
400  // Compute the state/observation covariance
401  // Eq (3.219)
402  gsl_matrix_set_zero(s.Pxyi);
403  for(j = 0 ; j < p.nbSamplesMeasure ; ++j)
404  {
405  for(i = 0 ; i < p.n ; ++i)
406  s.temp_n_1->data[i] = gsl_matrix_get(s.sigmaPointsMeasure,i,j) - s.xi_mean->data[i];
407 
408  for(i = 0 ; i < p.no ; ++i)
409  s.temp_1_no->data[i] = gsl_matrix_get(s.yi_prediction,i,j) - s.yi_mean->data[i];
410 
411  gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, s.wc_aug_j->data[j] , s.temp_n_1, s.temp_1_no, 1.0, s.Pxyi);
412  //gsl_matrix_add(s.Pxyi, s.temp_n_no);
413  }
414 
415  /*gsl_matrix_set_zero(s.Pxyi);
416  for(j = 0 ; j < p.nbSamples ; ++j)
417  {
418  for(i = 0 ; i < p.n ; ++i)
419  s.temp_n_1->data[i] = gsl_matrix_get(s.xi_prediction,i,j) - s.xi_mean->data[i];
420 
421  for(i = 0 ; i < p.no ; ++i)
422  s.temp_1_no->data[i] = gsl_matrix_get(s.yi_prediction,i,j) - s.yi_mean->data[i];
423 
424  gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, s.wc_j->data[j] , s.temp_n_1, s.temp_1_no, 1.0, s.Pxyi);
425  //gsl_matrix_add(s.Pxyi, s.temp_n_no);
426  }*/
427 
428  // Compute the Kalman gain,
429  // Eq (3.220)
430 
431  // We want to solve : Kxy . Sy Sy^T = Pxy
432  // Which can be solved using : Sy Sy^T Kxy^T = Pxy^T
433  // We have a number of no systems to solve of the form S x = Pxy^T[:,i] ; S^T Kxy[:,i] = x with S being triangular
434  // To solve this, we make use of gsl_blas_dtrsv
435  for(int i = 0 ; i < p.n ; ++i)
436  {
437  vec_view = gsl_matrix_row(s.Pxyi, i);
438  gsl_vector_memcpy(s.temp_no, &vec_view.vector);
439  gsl_blas_dtrsv(CblasLower,CblasNoTrans,CblasNonUnit,s.Syi,s.temp_no);
440  gsl_blas_dtrsv(CblasLower,CblasTrans,CblasNonUnit,s.Syi,s.temp_no);
441  // And then copy the result in the ith row of Ki
442  vec_view = gsl_matrix_row(s.Ki, i);
443  gsl_vector_memcpy(&vec_view.vector, s.temp_no);
444  }
445  if(DEBUGMODE) printf("Ki : \n");
446  if(DEBUGMODE) print_mat(s.Ki);
447 
448  // Correction : correct the estimation of the state
449  // Eq. 3.221
450  // Compute the innovations
451  for(i = 0 ; i < p.no ; ++i)
452  s.ino_yi->data[i] = yi->data[i] - s.yi_mean->data[i];
453  // And correct the current state estimate
454  gsl_blas_dgemv(CblasNoTrans, 1.0, s.Ki, s.ino_yi, 1.0, s.xi);
455 
456  // Compute the matrix U = Kk Syk
457  gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0 , s.Ki, s.Syi, 0, s.U);
458  if(DEBUGMODE) printf("Matrix U : \n");
459  if(DEBUGMODE) print_mat(s.U);
460 
461  // Perform the cholesky updates of Sxi
462  // We perform p.no updates rank-1 update with the columns of U
463  if(DEBUGMODE) printf("Before cholupdate 3 \n");
464  for(i = 0 ; i < p.no ; ++i)
465  {
466  vec_view = gsl_matrix_column(s.U, i);
467  gsl_vector_memcpy(s.temp_n, &vec_view.vector);
469  if(DEBUGMODE) printf("After cholupdate %i\n", i);
470  if(DEBUGMODE) print_mat(s.Sxi);
471  }
472 
473  //printf("After cholupdate %i\n", i);
474  //print_mat(s.Sxi);
475  //if(DEBUGMODE) printf("\n");
476 
477  //
478  // // Update of the process noise
479  // switch(p.process_noise_type)
480  // {
481  // case ukf::UKF_PROCESS_FIXED:
482  // //nothing to do
483  // break;
484  // case ukf::UKF_PROCESS_RLS:
485  // gsl_matrix_memcpy(s.Pvvi, s.Pxxi);
486  // gsl_matrix_scale(s.Pvvi, 1.0/p.process_noise-1.0);
487  // gsl_matrix_memcpy(s.cholPvvi, s.Pvvi);
488  // gsl_linalg_cholesky_decomp(s.cholPvvi);
489  // for(j = 0 ; j < p.n ; j++)
490  // for(k = j+1 ; k < p.n ; k++)
491  // gsl_matrix_set(s.cholPvvi,j,k,0.0);
492  // break;
493  // default:
494  // printf("Warning : Unrecognized process noise type\n");
495  // }
496 
497 
498  }
499 
504  template <typename FunctProcess, typename FunctObservation>
505  inline void ukf_evaluate(ukf_param &p, ukf_state &s, FunctProcess f, FunctObservation h, gsl_vector* yi)
506  {
507 
508  // int i,j,k;
509  // // ************************************************** //
510  // // ************ Compute the sigma points ************ //
511  // // ************************************************** //
512  //
513  // // 0 - Compute the Cholesky decomposition of s.Pxxi
514  // gsl_matrix_memcpy(s.cholPxxi, s.Pxxi);
515  // gsl_linalg_cholesky_decomp(s.cholPxxi);
516  // // Set all the elements of cholPvvi strictly above the diagonal to zero
517  // for(j = 0 ; j < p.n ; j++)
518  // for(k = j+1 ; k < p.n ; k++)
519  // gsl_matrix_set(s.cholPxxi,j,k,0.0);
520  //
521  // // 1- Compute the sigma points,
522  // // Equation (3.170)
523  // // sigmapoint_j = x_(i-1)
524  // // sigmapoint_j = x_(i-1) + gamma * sqrt(P_i-1)_j for 1 <= j <= n
525  // // sigmapoint_j = x_(i-1) - gamma * sqrt(P_i-1)_(j-(n+1)) for n+1 <= j <= 2n
526  // gsl_matrix_set_col(s.sigmaPoints, 0, s.xi);
527  // for(j = 1 ; j < p.n+1 ; ++j)
528  // for(i = 0 ; i < p.n ; ++i)
529  // {
530  // gsl_matrix_set(s.sigmaPoints,i,j, s.xi->data[i] + p.gamma * gsl_matrix_get(s.cholPxxi, i, j-1));
531  // gsl_matrix_set(s.sigmaPoints,i,j+p.n, s.xi->data[i] - p.gamma * gsl_matrix_get(s.cholPxxi, i, j-1));
532  // }
533  //
534  // /**********************************/
535  // /***** Time update equations *****/
536  // /**********************************/
537  //
538  // // Time update equations
539  // // 0 - Compute the image of the sigma points and the mean of these images
540  // gsl_vector_set_zero(s.xi_mean);
541  // for(j = 0 ; j < p.nbSamples ; ++j)
542  // {
543  // gsl_matrix_get_col(s.sigmaPoint, s.sigmaPoints, j);
544  // f(s.params, s.sigmaPoint, &gsl_matrix_column(s.xi_prediction,j).vector);
545  //
546  // // Update the mean, Eq (3.172)
547  // for(i = 0 ; i < p.n ; ++i)
548  // s.xi_mean->data[i] += s.wm_j->data[j] * gsl_matrix_get(s.xi_prediction,i,j);
549  // }
550  //
551  // // 1 - Compute the covariance of the images and add the process noise,
552  // // Equation (3.173)
553  // // Warning, s.Pxxi will now hold P_xk^-
554  // gsl_matrix_set_zero(s.Pxxi);
555  // for(j = 0 ; j < p.nbSamples ; ++j)
556  // {
557  // for(i = 0 ; i < p.n ; ++i)
558  // s.temp_n_1->data[i] = gsl_matrix_get(s.xi_prediction,i,j) - s.xi_mean->data[i];
559  //
560  // gsl_blas_dgemm(CblasNoTrans, CblasTrans, s.wc_j->data[j] , s.temp_n_1, s.temp_n_1, 0, s.temp_n_n);
561  // gsl_matrix_add(s.Pxxi, s.temp_n_n);
562  // }
563  // // Add the covariance of the evolution noise
564  // gsl_matrix_add(s.Pxxi, s.Pvvi);
565  //
566  // // Augment sigma points
567  // // Equation 3.174
568  // // First put the images of the initial sigma points
569  // gsl_matrix_memcpy(&gsl_matrix_submatrix(s.sigmaPointsMeasure, 0, 0, p.n, p.nbSamples).matrix, s.xi_prediction);
570  // // And add the additional sigma points eq. (7.56)
571  // for(j = 0 ; j < p.n ; ++j)
572  // {
573  // for(i = 0 ; i < p.n ; ++i)
574  // {
575  // gsl_matrix_set(s.sigmaPointsMeasure, i, j+p.nbSamples, gsl_matrix_get(s.xi_prediction,i,0)+p.gamma_aug*gsl_matrix_get(s.cholPvvi,i,j));
576  // gsl_matrix_set(s.sigmaPointsMeasure, i, j+p.nbSamples+p.n, gsl_matrix_get(s.xi_prediction,i,0)-p.gamma_aug*gsl_matrix_get(s.cholPvvi,i,j));
577  // }
578  // }
579  //
580  // // Compute the image of the sigma points through the observation equation
581  // // eq (3.175)
582  // gsl_vector_set_zero(yi);
583  // for(j = 0 ; j < p.nbSamplesMeasure ; ++j)
584  // {
585  // gsl_matrix_get_col(s.sigmaPointMeasure, s.sigmaPointsMeasure, j);
586  // h(s.sigmaPointMeasure, &gsl_matrix_column(s.yi_prediction,j).vector);
587  //
588  // // Update the mean , eq (3.176)
589  // for(i = 0 ; i < p.no ; ++i)
590  // yi->data[i] += s.wm_aug_j->data[j] * gsl_matrix_get(s.yi_prediction,i,j);
591  // }
592  }
593  } // srstate
594 } // ukf
595 
596 #endif // UKF_SR_STATE_NDIM_H
gsl_matrix * Sxi
Definition: ukf_types.h:832
gsl_matrix * xi_prediction
Definition: ukf_types.h:830
void ukf_free(ukf_param &p, ukf_state &s)
Free of memory allocation.
Definition: ukf_sr_state_ndim.h:180
gsl_vector * yi_mean
Definition: ukf_types.h:836
gsl_vector * temp_n
Definition: ukf_types.h:860
gsl_matrix * U
Definition: ukf_types.h:849
gsl_matrix * Sni
Definition: ukf_types.h:839
void print_mat(const gsl_matrix *A)
Definition: ukf_sr_state_ndim.h:32
gsl_vector * wm_aug_j
Definition: ukf_types.h:854
double measurement_noise
Covariance of the observation noise.
Definition: ukf_types.h:816
void print_vec(const gsl_vector *A)
Definition: ukf_sr_state_ndim.h:43
gsl_matrix * Pxyi
Definition: ukf_types.h:841
Structure holding the parameters of the statistical linearization.
Definition: ukf_types.h:749
void choleskyUpdate(gsl_matrix *sigmaTheta, double alpha, gsl_vector *x)
This function performs a cholesky update according to Strange et al.(2007)
Definition: ukf_math.h:64
gsl_vector * wc_aug_j
Definition: ukf_types.h:855
gsl_matrix * temp_no_1
Definition: ukf_types.h:870
void ukf_init(ukf_param &p, ukf_state &s)
Allocation of the vectors/matrices and initialization.
Definition: ukf_sr_state_ndim.h:65
gsl_matrix * sigmaPoints
Definition: ukf_types.h:844
#define DEBUGMODE
Definition: ukf_sr_state_ndim.h:20
gsl_vector * temp_no
Definition: ukf_types.h:861
double beta
Non negative weights used to introduce knowledge about the higher order moments of the distribution...
Definition: ukf_types.h:764
gsl_matrix * temp_1_no
Definition: ukf_types.h:871
void ukf_evaluate(ukf_param &p, ukf_state &s, FunctProcess f, FunctObservation h, gsl_vector *yi)
Evaluation of the output from the sigma points.
Definition: ukf_sr_state_ndim.h:505
gsl_matrix * temp_n_1
Definition: ukf_types.h:864
double lambda_aug
Definition: ukf_types.h:770
gsl_matrix * temp_n_no
Definition: ukf_types.h:867
gsl_matrix * temp_1_n
Definition: ukf_types.h:865
gsl_vector * wc_j
Definition: ukf_types.h:852
gsl_vector * sigmaPoint
Definition: ukf_types.h:843
double process_noise
Parameter used for the evolution noise.
Definition: ukf_types.h:811
Structure holding the matrices manipulated by the statistical linearization in the vectorial case for...
Definition: ukf_types.h:825
double kpa
, is a good choice. According to van der Merwe, its value is not critical
Definition: ukf_types.h:754
gsl_matrix * Ki
Definition: ukf_types.h:857
gsl_matrix * temp_no_no
Definition: ukf_types.h:869
int nbSamplesMeasure
Number of sigma-points
Definition: ukf_types.h:791
double gamma
Definition: ukf_types.h:775
gsl_vector * xi_mean
Definition: ukf_types.h:831
gsl_vector * params
Definition: ukf_types.h:827
double alpha
: "Size" of sigma-point distribution. Should be small if the function is strongly non-linear ...
Definition: ukf_types.h:759
int nbSamples
Number of sigma-points
Definition: ukf_types.h:786
gsl_matrix * temp_2nno_no
Definition: ukf_types.h:874
gsl_matrix * temp_n_n
Definition: ukf_types.h:863
int no
Dimension of the output : the measurements.
Definition: ukf_types.h:796
gsl_matrix * yi_prediction
Definition: ukf_types.h:835
gsl_vector * sigmaPointMeasure
Definition: ukf_types.h:846
gsl_vector * wm_j
Definition: ukf_types.h:851
double lambda
Definition: ukf_types.h:769
double signof(double x)
Definition: ukf_math.h:45
int n
Size of the state vector.
Definition: ukf_types.h:781
gsl_vector * xi
Definition: ukf_types.h:829
double prior_x
Prior estimate of the covariance matrix of the state.
Definition: ukf_types.h:801
gsl_matrix * Syi
Definition: ukf_types.h:838
gsl_matrix * Svi
Definition: ukf_types.h:833
void ukf_iterate(ukf_param &p, ukf_state &s, FunctProcess f, FunctObservation h, gsl_vector *yi)
UKF-additive (zero-mean) noise case, "Kalman Filtering and Neural Networks", p.233.
Definition: ukf_sr_state_ndim.h:234
gsl_matrix * temp_3n_n
Definition: ukf_types.h:873
gsl_matrix * Ki_T
Definition: ukf_types.h:858
gsl_vector * ino_yi
Definition: ukf_types.h:837
double gamma_aug
Definition: ukf_types.h:776
gsl_matrix * sigmaPointsMeasure
Definition: ukf_types.h:847