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 CASESTR(EIGEN_SPARSE);
100 default:
101 return "UNKNOWN";
102 }
103 }
104
StringToSparseLinearAlgebraLibraryType(string value,SparseLinearAlgebraLibraryType * type)105 bool StringToSparseLinearAlgebraLibraryType(
106 string value,
107 SparseLinearAlgebraLibraryType* type) {
108 UpperCase(&value);
109 STRENUM(SUITE_SPARSE);
110 STRENUM(CX_SPARSE);
111 STRENUM(EIGEN_SPARSE);
112 return false;
113 }
114
DenseLinearAlgebraLibraryTypeToString(DenseLinearAlgebraLibraryType type)115 const char* DenseLinearAlgebraLibraryTypeToString(
116 DenseLinearAlgebraLibraryType type) {
117 switch (type) {
118 CASESTR(EIGEN);
119 CASESTR(LAPACK);
120 default:
121 return "UNKNOWN";
122 }
123 }
124
StringToDenseLinearAlgebraLibraryType(string value,DenseLinearAlgebraLibraryType * type)125 bool StringToDenseLinearAlgebraLibraryType(
126 string value,
127 DenseLinearAlgebraLibraryType* type) {
128 UpperCase(&value);
129 STRENUM(EIGEN);
130 STRENUM(LAPACK);
131 return false;
132 }
133
TrustRegionStrategyTypeToString(TrustRegionStrategyType type)134 const char* TrustRegionStrategyTypeToString(TrustRegionStrategyType type) {
135 switch (type) {
136 CASESTR(LEVENBERG_MARQUARDT);
137 CASESTR(DOGLEG);
138 default:
139 return "UNKNOWN";
140 }
141 }
142
StringToTrustRegionStrategyType(string value,TrustRegionStrategyType * type)143 bool StringToTrustRegionStrategyType(string value,
144 TrustRegionStrategyType* type) {
145 UpperCase(&value);
146 STRENUM(LEVENBERG_MARQUARDT);
147 STRENUM(DOGLEG);
148 return false;
149 }
150
DoglegTypeToString(DoglegType type)151 const char* DoglegTypeToString(DoglegType type) {
152 switch (type) {
153 CASESTR(TRADITIONAL_DOGLEG);
154 CASESTR(SUBSPACE_DOGLEG);
155 default:
156 return "UNKNOWN";
157 }
158 }
159
StringToDoglegType(string value,DoglegType * type)160 bool StringToDoglegType(string value, DoglegType* type) {
161 UpperCase(&value);
162 STRENUM(TRADITIONAL_DOGLEG);
163 STRENUM(SUBSPACE_DOGLEG);
164 return false;
165 }
166
MinimizerTypeToString(MinimizerType type)167 const char* MinimizerTypeToString(MinimizerType type) {
168 switch (type) {
169 CASESTR(TRUST_REGION);
170 CASESTR(LINE_SEARCH);
171 default:
172 return "UNKNOWN";
173 }
174 }
175
StringToMinimizerType(string value,MinimizerType * type)176 bool StringToMinimizerType(string value, MinimizerType* type) {
177 UpperCase(&value);
178 STRENUM(TRUST_REGION);
179 STRENUM(LINE_SEARCH);
180 return false;
181 }
182
LineSearchDirectionTypeToString(LineSearchDirectionType type)183 const char* LineSearchDirectionTypeToString(LineSearchDirectionType type) {
184 switch (type) {
185 CASESTR(STEEPEST_DESCENT);
186 CASESTR(NONLINEAR_CONJUGATE_GRADIENT);
187 CASESTR(LBFGS);
188 CASESTR(BFGS);
189 default:
190 return "UNKNOWN";
191 }
192 }
193
StringToLineSearchDirectionType(string value,LineSearchDirectionType * type)194 bool StringToLineSearchDirectionType(string value,
195 LineSearchDirectionType* type) {
196 UpperCase(&value);
197 STRENUM(STEEPEST_DESCENT);
198 STRENUM(NONLINEAR_CONJUGATE_GRADIENT);
199 STRENUM(LBFGS);
200 STRENUM(BFGS);
201 return false;
202 }
203
LineSearchTypeToString(LineSearchType type)204 const char* LineSearchTypeToString(LineSearchType type) {
205 switch (type) {
206 CASESTR(ARMIJO);
207 CASESTR(WOLFE);
208 default:
209 return "UNKNOWN";
210 }
211 }
212
StringToLineSearchType(string value,LineSearchType * type)213 bool StringToLineSearchType(string value, LineSearchType* type) {
214 UpperCase(&value);
215 STRENUM(ARMIJO);
216 STRENUM(WOLFE);
217 return false;
218 }
219
LineSearchInterpolationTypeToString(LineSearchInterpolationType type)220 const char* LineSearchInterpolationTypeToString(
221 LineSearchInterpolationType type) {
222 switch (type) {
223 CASESTR(BISECTION);
224 CASESTR(QUADRATIC);
225 CASESTR(CUBIC);
226 default:
227 return "UNKNOWN";
228 }
229 }
230
StringToLineSearchInterpolationType(string value,LineSearchInterpolationType * type)231 bool StringToLineSearchInterpolationType(
232 string value,
233 LineSearchInterpolationType* type) {
234 UpperCase(&value);
235 STRENUM(BISECTION);
236 STRENUM(QUADRATIC);
237 STRENUM(CUBIC);
238 return false;
239 }
240
NonlinearConjugateGradientTypeToString(NonlinearConjugateGradientType type)241 const char* NonlinearConjugateGradientTypeToString(
242 NonlinearConjugateGradientType type) {
243 switch (type) {
244 CASESTR(FLETCHER_REEVES);
245 CASESTR(POLAK_RIBIERE);
246 CASESTR(HESTENES_STIEFEL);
247 default:
248 return "UNKNOWN";
249 }
250 }
251
StringToNonlinearConjugateGradientType(string value,NonlinearConjugateGradientType * type)252 bool StringToNonlinearConjugateGradientType(
253 string value,
254 NonlinearConjugateGradientType* type) {
255 UpperCase(&value);
256 STRENUM(FLETCHER_REEVES);
257 STRENUM(POLAK_RIBIERE);
258 STRENUM(HESTENES_STIEFEL);
259 return false;
260 }
261
CovarianceAlgorithmTypeToString(CovarianceAlgorithmType type)262 const char* CovarianceAlgorithmTypeToString(
263 CovarianceAlgorithmType type) {
264 switch (type) {
265 CASESTR(DENSE_SVD);
266 CASESTR(EIGEN_SPARSE_QR);
267 CASESTR(SUITE_SPARSE_QR);
268 default:
269 return "UNKNOWN";
270 }
271 }
272
StringToCovarianceAlgorithmType(string value,CovarianceAlgorithmType * type)273 bool StringToCovarianceAlgorithmType(
274 string value,
275 CovarianceAlgorithmType* type) {
276 UpperCase(&value);
277 STRENUM(DENSE_SVD);
278 STRENUM(EIGEN_SPARSE_QR);
279 STRENUM(SUITE_SPARSE_QR);
280 return false;
281 }
282
VisibilityClusteringTypeToString(VisibilityClusteringType type)283 const char* VisibilityClusteringTypeToString(
284 VisibilityClusteringType type) {
285 switch (type) {
286 CASESTR(CANONICAL_VIEWS);
287 CASESTR(SINGLE_LINKAGE);
288 default:
289 return "UNKNOWN";
290 }
291 }
292
StringToVisibilityClusteringType(string value,VisibilityClusteringType * type)293 bool StringToVisibilityClusteringType(
294 string value,
295 VisibilityClusteringType* type) {
296 UpperCase(&value);
297 STRENUM(CANONICAL_VIEWS);
298 STRENUM(SINGLE_LINKAGE);
299 return false;
300 }
301
TerminationTypeToString(TerminationType type)302 const char* TerminationTypeToString(TerminationType type) {
303 switch (type) {
304 CASESTR(CONVERGENCE);
305 CASESTR(NO_CONVERGENCE);
306 CASESTR(FAILURE);
307 CASESTR(USER_SUCCESS);
308 CASESTR(USER_FAILURE);
309 default:
310 return "UNKNOWN";
311 }
312 }
313
314 #undef CASESTR
315 #undef STRENUM
316
IsSchurType(LinearSolverType type)317 bool IsSchurType(LinearSolverType type) {
318 return ((type == SPARSE_SCHUR) ||
319 (type == DENSE_SCHUR) ||
320 (type == ITERATIVE_SCHUR));
321 }
322
IsSparseLinearAlgebraLibraryTypeAvailable(SparseLinearAlgebraLibraryType type)323 bool IsSparseLinearAlgebraLibraryTypeAvailable(
324 SparseLinearAlgebraLibraryType type) {
325 if (type == SUITE_SPARSE) {
326 #ifdef CERES_NO_SUITESPARSE
327 return false;
328 #else
329 return true;
330 #endif
331 }
332
333 if (type == CX_SPARSE) {
334 #ifdef CERES_NO_CXSPARSE
335 return false;
336 #else
337 return true;
338 #endif
339 }
340
341 LOG(WARNING) << "Unknown sparse linear algebra library " << type;
342 return false;
343 }
344
IsDenseLinearAlgebraLibraryTypeAvailable(DenseLinearAlgebraLibraryType type)345 bool IsDenseLinearAlgebraLibraryTypeAvailable(
346 DenseLinearAlgebraLibraryType type) {
347 if (type == EIGEN) {
348 return true;
349 }
350 if (type == LAPACK) {
351 #ifdef CERES_NO_LAPACK
352 return false;
353 #else
354 return true;
355 #endif
356 }
357
358 LOG(WARNING) << "Unknown dense linear algebra library " << type;
359 return false;
360 }
361
362 } // namespace ceres
363