| 26 | { |
| 27 | |
| 28 | void Marginalize(const Vector &Residual, const Matrix &Jacobian, |
| 29 | Vector &ResidualMarg, Matrix &JacobianMarg, |
| 30 | const int SizeMarginal, const double HessianInflation) |
| 31 | { |
| 32 | /** H = J^T * J */ |
| 33 | Matrix Hessian = Jacobian.transpose() * Jacobian; |
| 34 | Hessian = Matrix((Hessian.array().abs() > 1e-8).select(Hessian.array(), 0));/**< remove small non-zero entries for stability */ |
| 35 | |
| 36 | /** b = J^T * r */ |
| 37 | const Vector B = Jacobian.transpose() * Residual; |
| 38 | |
| 39 | /** calculate size of the linear system */ |
| 40 | const int SizeTotal = Hessian.cols(); |
| 41 | const int SizeRemain = SizeTotal - SizeMarginal; |
| 42 | |
| 43 | /** select sub matrices */ |
| 44 | /** |
| 45 | Hessian: |
| 46 | H = |H_MM H_MR| |
| 47 | |H_RM H_RR| |
| 48 | |
| 49 | Residual vector: |
| 50 | r = |r_M r_R|' |
| 51 | */ |
| 52 | const Matrix HessMM = Hessian.block(0, 0, SizeMarginal, SizeMarginal); |
| 53 | const Matrix HessRR = Hessian.block(SizeMarginal, SizeMarginal, SizeRemain, SizeRemain); |
| 54 | const Matrix HessMR = Hessian.block(0, SizeMarginal, SizeMarginal, SizeRemain); |
| 55 | const Matrix HessRM = HessMR.transpose(); |
| 56 | |
| 57 | const Vector BM = B.head(SizeMarginal); |
| 58 | const Vector BR = B.tail(SizeRemain); |
| 59 | |
| 60 | /** compute reduced linear system */ |
| 61 | /** |
| 62 | New Hessian: |
| 63 | H* = H_RR - H_RM x H_MM^-1 x H_MR |
| 64 | |
| 65 | New residual vector: |
| 66 | r* = r_R - H_RM x H_MM^-1 x r_M |
| 67 | */ |
| 68 | |
| 69 | /** at first, invert the marginalized Hessian part */ |
| 70 | Eigen::CompleteOrthogonalDecomposition<Matrix> CODHess(HessMM); |
| 71 | const Matrix HessMMInv = CODHess.pseudoInverse(); /**< pseudo-inverse for rank deficient matrices*/ |
| 72 | |
| 73 | /** than compute the new system */ |
| 74 | Matrix HessRRStar = HessRR - HessRM * HessMMInv * HessMR; |
| 75 | const Vector BRStar = BR - HessRM * HessMMInv * BM; |
| 76 | |
| 77 | /** add a small uncertainty to prevent accumulation of error (I recommend a value of 1.01)*/ |
| 78 | if (HessianInflation != 1.0) |
| 79 | { |
| 80 | HessRRStar /= HessianInflation; |
| 81 | } |
| 82 | |
| 83 | /** convert to unsquared system system */ |
| 84 | ResidualMarg.resize(SizeRemain); |
| 85 | JacobianMarg.resize(SizeRemain, SizeRemain); |
no test coverage detected