blob: 4ba0b75fb28223017988a845c7c54d9615d2052d [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#include "ceres/linear_solver.h"
32
Austin Schuh3de38b02024-06-25 18:25:10 -070033#include <memory>
34
Austin Schuh70cc9552019-01-21 19:46:48 -080035#include "ceres/cgnr_solver.h"
36#include "ceres/dense_normal_cholesky_solver.h"
37#include "ceres/dense_qr_solver.h"
Austin Schuh1d1e6ea2020-12-23 21:56:30 -080038#include "ceres/dynamic_sparse_normal_cholesky_solver.h"
Austin Schuh3de38b02024-06-25 18:25:10 -070039#include "ceres/internal/config.h"
Austin Schuh70cc9552019-01-21 19:46:48 -080040#include "ceres/iterative_schur_complement_solver.h"
41#include "ceres/schur_complement_solver.h"
Austin Schuh70cc9552019-01-21 19:46:48 -080042#include "ceres/sparse_normal_cholesky_solver.h"
43#include "ceres/types.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
Austin Schuh3de38b02024-06-25 18:25:10 -070048LinearSolver::~LinearSolver() = default;
Austin Schuh70cc9552019-01-21 19:46:48 -080049
50LinearSolverType LinearSolver::LinearSolverForZeroEBlocks(
51 LinearSolverType linear_solver_type) {
52 if (!IsSchurType(linear_solver_type)) {
53 return linear_solver_type;
54 }
55
56 if (linear_solver_type == SPARSE_SCHUR) {
57 return SPARSE_NORMAL_CHOLESKY;
58 }
59
60 if (linear_solver_type == DENSE_SCHUR) {
61 // TODO(sameeragarwal): This is probably not a great choice.
62 // Ideally, we should have a DENSE_NORMAL_CHOLESKY, that can take
63 // a BlockSparseMatrix as input.
64 return DENSE_QR;
65 }
66
67 if (linear_solver_type == ITERATIVE_SCHUR) {
68 return CGNR;
69 }
70
71 return linear_solver_type;
72}
73
Austin Schuh3de38b02024-06-25 18:25:10 -070074std::unique_ptr<LinearSolver> LinearSolver::Create(
75 const LinearSolver::Options& options) {
76 CHECK(options.context != nullptr);
Austin Schuh70cc9552019-01-21 19:46:48 -080077
78 switch (options.type) {
Austin Schuh3de38b02024-06-25 18:25:10 -070079 case CGNR: {
80#ifndef CERES_NO_CUDA
81 if (options.sparse_linear_algebra_library_type == CUDA_SPARSE) {
82 std::string error;
83 return CudaCgnrSolver::Create(options, &error);
84 }
85#endif
86 return std::make_unique<CgnrSolver>(options);
87 } break;
Austin Schuh70cc9552019-01-21 19:46:48 -080088
89 case SPARSE_NORMAL_CHOLESKY:
90#if defined(CERES_NO_SPARSE)
Austin Schuh3de38b02024-06-25 18:25:10 -070091 return nullptr;
Austin Schuh70cc9552019-01-21 19:46:48 -080092#else
93 if (options.dynamic_sparsity) {
Austin Schuh3de38b02024-06-25 18:25:10 -070094 return std::make_unique<DynamicSparseNormalCholeskySolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -080095 }
96
Austin Schuh3de38b02024-06-25 18:25:10 -070097 return std::make_unique<SparseNormalCholeskySolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -080098#endif
99
100 case SPARSE_SCHUR:
101#if defined(CERES_NO_SPARSE)
Austin Schuh3de38b02024-06-25 18:25:10 -0700102 return nullptr;
Austin Schuh70cc9552019-01-21 19:46:48 -0800103#else
Austin Schuh3de38b02024-06-25 18:25:10 -0700104 return std::make_unique<SparseSchurComplementSolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -0800105#endif
106
107 case DENSE_SCHUR:
Austin Schuh3de38b02024-06-25 18:25:10 -0700108 return std::make_unique<DenseSchurComplementSolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -0800109
110 case ITERATIVE_SCHUR:
111 if (options.use_explicit_schur_complement) {
Austin Schuh3de38b02024-06-25 18:25:10 -0700112 return std::make_unique<SparseSchurComplementSolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -0800113 } else {
Austin Schuh3de38b02024-06-25 18:25:10 -0700114 return std::make_unique<IterativeSchurComplementSolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -0800115 }
116
117 case DENSE_QR:
Austin Schuh3de38b02024-06-25 18:25:10 -0700118 return std::make_unique<DenseQRSolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -0800119
120 case DENSE_NORMAL_CHOLESKY:
Austin Schuh3de38b02024-06-25 18:25:10 -0700121 return std::make_unique<DenseNormalCholeskySolver>(options);
Austin Schuh70cc9552019-01-21 19:46:48 -0800122
123 default:
Austin Schuh1d1e6ea2020-12-23 21:56:30 -0800124 LOG(FATAL) << "Unknown linear solver type :" << options.type;
Austin Schuh3de38b02024-06-25 18:25:10 -0700125 return nullptr; // MSVC doesn't understand that LOG(FATAL) never returns.
Austin Schuh70cc9552019-01-21 19:46:48 -0800126 }
127}
128
Austin Schuh3de38b02024-06-25 18:25:10 -0700129} // namespace ceres::internal