blob: a6af6b2c2071a1534c7c7693e7e7f521c623ffbc [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2017 Google Inc. All rights reserved.
3// http://ceres-solver.org/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: sameeragarwal@google.com (Sameer Agarwal)
30
31#ifndef CERES_INTERNAL_SPARSE_CHOLESKY_H_
32#define CERES_INTERNAL_SPARSE_CHOLESKY_H_
33
34// This include must come before any #ifndef check on Ceres compile options.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080035// clang-format off
Austin Schuh70cc9552019-01-21 19:46:48 -080036#include "ceres/internal/port.h"
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080037// clang-format on
Austin Schuh70cc9552019-01-21 19:46:48 -080038
39#include <memory>
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080040
Austin Schuh70cc9552019-01-21 19:46:48 -080041#include "ceres/linear_solver.h"
42#include "glog/logging.h"
43
44namespace ceres {
45namespace internal {
46
47// An interface that abstracts away the internal details of various
48// sparse linear algebra libraries and offers a simple API for solving
49// symmetric positive definite linear systems using a sparse Cholesky
50// factorization.
51//
52// Instances of SparseCholesky are expected to cache the symbolic
53// factorization of the linear system. They do this on the first call
54// to Factorize or FactorAndSolve. Subsequent calls to Factorize and
55// FactorAndSolve are expected to have the same sparsity structure.
56//
57// Example usage:
58//
59// std::unique_ptr<SparseCholesky>
60// sparse_cholesky(SparseCholesky::Create(SUITE_SPARSE, AMD));
61//
62// CompressedRowSparseMatrix lhs = ...;
63// std::string message;
64// CHECK_EQ(sparse_cholesky->Factorize(&lhs, &message), LINEAR_SOLVER_SUCCESS);
65// Vector rhs = ...;
66// Vector solution = ...;
67// CHECK_EQ(sparse_cholesky->Solve(rhs.data(), solution.data(), &message),
68// LINEAR_SOLVER_SUCCESS);
69
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080070class CERES_EXPORT_INTERNAL SparseCholesky {
Austin Schuh70cc9552019-01-21 19:46:48 -080071 public:
72 static std::unique_ptr<SparseCholesky> Create(
73 const LinearSolver::Options& options);
74
75 virtual ~SparseCholesky();
76
77 // Due to the symmetry of the linear system, sparse linear algebra
78 // libraries only use one half of the input matrix. Whether it is
79 // the upper or the lower triangular part of the matrix depends on
80 // the library and the re-ordering strategy being used. This
81 // function tells the user the storage type expected of the input
82 // matrix for the sparse linear algebra library and reordering
83 // strategy used.
84 virtual CompressedRowSparseMatrix::StorageType StorageType() const = 0;
85
86 // Computes the numeric factorization of the given matrix. If this
87 // is the first call to Factorize, first the symbolic factorization
88 // will be computed and cached and the numeric factorization will be
89 // computed based on that.
90 //
91 // Subsequent calls to Factorize will use that symbolic
92 // factorization assuming that the sparsity of the matrix has
93 // remained constant.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080094 virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
95 std::string* message) = 0;
Austin Schuh70cc9552019-01-21 19:46:48 -080096
97 // Computes the solution to the equation
98 //
99 // lhs * solution = rhs
100 virtual LinearSolverTerminationType Solve(const double* rhs,
101 double* solution,
102 std::string* message) = 0;
103
104 // Convenience method which combines a call to Factorize and
105 // Solve. Solve is only called if Factorize returns
106 // LINEAR_SOLVER_SUCCESS.
107 virtual LinearSolverTerminationType FactorAndSolve(
108 CompressedRowSparseMatrix* lhs,
109 const double* rhs,
110 double* solution,
111 std::string* message);
Austin Schuh70cc9552019-01-21 19:46:48 -0800112};
113
114class IterativeRefiner;
115
116// Computes an initial solution using the given instance of
117// SparseCholesky, and then refines it using the IterativeRefiner.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800118class CERES_EXPORT_INTERNAL RefinedSparseCholesky : public SparseCholesky {
Austin Schuh70cc9552019-01-21 19:46:48 -0800119 public:
120 RefinedSparseCholesky(std::unique_ptr<SparseCholesky> sparse_cholesky,
121 std::unique_ptr<IterativeRefiner> iterative_refiner);
122 virtual ~RefinedSparseCholesky();
123
124 virtual CompressedRowSparseMatrix::StorageType StorageType() const;
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800125 virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
126 std::string* message);
Austin Schuh70cc9552019-01-21 19:46:48 -0800127 virtual LinearSolverTerminationType Solve(const double* rhs,
128 double* solution,
129 std::string* message);
130
131 private:
132 std::unique_ptr<SparseCholesky> sparse_cholesky_;
133 std::unique_ptr<IterativeRefiner> iterative_refiner_;
134 CompressedRowSparseMatrix* lhs_ = nullptr;
135};
136
137} // namespace internal
138} // namespace ceres
139
140#endif // CERES_INTERNAL_SPARSE_CHOLESKY_H_