aboutsummaryrefslogtreecommitdiff
path: root/internal/ceres/lapack.cc
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ceres/lapack.cc')
-rw-r--r--internal/ceres/lapack.cc76
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
}