| 440 | |
| 441 | |
| 442 | UD_scheme::Float |
| 443 | UD_scheme::observeUD (FM::Vec& gain, Float & alpha, const Vec& h, const Float r) |
| 444 | /** Linear UD factorisation update |
| 445 | * Bierman UdU' factorisation update. Bierman p.100 |
| 446 | * Input |
| 447 | * h observation coefficients |
| 448 | * r observation variance |
| 449 | * Output |
| 450 | * gain observation Kalman gain |
| 451 | * alpha observation innovation variance |
| 452 | * Variables with physical significance |
| 453 | * gamma becomes covariance of innovation |
| 454 | * Precondition: |
| 455 | * UD |
| 456 | * r is PSD (not checked) |
| 457 | * Postcondition: |
| 458 | * UD (see return value) |
| 459 | * Return: |
| 460 | * reciprocal condition number of UD, -1 if alpha singular (negative or zero) |
| 461 | */ |
| 462 | { |
| 463 | std::size_t i,j,k; |
| 464 | const std::size_t n = UD.size1(); |
| 465 | Float gamma, alpha_jm1, lamda; |
| 466 | // a(n) is U'a |
| 467 | // b(n) is Unweighted Kalman gain |
| 468 | |
| 469 | // Compute b = DU'h, a = U'h |
| 470 | a = h; |
| 471 | for (j = n-1; j >= 1; --j) // n-1..1 |
| 472 | { |
| 473 | for (k = 0; k < j; ++k) // 0..j-1 |
| 474 | { |
| 475 | a[j] += UD(k,j) * a[k]; |
| 476 | } |
| 477 | b[j] = UD(j,j) * a[j]; |
| 478 | } |
| 479 | b[0] = UD(0,0) * a[0]; |
| 480 | |
| 481 | // Update UD(0,0), d(0) modification |
| 482 | alpha = r + b[0] * a[0]; |
| 483 | if (alpha <= 0) goto alphaNotPD; |
| 484 | gamma = 1 / alpha; |
| 485 | UD(0,0) *= r * gamma; |
| 486 | // Update rest of UD and gain b |
| 487 | for (j = 1; j < n; ++j) // 1..n-1 |
| 488 | { |
| 489 | // d modification |
| 490 | alpha_jm1 = alpha; // alpha at j-1 |
| 491 | alpha += b[j] * a[j]; |
| 492 | lamda = -a[j] * gamma; |
| 493 | if (alpha <= 0) goto alphaNotPD; |
| 494 | gamma = 1 / alpha; |
| 495 | UD(j,j) *= alpha_jm1 * gamma; |
| 496 | // U modification |
| 497 | for (i = 0; i < j; ++i) // 0..j-1 |
| 498 | { |
| 499 | Float UD_jm1 = UD(i,j); |
nothing calls this directly
no test coverage detected