Better crash error messages.

When a user requests an operation on a parameter block which has
not been added to the problem, we now display a more helpful
error message with more context.

Change-Id: Ia7e54815111eb6375b31ed0d1cddca5917138ae1
diff --git a/internal/ceres/problem_impl.cc b/internal/ceres/problem_impl.cc
index ee1e32e..1c76ea6 100644
--- a/internal/ceres/problem_impl.cc
+++ b/internal/ceres/problem_impl.cc
@@ -61,15 +61,6 @@
 typedef std::map<double*, internal::ParameterBlock*> ParameterMap;
 
 namespace {
-internal::ParameterBlock* FindParameterBlockOrDie(
-    const ParameterMap& parameter_map,
-    double* parameter_block) {
-  ParameterMap::const_iterator it = parameter_map.find(parameter_block);
-  CHECK(it != parameter_map.end())
-      << "Parameter block not found: " << parameter_block;
-  return it->second;
-}
-
 // Returns true if two regions of memory, a and b, with sizes size_a and size_b
 // respectively, overlap.
 bool RegionsAlias(const double* a, int size_a,
@@ -533,7 +524,12 @@
 
 void ProblemImpl::RemoveParameterBlock(double* values) {
   ParameterBlock* parameter_block =
-      FindParameterBlockOrDie(parameter_block_map_, values);
+      FindWithDefault(parameter_block_map_, values, NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "it can be removed.";
+  }
 
   if (options_.enable_fast_removal) {
     // Copy the dependent residuals from the parameter block because the set of
@@ -565,38 +561,81 @@
 }
 
 void ProblemImpl::SetParameterBlockConstant(double* values) {
-  FindParameterBlockOrDie(parameter_block_map_, values)->SetConstant();
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, values, NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "it can be set constant.";
+  }
+
+  parameter_block->SetConstant();
 }
 
 void ProblemImpl::SetParameterBlockVariable(double* values) {
-  FindParameterBlockOrDie(parameter_block_map_, values)->SetVarying();
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, values, NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "it can be set varying.";
+  }
+
+  parameter_block->SetVarying();
 }
 
 void ProblemImpl::SetParameterization(
     double* values,
     LocalParameterization* local_parameterization) {
-  FindParameterBlockOrDie(parameter_block_map_, values)
-      ->SetParameterization(local_parameterization);
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, values, NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "you can set its local parameterization.";
+  }
+
+  parameter_block->SetParameterization(local_parameterization);
 }
 
 const LocalParameterization* ProblemImpl::GetParameterization(
     double* values) const {
-  return FindParameterBlockOrDie(parameter_block_map_, values)
-      ->local_parameterization();
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, values, NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "you can get its local parameterization.";
+  }
+
+  return parameter_block->local_parameterization();
 }
 
 void ProblemImpl::SetParameterLowerBound(double* values,
                                          int index,
                                          double lower_bound) {
-  FindParameterBlockOrDie(parameter_block_map_, values)
-      ->SetLowerBound(index, lower_bound);
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, values, NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "you can set a lower bound on one of its components.";
+  }
+
+  parameter_block->SetLowerBound(index, lower_bound);
 }
 
 void ProblemImpl::SetParameterUpperBound(double* values,
                                          int index,
                                          double upper_bound) {
-  FindParameterBlockOrDie(parameter_block_map_, values)
-      ->SetUpperBound(index, upper_bound);
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, values, NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "you can set an upper bound on one of its components.";
+  }
+  parameter_block->SetUpperBound(index, upper_bound);
 }
 
 bool ProblemImpl::Evaluate(const Problem::EvaluateOptions& evaluate_options,
@@ -638,9 +677,14 @@
     // 1. Convert double* into ParameterBlock*
     parameter_blocks.resize(parameter_block_ptrs.size());
     for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
-      parameter_blocks[i] =
-          FindParameterBlockOrDie(parameter_block_map_,
-                                  parameter_block_ptrs[i]);
+      parameter_blocks[i] = FindWithDefault(parameter_block_map_,
+                                            parameter_block_ptrs[i],
+                                            NULL);
+      if (parameter_blocks[i] == NULL) {
+        LOG(FATAL) << "No known parameter block for "
+                   << "Problem::Evaluate::Options.parameter_blocks[" << i << "]"
+                   << " = " << parameter_block_ptrs[i];
+      }
     }
 
     // 2. The user may have only supplied a subset of parameter
@@ -784,14 +828,28 @@
   return program_->NumResiduals();
 }
 
-int ProblemImpl::ParameterBlockSize(const double* parameter_block) const {
-  return FindParameterBlockOrDie(parameter_block_map_,
-                                 const_cast<double*>(parameter_block))->Size();
+int ProblemImpl::ParameterBlockSize(const double* values) const {
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, const_cast<double*>(values), NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "you can get its size.";
+  }
+
+  return parameter_block->Size();
 }
 
-int ProblemImpl::ParameterBlockLocalSize(const double* parameter_block) const {
-  return FindParameterBlockOrDie(
-      parameter_block_map_, const_cast<double*>(parameter_block))->LocalSize();
+int ProblemImpl::ParameterBlockLocalSize(const double* values) const {
+  ParameterBlock* parameter_block =
+      FindWithDefault(parameter_block_map_, const_cast<double*>(values), NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "you can get its local size.";
+  }
+
+  return parameter_block->LocalSize();
 }
 
 bool ProblemImpl::HasParameterBlock(const double* parameter_block) const {
@@ -840,8 +898,12 @@
     const double* values,
     vector<ResidualBlockId>* residual_blocks) const {
   ParameterBlock* parameter_block =
-      FindParameterBlockOrDie(parameter_block_map_,
-                              const_cast<double*>(values));
+      FindWithDefault(parameter_block_map_, const_cast<double*>(values), NULL);
+  if (parameter_block == NULL) {
+    LOG(FATAL) << "Parameter block not found: " << values
+               << ". You must add the parameter block to the problem before "
+               << "you can get the residual blocks that depend on it.";
+  }
 
   if (options_.enable_fast_removal) {
     // In this case the residual blocks that depend on the parameter block are