diff options
Diffstat (limited to 'internal/ceres/lapack.cc')
-rw-r--r-- | internal/ceres/lapack.cc | 76 |
1 files changed, 56 insertions, 20 deletions
diff --git a/internal/ceres/lapack.cc b/internal/ceres/lapack.cc index 73bfa69..e124d75 100644 --- a/internal/ceres/lapack.cc +++ b/internal/ceres/lapack.cc @@ -29,6 +29,9 @@ // Author: sameeragarwal@google.com (Sameer Agarwal) #include "ceres/lapack.h" + +#include "ceres/internal/port.h" +#include "ceres/linear_solver.h" #include "glog/logging.h" // C interface to the LAPACK Cholesky factorization and triangular solve. @@ -63,12 +66,14 @@ extern "C" void dgels_(char* uplo, namespace ceres { namespace internal { -int LAPACK::SolveInPlaceUsingCholesky(int num_rows, - const double* in_lhs, - double* rhs_and_solution) { +LinearSolverTerminationType LAPACK::SolveInPlaceUsingCholesky( + int num_rows, + const double* in_lhs, + double* rhs_and_solution, + string* message) { #ifdef CERES_NO_LAPACK LOG(FATAL) << "Ceres was built without a BLAS library."; - return -1; + return LINEAR_SOLVER_FATAL_ERROR; #else char uplo = 'L'; int n = num_rows; @@ -77,17 +82,33 @@ int LAPACK::SolveInPlaceUsingCholesky(int num_rows, double* lhs = const_cast<double*>(in_lhs); dpotrf_(&uplo, &n, lhs, &n, &info); - if (info != 0) { - LOG(INFO) << "Cholesky factorization (dpotrf) failed: " << info; - return info; + if (info < 0) { + LOG(FATAL) << "Congratulations, you found a bug in Ceres." + << "Please report it." + << "LAPACK::dpotrf fatal error." + << "Argument: " << -info << " is invalid."; + return LINEAR_SOLVER_FATAL_ERROR; + } + + if (info > 0) { + *message = + StringPrintf( + "LAPACK::dpotrf numerical failure. " + "The leading minor of order %d is not positive definite.", info); + return LINEAR_SOLVER_FAILURE; } dpotrs_(&uplo, &n, &nrhs, lhs, &n, rhs_and_solution, &n, &info); - if (info != 0) { - LOG(INFO) << "Triangular solve (dpotrs) failed: " << info; + if (info < 0) { + LOG(FATAL) << "Congratulations, you found a bug in Ceres." + << "Please report it." + << "LAPACK::dpotrs fatal error." + << "Argument: " << -info << " is invalid."; + return LINEAR_SOLVER_FATAL_ERROR; } - return info; + *message = "Success"; + return LINEAR_SOLVER_SUCCESS; #endif }; @@ -113,20 +134,27 @@ int LAPACK::EstimateWorkSizeForQR(int num_rows, int num_cols) { &lwork, &info); - CHECK_EQ(info, 0); - return work; + if (info < 0) { + LOG(FATAL) << "Congratulations, you found a bug in Ceres." + << "Please report it." + << "LAPACK::dgels fatal error." + << "Argument: " << -info << " is invalid."; + } + return static_cast<int>(work); #endif } -int LAPACK::SolveUsingQR(int num_rows, - int num_cols, - const double* in_lhs, - int work_size, - double* work, - double* rhs_and_solution) { +LinearSolverTerminationType LAPACK::SolveInPlaceUsingQR( + int num_rows, + int num_cols, + const double* in_lhs, + int work_size, + double* work, + double* rhs_and_solution, + string* message) { #ifdef CERES_NO_LAPACK LOG(FATAL) << "Ceres was built without a LAPACK library."; - return -1; + return LINEAR_SOLVER_FATAL_ERROR; #else char trans = 'N'; int m = num_rows; @@ -149,7 +177,15 @@ int LAPACK::SolveUsingQR(int num_rows, &work_size, &info); - return info; + if (info < 0) { + LOG(FATAL) << "Congratulations, you found a bug in Ceres." + << "Please report it." + << "LAPACK::dgels fatal error." + << "Argument: " << -info << " is invalid."; + } + + *message = "Success."; + return LINEAR_SOLVER_SUCCESS; #endif } |