0.5.0
Loading...
Searching...
No Matches
Decorrelation.hpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9/// @file Decorrelation.hpp
10/// @brief Ambiguity decorrelation algorithms
11/// @author T. Topp (topp@ins.uni-stuttgart.de)
12/// @date 2023-09-04
13
14#pragma once
15
16#include <tuple>
17
19#include "util/Eigen.hpp"
20#include "util/Logger.hpp"
21#include "util/Assert.h"
22#include <Eigen/src/Core/ArithmeticSequence.h>
23#include <Eigen/src/Core/MatrixBase.h>
24#include <Eigen/src/Core/util/Meta.h>
25
27{
28
29namespace internal
30{
31
32/// @brief \cite chang2005 Chang 2005, Integer Gauss Transformations algorithm
33/// @param[in, out] L (L^T * D * L) decomposition of Q_z
34/// @param[in] i Row index
35/// @param[in] j Col index
36/// @param[in, out] a Float ambiguity vector [cycles]
37/// @param[in, out] Z Decorrelation transformation matrix
38/// @param[in] n Dimension
39template<typename DerivedL, typename DerivedZ, typename DerivedA>
40void gauss(Eigen::MatrixBase<DerivedL>& L, Eigen::Index i, Eigen::Index j, Eigen::MatrixBase<DerivedA>& a, Eigen::MatrixBase<DerivedZ>& Z, Eigen::Index n)
41{
42 using Eigen::seq;
43
44 auto mu = std::round(L(i, j));
45 if (mu != 0)
46 {
47 L(seq(i, n - 1), j) -= mu * L(seq(i, n - 1), i);
48 Z(seq(0, n - 1), j) -= mu * Z(seq(0, n - 1), i);
49 a(j) -= mu * a(i);
50 }
51}
52
53/// @brief \cite chang2005 Chang 2005, Permutations algorithm
54/// @param[in, out] L (L^T * D * L) decomposition of Q_z
55/// @param[in, out] D (L^T * D * L) decomposition of Q_z
56/// @param[in] k Index
57/// @param[in] delta Delta parameter
58/// @param[in, out] a Float ambiguity vector [cycles]
59/// @param[in, out] Z Z trafo
60/// @param[in] n Dimension
61template<typename DerivedL, typename DerivedD, typename DerivedA, typename DerivedZ>
62void permute(Eigen::MatrixBase<DerivedL>& L, Eigen::MatrixBase<DerivedD>& D, Eigen::Index k, double delta, Eigen::MatrixBase<DerivedA>& a, Eigen::MatrixBase<DerivedZ>& Z, Eigen::Index n)
63{
64 using Eigen::seq;
65
66 auto eta = D(k) / delta;
67 auto lambda = D(k + 1) * L(k + 1, k) / delta;
68 D(k) = eta * D(k + 1);
69 D(k + 1) = delta;
70
71 L(seq(k, k + 1), seq(0, k - 1)) = (Eigen::MatrixXd(2, 2) << -L(k + 1, k), 1,
72 eta, lambda)
73 .finished()
74 * L(seq(k, k + 1), seq(0, k - 1));
75 L(k + 1, k) = lambda;
76 L(seq(k + 2, n - 1), k).swap(L(seq(k + 2, n - 1), k + 1));
77 Z.col(k).swap(Z.col(k + 1));
78 std::swap(a(k), a(k + 1));
79}
80
81} // namespace internal
82
83/// @brief Decorrelates the ambiguities
84/// @param[in] a Float ambiguity vector [cycles]
85/// @param[in] Q Variance/covariance matrix of the ambiguities
86/// @return [Qz, Z, L, D, z] L, D are a (L^T * D * L) decomposition of Q_z
87/// @note See \cite chang2005 Chang 2005, Reduction algorithm
88template<typename DerivedA, typename DerivedQ>
89[[nodiscard]] std::optional<std::tuple<typename DerivedQ::PlainObject, // Qz
90 typename DerivedQ::PlainObject, // Z
91 typename DerivedQ::PlainObject, // L
92 typename DerivedA::PlainObject, // D
93 typename DerivedA::PlainObject>> // z
94 decorrelate_ztrafo(const Eigen::MatrixBase<DerivedA>& a, const Eigen::MatrixBase<DerivedQ>& Q)
95{
96 static_assert(DerivedA::ColsAtCompileTime == Eigen::Dynamic || DerivedA::ColsAtCompileTime == 1);
97 INS_ASSERT_USER_ERROR(a.cols() == 1, "Parameter 'a' has to be a vector");
98
99 using Eigen::seq;
100
101 auto n = a.rows(); // Amount of ambiguities
102 auto ltdl_decomp = math::LtDLdecomp_choleskyFact(Q);
103 if (!ltdl_decomp) { return {}; }
104 auto [L, D] = *ltdl_decomp;
105
106 typename DerivedQ::PlainObject Z;
107 if constexpr (DerivedQ::RowsAtCompileTime == Eigen::Dynamic) { Z.setIdentity(n, n); }
108 else { Z.setIdentity(); }
109
110 typename DerivedA::PlainObject z = a;
111
112 auto k = n - 2;
113 auto k1 = n - 2;
114
115 while (k >= 0)
116 {
117 if (k <= k1)
118 {
119 for (auto i = k + 1; i < n; i++)
120 {
121 internal::gauss(L, i, k, z, Z, n);
122 }
123 }
124 auto delta = D(k) + std::pow(L(k + 1, k), 2) * D(k + 1);
125 if (delta + 1e-6 < D(k + 1))
126 {
127 internal::permute(L, D, k, delta, z, Z, n);
128 k1 = k;
129 k = n - 2;
130 }
131 else
132 {
133 k--;
134 }
135 }
136
137 typename DerivedQ::PlainObject Qz = Z.transpose() * Q * Z;
138
139 return std::make_tuple(Qz, Z, L, D, z);
140}
141
142} // namespace NAV::Ambiguity
Assertion helpers.
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Definition Assert.h:21
Vector space operations.
Utility class for logging to console and file.
Simple Math functions.
void gauss(Eigen::MatrixBase< DerivedL > &L, Eigen::Index i, Eigen::Index j, Eigen::MatrixBase< DerivedA > &a, Eigen::MatrixBase< DerivedZ > &Z, Eigen::Index n)
chang2005 Chang 2005, Integer Gauss Transformations algorithm
void permute(Eigen::MatrixBase< DerivedL > &L, Eigen::MatrixBase< DerivedD > &D, Eigen::Index k, double delta, Eigen::MatrixBase< DerivedA > &a, Eigen::MatrixBase< DerivedZ > &Z, Eigen::Index n)
chang2005 Chang 2005, Permutations algorithm
std::optional< std::tuple< typename DerivedQ::PlainObject, typename DerivedQ::PlainObject, typename DerivedQ::PlainObject, typename DerivedA::PlainObject, typename DerivedA::PlainObject > > decorrelate_ztrafo(const Eigen::MatrixBase< DerivedA > &a, const Eigen::MatrixBase< DerivedQ > &Q)
Decorrelates the ambiguities.
std::optional< std::pair< Eigen::Matrix< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime >, Eigen::Vector< typename Derived::Scalar, Derived::RowsAtCompileTime > > > LtDLdecomp_choleskyFact(const Eigen::MatrixBase< Derived > &Q)
Find (L^T D L)-decomposition of Q-matrix via a backward Cholesky factorization in a bordering method ...
Definition Math.hpp:278