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