45 template<
typename Derived_A,
typename Derived_U,
typename Derived_W,
48 const std::vector<std::pair<int, int> >& marginalizationStartIdxAndLengthPairs,
49 const Eigen::MatrixBase<Derived_A>& A,
50 const Eigen::MatrixBase<Derived_U>& U,
51 const Eigen::MatrixBase<Derived_W>& W,
52 const Eigen::MatrixBase<Derived_V>& V) {
55 const int size = A.cols();
58 "matrix not symmetric");
60 "matrix not symmetric");
62 "matrix not symmetric");
65 V.rows() + U.rows() == size,
66 "matrices supplied to be split into do not form exact upper triangular blocks of the original one");
68 "matrix not symmetric");
70 std::vector<std::pair<int, int> > marginalizationStartIdxAndLengthPairs2 =
71 marginalizationStartIdxAndLengthPairs;
72 marginalizationStartIdxAndLengthPairs2.push_back(
73 std::pair<int, int>(size, 0));
75 const size_t length = marginalizationStartIdxAndLengthPairs2.size();
80 for (
size_t i = 0; i < length; ++i) {
84 int thisIdx_row = marginalizationStartIdxAndLengthPairs2[i].first;
85 const int size_b_i = marginalizationStartIdxAndLengthPairs2[i].second;
86 const int size_a_i = thisIdx_row - lastIdx_row;
87 for (
size_t j = 0; j < length; ++j) {
88 int thisIdx_col = marginalizationStartIdxAndLengthPairs2[j].first;
89 const int size_a_j = thisIdx_col - lastIdx_col;
90 const int size_b_j = marginalizationStartIdxAndLengthPairs2[j].second;
93 if (size_a_j > 0 && size_a_i > 0) {
94 const_cast<Eigen::MatrixBase<Derived_U>&
>(U).block(start_a_i, start_a_j,
96 A.block(lastIdx_row, lastIdx_col, size_a_i, size_a_j);
100 if (size_b_j > 0 && size_a_i > 0) {
101 const_cast<Eigen::MatrixBase<Derived_W>&
>(W).block(start_a_i, start_b_j,
102 size_a_i, size_b_j) =
103 A.block(lastIdx_row, thisIdx_col, size_a_i, size_b_j);
107 if (size_b_j > 0 && size_b_i > 0) {
108 const_cast<Eigen::MatrixBase<Derived_V>&
>(V).block(start_b_i, start_b_j,
109 size_b_i, size_b_j) =
110 A.block(thisIdx_row, thisIdx_col, size_b_i, size_b_j);
113 lastIdx_col = thisIdx_col + size_b_j;
114 start_a_j += size_a_j;
115 start_b_j += size_b_j;
117 lastIdx_row = thisIdx_row + size_b_i;
118 start_a_i += size_a_i;
119 start_b_i += size_b_i;
124 template<
typename Derived_b,
typename Derived_b_a,
typename Derived_b_b>
126 const std::vector<std::pair<int, int> >& marginalizationStartIdxAndLengthPairs,
127 const Eigen::MatrixBase<Derived_b>& b,
128 const Eigen::MatrixBase<Derived_b_a>& b_a,
129 const Eigen::MatrixBase<Derived_b_b>& b_b) {
131 const int size = b.rows();
135 "supplied vector not x-by-1");
137 "supplied vector not x-by-1");
140 b_a.rows() + b_b.rows() == size,
141 "vector supplied to be split into cannot be concatenated to the original one");
143 std::vector<std::pair<int, int> > marginalizationStartIdxAndLengthPairs2 =
144 marginalizationStartIdxAndLengthPairs;
145 marginalizationStartIdxAndLengthPairs2.push_back(
146 std::pair<int, int>(size, 0));
148 const size_t length = marginalizationStartIdxAndLengthPairs2.size();
153 for (
size_t i = 0; i < length; ++i) {
154 int thisIdx_row = marginalizationStartIdxAndLengthPairs2[i].first;
155 const int size_b_i = marginalizationStartIdxAndLengthPairs2[i].second;
156 const int size_a_i = thisIdx_row - lastIdx_row;
160 const_cast<Eigen::MatrixBase<Derived_b_a>&
>(b_a).segment(start_a_i,
162 .segment(lastIdx_row, size_a_i);
167 const_cast<Eigen::MatrixBase<Derived_b_b>&
>(b_b).segment(start_b_i,
169 .segment(thisIdx_row, size_b_i);
172 lastIdx_row = thisIdx_row + size_b_i;
173 start_a_i += size_a_i;
174 start_b_i += size_b_i;
181 template<
typename Derived>
183 const Eigen::MatrixBase<Derived>&a,
const Eigen::MatrixBase<Derived>&result,
184 double epsilon,
int * rank) {
187 "matrix supplied is not quadratic");
189 Eigen::SelfAdjointEigenSolver<Derived> saes(a);
191 typename Derived::Scalar tolerance = epsilon * a.cols()
192 * saes.eigenvalues().array().maxCoeff();
194 const_cast<Eigen::MatrixBase<Derived>&
>(result) = (saes.eigenvectors())
196 (saes.eigenvalues().array() > tolerance).select(
197 saes.eigenvalues().array().inverse(), 0)).asDiagonal()
198 * (saes.eigenvectors().transpose());
202 for (
int i = 0; i < a.rows(); ++i) {
203 if (saes.eigenvalues()[i] > tolerance)
214 template<
typename Derived>
216 const Eigen::MatrixBase<Derived>&a,
const Eigen::MatrixBase<Derived>&result,
217 double epsilon,
int * rank) {
220 "matrix supplied is not quadratic");
222 Eigen::SelfAdjointEigenSolver<Derived> saes(a);
224 typename Derived::Scalar tolerance = epsilon * a.cols()
225 * saes.eigenvalues().array().maxCoeff();
227 const_cast<Eigen::MatrixBase<Derived>&
>(result) = (saes.eigenvectors())
230 (saes.eigenvalues().array() > tolerance).select(
231 saes.eigenvalues().array().inverse(), 0)).array().sqrt())
236 for (
int i = 0; i < a.rows(); ++i) {
237 if (saes.eigenvalues()[i] > tolerance)
248 template<
typename Derived,
int blockDim>
250 const Eigen::MatrixBase<Derived>& M_in,
251 const Eigen::MatrixBase<Derived>& M_out,
double epsilon) {
254 "matrix supplied is not quadratic");
256 const_cast<Eigen::MatrixBase<Derived>&
>(M_out).resize(M_in.rows(),
258 const_cast<Eigen::MatrixBase<Derived>&
>(M_out).setZero();
259 for (
int i = 0; i < M_in.cols(); i += blockDim) {
260 Eigen::Matrix<double, blockDim, blockDim> inv;
261 const Eigen::Matrix<double, blockDim, blockDim> in = M_in
262 .template block<blockDim, blockDim>(i, i);
265 const_cast<Eigen::MatrixBase<Derived>&
>(M_out)
266 .
template block<blockDim, blockDim>(i, i) = inv;
274 template<
typename Derived,
int blockDim>
276 const Eigen::MatrixBase<Derived>& M_in,
277 const Eigen::MatrixBase<Derived>& M_out,
double epsilon) {
280 "matrix supplied is not quadratic");
282 const_cast<Eigen::MatrixBase<Derived>&
>(M_out).resize(M_in.rows(),
284 const_cast<Eigen::MatrixBase<Derived>&
>(M_out).setZero();
285 for (
int i = 0; i < M_in.cols(); i += blockDim) {
286 Eigen::Matrix<double, blockDim, blockDim> inv;
287 const Eigen::Matrix<double, blockDim, blockDim> in = M_in
288 .template block<blockDim, blockDim>(i, i);
291 const_cast<Eigen::MatrixBase<Derived>&
>(M_out)
292 .
template block<blockDim, blockDim>(i, i) = inv;
static void splitSymmetricMatrix(const std::vector< std::pair< int, int > > &marginalizationStartIdxAndLengthPairs, const Eigen::MatrixBase< Derived_A > &A, const Eigen::MatrixBase< Derived_U > &U, const Eigen::MatrixBase< Derived_W > &W, const Eigen::MatrixBase< Derived_V > &V)
Split for Schur complement op.
Definition: MarginalizationError.hpp:47
static void splitVector(const std::vector< std::pair< int, int > > &marginalizationStartIdxAndLengthPairs, const Eigen::MatrixBase< Derived_b > &b, const Eigen::MatrixBase< Derived_b_a > &b_a, const Eigen::MatrixBase< Derived_b_b > &b_b)
Split for Schur complement op.
Definition: MarginalizationError.hpp:125
static bool pseudoInverseSymmSqrt(const Eigen::MatrixBase< Derived > &a, const Eigen::MatrixBase< Derived > &result, double epsilon=std::numeric_limits< typename Derived::Scalar >::epsilon(), int *rank=NULL)
Pseudo inversion and square root (Cholesky decomposition) of a symmetric matrix.
Definition: MarginalizationError.hpp:215
static void blockPinverseSqrt(const Eigen::MatrixBase< Derived > &M_in, const Eigen::MatrixBase< Derived > &M_out, double epsilon=std::numeric_limits< typename Derived::Scalar >::epsilon())
Block-wise pseudo inversion and square root (Cholesky decomposition) of a symmetric matrix with non-z...
Definition: MarginalizationError.hpp:275
#define OKVIS_ASSERT_TRUE_DBG(exceptionType, condition, message)
Definition: assert_macros.hpp:211
static bool pseudoInverseSymm(const Eigen::MatrixBase< Derived > &a, const Eigen::MatrixBase< Derived > &result, double epsilon=std::numeric_limits< typename Derived::Scalar >::epsilon(), int *rank=0)
Pseudo inversion of a symmetric matrix.
Definition: MarginalizationError.hpp:182
static void blockPinverse(const Eigen::MatrixBase< Derived > &M_in, const Eigen::MatrixBase< Derived > &M_out, double epsilon=std::numeric_limits< typename Derived::Scalar >::epsilon())
Block-wise pseudo inversion of a symmetric matrix with non-zero diagonal blocks.
Definition: MarginalizationError.hpp:249