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 CASESTR(EIGEN_SPARSE); 100 default: 101 return "UNKNOWN"; 102 } 103 } 104 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 115 const char* DenseLinearAlgebraLibraryTypeToString( 116 DenseLinearAlgebraLibraryType type) { 117 switch (type) { 118 CASESTR(EIGEN); 119 CASESTR(LAPACK); 120 default: 121 return "UNKNOWN"; 122 } 123 } 124 125 bool StringToDenseLinearAlgebraLibraryType( 126 string value, 127 DenseLinearAlgebraLibraryType* type) { 128 UpperCase(&value); 129 STRENUM(EIGEN); 130 STRENUM(LAPACK); 131 return false; 132 } 133 134 const char* TrustRegionStrategyTypeToString(TrustRegionStrategyType type) { 135 switch (type) { 136 CASESTR(LEVENBERG_MARQUARDT); 137 CASESTR(DOGLEG); 138 default: 139 return "UNKNOWN"; 140 } 141 } 142 143 bool StringToTrustRegionStrategyType(string value, 144 TrustRegionStrategyType* type) { 145 UpperCase(&value); 146 STRENUM(LEVENBERG_MARQUARDT); 147 STRENUM(DOGLEG); 148 return false; 149 } 150 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 160 bool StringToDoglegType(string value, DoglegType* type) { 161 UpperCase(&value); 162 STRENUM(TRADITIONAL_DOGLEG); 163 STRENUM(SUBSPACE_DOGLEG); 164 return false; 165 } 166 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 176 bool StringToMinimizerType(string value, MinimizerType* type) { 177 UpperCase(&value); 178 STRENUM(TRUST_REGION); 179 STRENUM(LINE_SEARCH); 180 return false; 181 } 182 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 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 204 const char* LineSearchTypeToString(LineSearchType type) { 205 switch (type) { 206 CASESTR(ARMIJO); 207 CASESTR(WOLFE); 208 default: 209 return "UNKNOWN"; 210 } 211 } 212 213 bool StringToLineSearchType(string value, LineSearchType* type) { 214 UpperCase(&value); 215 STRENUM(ARMIJO); 216 STRENUM(WOLFE); 217 return false; 218 } 219 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 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 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 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 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 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 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 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 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 317 bool IsSchurType(LinearSolverType type) { 318 return ((type == SPARSE_SCHUR) || 319 (type == DENSE_SCHUR) || 320 (type == ITERATIVE_SCHUR)); 321 } 322 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 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