00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "graph_optimizer_sparse.h"
00018 #include <Eigen/LU>
00019 #include <fstream>
00020 #include <iomanip>
00021
00022 #include "g2o/stuff/timeutil.h"
00023
00024 namespace g2o {
00025 using namespace std;
00026 using namespace Eigen;
00027
00028 template <typename Traits>
00029 BlockSolver<Traits>::BlockSolver
00030 (
00031 SparseOptimizer* optimizer, LinearSolverType* linearSolver
00032 ):
00033 Solver(optimizer), _linearSolver(linearSolver)
00034 {
00035
00036 _Hpp=0;
00037 _Hll=0;
00038 _Hpl=0;
00039 _Hschur=0;
00040 _DInvSchur=0;
00041 _coefficients=0;
00042 _bschur = 0;
00043 _xSize=0;
00044 _numPoses=0;
00045 _numLandmarks=0;
00046 _sizePoses=0;
00047 _sizeLandmarks=0;
00048 _doSchur=true;
00049 }
00050
00051
00052
00053 template <typename Traits>
00054 void BlockSolver<Traits>::resize
00055 (
00056 int* blockPoseIndices, int numPoseBlocks,
00057 int* blockLandmarkIndices, int numLandmarkBlocks, int s
00058 )
00059 {
00060 delete[] _coefficients;
00061 _coefficients = 0;
00062
00063
00064
00065 resizeVector(s);
00066 delete _Hpp;
00067 _Hpp=0;
00068 delete _Hll;
00069 _Hll=0;
00070 delete _Hpl;
00071 _Hpl = 0;
00072 delete _Hschur;
00073 _Hschur=0;
00074 delete _DInvSchur;
00075 _DInvSchur=0;
00076
00077 if (_doSchur)
00078 {
00079
00080 _coefficients = new double [s];
00081 _bschur = new double[s];
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 _Hpp = new
00109 PoseHessianType
00110 (
00111 blockPoseIndices, blockPoseIndices, numPoseBlocks, numPoseBlocks
00112 );
00113 if (_doSchur)
00114 {
00115 _Hschur = new
00116 PoseHessianType
00117 (
00118 blockPoseIndices, blockPoseIndices, numPoseBlocks, numPoseBlocks
00119 );
00120
00121
00122
00123 _Hll = new
00124 LandmarkHessianType
00125 (
00126 blockLandmarkIndices, blockLandmarkIndices,
00127 numLandmarkBlocks, numLandmarkBlocks
00128 );
00129
00130 _DInvSchur = new
00131 LandmarkHessianType
00132 (
00133 blockLandmarkIndices, blockLandmarkIndices,
00134 numLandmarkBlocks, numLandmarkBlocks
00135 );
00136
00137
00138
00139 _Hpl=new
00140 PoseLandmarkHessianType
00141 (
00142 blockPoseIndices, blockLandmarkIndices,
00143 numPoseBlocks, numLandmarkBlocks
00144 );
00145 }
00146 }
00147
00148
00149
00150 template <typename Traits>
00151 BlockSolver<Traits>::~BlockSolver()
00152 {
00153 delete _linearSolver;
00154 if (_Hpp)
00155 {
00156 delete _Hpp;
00157 _Hpp=0;
00158 }
00159 if (_Hll)
00160 {
00161 delete _Hll;
00162 _Hll=0;
00163 }
00164 if (_Hpl)
00165 {
00166 delete _Hpl;
00167 _Hpl = 0;
00168 }
00169 if (_Hschur){
00170 delete _Hschur;
00171 _Hschur=0;
00172 }
00173 if (_DInvSchur){
00174 delete _DInvSchur;
00175 _DInvSchur=0;
00176 }
00177 if (_coefficients) {
00178 delete[] _coefficients;
00179 _coefficients = 0;
00180 }
00181 delete[] _bschur;
00182 _bschur = 0;
00183 }
00184
00185
00186
00187 template <typename Traits>
00188 bool BlockSolver<Traits>::buildStructure(bool zeroBlocks)
00189 {
00190 assert(_optimizer);
00191
00192 size_t sparseDim = 0;
00193 _numPoses=0;
00194 _numLandmarks=0;
00195 _sizePoses=0;
00196 _sizeLandmarks=0;
00197
00198
00199
00200
00201
00202
00203
00204 int blockPoseIndices[_optimizer->indexMapping().size()];
00205 int blockLandmarkIndices[_optimizer->indexMapping().size()];
00206
00207
00208 for (size_t i = 0; i < _optimizer->indexMapping().size(); ++i)
00209 {
00210 OptimizableGraph::Vertex* v = _optimizer->indexMapping()[i];
00211 int dim = v->dimension();
00212
00213 if (! v->marginalized())
00214 {
00215 v->setColInHessian(_sizePoses);
00216 _sizePoses += dim;
00217 blockPoseIndices[_numPoses] = _sizePoses;
00218 _numPoses++;
00219 } else
00220 {
00221 v->setColInHessian(_sizeLandmarks);
00222 _sizeLandmarks += dim;
00223 blockLandmarkIndices[_numLandmarks] = _sizeLandmarks;
00224 _numLandmarks++;
00225 }
00226 sparseDim += dim;
00227 }
00228
00229 resize
00230 (
00231 blockPoseIndices, _numPoses, blockLandmarkIndices,
00232 _numLandmarks, sparseDim
00233 );
00234
00235
00236
00237
00238
00239 int poseIdx = 0;
00240 int landmarkIdx = 0;
00241 for (size_t i = 0; i < _optimizer->indexMapping().size(); ++i)
00242 {
00243 OptimizableGraph::Vertex* v = _optimizer->indexMapping()[i];
00244 if (! v->marginalized())
00245 {
00246
00247
00248 PoseMatrixType* m = _Hpp->block(poseIdx, poseIdx, true);
00249 if (zeroBlocks) m->setZero();
00250 v->mapHessianMemory(m->data());
00251 ++poseIdx;
00252 } else
00253 {
00254 LandmarkMatrixType* m = _Hll->block(landmarkIdx, landmarkIdx, true);
00255 if (zeroBlocks) m->setZero();
00256 v->mapHessianMemory(m->data());
00257 _DInvSchur->block(landmarkIdx, landmarkIdx, true);
00258 ++landmarkIdx;
00259 }
00260 }
00261 assert(poseIdx == _numPoses && landmarkIdx == _numLandmarks);
00262
00263
00264
00265
00266
00267
00268
00269
00270 for (SparseOptimizer::EdgeContainer::const_iterator
00271 it = _optimizer->activeEdges().begin();
00272 it != _optimizer->activeEdges().end();
00273 ++it)
00274 {
00275 OptimizableGraph::Edge* e = *it;
00276
00277 for (size_t viIdx = 0; viIdx < e->vertices().size(); ++viIdx)
00278 {
00279 OptimizableGraph::Vertex* v1 =
00280 (OptimizableGraph::Vertex*) e->vertices()[viIdx];
00281
00282 int ind1 = v1->tempIndex();
00283
00284 if (ind1 == -1) continue;
00285 int indexV1Bak = ind1;
00286
00287 for (size_t vjIdx = viIdx + 1; vjIdx < e->vertices().size(); ++vjIdx)
00288 {
00289 OptimizableGraph::Vertex* v2 =
00290 (OptimizableGraph::Vertex*) e->vertices()[vjIdx];
00291
00292 int ind2 = v2->tempIndex();
00293
00294 if (ind2 == -1) continue;
00295 ind1 = indexV1Bak;
00296
00297
00298 bool transposedBlock = ind1 > ind2;
00299 if(transposedBlock) swap(ind1, ind2);
00300
00301 if (! v1->marginalized() && !v2->marginalized())
00302
00303 {
00304 PoseMatrixType* m = _Hpp->block(ind1, ind2, true);
00305 if (zeroBlocks) m->setZero();
00306 e->mapHessianMemory(m->data(), viIdx, vjIdx, transposedBlock);
00307
00308
00309
00310 if (_Hschur) _Hschur->block(ind1, ind2, true);
00311
00312 }else if (v1->marginalized() && v2->marginalized())
00313
00314
00315
00316 {
00317
00318 LandmarkMatrixType* m =
00319 _Hll->block(ind1-_numPoses, ind2-_numPoses, true);
00320 if (zeroBlocks) m->setZero();
00321 e->mapHessianMemory(m->data(), viIdx, vjIdx, false);
00322
00323 }else
00324
00325 {
00326 if (v1->marginalized())
00327
00328 {
00329 PoseLandmarkMatrixType* m =
00330 _Hpl->block
00331 (v2->tempIndex(),v1->tempIndex()-_numPoses, true);
00332 if (zeroBlocks) m->setZero();
00333
00334
00335 e->mapHessianMemory(m->data(), viIdx, vjIdx, true);
00336 }else
00337
00338 {
00339 PoseLandmarkMatrixType* m =
00340 _Hpl->block
00341 (v1->tempIndex(),v2->tempIndex()-_numPoses, true);
00342 if (zeroBlocks) m->setZero();
00343
00344
00345 e->mapHessianMemory(m->data(), viIdx, vjIdx, false);
00346 }
00347 }
00348 }
00349 }
00350 }
00351
00352 if (! _doSchur) return true;
00353
00354
00355
00356
00358
00359 for (size_t i = 0; i < _optimizer->indexMapping().size(); ++i)
00360 {
00361 OptimizableGraph::Vertex* v = _optimizer->indexMapping()[i];
00362 if (v->marginalized())
00363 {
00364 const HyperGraph::EdgeSet& vedges = v->edges();
00365 for (HyperGraph::EdgeSet::const_iterator
00366 it1 = vedges.begin();
00367 it1 != vedges.end();
00368 it1++)
00369 {
00370
00371
00372 for(size_t i = 0; i < (*it1)->vertices().size(); i++)
00373 {
00374 OptimizableGraph::Vertex* v1;
00375 v1 = (OptimizableGraph::Vertex*) (*it1)->vertices()[i];
00376
00377 if(v1->marginalized() || v1->tempIndex() == -1) continue;
00378
00379 for(HyperGraph::EdgeSet::const_iterator
00380 it2 = vedges.begin();
00381 it2 != vedges.end();
00382 it2++)
00383 {
00384 for(size_t i = 0; i < (*it1)->vertices().size(); i++)
00385 {
00386 OptimizableGraph::Vertex* v2;
00387 v2 = (OptimizableGraph::Vertex*) (*it2)->vertices()[i];
00388
00389 if(v2->marginalized() || v2->tempIndex() == -1) continue;
00390
00391 int i1 = v1->tempIndex();
00392 int i2 = v2->tempIndex();
00393 if (i1 <= i2) _Hschur->block(i1,i2,true)->setZero();
00394 }
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 }
00423 }
00424 }
00425 return true;
00426 }
00427
00428
00429
00430
00431
00432
00433 template <typename Traits>
00434 bool BlockSolver<Traits>::updateStructure
00435 (
00436 const std::vector<HyperGraph::Vertex*>& vset,
00437 const HyperGraph::EdgeSet& edges
00438 )
00439 {
00440 for (std::vector<HyperGraph::Vertex*>::const_iterator
00441 vit = vset.begin();
00442 vit != vset.end();
00443 ++vit)
00444 {
00445 OptimizableGraph::Vertex* v =
00446 static_cast<OptimizableGraph::Vertex*>(*vit);
00447 int dim = v->dimension();
00448 if (! v->marginalized())
00449 {
00450
00451 v->setColInHessian(_sizePoses);
00452 _sizePoses += dim;
00453 _Hpp->rowBlockIndices().push_back(_sizePoses);
00454 _Hpp->colBlockIndices().push_back(_sizePoses);
00455 _Hpp->blockCols().push_back
00456 (
00457 typename SparseBlockMatrix<PoseMatrixType>::IntBlockMap()
00458 );
00459 _numPoses++;
00460 int ind = v->tempIndex();
00461 PoseMatrixType* m = _Hpp->block(ind, ind, true);
00462 v->mapHessianMemory(m->data());
00463 }else
00464 {
00465 std::cerr << "updateStructure(): Schur not supported" << std::endl;
00466 abort();
00467 }
00468 }
00469 resizeVector(_sizePoses + _sizeLandmarks);
00470
00471
00472 for (HyperGraph::EdgeSet::const_iterator
00473 it = edges.begin();
00474 it != edges.end();
00475 ++it)
00476 {
00477 OptimizableGraph::Edge* e = static_cast<OptimizableGraph::Edge*>(*it);
00478
00479 for (size_t viIdx = 0; viIdx < e->vertices().size(); ++viIdx)
00480 {
00481 OptimizableGraph::Vertex* v1 =
00482 (OptimizableGraph::Vertex*) e->vertices()[viIdx];
00483
00484 int ind1 = v1->tempIndex();
00485 int indexV1Bak = ind1;
00486
00487 if (ind1 == -1) continue;
00488
00489 for (size_t vjIdx = viIdx + 1; vjIdx < e->vertices().size(); ++vjIdx)
00490 {
00491 OptimizableGraph::Vertex* v2 =
00492 (OptimizableGraph::Vertex*) e->vertices()[vjIdx];
00493
00494 int ind2 = v2->tempIndex();
00495
00496 if (ind2 == -1) continue;
00497 ind1 = indexV1Bak;
00498
00499 bool transposedBlock = ind1 > ind2;
00500
00501 if (transposedBlock) swap(ind1, ind2);
00502
00503 if (! v1->marginalized() && !v2->marginalized())
00504 {
00505
00506 PoseMatrixType* m = _Hpp->block(ind1, ind2, true);
00507 e->mapHessianMemory(m->data(), viIdx, vjIdx, transposedBlock);
00508 }else
00509 {
00510 std::cerr << __PRETTY_FUNCTION__ << ": not supported\n";
00511 }
00512 }
00513 }
00514 }
00515
00516 return true;
00517 }
00518
00519
00520
00521
00522 template <typename Traits>
00523 bool BlockSolver<Traits>::solve()
00524 {
00525
00526 if (! _doSchur)
00527 {
00528
00529 double t=get_time();
00530 bool ok = _linearSolver->solve(*_Hpp, _x, _b);
00531 if (globalStats)
00532 {
00533 globalStats->timeLinearSolver = get_time() - t;
00534 globalStats->hessianDimension =
00535 globalStats->hessianPoseDimension =
00536 _Hpp->cols();
00537 }
00538 return ok;
00539 }
00540
00541 char fich[] = "Hpp.m";
00542 _Hpp->writeOctave(fich, false);
00543 fich[2] = 'l';
00544 _Hpl->writeOctave(fich, false);
00545 fich[1] = 'l';
00546 _Hll->writeOctave(fich, false);
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 double t=get_time();
00558 _Hschur->clear();
00559 _Hpp->add(_Hschur);
00560 _DInvSchur->clear();
00561 memset(_coefficients, 0, _xSize*sizeof(double));
00562
00563 for (size_t i = 0; i < _optimizer->indexMapping().size(); ++i)
00564 {
00565 OptimizableGraph::Vertex* v = _optimizer->indexMapping()[i];
00566 if (v->marginalized())
00567 {
00568
00569 int landmarkIndex = i - _numPoses;
00570 const HyperGraph::EdgeSet& vedges = v->edges();
00571
00572 const LandmarkMatrixType *D = _Hll->block(landmarkIndex,landmarkIndex);
00573 assert (D && D->rows()==D->cols());
00574
00575 LandmarkMatrixType Dinv = D->inverse();
00576 LandmarkMatrixType *_DInvSchurBlock =
00577 _DInvSchur->block(landmarkIndex, landmarkIndex, false);
00578 assert( _DInvSchurBlock
00579 && _DInvSchurBlock->rows() == D->rows()
00580 && _DInvSchurBlock->cols() == D->cols());
00581
00582 *_DInvSchurBlock = Dinv;
00583 LandmarkVectorType db(D->rows());
00584 for (int j=0; j<D->rows(); j++)
00585 {
00586 db[j] = _b[v->colInHessian()+_sizePoses+j];
00587 }
00588
00589
00590 db = Dinv * db;
00591
00592
00593 size_t tmpIdx = 0;
00594 # ifdef _MSC_VER
00595 OptimizableGraph::Edge* tmpEdges =
00596 new OptimizableGraph::Edge*[vedges.size()];
00597 # else
00598 OptimizableGraph::Edge* tmpEdges[vedges.size()];
00599 # endif
00600 for (HyperGraph::EdgeSet::const_iterator
00601 it2 = vedges.begin();
00602 it2 != vedges.end();
00603 ++it2)
00604 {
00605 OptimizableGraph::Edge* e2 =
00606 static_cast<OptimizableGraph::Edge*>(*it2);
00607 tmpEdges[tmpIdx++] = e2;
00608 }
00609
00610 # ifdef G2O_OPENMP
00611 # pragma omp parallel for default (shared)
00612 # endif
00613
00615 for (size_t l=0; l < tmpIdx; ++l)
00616 {
00617 OptimizableGraph::Edge* e1 = tmpEdges[l];
00618
00619
00620
00621 for(size_t i = 0; i < e1->vertices().size(); i++)
00622 {
00623 OptimizableGraph::Vertex* v1;
00624 v1 = static_cast<OptimizableGraph::Vertex*>( e1->vertices()[i] );
00625
00626 if (v1==v) continue;
00627 assert (!v1->marginalized());
00628
00629 int i1 = v1->tempIndex();
00630
00631 if (i1<0) continue;
00632
00633 const PoseLandmarkMatrixType* Bi = _Hpl->block(i1,landmarkIndex);
00634 assert(Bi);
00635
00636
00637 PoseVectorType Bb = (*Bi)*db;
00638
00639 v1->lockQuadraticForm();
00640
00641 for (int j=0; j<Bb.rows(); j++)
00642 {
00643 _coefficients[v1->colInHessian()+j] += Bb(j);
00644 }
00645
00646
00647 PoseLandmarkMatrixType BDinv = (*Bi)*(Dinv);
00648
00649 for (size_t k =0; k < tmpIdx; ++k)
00650 {
00651 OptimizableGraph::Edge* e2 = tmpEdges[k];
00652 for(size_t i = 0; i < e1->vertices().size(); i++)
00653 {
00654 OptimizableGraph::Vertex* v2;
00655 v2 = (OptimizableGraph::Vertex*) e2->vertices()[i];
00656
00657 if(v2==v) continue;;
00658 assert (!v2->marginalized());
00659
00660 int i2 = v2->tempIndex();
00661
00662
00663 if (i2<0 || i1>i2) continue;
00664
00665 const PoseLandmarkMatrixType* Bj =
00666 _Hpl->block(i2,landmarkIndex);
00667 assert(Bj);
00668
00669 PoseMatrixType* Hi1i2 = _Hschur->block(i1,i2);
00670 assert(Hi1i2);
00671
00672 (*Hi1i2).noalias() -= BDinv * Bj->transpose();
00673 }
00674 }
00675 v1->unlockQuadraticForm();
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 }
00732 # ifdef _MSC_VER
00733 delete[] tmpEdges;
00734 # endif
00735 }
00736 }
00737
00738
00739
00740
00741
00742
00743 memcpy(_bschur, _b, _xSize * sizeof(double));
00744 for (int i=0; i<_sizePoses; i++) _bschur[i] -= _coefficients[i];
00745
00746 if (globalStats) globalStats->timeSchurrComplement = get_time() - t;
00747 t = get_time();
00748
00749
00750
00751
00752 bool solvedPoses = _linearSolver->solve(*_Hschur, _x, _bschur);
00753
00754 if (globalStats)
00755 {
00756 globalStats->timeLinearSolver = get_time() - t;
00757 globalStats->hessianPoseDimension = _Hpp->cols();
00758 globalStats->hessianLandmarkDimension = _Hll->cols();
00759 globalStats->hessianDimension =
00760 globalStats->hessianPoseDimension
00761 + globalStats->hessianLandmarkDimension;
00762 }
00763
00764
00765 if (! solvedPoses) return false;
00766
00767
00768
00769
00770
00771
00772
00773 double* xp = _x;
00774 double* cp = _coefficients;
00775
00776 double* xl = _x + _sizePoses;
00777 double* cl = _coefficients + _sizePoses;
00778 double* bl = _b + _sizePoses;
00779
00780
00781 for (int i=0; i<_sizePoses; i++) cp[i] = -xp[i];
00782
00783
00784 memcpy(cl, bl,_sizeLandmarks * sizeof(double));
00785
00786
00787
00788 _Hpl->rightMultiply(cl, cp);
00789
00790
00791 memset(xl, 0, _sizeLandmarks * sizeof(double));
00792
00793 _DInvSchur->rightMultiply(xl,cl);
00794
00795
00796 return true;
00797 }
00798
00799
00800
00801 template <typename Traits>
00802 bool BlockSolver<Traits>::computeMarginals()
00803 {
00804 double t = get_time();
00805 double** blocks = new double*[_optimizer->indexMapping().size()];
00806
00807 for (size_t i = 0; i < _optimizer->indexMapping().size(); ++i)
00808 {
00809 OptimizableGraph::Vertex* v = _optimizer->indexMapping()[i];
00810 assert(v->uncertaintyData());
00811 blocks[i] = v->uncertaintyData();
00812 }
00813 bool ok = _linearSolver->solveBlocks(blocks, *_Hpp);
00814 delete [] blocks;
00815
00816 if (globalStats) globalStats->timeMarginals = get_time() - t;
00817 return ok;
00818 }
00819
00820
00821
00822 template <typename Traits>
00823 bool BlockSolver<Traits>::computeMarginals
00824 (
00825 SparseBlockMatrix<MatrixXd>& spinv,
00826 const std::vector<std::pair<int, int> >& blockIndices
00827 )
00828 {
00829 double t = get_time();
00830 bool ok = _linearSolver->solvePattern(spinv, blockIndices, *_Hpp);
00831 if (globalStats) globalStats->timeMarginals = get_time() - t;
00832 return ok;
00833 }
00834
00835
00836
00837
00838
00839 template <typename Traits>
00840 bool BlockSolver<Traits>::buildSystem()
00841 {
00842
00843 # ifdef G2O_OPENMP
00844 # pragma omp parallel for default (shared) \
00845 if (_optimizer->indexMapping().size() > 1000)
00846 # endif
00847 for (int i = 0; i < static_cast<int>(_optimizer->indexMapping().size()); ++i)
00848 {
00849 OptimizableGraph::Vertex* v = _optimizer->indexMapping()[i];
00850 assert(v);
00851
00852
00853 v->clearQuadraticForm();
00854 }
00855
00856 _Hpp->clear();
00857
00858 if (_doSchur)
00859 {
00860 _Hll->clear();
00861 _Hpl->clear();
00862 }
00863
00864
00865
00866
00867 # ifdef G2O_OPENMP
00868 # pragma omp parallel for default (shared) \
00869 if (_optimizer->activeEdges().size() > 100)
00870 # endif
00871 for (int k = 0; k < static_cast<int>(_optimizer->activeEdges().size()); ++k)
00872 {
00873 OptimizableGraph::Edge* e = _optimizer->activeEdges()[k];
00874
00875 e->constructQuadraticForm();
00876 }
00877
00878
00879 # ifdef G2O_OPENMP
00880 # pragma omp parallel for default (shared) \
00881 if (_optimizer->indexMapping().size() > 1000)
00882 # endif
00883 for (int i = 0; i < static_cast<int>(_optimizer->indexMapping().size()); ++i)
00884 {
00885 OptimizableGraph::Vertex* v = _optimizer->indexMapping()[i];
00886 int iBase = v->colInHessian();
00887
00888
00889
00890 if (v->marginalized()) iBase += _sizePoses;
00891 v->copyB( _b+iBase );
00892 }
00893
00894
00895
00896
00897
00898
00899 return 0;
00900 }
00901
00902
00903
00904
00905 template <typename Traits>
00906 bool BlockSolver<Traits>::setLambda(double lambda)
00907 {
00908 # ifdef G2O_OPENMP
00909 # pragma omp parallel for default (shared) if (_numPoses > 100)
00910 # endif
00911 for (int i = 0; i < _numPoses; i++)
00912 {
00913 PoseMatrixType *b = _Hpp->block(i,i);
00914 b->diagonal().array() += lambda;
00915 }
00916 # ifdef G2O_OPENMP
00917 # pragma omp parallel for default (shared) if (_numLandmarks > 100)
00918 # endif
00919 for (int i = 0; i < _numLandmarks; i++)
00920 {
00921 LandmarkMatrixType *b=_Hll->block(i,i);
00922 b->diagonal().array() += lambda;
00923 }
00924 return true;
00925 }
00926
00927
00928
00929 template <typename Traits>
00930 bool BlockSolver<Traits>::init(bool online)
00931 {
00932 if (! online)
00933 {
00934 if (_Hpp) _Hpp->clear();
00935 if (_Hpl) _Hpl->clear();
00936 if (_Hll) _Hll->clear();
00937 }
00938 _linearSolver->init();
00939 return true;
00940 }
00941
00942
00943
00944 }