blob: 53f475a74816aa6b2b02f241541e38a404b6ddd3 [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001// Ceres Solver - A fast non-linear least squares minimizer
Austin Schuh3de38b02024-06-25 18:25:10 -07002// Copyright 2023 Google Inc. All rights reserved.
Austin Schuh70cc9552019-01-21 19:46:48 -08003// 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 Schuh3de38b02024-06-25 18:25:10 -070036#include "ceres/internal/config.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 Schuh3de38b02024-06-25 18:25:10 -070041#include "ceres/internal/disable_warnings.h"
42#include "ceres/internal/export.h"
Austin Schuh70cc9552019-01-21 19:46:48 -080043#include "ceres/linear_solver.h"
44#include "glog/logging.h"
45
Austin Schuh3de38b02024-06-25 18:25:10 -070046namespace ceres::internal {
Austin Schuh70cc9552019-01-21 19:46:48 -080047
48// An interface that abstracts away the internal details of various
49// sparse linear algebra libraries and offers a simple API for solving
50// symmetric positive definite linear systems using a sparse Cholesky
51// factorization.
52//
53// Instances of SparseCholesky are expected to cache the symbolic
54// factorization of the linear system. They do this on the first call
55// to Factorize or FactorAndSolve. Subsequent calls to Factorize and
56// FactorAndSolve are expected to have the same sparsity structure.
57//
58// Example usage:
59//
60// std::unique_ptr<SparseCholesky>
61// sparse_cholesky(SparseCholesky::Create(SUITE_SPARSE, AMD));
62//
63// CompressedRowSparseMatrix lhs = ...;
64// std::string message;
Austin Schuh3de38b02024-06-25 18:25:10 -070065// CHECK_EQ(sparse_cholesky->Factorize(&lhs, &message),
66// LinearSolverTerminationType::SUCCESS);
Austin Schuh70cc9552019-01-21 19:46:48 -080067// Vector rhs = ...;
68// Vector solution = ...;
69// CHECK_EQ(sparse_cholesky->Solve(rhs.data(), solution.data(), &message),
Austin Schuh3de38b02024-06-25 18:25:10 -070070// LinearSolverTerminationType::SUCCESS);
Austin Schuh70cc9552019-01-21 19:46:48 -080071
Austin Schuh3de38b02024-06-25 18:25:10 -070072class CERES_NO_EXPORT SparseCholesky {
Austin Schuh70cc9552019-01-21 19:46:48 -080073 public:
74 static std::unique_ptr<SparseCholesky> Create(
75 const LinearSolver::Options& options);
76
77 virtual ~SparseCholesky();
78
79 // Due to the symmetry of the linear system, sparse linear algebra
80 // libraries only use one half of the input matrix. Whether it is
81 // the upper or the lower triangular part of the matrix depends on
82 // the library and the re-ordering strategy being used. This
83 // function tells the user the storage type expected of the input
84 // matrix for the sparse linear algebra library and reordering
85 // strategy used.
86 virtual CompressedRowSparseMatrix::StorageType StorageType() const = 0;
87
88 // Computes the numeric factorization of the given matrix. If this
89 // is the first call to Factorize, first the symbolic factorization
90 // will be computed and cached and the numeric factorization will be
91 // computed based on that.
92 //
93 // Subsequent calls to Factorize will use that symbolic
94 // factorization assuming that the sparsity of the matrix has
95 // remained constant.
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080096 virtual LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
97 std::string* message) = 0;
Austin Schuh70cc9552019-01-21 19:46:48 -080098
99 // Computes the solution to the equation
100 //
101 // lhs * solution = rhs
102 virtual LinearSolverTerminationType Solve(const double* rhs,
103 double* solution,
104 std::string* message) = 0;
105
106 // Convenience method which combines a call to Factorize and
107 // Solve. Solve is only called if Factorize returns
Austin Schuh3de38b02024-06-25 18:25:10 -0700108 // LinearSolverTerminationType::SUCCESS.
109 LinearSolverTerminationType FactorAndSolve(CompressedRowSparseMatrix* lhs,
110 const double* rhs,
111 double* solution,
112 std::string* message);
Austin Schuh70cc9552019-01-21 19:46:48 -0800113};
114
Austin Schuh3de38b02024-06-25 18:25:10 -0700115class SparseIterativeRefiner;
Austin Schuh70cc9552019-01-21 19:46:48 -0800116
117// Computes an initial solution using the given instance of
Austin Schuh3de38b02024-06-25 18:25:10 -0700118// SparseCholesky, and then refines it using the SparseIterativeRefiner.
119class CERES_NO_EXPORT RefinedSparseCholesky final : public SparseCholesky {
Austin Schuh70cc9552019-01-21 19:46:48 -0800120 public:
Austin Schuh3de38b02024-06-25 18:25:10 -0700121 RefinedSparseCholesky(
122 std::unique_ptr<SparseCholesky> sparse_cholesky,
123 std::unique_ptr<SparseIterativeRefiner> iterative_refiner);
124 ~RefinedSparseCholesky() override;
Austin Schuh70cc9552019-01-21 19:46:48 -0800125
Austin Schuh3de38b02024-06-25 18:25:10 -0700126 CompressedRowSparseMatrix::StorageType StorageType() const override;
127 LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
128 std::string* message) override;
129 LinearSolverTerminationType Solve(const double* rhs,
130 double* solution,
131 std::string* message) override;
Austin Schuh70cc9552019-01-21 19:46:48 -0800132
133 private:
134 std::unique_ptr<SparseCholesky> sparse_cholesky_;
Austin Schuh3de38b02024-06-25 18:25:10 -0700135 std::unique_ptr<SparseIterativeRefiner> iterative_refiner_;
Austin Schuh70cc9552019-01-21 19:46:48 -0800136 CompressedRowSparseMatrix* lhs_ = nullptr;
137};
138
Austin Schuh3de38b02024-06-25 18:25:10 -0700139} // namespace ceres::internal
140
141#include "ceres/internal/reenable_warnings.h"
Austin Schuh70cc9552019-01-21 19:46:48 -0800142
143#endif // CERES_INTERNAL_SPARSE_CHOLESKY_H_