1 // Ceres Solver - A fast non-linear least squares minimizer
2 // Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3 // http://code.google.com/p/ceres-solver/
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 <algorithm>
32 #include <cctype>
33 #include <string>
34 #include "ceres/types.h"
35 #include "glog/logging.h"
36
37 namespace ceres {
38
39 #define CASESTR(x) case x: return #x
40 #define STRENUM(x) if (value == #x) { *type = x; return true;}
41
UpperCase(string * input)42 static void UpperCase(string* input) {
43 std::transform(input->begin(), input->end(), input->begin(), ::toupper);
44 }
45
LinearSolverTypeToString(LinearSolverType type)46 const char* LinearSolverTypeToString(LinearSolverType type) {
47 switch (type) {
48 CASESTR(DENSE_NORMAL_CHOLESKY);
49 CASESTR(DENSE_QR);
50 CASESTR(SPARSE_NORMAL_CHOLESKY);
51 CASESTR(DENSE_SCHUR);
52 CASESTR(SPARSE_SCHUR);
53 CASESTR(ITERATIVE_SCHUR);
54 CASESTR(CGNR);
55 default:
56 return "UNKNOWN";
57 }
58 }
59
StringToLinearSolverType(string value,LinearSolverType * type)60 bool StringToLinearSolverType(string value, LinearSolverType* type) {
61 UpperCase(&value);
62 STRENUM(DENSE_NORMAL_CHOLESKY);
63 STRENUM(DENSE_QR);
64 STRENUM(SPARSE_NORMAL_CHOLESKY);
65 STRENUM(DENSE_SCHUR);
66 STRENUM(SPARSE_SCHUR);
67 STRENUM(ITERATIVE_SCHUR);
68 STRENUM(CGNR);
69 return false;
70 }
71
PreconditionerTypeToString(PreconditionerType type)72 const char* PreconditionerTypeToString(PreconditionerType type) {
73 switch (type) {
74 CASESTR(IDENTITY);
75 CASESTR(JACOBI);
76 CASESTR(SCHUR_JACOBI);
77 CASESTR(CLUSTER_JACOBI);
78 CASESTR(CLUSTER_TRIDIAGONAL);
79 default:
80 return "UNKNOWN";
81 }
82 }
83
StringToPreconditionerType(string value,PreconditionerType * type)84 bool StringToPreconditionerType(string value, PreconditionerType* type) {
85 UpperCase(&value);
86 STRENUM(IDENTITY);
87 STRENUM(JACOBI);
88 STRENUM(SCHUR_JACOBI);
89 STRENUM(CLUSTER_JACOBI);
90 STRENUM(CLUSTER_TRIDIAGONAL);
91 return false;
92 }
93
SparseLinearAlgebraLibraryTypeToString(SparseLinearAlgebraLibraryType type)94 const char* SparseLinearAlgebraLibraryTypeToString(
95 SparseLinearAlgebraLibraryType type) {
96 switch (type) {
97 CASESTR(SUITE_SPARSE);
98 CASESTR(CX_SPARSE);
99 default:
100 return "UNKNOWN";
101 }
102 }
103
StringToSparseLinearAlgebraLibraryType(string value,SparseLinearAlgebraLibraryType * type)104 bool StringToSparseLinearAlgebraLibraryType(
105 string value,
106 SparseLinearAlgebraLibraryType* type) {
107 UpperCase(&value);
108 STRENUM(SUITE_SPARSE);
109 STRENUM(CX_SPARSE);
110 return false;
111 }
112
DenseLinearAlgebraLibraryTypeToString(DenseLinearAlgebraLibraryType type)113 const char* DenseLinearAlgebraLibraryTypeToString(
114 DenseLinearAlgebraLibraryType type) {
115 switch (type) {
116 CASESTR(EIGEN);
117 CASESTR(LAPACK);
118 default:
119 return "UNKNOWN";
120 }
121 }
122
StringToDenseLinearAlgebraLibraryType(string value,DenseLinearAlgebraLibraryType * type)123 bool StringToDenseLinearAlgebraLibraryType(
124 string value,
125 DenseLinearAlgebraLibraryType* type) {
126 UpperCase(&value);
127 STRENUM(EIGEN);
128 STRENUM(LAPACK);
129 return false;
130 }
131
TrustRegionStrategyTypeToString(TrustRegionStrategyType type)132 const char* TrustRegionStrategyTypeToString(TrustRegionStrategyType type) {
133 switch (type) {
134 CASESTR(LEVENBERG_MARQUARDT);
135 CASESTR(DOGLEG);
136 default:
137 return "UNKNOWN";
138 }
139 }
140
StringToTrustRegionStrategyType(string value,TrustRegionStrategyType * type)141 bool StringToTrustRegionStrategyType(string value,
142 TrustRegionStrategyType* type) {
143 UpperCase(&value);
144 STRENUM(LEVENBERG_MARQUARDT);
145 STRENUM(DOGLEG);
146 return false;
147 }
148
DoglegTypeToString(DoglegType type)149 const char* DoglegTypeToString(DoglegType type) {
150 switch (type) {
151 CASESTR(TRADITIONAL_DOGLEG);
152 CASESTR(SUBSPACE_DOGLEG);
153 default:
154 return "UNKNOWN";
155 }
156 }
157
StringToDoglegType(string value,DoglegType * type)158 bool StringToDoglegType(string value, DoglegType* type) {
159 UpperCase(&value);
160 STRENUM(TRADITIONAL_DOGLEG);
161 STRENUM(SUBSPACE_DOGLEG);
162 return false;
163 }
164
MinimizerTypeToString(MinimizerType type)165 const char* MinimizerTypeToString(MinimizerType type) {
166 switch (type) {
167 CASESTR(TRUST_REGION);
168 CASESTR(LINE_SEARCH);
169 default:
170 return "UNKNOWN";
171 }
172 }
173
StringToMinimizerType(string value,MinimizerType * type)174 bool StringToMinimizerType(string value, MinimizerType* type) {
175 UpperCase(&value);
176 STRENUM(TRUST_REGION);
177 STRENUM(LINE_SEARCH);
178 return false;
179 }
180
LineSearchDirectionTypeToString(LineSearchDirectionType type)181 const char* LineSearchDirectionTypeToString(LineSearchDirectionType type) {
182 switch (type) {
183 CASESTR(STEEPEST_DESCENT);
184 CASESTR(NONLINEAR_CONJUGATE_GRADIENT);
185 CASESTR(LBFGS);
186 CASESTR(BFGS);
187 default:
188 return "UNKNOWN";
189 }
190 }
191
StringToLineSearchDirectionType(string value,LineSearchDirectionType * type)192 bool StringToLineSearchDirectionType(string value,
193 LineSearchDirectionType* type) {
194 UpperCase(&value);
195 STRENUM(STEEPEST_DESCENT);
196 STRENUM(NONLINEAR_CONJUGATE_GRADIENT);
197 STRENUM(LBFGS);
198 STRENUM(BFGS);
199 return false;
200 }
201
LineSearchTypeToString(LineSearchType type)202 const char* LineSearchTypeToString(LineSearchType type) {
203 switch (type) {
204 CASESTR(ARMIJO);
205 CASESTR(WOLFE);
206 default:
207 return "UNKNOWN";
208 }
209 }
210
StringToLineSearchType(string value,LineSearchType * type)211 bool StringToLineSearchType(string value, LineSearchType* type) {
212 UpperCase(&value);
213 STRENUM(ARMIJO);
214 STRENUM(WOLFE);
215 return false;
216 }
217
LineSearchInterpolationTypeToString(LineSearchInterpolationType type)218 const char* LineSearchInterpolationTypeToString(
219 LineSearchInterpolationType type) {
220 switch (type) {
221 CASESTR(BISECTION);
222 CASESTR(QUADRATIC);
223 CASESTR(CUBIC);
224 default:
225 return "UNKNOWN";
226 }
227 }
228
StringToLineSearchInterpolationType(string value,LineSearchInterpolationType * type)229 bool StringToLineSearchInterpolationType(
230 string value,
231 LineSearchInterpolationType* type) {
232 UpperCase(&value);
233 STRENUM(BISECTION);
234 STRENUM(QUADRATIC);
235 STRENUM(CUBIC);
236 return false;
237 }
238
NonlinearConjugateGradientTypeToString(NonlinearConjugateGradientType type)239 const char* NonlinearConjugateGradientTypeToString(
240 NonlinearConjugateGradientType type) {
241 switch (type) {
242 CASESTR(FLETCHER_REEVES);
243 CASESTR(POLAK_RIBIRERE);
244 CASESTR(HESTENES_STIEFEL);
245 default:
246 return "UNKNOWN";
247 }
248 }
249
StringToNonlinearConjugateGradientType(string value,NonlinearConjugateGradientType * type)250 bool StringToNonlinearConjugateGradientType(
251 string value,
252 NonlinearConjugateGradientType* type) {
253 UpperCase(&value);
254 STRENUM(FLETCHER_REEVES);
255 STRENUM(POLAK_RIBIRERE);
256 STRENUM(HESTENES_STIEFEL);
257 return false;
258 }
259
CovarianceAlgorithmTypeToString(CovarianceAlgorithmType type)260 const char* CovarianceAlgorithmTypeToString(
261 CovarianceAlgorithmType type) {
262 switch (type) {
263 CASESTR(DENSE_SVD);
264 CASESTR(SPARSE_CHOLESKY);
265 CASESTR(SPARSE_QR);
266 default:
267 return "UNKNOWN";
268 }
269 }
270
StringToCovarianceAlgorithmType(string value,CovarianceAlgorithmType * type)271 bool StringToCovarianceAlgorithmType(
272 string value,
273 CovarianceAlgorithmType* type) {
274 UpperCase(&value);
275 STRENUM(DENSE_SVD);
276 STRENUM(SPARSE_CHOLESKY);
277 STRENUM(SPARSE_QR);
278 return false;
279 }
280
SolverTerminationTypeToString(SolverTerminationType type)281 const char* SolverTerminationTypeToString(SolverTerminationType type) {
282 switch (type) {
283 CASESTR(NO_CONVERGENCE);
284 CASESTR(FUNCTION_TOLERANCE);
285 CASESTR(GRADIENT_TOLERANCE);
286 CASESTR(PARAMETER_TOLERANCE);
287 CASESTR(NUMERICAL_FAILURE);
288 CASESTR(USER_ABORT);
289 CASESTR(USER_SUCCESS);
290 CASESTR(DID_NOT_RUN);
291 default:
292 return "UNKNOWN";
293 }
294 }
295
LinearSolverTerminationTypeToString(LinearSolverTerminationType type)296 const char* LinearSolverTerminationTypeToString(
297 LinearSolverTerminationType type) {
298 switch (type) {
299 CASESTR(TOLERANCE);
300 CASESTR(MAX_ITERATIONS);
301 CASESTR(STAGNATION);
302 CASESTR(FAILURE);
303 default:
304 return "UNKNOWN";
305 }
306 }
307
308 #undef CASESTR
309 #undef STRENUM
310
IsSchurType(LinearSolverType type)311 bool IsSchurType(LinearSolverType type) {
312 return ((type == SPARSE_SCHUR) ||
313 (type == DENSE_SCHUR) ||
314 (type == ITERATIVE_SCHUR));
315 }
316
IsSparseLinearAlgebraLibraryTypeAvailable(SparseLinearAlgebraLibraryType type)317 bool IsSparseLinearAlgebraLibraryTypeAvailable(
318 SparseLinearAlgebraLibraryType type) {
319 if (type == SUITE_SPARSE) {
320 #ifdef CERES_NO_SUITESPARSE
321 return false;
322 #else
323 return true;
324 #endif
325 }
326
327 if (type == CX_SPARSE) {
328 #ifdef CERES_NO_CXSPARSE
329 return false;
330 #else
331 return true;
332 #endif
333 }
334
335 LOG(WARNING) << "Unknown sparse linear algebra library " << type;
336 return false;
337 }
338
IsDenseLinearAlgebraLibraryTypeAvailable(DenseLinearAlgebraLibraryType type)339 bool IsDenseLinearAlgebraLibraryTypeAvailable(
340 DenseLinearAlgebraLibraryType type) {
341 if (type == EIGEN) {
342 return true;
343 }
344 if (type == LAPACK) {
345 #ifdef CERES_NO_LAPACK
346 return false;
347 #else
348 return true;
349 #endif
350 }
351
352 LOG(WARNING) << "Unknown dense linear algebra library " << type;
353 return false;
354 }
355
356 } // namespace ceres
357