g2o
Loading...
Searching...
No Matches
cholmod_wrapper.cpp
Go to the documentation of this file.
1// g2o - General Graph Optimization
2// Copyright (C) 2011 R. Kuemmerle, G. Grisetti, W. Burgard
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright notice,
10// this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27#include "cholmod_wrapper.h"
28
29#include <cholmod.h>
30
31#include <cassert>
32#include <cstring>
33#include <memory>
34
35#include "cholmod_ext.h"
36
37namespace g2o {
38namespace cholmod {
39
41 public:
42 Impl() {
43 cholmod_start(&cholmodCommon);
44
45 // setup ordering strategy
46 cholmodCommon.nmethods = 1;
47 cholmodCommon.method[0].ordering = CHOLMOD_AMD; // CHOLMOD_COLAMD
48 //_cholmodCommon.postorder = 0;
49
50 cholmodCommon.supernodal =
51 CHOLMOD_AUTO; // CHOLMOD_SUPERNODAL; //CHOLMOD_SIMPLICIAL;
52 }
54 freeFactor();
55 cholmod_finish(&cholmodCommon);
56 }
57
58 void freeFactor() {
59 if (cholmodFactor != nullptr) {
60 cholmod_free_factor(&cholmodFactor, &cholmodCommon);
61 cholmodFactor = nullptr;
62 }
63 }
64
65 cholmod_common cholmodCommon;
67 cholmod_factor* cholmodFactor = nullptr;
68};
69
70Cholmod::Cholmod() : pImpl(std::make_unique<Impl>()) {}
71
72Cholmod::~Cholmod() = default;
73
74void Cholmod::freeFactor() { pImpl->freeFactor(); }
75
76bool Cholmod::hasFactor() const { return pImpl->cholmodFactor != nullptr; }
77
78bool Cholmod::amd(SparseView& sparseView, int* result) {
79 cholmod_sparse auxCholmodSparse;
80 auxCholmodSparse.nzmax = sparseView.nzmax;
81 auxCholmodSparse.nrow = sparseView.nrow;
82 auxCholmodSparse.ncol = sparseView.ncol;
83 auxCholmodSparse.p = sparseView.p;
84 auxCholmodSparse.i = sparseView.i;
85 auxCholmodSparse.nz = 0;
86 auxCholmodSparse.x = 0;
87 auxCholmodSparse.z = 0;
88 auxCholmodSparse.stype = 1;
89 auxCholmodSparse.xtype = CHOLMOD_PATTERN;
90 auxCholmodSparse.itype = CHOLMOD_INT;
91 auxCholmodSparse.dtype = CHOLMOD_DOUBLE;
92 auxCholmodSparse.sorted = 1;
93 auxCholmodSparse.packed = 1;
94
95 int amdStatus =
96 cholmod_amd(&auxCholmodSparse, NULL, 0, result, &pImpl->cholmodCommon);
97 return amdStatus != 0;
98}
99
101 CholmodExt& sparse = pImpl->cholmodSparse;
102 return Cholmod::SparseView(
103 sparse.nrow, sparse.ncol, sparse.nzmax,
104 *reinterpret_cast<int**>(&sparse.p), *reinterpret_cast<int**>(&sparse.i),
105 *reinterpret_cast<double**>(&sparse.x), sparse.columnsAllocated);
106}
107
109 cholmod_factor& factor = *pImpl->cholmodFactor;
110 return Cholmod::FactorView(factor.n, *reinterpret_cast<int**>(&factor.p),
111 *reinterpret_cast<int**>(&factor.i),
112 *reinterpret_cast<double**>(&factor.x),
113 *reinterpret_cast<int**>(&factor.Perm));
114}
115
116void Cholmod::solve(double* x, double* b) const {
117 // setting up b for calling cholmod
118 cholmod_dense bcholmod;
119 bcholmod.nrow = bcholmod.d = pImpl->cholmodSparse.nrow;
120 bcholmod.ncol = 1;
121 bcholmod.x = b;
122 bcholmod.xtype = CHOLMOD_REAL;
123 bcholmod.dtype = CHOLMOD_DOUBLE;
124 cholmod_dense* xcholmod = cholmod_solve(CHOLMOD_A, pImpl->cholmodFactor,
125 &bcholmod, &pImpl->cholmodCommon);
126 std::memcpy(x, xcholmod->x,
127 sizeof(double) * bcholmod.nrow); // copy back to our array
128 cholmod_free_dense(&xcholmod, &pImpl->cholmodCommon);
129}
130
132 // setup ordering strategy
133 pImpl->cholmodCommon.nmethods = 1;
134 pImpl->cholmodCommon.method[0].ordering = CHOLMOD_AMD; // CHOLMOD_COLAMD
135 pImpl->cholmodFactor =
136 cholmod_analyze(&pImpl->cholmodSparse,
137 &pImpl->cholmodCommon); // symbolic factorization
138 return true;
139}
140
141bool Cholmod::analyze_p(int* permutation) {
142 pImpl->cholmodCommon.nmethods = 1;
143 pImpl->cholmodCommon.method[0].ordering = CHOLMOD_GIVEN;
144 pImpl->cholmodFactor = cholmod_analyze_p(&pImpl->cholmodSparse, permutation,
145 NULL, 0, &pImpl->cholmodCommon);
146 return true;
147}
148
150 return static_cast<int>(pImpl->cholmodCommon.method[0].lnz);
151}
152
154 cholmod_factorize(&pImpl->cholmodSparse, pImpl->cholmodFactor,
155 &pImpl->cholmodCommon);
156 return pImpl->cholmodCommon.status == CHOLMOD_OK;
157}
158
160 // convert the factorization to LL, simplical, packed, monotonic
161 int change_status = cholmod_change_factor(
162 CHOLMOD_REAL, 1, 0, 1, 1, pImpl->cholmodFactor, &pImpl->cholmodCommon);
163 assert(pImpl->cholmodFactor->is_ll && !pImpl->cholmodFactor->is_super &&
164 pImpl->cholmodFactor->is_monotonic &&
165 "Cholesky factor has wrong format");
166 return change_status != 0;
167}
168
169} // namespace cholmod
170} // namespace g2o
bool amd(SparseView &sparseView, int *result)
compute AMD ordering on the given SparseView, store into result
bool analyze_p(int *permutation)
void solve(double *x, double *b) const
std::unique_ptr< Impl > pImpl
Definition jet.h:876
Our extension of the CHOLMOD matrix struct.
Definition cholmod_ext.h:38
View onto the cholesky factor.
View onto the sparse matrix structure of Cholmod using CCS storage.