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 (at) 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 42 static void UpperCase(string* input) { 43 std::transform(input->begin(), input->end(), input->begin(), ::toupper); 44 } 45 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 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 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 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 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 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 113 const char* DenseLinearAlgebraLibraryTypeToString( 114 DenseLinearAlgebraLibraryType type) { 115 switch (type) { 116 CASESTR(EIGEN); 117 CASESTR(LAPACK); 118 default: 119 return "UNKNOWN"; 120 } 121 } 122 123 bool StringToDenseLinearAlgebraLibraryType( 124 string value, 125 DenseLinearAlgebraLibraryType* type) { 126 UpperCase(&value); 127 STRENUM(EIGEN); 128 STRENUM(LAPACK); 129 return false; 130 } 131 132 const char* TrustRegionStrategyTypeToString(TrustRegionStrategyType type) { 133 switch (type) { 134 CASESTR(LEVENBERG_MARQUARDT); 135 CASESTR(DOGLEG); 136 default: 137 return "UNKNOWN"; 138 } 139 } 140 141 bool StringToTrustRegionStrategyType(string value, 142 TrustRegionStrategyType* type) { 143 UpperCase(&value); 144 STRENUM(LEVENBERG_MARQUARDT); 145 STRENUM(DOGLEG); 146 return false; 147 } 148 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 158 bool StringToDoglegType(string value, DoglegType* type) { 159 UpperCase(&value); 160 STRENUM(TRADITIONAL_DOGLEG); 161 STRENUM(SUBSPACE_DOGLEG); 162 return false; 163 } 164 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 174 bool StringToMinimizerType(string value, MinimizerType* type) { 175 UpperCase(&value); 176 STRENUM(TRUST_REGION); 177 STRENUM(LINE_SEARCH); 178 return false; 179 } 180 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 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 202 const char* LineSearchTypeToString(LineSearchType type) { 203 switch (type) { 204 CASESTR(ARMIJO); 205 CASESTR(WOLFE); 206 default: 207 return "UNKNOWN"; 208 } 209 } 210 211 bool StringToLineSearchType(string value, LineSearchType* type) { 212 UpperCase(&value); 213 STRENUM(ARMIJO); 214 STRENUM(WOLFE); 215 return false; 216 } 217 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 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 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 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 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 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 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 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 311 bool IsSchurType(LinearSolverType type) { 312 return ((type == SPARSE_SCHUR) || 313 (type == DENSE_SCHUR) || 314 (type == ITERATIVE_SCHUR)); 315 } 316 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 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