17 #ifndef G2O_LINEAR_SOLVER_CHOLMOD_ONLINE 18 #define G2O_LINEAR_SOLVER_CHOLMOD_ONLINE 34 virtual int choleskyUpdate(cholmod_sparse* update) = 0;
35 virtual bool solve(
double* x,
double* b) = 0;
36 virtual cholmod_factor* L()
const = 0;
37 virtual size_t nonZerosInL()
const = 0;
45 template <
typename MatrixType>
54 cholmod_start(&_cholmodCommon);
57 _cholmodCommon.nmethods = 1 ;
58 _cholmodCommon.method[0].ordering = CHOLMOD_AMD;
61 _cholmodCommon.supernodal = CHOLMOD_AUTO;
67 delete _cholmodSparse;
69 cholmod_free_factor(&_cholmodFactor, &_cholmodCommon);
72 cholmod_finish(&_cholmodCommon);
82 cholmod_free_factor(&_cholmodFactor, &_cholmodCommon);
84 fillCholmodExt(A,
false);
86 computeSymbolicDecomposition(A);
87 assert(_cholmodFactor &&
"Symbolic cholesky failed");
91 cholmod_dense bcholmod;
92 bcholmod.nrow = bcholmod.d = _cholmodSparse->nrow;
95 bcholmod.xtype = CHOLMOD_REAL;
96 bcholmod.dtype = CHOLMOD_DOUBLE;
98 cholmod_factorize(_cholmodSparse, _cholmodFactor, &_cholmodCommon);
99 if (_cholmodCommon.status == CHOLMOD_NOT_POSDEF) {
100 std::cerr <<
"solve(): Cholesky failure, writing debug.txt (Hessian loadable by Octave)" << std::endl;
101 writeCCSMatrix(
"debug.txt", _cholmodSparse->nrow, _cholmodSparse->ncol, (
int*)_cholmodSparse->p, (
int*)_cholmodSparse->i, (
double*)_cholmodSparse->x,
true);
105 cholmod_dense* xcholmod = cholmod_solve(CHOLMOD_A, _cholmodFactor, &bcholmod, &_cholmodCommon);
106 memcpy(x, xcholmod->x,
sizeof(
double) * bcholmod.nrow);
107 cholmod_free_dense(&xcholmod, &_cholmodCommon);
112 globalStats->
choleskyNNZ =
static_cast<size_t>(_cholmodCommon.method[0].lnz);
120 cholmod_factor*
L()
const {
return _cholmodFactor;}
127 int* nz = (
int*)_cholmodFactor->nz;
130 for (
size_t i = 0; i < _cholmodFactor->n; ++i)
137 int result = cholmod_updown(1, update, _cholmodFactor, &_cholmodCommon);
139 if (_cholmodCommon.status == CHOLMOD_NOT_POSDEF) {
140 std::cerr <<
"Cholesky failure, writing debug.txt (Hessian loadable by Octave)" << std::endl;
141 writeCCSMatrix(
"debug.txt", _cholmodSparse->nrow, _cholmodSparse->ncol, (
int*)_cholmodSparse->p, (
int*)_cholmodSparse->i, (
double*)_cholmodSparse->x,
true);
150 cholmod_dense bcholmod;
151 bcholmod.nrow = bcholmod.d = _cholmodSparse->nrow;
154 bcholmod.xtype = CHOLMOD_REAL;
155 bcholmod.dtype = CHOLMOD_DOUBLE;
157 cholmod_dense* xcholmod = cholmod_solve(CHOLMOD_A, _cholmodFactor, &bcholmod, &_cholmodCommon);
158 memcpy(x, xcholmod->x,
sizeof(
double) * bcholmod.nrow);
159 cholmod_free_dense(&xcholmod, &_cholmodCommon);
180 if (_blockPermutation.size() < _matrixStructure.
n)
181 _blockPermutation.resize(2*_matrixStructure.
n);
183 int amdStatus = camd_order(_matrixStructure.
n, _matrixStructure.
Ap, _matrixStructure.
Aii, _blockPermutation.data(), NULL, NULL, cmember->data());
184 if (amdStatus != CAMD_OK) {
185 std::cerr <<
"Error while computing ordering" << std::endl;
189 if (_scalarPermutation.size() == 0)
190 _scalarPermutation.resize(_cholmodSparse->ncol);
191 if (_scalarPermutation.size() < (int)_cholmodSparse->ncol)
192 _scalarPermutation.resize(2*_cholmodSparse->ncol);
193 size_t scalarIdx = 0;
194 for (
int i = 0; i < _matrixStructure.
n; ++i) {
195 const int& p = _blockPermutation(i);
198 for (
int j = 0; j < nCols; ++j)
199 _scalarPermutation(scalarIdx++) = base++;
202 for (; scalarIdx < _cholmodSparse->ncol; ++scalarIdx)
203 _scalarPermutation(scalarIdx) = scalarIdx;
204 assert(scalarIdx == _cholmodSparse->ncol);
207 _cholmodCommon.nmethods = 1;
208 _cholmodCommon.method[0].ordering = CHOLMOD_GIVEN;
209 _cholmodFactor = cholmod_analyze_p(_cholmodSparse, _scalarPermutation.data(), NULL, 0, &_cholmodCommon);
219 int blockDimension = MatrixType::RowsAtCompileTime;
220 assert(blockDimension > 0);
222 size_t origN = A.
cols();
223 int additionalSpace = blockDimension * batchEveryN;
224 size_t m = A.
rows() + additionalSpace;
225 size_t n = A.
cols() + additionalSpace;
230 delete[] (
int*)_cholmodSparse->p;
234 size_t nzmax = A.
nonZeros() + additionalSpace;
235 if (_cholmodSparse->nzmax < nzmax) {
237 _cholmodSparse->nzmax = _cholmodSparse->nzmax == 0 ? nzmax : 2 * nzmax;
238 delete[] (
double*)_cholmodSparse->x;
239 delete[] (
int*)_cholmodSparse->i;
240 _cholmodSparse->i =
new int[_cholmodSparse->nzmax];
241 _cholmodSparse->x =
new double[_cholmodSparse->nzmax];
244 _cholmodSparse->ncol = n;
245 _cholmodSparse->nrow = m;
249 nz = A.
fillCCS((
double*)_cholmodSparse->x,
true);
251 nz = A.
fillCCS((
int*)_cholmodSparse->p, (
int*)_cholmodSparse->i, (
double*)_cholmodSparse->x,
true);
253 int* cp = (
int*)_cholmodSparse->p;
254 int* ci = (
int*)_cholmodSparse->i;
255 double* cx = (
double*)_cholmodSparse->x;
262 for (
int i = 0; i < additionalSpace; ++i) {
cholmod_factor * _cholmodFactor
double get_monotonic_time()
statistics about the optimization
int choleskyUpdate(cholmod_sparse *update)
cholmod_common _cholmodCommon
int cols() const
columns of the matrix
int * Ap
column pointers for A, of size n+1
CholmodExt * _cholmodSparse
int n
A is m-by-n. n must be >= 0.
bool solve(const SparseBlockMatrix< MatrixType > &A, double *x, double *b)
size_t nonZerosInL() const
cholmod_factor * L() const
Eigen::VectorXi * cmember
int rows() const
rows of the matrix
representing the structure of a matrix in column compressed structure (only the upper triangular part...
bool writeCCSMatrix(const string &filename, int rows, int cols, const int *Ap, const int *Ai, const double *Ax, bool upperTriangleSymmetric)
void fillCholmodExt(const SparseBlockMatrix< MatrixType > &A, bool onlyValues)
int colsOfBlock(int c) const
how many cols does the block at block-col c has?
size_t nonZeros() const
number of non-zero elements
Our extension of the CHOLMOD matrix struct.
void fillBlockStructure(MatrixStructure &ms) const
exports the non zero blocks in the structure matrix ms
size_t choleskyNNZ
number of non-zeros in the cholesky factor
LinearSolverCholmodOnlineInterface()
bool blockOrdering() const
virtual ~LinearSolverCholmodOnline()
#define G2O_INCREMENTAL_API
Eigen::VectorXi _scalarPermutation
if(POLICY CMP0020) cmake_policy(SET CMP0020 OLD) endif() if(Qt4_FOUND) endif() if(Qt5_FOUND) endif() ADD_LIBRARY(viewer_library $
generic interface for the online solver
static G2OBatchStatistics * globalStats()
double timeNumericDecomposition
numeric decomposition (0 if not done)
int colBaseOfBlock(int c) const
where does the col at block-col r starts?
int * Aii
row indices of A, of size nz = Ap [n]
bool solve(double *x, double *b)
void computeSymbolicDecomposition(const SparseBlockMatrix< MatrixType > &A)
LinearSolverCholmodOnline()
MatrixStructure _matrixStructure
linear solver which allows to update the cholesky factor
Sparse matrix which uses blocks.
int fillCCS(int *Cp, int *Ci, double *Cx, bool upperTriangle=false) const